요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===============================
Creating an input device driver
===============================
The simplest example
~~~~~~~~~~~~~~~~~~~~
Here comes a very simple example of an input device driver. The device has
just one button and the button is accessible at i/o port BUTTON_PORT. When
pressed or released a BUTTON_IRQ happens. The driver could look like::
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/io.h>
static struct input_dev *button_dev;
static irqreturn_t button_interrupt(int irq, void *dummy)
{
input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1);
input_sync(button_dev);
return IRQ_HANDLED;
}
static int __init button_init(void)
{
int error;
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
return -EBUSY;
}
button_dev = input_allocate_device();
if (!button_dev) {
printk(KERN_ERR "button.c: Not enough memory\n");
error = -ENOMEM;
goto err_free_irq;
}
button_dev->evbit[0] = BIT_MASK(EV_KEY);
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
error = input_register_device(button_dev);
if (error) {
printk(KERN_ERR "button.c: Failed to register device\n");
goto err_free_dev;
}
return 0;
err_free_dev:
input_free_device(button_dev);
err_free_irq:
free_irq(BUTTON_IRQ, button_interrupt);
return error;
}
static void __exit button_exit(void)
{
input_unregister_device(button_dev);
free_irq(BUTTON_IRQ, button_interrupt);
}
module_init(button_init);
module_exit(button_exit);
What the example does
~~~~~~~~~~~~~~~~~~~~~
First it has to include the <linux/input.h> file, which interfaces to the
input subsystem. This provides all the definitions needed.
In the _init function, which is called either upon module load or when
booting the kernel, it grabs the required resources (it should also check
for the presence of the device).
Then it allocates a new input device structure with input_allocate_device()
and sets up input bitfields. This way the device driver tells the other
parts of the input systems what it is - what events can be generated or
accepted by this input device. Our example device can only generate EV_KEY
type events, and from those only BTN_0 event code. Thus we only set these
two bits. We could have used::
set_bit(EV_KEY, button_dev->evbit);
set_bit(BTN_0, button_dev->keybit);
as well, but with more than single bits the first approach tends to be
shorter.
Then the example driver registers the input device structure by calling::
input_register_device(button_dev);
This adds the button_dev structure to linked lists of the input driver and
calls device handler modules _connect functions to tell them a new input
device has appeared. input_register_device() may sleep and therefore must
not be called from an interrupt or with a spinlock held.
While in use, the only used function of the driver is::
button_interrupt()
which upon every interrupt from the button checks its state and reports it
via the::
input_report_key()
call to the input system. There is no need to check whether the interrupt
routine isn't reporting two same value events (press, press for example) to
the input system, because the input_report_* functions check that
themselves.
Then there is the::
input_sync()
call to tell those who receive the events that we've sent a complete report.
This doesn't seem important in the one button case, but is quite important
for example for mouse movement, where you don't want the X and Y values
to be interpreted separately, because that'd result in a different movement.
dev->open() and dev->close()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In case the driver has to repeatedly poll the device, because it doesn't
have an interrupt coming from it and the polling is too expensive to be done
all the time, or if the device uses a valuable resource (e.g. interrupt), it
can use the open and close callback to know when it can stop polling or
release the interrupt and when it must resume polling or grab the interrupt
again. To do that, we would add this to our example driver::
static int button_open(struct input_dev *dev)
{
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
return -EBUSY;
}
return 0;
}
static void button_close(struct input_dev *dev)
{
free_irq(IRQ_AMIGA_VERTB, button_interrupt);
}
static int __init button_init(void)
{
...
button_dev->open = button_open;
button_dev->close = button_close;
...
}
Note that input core keeps track of number of users for the device and
makes sure that dev->open() is called only when the first user connects
to the device and that dev->close() is called when the very last user
disconnects. Calls to both callbacks are serialized.
The open() callback should return a 0 in case of success or any non-zero value
in case of failure. The close() callback (which is void) must always succeed.
Inhibiting input devices
~~~~~~~~~~~~~~~~~~~~~~~~
Inhibiting a device means ignoring input events from it. As such it is about
maintaining relationships with input handlers - either already existing
relationships, or relationships to be established while the device is in
inhibited state.
If a device is inhibited, no input handler will receive events from it.
The fact that nobody wants events from the device is exploited further, by
calling device's close() (if there are users) and open() (if there are users) on
inhibit and uninhibit operations, respectively. Indeed, the meaning of close()
is to stop providing events to the input core and that of open() is to start
providing events to the input core.
Calling the device's close() method on inhibit (if there are users) allows the
driver to save power. Either by directly powering down the device or by
releasing the runtime-PM reference it got in open() when the driver is using
runtime-PM.
Inhibiting and uninhibiting are orthogonal to opening and closing the device by
input handlers. Userspace might want to inhibit a device in anticipation before
any handler is positively matched against it.
Inhibiting and uninhibiting are orthogonal to device's being a wakeup source,
too. Being a wakeup source plays a role when the system is sleeping, not when
the system is operating. How drivers should program their interaction between
inhibiting, sleeping and being a wakeup source is driver-specific.
Taking the analogy with the network devices - bringing a network interface down
doesn't mean that it should be impossible be wake the system up on LAN through
this interface. So, there may be input drivers which should be considered wakeup
sources even when inhibited. Actually, in many I2C input devices their interrupt
is declared a wakeup interrupt and its handling happens in driver's core, which
is not aware of input-specific inhibit (nor should it be). Composite devices
containing several interfaces can be inhibited on a per-interface basis and e.g.
inhibiting one interface shouldn't affect the device's capability of being a
wakeup source.
If a device is to be considered a wakeup source while inhibited, special care
must be taken when programming its suspend(), as it might need to call device's
open(). Depending on what close() means for the device in question, not
opening() it before going to sleep might make it impossible to provide any
wakeup events. The device is going to sleep anyway.
Basic event types
~~~~~~~~~~~~~~~~~
The most simple event type is EV_KEY, which is used for keys and buttons.
It's reported to the input system via::
input_report_key(struct input_dev *dev, int code, int value)
See uapi/linux/input-event-codes.h for the allowable values of code (from 0 to
KEY_MAX). Value is interpreted as a truth value, i.e. any non-zero value means
key pressed, zero value means key released. The input code generates events only
in case the value is different from before.
In addition to EV_KEY, there are two more basic event types: EV_REL and
EV_ABS. They are used for relative and absolute values supplied by the
device. A relative value may be for example a mouse movement in the X axis.
The mouse reports it as a relative difference from the last position,
because it doesn't have any absolute coordinate system to work in. Absolute
events are namely for joysticks and digitizers - devices that do work in an
absolute coordinate systems.
Having the device report EV_REL buttons is as simple as with EV_KEY; simply
set the corresponding bits and call the::
input_report_rel(struct input_dev *dev, int code, int value)
function. Events are generated only for non-zero values.
However EV_ABS requires a little special care. Before calling
input_register_device, you have to fill additional fields in the input_dev
struct for each absolute axis your device has. If our button device had also
the ABS_X axis::
button_dev.absmin[ABS_X] = 0;
button_dev.absmax[ABS_X] = 255;
button_dev.absfuzz[ABS_X] = 4;
button_dev.absflat[ABS_X] = 8;
Or, you can just say::
input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8);
This setting would be appropriate for a joystick X axis, with the minimum of
0, maximum of 255 (which the joystick *must* be able to reach, no problem if
it sometimes reports more, but it must be able to always reach the min and
max values), with noise in the data up to +- 4, and with a center flat
position of size 8.
If you don't need absfuzz and absflat, you can set them to zero, which mean
that the thing is precise and always returns to exactly the center position
(if it has any).
BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These three macros from bitops.h help some bitfield computations::
BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
x bits
BIT_WORD(x) - returns the index in the array in longs for bit x
BIT_MASK(x) - returns the index in a long for bit x
The id* and name fields
~~~~~~~~~~~~~~~~~~~~~~~
The dev->name should be set before registering the input device by the input
device driver. It's a string like 'Generic button device' containing a
user friendly name of the device.
The id* fields contain the bus ID (PCI, USB, ...), vendor ID and device ID
of the device. The bus IDs are defined in input.h. The vendor and device IDs
are defined in pci_ids.h, usb_ids.h and similar include files. These fields
should be set by the input device driver before registering it.
The idtype field can be used for specific information for the input device
driver.
The id and name fields can be passed to userland via the evdev interface.
The keycode, keycodemax, keycodesize fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These three fields should be used by input devices that have dense keymaps.
The keycode is an array used to map from scancodes to input system keycodes.
The keycode max should contain the size of the array and keycodesize the
size of each entry in it (in bytes).
Userspace can query and alter current scancode to keycode mappings using
EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface.
When a device has all 3 aforementioned fields filled in, the driver may
rely on kernel's default implementation of setting and querying keycode
mappings.
dev->getkeycode() and dev->setkeycode()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getkeycode() and setkeycode() callbacks allow drivers to override default
keycode/keycodesize/keycodemax mapping mechanism provided by input core
and implement sparse keycode maps.
Key autorepeat
~~~~~~~~~~~~~~
... is simple. It is handled by the input.c module. Hardware autorepeat is
not used, because it's not present in many devices and even where it is
present, it is broken sometimes (at keyboards: Toshiba notebooks). To enable
autorepeat for your device, just set EV_REP in dev->evbit. All will be
handled by the input system.
Other event types, handling output events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The other event types up to now are:
- EV_LED - used for the keyboard LEDs.
- EV_SND - used for keyboard beeps.
They are very similar to for example key events, but they go in the other
direction - from the system to the input device driver. If your input device
driver can handle these events, it has to set the respective bits in evbit,
*and* also the callback routine::
button_dev->event = button_event;
int button_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
if (type == EV_SND && code == SND_BELL) {
outb(value, BUTTON_BELL);
return 0;
}
return -1;
}
This callback routine can be called from an interrupt or a BH (although that
isn't a rule), and thus must not sleep, and must not take too long to finish.
Polled input devices
~~~~~~~~~~~~~~~~~~~~
Input polling is set up by passing an input device struct and a callback to
the function::
int input_setup_polling(struct input_dev *dev,
void (*poll_fn)(struct input_dev *dev))
Within the callback, devices should use the regular input_report_* functions
and input_sync as is used by other devices.
There is also the function::
void input_set_poll_interval(struct input_dev *dev, unsigned int interval)
which is used to configure the interval, in milliseconds, that the device will
be polled at.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
가장 단순한 input device driver
1-70예제 장치는 I/O port `BUTTON_PORT`에서 읽는 button 하나를 가지며 press 또는 release 때 `BUTTON_IRQ`가 발생합니다. Driver는 `<linux/input.h>`를 포함하고 전역 `struct input_dev *button_dev`를 유지합니다.
Interrupt handler `button_interrupt()`는 `inb(BUTTON_PORT) & 1`로 상태를 읽어 `input_report_key(button_dev, BTN_0, value)`로 보고한 뒤 `input_sync()`로 report를 끝내고 `IRQ_HANDLED`를 반환합니다.
예제의 초기화, event 보고, 오류 처리와 종료 경로입니다.
초기화에서 IRQ를 얻지 못하면 `-EBUSY`, input device를 할당하지 못하면 `-ENOMEM`을 반환합니다. 등록이 실패하면 device를 free하고 IRQ를 반환합니다. 정상 종료에서는 `input_unregister_device()`가 등록된 device를 해제한 뒤 IRQ를 반환합니다.
Hardware interrupt가 하나의 완전한 input report가 되는 과정입니다.
===============================
Creating an input device driver
===============================
The simplest example
~~~~~~~~~~~~~~~~~~~~
Here comes a very simple example of an input device driver. The device has
just one button and the button is accessible at i/o port BUTTON_PORT. When
pressed or released a BUTTON_IRQ happens. The driver could look like::
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/io.h>
static struct input_dev *button_dev;
static irqreturn_t button_interrupt(int irq, void *dummy)
{
input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1);
input_sync(button_dev);
return IRQ_HANDLED;
}
static int __init button_init(void)
{
int error;
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
return -EBUSY;
}
button_dev = input_allocate_device();
if (!button_dev) {
printk(KERN_ERR "button.c: Not enough memory\n");
error = -ENOMEM;
goto err_free_irq;
}
button_dev->evbit[0] = BIT_MASK(EV_KEY);
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
error = input_register_device(button_dev);
if (error) {
printk(KERN_ERR "button.c: Failed to register device\n");
goto err_free_dev;
}
return 0;
err_free_dev:
input_free_device(button_dev);
err_free_irq:
free_irq(BUTTON_IRQ, button_interrupt);
return error;
}
static void __exit button_exit(void)
{
input_unregister_device(button_dev);
free_irq(BUTTON_IRQ, button_interrupt);
}
module_init(button_init);
module_exit(button_exit);
예제의 등록과 event 보고 동작
71-125`<linux/input.h>`는 input subsystem에 필요한 정의를 제공합니다. Module load 또는 kernel boot 때 호출되는 `_init` 함수는 장치 존재 여부를 확인하고 IRQ 같은 필요한 자원을 확보해야 합니다.
`input_allocate_device()`로 input device를 만들고 bitfield를 설정해 장치가 생성하거나 받아들일 수 있는 event를 input subsystem에 알립니다. 예제는 `EV_KEY` 중 `BTN_0`만 생성하므로 두 bit만 설정합니다. 같은 설정을 `set_bit(EV_KEY, button_dev->evbit)`와 `set_bit(BTN_0, button_dev->keybit)`로 할 수도 있지만 여러 bit에서는 직접 mask를 쓰는 방식이 더 짧을 수 있습니다.
`input_register_device(button_dev)`는 device를 input driver의 linked list에 추가하고 handler module의 `_connect` 함수를 호출해 새 장치 출현을 알립니다. 이 함수는 sleep할 수 있으므로 interrupt context 또는 spinlock을 잡은 상태에서 호출하면 안 됩니다.
사용 중에는 `button_interrupt()`가 상태를 읽어 `input_report_key()`로 전달합니다. `input_report_*` 함수가 이전 값과 같은 중복 event를 자체 검사하므로 driver가 press 뒤 press 같은 중복을 따로 걸러낼 필요가 없습니다.
`input_sync()`는 앞서 보낸 event가 하나의 완전한 report임을 수신자에게 알립니다. Button 하나에서는 중요성이 작아 보이지만 mouse의 X와 Y를 따로 해석해 다른 이동이 생기지 않도록 여러 값을 한 report로 묶을 때 필수입니다.
호출 문맥과 input core가 제공하는 동작을 구분합니다.
Capability 선언 뒤 handler가 새 device와 연결됩니다.
What the example does
~~~~~~~~~~~~~~~~~~~~~
First it has to include the <linux/input.h> file, which interfaces to the
input subsystem. This provides all the definitions needed.
In the _init function, which is called either upon module load or when
booting the kernel, it grabs the required resources (it should also check
for the presence of the device).
Then it allocates a new input device structure with input_allocate_device()
and sets up input bitfields. This way the device driver tells the other
parts of the input systems what it is - what events can be generated or
accepted by this input device. Our example device can only generate EV_KEY
type events, and from those only BTN_0 event code. Thus we only set these
two bits. We could have used::
set_bit(EV_KEY, button_dev->evbit);
set_bit(BTN_0, button_dev->keybit);
as well, but with more than single bits the first approach tends to be
shorter.
Then the example driver registers the input device structure by calling::
input_register_device(button_dev);
This adds the button_dev structure to linked lists of the input driver and
calls device handler modules _connect functions to tell them a new input
device has appeared. input_register_device() may sleep and therefore must
not be called from an interrupt or with a spinlock held.
While in use, the only used function of the driver is::
button_interrupt()
which upon every interrupt from the button checks its state and reports it
via the::
input_report_key()
call to the input system. There is no need to check whether the interrupt
routine isn't reporting two same value events (press, press for example) to
the input system, because the input_report_* functions check that
themselves.
Then there is the::
input_sync()
call to tell those who receive the events that we've sent a complete report.
This doesn't seem important in the one button case, but is quite important
for example for mouse movement, where you don't want the X and Y values
to be interpreted separately, because that'd result in a different movement.
`dev->open()`과 `dev->close()`
126-166Interrupt가 없어 반복 polling해야 하지만 계속 poll하기에는 비용이 크거나 IRQ처럼 귀한 자원을 사용하는 driver는 `open`과 `close` callback으로 polling을 멈추거나 IRQ를 반환할 시점, 다시 polling하거나 IRQ를 확보할 시점을 알 수 있습니다.
예제의 `button_open()`은 `request_irq()`를 호출하고 실패하면 `-EBUSY`, 성공하면 0을 반환합니다. `button_close()`는 IRQ를 반환합니다. 초기화에서 이 두 함수를 `button_dev->open`과 `button_dev->close`에 연결합니다.
Input core는 device 사용자 수를 추적합니다. 첫 사용자가 연결될 때만 `dev->open()`을 호출하고 마지막 사용자가 끊길 때 `dev->close()`를 호출하며 두 callback 호출을 직렬화합니다.
`open()`은 성공 시 0, 실패 시 0이 아닌 값을 반환해야 합니다. 반환형이 `void`인 `close()`는 항상 성공해야 합니다.
Input core의 사용자 수 전이에 따라 callback이 한 번씩 호출됩니다.
비싼 장치 자원은 실제 input 사용자가 있을 때만 유지합니다.
dev->open() and dev->close()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In case the driver has to repeatedly poll the device, because it doesn't
have an interrupt coming from it and the polling is too expensive to be done
all the time, or if the device uses a valuable resource (e.g. interrupt), it
can use the open and close callback to know when it can stop polling or
release the interrupt and when it must resume polling or grab the interrupt
again. To do that, we would add this to our example driver::
static int button_open(struct input_dev *dev)
{
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
return -EBUSY;
}
return 0;
}
static void button_close(struct input_dev *dev)
{
free_irq(IRQ_AMIGA_VERTB, button_interrupt);
}
static int __init button_init(void)
{
...
button_dev->open = button_open;
button_dev->close = button_close;
...
}
Note that input core keeps track of number of users for the device and
makes sure that dev->open() is called only when the first user connects
to the device and that dev->close() is called when the very last user
disconnects. Calls to both callbacks are serialized.
The open() callback should return a 0 in case of success or any non-zero value
in case of failure. The close() callback (which is void) must always succeed.
Input device inhibit와 wakeup
167-212Device inhibit는 그 장치의 input event를 무시하는 것입니다. 이미 존재하는 input handler 관계와 inhibited 상태에서 새로 맺어질 관계는 유지하지만 어떤 handler도 event를 받지 않습니다.
사용자가 있는 device를 inhibit하면 core가 `close()`를 호출하고 uninhibit하면 `open()`을 호출합니다. `close()`는 core에 event 제공을 멈추고 `open()`은 다시 시작한다는 의미이므로, driver는 장치 전원을 직접 끄거나 `open()`에서 얻은 runtime-PM reference를 반환해 전력을 절약할 수 있습니다.
Inhibit·uninhibit는 handler가 device를 open·close하는 동작과 독립적입니다. 사용자 공간은 handler가 아직 match되기 전에 장치를 미리 inhibit할 수 있습니다.
Wakeup source 여부도 inhibit와 독립적입니다. Wakeup source는 system sleep 중에 의미가 있고 inhibit는 system 동작 중 event 전달에 관한 것입니다. Suspend, inhibit, wakeup의 상호작용은 driver별로 정해야 합니다.
Network interface를 down해도 Wake-on-LAN이 가능할 수 있는 것처럼 inhibited input device도 wakeup source일 수 있습니다. 많은 I2C input device의 interrupt는 driver core에서 wakeup interrupt로 선언되고 input-specific inhibit를 알지 못합니다. 여러 interface를 가진 composite device에서 한 interface를 inhibit해도 전체 장치의 wakeup 능력을 없애서는 안 됩니다.
Inhibited 상태에서도 wakeup source여야 한다면 `suspend()` 작성 시 주의해야 합니다. 해당 device에서 `close()`가 hardware를 완전히 멈춘다면 sleep 전 `open()`을 호출하지 않을 경우 wakeup event를 만들 수 없을 수 있습니다.
Event 전달, handler 관계, power와 wakeup을 서로 분리해 봅니다.
Event 억제와 sleep wakeup 준비를 동시에 만족시키는 예입니다.
Inhibiting input devices
~~~~~~~~~~~~~~~~~~~~~~~~
Inhibiting a device means ignoring input events from it. As such it is about
maintaining relationships with input handlers - either already existing
relationships, or relationships to be established while the device is in
inhibited state.
If a device is inhibited, no input handler will receive events from it.
The fact that nobody wants events from the device is exploited further, by
calling device's close() (if there are users) and open() (if there are users) on
inhibit and uninhibit operations, respectively. Indeed, the meaning of close()
is to stop providing events to the input core and that of open() is to start
providing events to the input core.
Calling the device's close() method on inhibit (if there are users) allows the
driver to save power. Either by directly powering down the device or by
releasing the runtime-PM reference it got in open() when the driver is using
runtime-PM.
Inhibiting and uninhibiting are orthogonal to opening and closing the device by
input handlers. Userspace might want to inhibit a device in anticipation before
any handler is positively matched against it.
Inhibiting and uninhibiting are orthogonal to device's being a wakeup source,
too. Being a wakeup source plays a role when the system is sleeping, not when
the system is operating. How drivers should program their interaction between
inhibiting, sleeping and being a wakeup source is driver-specific.
Taking the analogy with the network devices - bringing a network interface down
doesn't mean that it should be impossible be wake the system up on LAN through
this interface. So, there may be input drivers which should be considered wakeup
sources even when inhibited. Actually, in many I2C input devices their interrupt
is declared a wakeup interrupt and its handling happens in driver's core, which
is not aware of input-specific inhibit (nor should it be). Composite devices
containing several interfaces can be inhibited on a per-interface basis and e.g.
inhibiting one interface shouldn't affect the device's capability of being a
wakeup source.
If a device is to be considered a wakeup source while inhibited, special care
must be taken when programming its suspend(), as it might need to call device's
open(). Depending on what close() means for the device in question, not
opening() it before going to sleep might make it impossible to provide any
wakeup events. The device is going to sleep anyway.
EV_KEY, EV_REL과 EV_ABS
213-264가장 단순한 `EV_KEY`는 key와 button에 사용하며 `input_report_key(struct input_dev *dev, int code, int value)`로 보고합니다. 허용 code는 `uapi/linux/input-event-codes.h`의 0부터 `KEY_MAX`까지입니다. 0이 아닌 값은 press, 0은 release이며 값이 이전과 다를 때만 event를 생성합니다.
`EV_REL`은 mouse X 이동처럼 마지막 위치에 대한 상대 변화량, `EV_ABS`는 joystick이나 digitizer처럼 절대 좌표계를 가진 장치의 새 값을 나타냅니다. Relative event는 capability bit를 설정하고 `input_report_rel()`을 호출하며 값이 0이 아닐 때만 생성됩니다.
`EV_ABS` axis는 `input_register_device()` 전에 최소·최대·fuzz·flat을 설정해야 합니다. 예제 `ABS_X`는 0~255 범위, noise ±4, 중앙 flat 영역 8입니다. 같은 설정은 `input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8)`로 한 번에 지정할 수 있습니다.
Joystick은 선언한 최소와 최대값에 항상 도달할 수 있어야 합니다. 가끔 범위를 넘어 보고하는 것은 허용됩니다. `absfuzz`와 `absflat`이 필요 없다면 0으로 설정하며, 이는 정밀하고 중앙이 있다면 정확히 중앙으로 복귀한다는 뜻입니다.
Event type별 값 의미와 보고 조건입니다.
`input_set_abs_params()`의 각 인자가 표현하는 범위와 보정입니다.
Axis parameter는 device 등록 전에 완성해야 합니다.
Basic event types
~~~~~~~~~~~~~~~~~
The most simple event type is EV_KEY, which is used for keys and buttons.
It's reported to the input system via::
input_report_key(struct input_dev *dev, int code, int value)
See uapi/linux/input-event-codes.h for the allowable values of code (from 0 to
KEY_MAX). Value is interpreted as a truth value, i.e. any non-zero value means
key pressed, zero value means key released. The input code generates events only
in case the value is different from before.
In addition to EV_KEY, there are two more basic event types: EV_REL and
EV_ABS. They are used for relative and absolute values supplied by the
device. A relative value may be for example a mouse movement in the X axis.
The mouse reports it as a relative difference from the last position,
because it doesn't have any absolute coordinate system to work in. Absolute
events are namely for joysticks and digitizers - devices that do work in an
absolute coordinate systems.
Having the device report EV_REL buttons is as simple as with EV_KEY; simply
set the corresponding bits and call the::
input_report_rel(struct input_dev *dev, int code, int value)
function. Events are generated only for non-zero values.
However EV_ABS requires a little special care. Before calling
input_register_device, you have to fill additional fields in the input_dev
struct for each absolute axis your device has. If our button device had also
the ABS_X axis::
button_dev.absmin[ABS_X] = 0;
button_dev.absmax[ABS_X] = 255;
button_dev.absfuzz[ABS_X] = 4;
button_dev.absflat[ABS_X] = 8;
Or, you can just say::
input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8);
This setting would be appropriate for a joystick X axis, with the minimum of
0, maximum of 255 (which the joystick *must* be able to reach, no problem if
it sometimes reports more, but it must be able to always reach the min and
max values), with noise in the data up to +- 4, and with a center flat
position of size 8.
If you don't need absfuzz and absflat, you can set them to zero, which mean
that the thing is precise and always returns to exactly the center position
(if it has any).
Bit macro, device 식별과 keymap
265-312`bitops.h`의 `BITS_TO_LONGS(x)`는 x bit를 담는 `long` 배열 길이, `BIT_WORD(x)`는 bit x가 들어갈 `long` 배열 index, `BIT_MASK(x)`는 해당 `long` 안의 bit mask를 계산합니다.
Input capability 배열을 설정할 때 쓰는 세 macro입니다.
Driver는 등록 전에 `dev->name`에 `Generic button device` 같은 사용자 친화적 이름을 넣어야 합니다. `id*` field는 PCI·USB 같은 bus ID, vendor ID와 device ID를 담습니다. Bus ID는 `input.h`, vendor와 device ID는 `pci_ids.h`, `usb_ids.h` 같은 header에 정의됩니다.
`idtype`은 input driver 전용 정보를 담는 데 사용할 수 있습니다. ID와 name은 evdev interface를 통해 사용자 공간에 전달될 수 있습니다.
Dense keymap을 가진 장치는 `keycode`, `keycodemax`, `keycodesize`를 사용합니다. `keycode`는 scancode를 input keycode로 매핑하는 배열, `keycodemax`는 배열 크기, `keycodesize`는 각 entry의 byte 크기입니다.
사용자 공간은 해당 evdev interface에서 `EVIOCGKEYCODE`와 `EVIOCSKEYCODE` ioctl로 현재 scancode-keycode mapping을 조회하고 바꿀 수 있습니다. 세 field가 모두 채워졌다면 driver는 kernel의 기본 mapping 조회·설정 구현을 사용할 수 있습니다.
`dev->getkeycode()`와 `dev->setkeycode()` callback은 input core의 기본 dense mapping 방식을 대체해 sparse keycode map을 구현할 수 있게 합니다.
등록 전에 제공할 식별자와 key mapping 정보입니다.
Keymap 밀도에 따라 core 기본 구현 또는 driver callback을 사용합니다.
BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These three macros from bitops.h help some bitfield computations::
BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
x bits
BIT_WORD(x) - returns the index in the array in longs for bit x
BIT_MASK(x) - returns the index in a long for bit x
The id* and name fields
~~~~~~~~~~~~~~~~~~~~~~~
The dev->name should be set before registering the input device by the input
device driver. It's a string like 'Generic button device' containing a
user friendly name of the device.
The id* fields contain the bus ID (PCI, USB, ...), vendor ID and device ID
of the device. The bus IDs are defined in input.h. The vendor and device IDs
are defined in pci_ids.h, usb_ids.h and similar include files. These fields
should be set by the input device driver before registering it.
The idtype field can be used for specific information for the input device
driver.
The id and name fields can be passed to userland via the evdev interface.
The keycode, keycodemax, keycodesize fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These three fields should be used by input devices that have dense keymaps.
The keycode is an array used to map from scancodes to input system keycodes.
The keycode max should contain the size of the array and keycodesize the
size of each entry in it (in bytes).
Userspace can query and alter current scancode to keycode mappings using
EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface.
When a device has all 3 aforementioned fields filled in, the driver may
rely on kernel's default implementation of setting and querying keycode
mappings.
dev->getkeycode() and dev->setkeycode()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getkeycode() and setkeycode() callbacks allow drivers to override default
keycode/keycodesize/keycodemax mapping mechanism provided by input core
and implement sparse keycode maps.
Autorepeat와 output event 처리
313-349Key autorepeat는 `input.c`가 처리합니다. Hardware autorepeat는 많은 장치에 없고 있는 경우에도 고장난 구현이 있으므로 사용하지 않습니다. Device의 `dev->evbit`에 `EV_REP`를 설정하면 나머지는 input subsystem이 담당합니다.
`EV_LED`는 keyboard LED, `EV_SND`는 keyboard beep에 사용합니다. Key event와 비슷하지만 system에서 input device driver 방향으로 전달되는 output event입니다.
Driver가 output event를 처리하려면 `evbit`에 해당 type bit를 설정하고 `button_dev->event = button_event`처럼 callback을 연결해야 합니다. 예제는 `EV_SND`와 `SND_BELL`이면 `outb(value, BUTTON_BELL)`을 수행하고 0을 반환하며 나머지는 -1입니다.
이 callback은 interrupt 또는 bottom half에서 호출될 수 있으므로 sleep하면 안 되고 실행 시간이 길어도 안 됩니다.
Input core가 처리하는 반복과 driver가 받아 처리하는 출력입니다.
사용자 또는 kernel 요청이 device hardware 동작으로 이어집니다.
Key autorepeat
~~~~~~~~~~~~~~
... is simple. It is handled by the input.c module. Hardware autorepeat is
not used, because it's not present in many devices and even where it is
present, it is broken sometimes (at keyboards: Toshiba notebooks). To enable
autorepeat for your device, just set EV_REP in dev->evbit. All will be
handled by the input system.
Other event types, handling output events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The other event types up to now are:
- EV_LED - used for the keyboard LEDs.
- EV_SND - used for keyboard beeps.
They are very similar to for example key events, but they go in the other
direction - from the system to the input device driver. If your input device
driver can handle these events, it has to set the respective bits in evbit,
*and* also the callback routine::
button_dev->event = button_event;
int button_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
if (type == EV_SND && code == SND_BELL) {
outb(value, BUTTON_BELL);
return 0;
}
return -1;
}
This callback routine can be called from an interrupt or a BH (although that
isn't a rule), and thus must not sleep, and must not take too long to finish.
Polling 기반 input device
350-367Input polling은 input device 구조체와 callback을 `input_setup_polling(struct input_dev *dev, void (*poll_fn)(struct input_dev *dev))`에 전달해 설정합니다.
Polling callback 안에서도 다른 input device와 똑같이 일반 `input_report_*` 함수와 `input_sync()`를 사용해야 합니다.
`input_set_poll_interval(struct input_dev *dev, unsigned int interval)`은 polling 간격을 millisecond 단위로 설정합니다.
Callback 설치와 실행 주기를 별도 함수로 설정합니다.
Timer 기반 sample도 interrupt 기반 장치와 같은 event API를 사용합니다.
Polled input devices
~~~~~~~~~~~~~~~~~~~~
Input polling is set up by passing an input device struct and a callback to
the function::
int input_setup_polling(struct input_dev *dev,
void (*poll_fn)(struct input_dev *dev))
Within the callback, devices should use the regular input_report_* functions
and input_sync as is used by other devices.
There is also the function::
void input_set_poll_interval(struct input_dev *dev, unsigned int interval)
which is used to configure the interval, in milliseconds, that the device will
be polled at.
요약·해설
input-programming.rst:1-367단일 button 예제를 따라 `struct input_dev`의 capability, 등록·해제, report 경계, 사용자 기반 open·close, inhibit와 wakeup, 기본 event type, identity·keymap, autorepeat·output과 polling을 구현하는 kernel driver 안내서입니다.
Input driver의 생명주기와 API 책임을 요약했습니다.
Hardware 자원 준비부터 event 처리와 제거까지의 흐름입니다.