The handler is used to process input_event, and the device is the device that sends the input_event event. First, let's take a look at which devices and handlers (parts) are there.
input_register_handler 对应 input_dev_list
cpu-boost cpu-boost.c
sysrq sysrq.c
leds input-leds.c
evdev evdev.c
kgsl adreno.c
...
input_register_device 对应 input_handler_list
gpio-keys gpio_keys.c
atmle_mxt_ts atmel_maxtouch_ts.c
qpnp_pon qpnp-power-on.c
...
The input-related initialization interface mainly has two input_register_handler/input_register_device to bind dev and handler through two linked lists of input_dev_list and input_handler_list . One dev corresponds to multiple handlers, and one handler corresponds to multiple devs.
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
input_register_handler registers an interface with the system ( kernel/msm-4.19/include/linux/input.h )
struct input_handler {
void *private;
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
void (*events)(struct input_handle *handle,
const struct input_value *vals, unsigned int count);
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
bool legacy_minors;
int minor;
const char *name;
const struct input_device_id *id_table;
struct list_head h_list;
struct list_head node;
};
Let's take a look at where these functions in the handler are used. When registering, call the handler's id_table/connect/match
input_attach_handler -> input_match_device -> input_match_device_id(通过handler->id_table与dev的id进行匹配)
-> handler->match(match为空或者调用handler的match进行匹配)
-> handler->connect (匹配成功后会再connect中做handler和device的绑定)
-> input_open_device(其中会有标志handle->open++ input_event中会用到)
The following is the id_table that supports all devices, and evdev_ids corresponds to evdev, because all basically all events of match all devices will be processed here
static const struct input_device_id evdev_ids[] = {
{
.driver_info = 1 }, /* Matches all devices */
{
}, /* Terminating zero entry */
};
Call the filter/events/event of the handler in the process of reporting the event
input_event -> input_handle_event -> input_pass_values -> (其中会遍历handler list(h_list))
-> input_to_handler (主要是对应handler的三个api)
(1)handler->filter 过滤event,如果filter成功则会直接return(因此也可以在kernel中去做键值隐射)
(2)handler->events 处理events的函数,同下
(3)handler->event 当events不存在时调用event
The handler will eventually be processed by evdev, and written into the buffer through __pass_event for the upper layer evdev_read to read the event.