I
- Unified management of external input devices, such as:
Key
keyboard
mouse
touch screen
...
User space interface
- /dev/input/event0/1/2/...
- /dev/input/mouse0/1/2 /... (mouse)
- /dev/input/sj0/1/2/...
- ...
Hierarchical model
Core layer
Create input device class
Distribute events to different event processors according to the type of input device
Event processing layer
Includes various event handlers
Provide the operation interface of specific devices and create specific device files for input devices (input_dev structure). Therefore, we do not need to create device files for these input devices. The corresponding event processor of the event processing layer will create specific device files for us.
General purpose event processor (drivers/input/evdev.c), most used
Mouse event handler (drivers/input/mousedev.c)
Rocker event processor (drivers/input/joydev.c)
...
Create input device class
input_init() function
drivers/input/input.c
This function runs automatically after the system starts
static int __init input_init(void) { int err; // Register an input device class. See the following for details // After registration, a new directory will be generated: / sys/class/input err = class_register(&input_class); if (err) { pr_err("unable to register input_dev class\n"); return err; } ... // Application equipment No // Parameter 1 starting equipment number, parameter 2 number of secondary equipment numbers, parameter 3 name err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0), INPUT_MAX_CHAR_DEVICES, "input"); if (err) { pr_err("unable to register char major %d", INPUT_MAJOR); goto fail2; } return 0; fail2: input_proc_exit(); fail1: class_unregister(&input_class); return err; }
input_class definition
drivers/input/input.c
struct class input_class = { .name = "input", .devnode = input_devnode, };
INPUT_MAJOR definition
include/uapi/linux/major.h
#define INPUT_MAJOR 13
INPUT_MAX_CHAR_DEVICES definition
drivers/input/input.c
#define INPUT_MAX_CHAR_DEVICES 1024
input_dev structure
Identify an input device
include/linux/input.h
struct input_dev { // Device name const char *name; const char *phys; const char *uniq; // Save the attributes of the input device, support the manufacturer and version number, and match the input device with the specific event processor through this member struct input_id id; unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; // Record which input events are supported by the input device unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // Key events, which specific key types are supported unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; // Relative coordinate time, specifying the supported relative coordinate type unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; // Absolute coordinate event, specifying the absolute coordinate type supported unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; ... int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); ... // inherit struct device dev; struct list_head h_list; struct list_head node; unsigned int num_vals; unsigned int max_vals; struct input_value *vals; bool devres_managed; };
-
Name: enter the device name
-
id: enter the matching information between the device and the event processor
-
evbit: Specifies the supported event types
- Synchronization event, key event, coordinate event
-
keybit: Specifies the supported key value types
- key1,key2...
-
relbit: Specifies the relative coordinate type supported
- x-axis, y-axis, z-axis, pulley
-
absbit: Specifies the absolute coordinate type supported
- x-axis, y-axis, z-axis, pulley
Event type
include/linux/input.h
// Synchronization event #define EV_SYN 0x00 // Key event #define EV_KEY 0x01 // Relative coordinate event #define EV_REL 0x02 // Absolute coordinate event #define EV_ABS 0x03 ... #define EV_CNT (EV_MAX+1)
Key value type
include/linux/input.h
#define KEY_RESERVED 0 #define KEY_ESC 1 #define KEY_1 2 #define KEY_2 3 #define KEY_3 4 #define KEY_4 5 #define KEY_5 6 ...
Register / destroy input devices
Assignment, registration, cancellation, release
input_allocate_device() function
drivers/input/input.c
Allocate and initially initialize input_dev struct variable
struct input_dev *input_allocate_device(void)
input_register_device() function
drivers/input/input.c
Register the input device with the system
int input_register_device(struct input_dev *dev)
Return value:
0: successful
-1: Fail
input_unregister_device() function
drivers/input/input.c
Log off the input device to the system
void input_unregister_device(struct input_dev *dev)
input_free_device() function
drivers/input/input.c
Release input_dev struct variable
void input_free_device(struct input_dev *dev)
Report input events
input_event() function
drivers/input/input.c
General event reporting interface
void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
-
dev
Input device for reporting information -
Type: the specific input event type reported
Key input type: EV_KEY
Coordinate input type: EV_REL,EV_ABS
Special type: EV_SYN
Synchronization event: notifies user space programs to receive messages
... -
code
Record specific events in the input event type
When a key input type event occurs on the keyboard, record which value of the keyboard is pressed
... -
Value: the corresponding value of the specific event
Press the key, and the value is 1; When the key is released, the value is 0
...
input_report_key() function
include/linux/input.h
Key event special reporting interface
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_KEY, code, !!value); }
input_report_rel() function
include/linux/input.h
Special reporting interface for relative coordinate events
static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_REL, code, value); }
input_report_abs() function
include/linux/input.h
Special reporting interface for absolute coordinate events
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_ABS, code, value); }
input_sync() function
include/linux/input.h
Special reporting interface for synchronization events
The special events reported above, such as key, rel, key, etc., are not reported immediately.
Instead, the data is temporarily stored in a circular queue buffer until input is called_ Sync, will notify the user space to read the data in the circular queue buffer
static inline void input_sync(struct input_dev *dev) { input_event(dev, EV_SYN, SYN_REPORT, 0); }