요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
============================================================
rotary-encoder - a generic driver for GPIO connected devices
============================================================
:Author: Daniel Mack <[email protected]>, Feb 2009
Function
--------
Rotary encoders are devices which are connected to the CPU or other
peripherals with two wires. The outputs are phase-shifted by 90 degrees
and by triggering on falling and rising edges, the turn direction can
be determined.
Some encoders have both outputs low in stable states, others also have
a stable state with both outputs high (half-period mode) and some have
a stable state in all steps (quarter-period mode).
The phase diagram of these two outputs look like this::
_____ _____ _____
| | | | | |
Channel A ____| |_____| |_____| |____
: : : : : : : : : : : :
__ _____ _____ _____
| | | | | | |
Channel B |_____| |_____| |_____| |__
: : : : : : : : : : : :
Event a b c d a b c d a b c d
|<-------->|
one step
|<-->|
one step (half-period mode)
|<>|
one step (quarter-period mode)
For more information, please see
https://en.wikipedia.org/wiki/Rotary_encoder
Events / state machine
----------------------
In half-period mode, state a) and c) above are used to determine the
rotational direction based on the last stable state. Events are reported in
states b) and d) given that the new stable state is different from the last
(i.e. the rotation was not reversed half-way).
Otherwise, the following apply:
a) Rising edge on channel A, channel B in low state
This state is used to recognize a clockwise turn
b) Rising edge on channel B, channel A in high state
When entering this state, the encoder is put into 'armed' state,
meaning that there it has seen half the way of a one-step transition.
c) Falling edge on channel A, channel B in high state
This state is used to recognize a counter-clockwise turn
d) Falling edge on channel B, channel A in low state
Parking position. If the encoder enters this state, a full transition
should have happened, unless it flipped back on half the way. The
'armed' state tells us about that.
Platform requirements
---------------------
As there is no hardware dependent call in this driver, the platform it is
used with must support gpiolib. Another requirement is that IRQs must be
able to fire on both edges.
Board integration
-----------------
To use this driver in your system, register a platform_device with the
name 'rotary-encoder' and associate the IRQs and some specific platform
data with it. Because the driver uses generic device properties, this can
be done either via device tree, ACPI, or using static board files, like in
example below:
::
/* board support file example */
#include <linux/input.h>
#include <linux/gpio/machine.h>
#include <linux/property.h>
#define GPIO_ROTARY_A 1
#define GPIO_ROTARY_B 2
static struct gpiod_lookup_table rotary_encoder_gpios = {
.dev_id = "rotary-encoder.0",
.table = {
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_A, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_B, NULL, 1, GPIO_ACTIVE_HIGH),
{ },
},
};
static const struct property_entry rotary_encoder_properties[] = {
PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24),
PROPERTY_ENTRY_U32("linux,axis", ABS_X),
PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 0),
{ },
};
static const struct software_node rotary_encoder_node = {
.properties = rotary_encoder_properties,
};
static struct platform_device rotary_encoder_device = {
.name = "rotary-encoder",
.id = 0,
};
...
gpiod_add_lookup_table(&rotary_encoder_gpios);
device_add_software_node(&rotary_encoder_device.dev, &rotary_encoder_node);
platform_device_register(&rotary_encoder_device);
...
Please consult device tree binding documentation to see all properties
supported by the driver.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
2채널 90도 위상과 스텝 모드
1-45`rotary-encoder`는 GPIO에 연결된 회전식 엔코더용 범용 드라이버입니다. 엔코더의 두 출력은 90도 위상차를 가지며, 각 채널의 상승·하강 에지 순서를 관찰해 회전 방향을 판단합니다.
엔코더에 따라 안정 상태의 수가 다릅니다. 기본형은 두 출력이 모두 낮은 상태를 안정점으로 쓰고, half-period 모드는 둘 다 낮거나 둘 다 높은 상태를 안정점으로 사용합니다. quarter-period 모드는 네 상태 모두를 각 스텝의 안정점으로 취급합니다.
원문의 Channel A/B 파형에서 a~d 한 주기를 논리 상태로 다시 그렸습니다.
파형에서 한 기계적 스텝으로 묶는 상태 간격입니다.
두 GPIO의 에지 순서가 회전 이벤트가 되는 흐름입니다.
추가 원리는 원문에 연결된 Wikipedia `Rotary encoder` 문서를 참조할 수 있습니다. 드라이버 동작에서는 파형 자체보다 에지가 발생한 채널과 반대 채널의 현재 상태 조합이 중요합니다.
============================================================
rotary-encoder - a generic driver for GPIO connected devices
============================================================
:Author: Daniel Mack <[email protected]>, Feb 2009
Function
--------
Rotary encoders are devices which are connected to the CPU or other
peripherals with two wires. The outputs are phase-shifted by 90 degrees
and by triggering on falling and rising edges, the turn direction can
be determined.
Some encoders have both outputs low in stable states, others also have
a stable state with both outputs high (half-period mode) and some have
a stable state in all steps (quarter-period mode).
The phase diagram of these two outputs look like this::
_____ _____ _____
| | | | | |
Channel A ____| |_____| |_____| |____
: : : : : : : : : : : :
__ _____ _____ _____
| | | | | | |
Channel B |_____| |_____| |_____| |__
: : : : : : : : : : : :
Event a b c d a b c d a b c d
|<-------->|
one step
|<-->|
one step (half-period mode)
|<>|
one step (quarter-period mode)
For more information, please see
https://en.wikipedia.org/wiki/Rotary_encoder
방향 판별과 armed 상태 머신
46-70Half-period 모드에서는 위상도의 a와 c를 안정 상태로 사용해 마지막 안정 상태와 새 안정 상태를 비교합니다. 새 안정 상태가 이전과 다를 때 b 또는 d에서 이벤트를 보고하며, 중간에서 방향을 되돌린 경우에는 스텝으로 계산하지 않습니다.
각 에지, 반대 채널 상태와 드라이버의 의미입니다.
b에서 설정되는 `armed`는 한 스텝 전이의 절반을 지났음을 기록합니다. d에 도착하면 보통 전체 전이가 끝났지만 중간에 되돌아왔을 수도 있으므로, `armed` 상태가 유효한 완전한 전이인지 구분합니다.
중간 반전을 잘못된 회전 이벤트로 보고하지 않는 절차입니다.
Events / state machine
----------------------
In half-period mode, state a) and c) above are used to determine the
rotational direction based on the last stable state. Events are reported in
states b) and d) given that the new stable state is different from the last
(i.e. the rotation was not reversed half-way).
Otherwise, the following apply:
a) Rising edge on channel A, channel B in low state
This state is used to recognize a clockwise turn
b) Rising edge on channel B, channel A in high state
When entering this state, the encoder is put into 'armed' state,
meaning that there it has seen half the way of a one-step transition.
c) Falling edge on channel A, channel B in high state
This state is used to recognize a counter-clockwise turn
d) Falling edge on channel B, channel A in low state
Parking position. If the encoder enters this state, a full transition
should have happened, unless it flipped back on half the way. The
'armed' state tells us about that.
플랫폼 요구사항과 장치 등록 방식
71-87드라이버에는 하드웨어 종속 호출이 없으므로 사용하는 플랫폼이 `gpiolib`을 지원해야 합니다. 또한 두 GPIO의 IRQ가 상승 에지와 하강 에지 모두에서 발생할 수 있어야 네 위상 상태를 빠짐없이 추적할 수 있습니다.
시스템에 통합하려면 이름이 `rotary-encoder`인 `platform_device`를 등록하고 IRQ와 장치별 속성을 연결합니다. 드라이버가 범용 device property를 사용하므로 Device Tree, ACPI, 정적 board file 중 어느 방식으로든 기술할 수 있습니다.
드라이버가 하드웨어 계층에 요구하는 기능입니다.
플랫폼 펌웨어 방식과 무관한 공통 등록 구조입니다.
Platform requirements
---------------------
As there is no hardware dependent call in this driver, the platform it is
used with must support gpiolib. Another requirement is that IRQs must be
able to fire on both edges.
Board integration
-----------------
To use this driver in your system, register a platform_device with the
name 'rotary-encoder' and associate the IRQs and some specific platform
data with it. Because the driver uses generic device properties, this can
be done either via device tree, ACPI, or using static board files, like in
example below:
정적 보드 파일의 GPIO·속성 등록 예제
88-135정적 board support file 예제는 `linux/input.h`, `linux/gpio/machine.h`, `linux/property.h`를 포함하고 GPIO 번호 1과 2를 `GPIO_ROTARY_A`, `GPIO_ROTARY_B`로 정의합니다.
두 GPIO lookup 항목의 controller, index와 active polarity입니다.
software node에 제공되는 세 속성입니다.
속성 배열은 `software_node`에 연결되고, platform device는 이름 `rotary-encoder`, ID 0으로 생성됩니다. 실제 등록 순서는 GPIO lookup table 추가, software node 연결, platform device 등록입니다.
예제의 세 API 호출이 구성 요소를 결합하는 흐름입니다.
드라이버가 지원하는 모든 속성은 Device Tree binding 문서를 참조해야 합니다. 예제 값은 정적 보드 파일에서 범용 property API를 사용하는 한 가지 구성일 뿐이며, 실제 엔코더의 분해능과 출력 극성에 맞춰야 합니다.
::
/* board support file example */
#include <linux/input.h>
#include <linux/gpio/machine.h>
#include <linux/property.h>
#define GPIO_ROTARY_A 1
#define GPIO_ROTARY_B 2
static struct gpiod_lookup_table rotary_encoder_gpios = {
.dev_id = "rotary-encoder.0",
.table = {
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_A, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_B, NULL, 1, GPIO_ACTIVE_HIGH),
{ },
},
};
static const struct property_entry rotary_encoder_properties[] = {
PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24),
PROPERTY_ENTRY_U32("linux,axis", ABS_X),
PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 0),
{ },
};
static const struct software_node rotary_encoder_node = {
.properties = rotary_encoder_properties,
};
static struct platform_device rotary_encoder_device = {
.name = "rotary-encoder",
.id = 0,
};
...
gpiod_add_lookup_table(&rotary_encoder_gpios);
device_add_software_node(&rotary_encoder_device.dev, &rotary_encoder_node);
platform_device_register(&rotary_encoder_device);
...
Please consult device tree binding documentation to see all properties
supported by the driver.
요약·해설
rotary-encoder.rst:1-135범용 회전식 엔코더 드라이버는 90도 위상차가 나는 두 GPIO의 에지 순서로 방향과 완전한 스텝을 판단합니다. full·half·quarter-period 모드의 안정점이 다르며, `armed` 상태로 중간 반전을 걸러냅니다.
상태 머신과 플랫폼 요구사항을 요약합니다.
GPIO 전이에서 input 이벤트까지의 공통 흐름입니다.