The input subsystem is provided in Linux. input devices, such as buttons, touch screens, keyboards, and mouse, can use the input interface function to drive devices.
In the Linux kernel, the input device uses the input_dev struct to describe the input device driver, the core work of the driver is to report input events (events, which are described by the input_event struct) such as buttons, touch screens, keyboards, and mouse to the system, because the input subsystem has completed the file operation interface. The events reported by the driver pass through inputcore and eventhandler and finally reach the user space.
Through the input subsystem, the specific input device driver only needs to complete the following work.
(1) events that the input subsystem can report in the module loading function.
The device driver uses set_bit () to tell the input subsystem what events it supports, as shown below:
set_bit(EV_KEY, button_dev.evbit);
(2) register the input device in the module loading function. The registration function is:
int input_register_device(struct input_dev *dev);
(3) When the buttons are pressed/lifted, the touch screen is touched/lifted/moved, and the mouse is moved/clicked/lifted, input_report_xxx () report events and corresponding key values/coordinates.
The main event types include ev_key (key event), ev_rel (relative value, such as moving the cursor, reporting the offset relative to the last position), and ev_abs (absolute value, such as touch screen and joystick, they work in absolute coordinate systems ).
The functions used to report ev_key, ev_rel, and ev_abs events are:
void input_report_key(struct input_dev *dev, unsigned int code, int value);void input_report_rel(struct input_dev *dev, unsigned int code, int value);void input_report_abs(struct input_dev *dev, unsigned int code, int value);
Input_sync () is used for event synchronization. It notifies the receiver driver of the event that a complete report has been issued.
For example, in the driver of a touch screen device, the entire report process of one coordinate and one pressing state is as follows:
Input_report_abs (input_dev, abs_x, x); // X coordinate input_report_abs (input_dev, abs_y, Y); // y coordinate input_report_abs (input_dev, abs_pressure, Pres ); // pressure input_sync (input_dev); // synchronous
(4) log out of the input device from the module uninstallation function. The function is:
void input_unregister_device(struct input_dev *dev);
The following is a simple example of using the input interface to implement the key device driver. It reports the keys and synchronization events to the system in the interrupt service program.
/* Report the event during key interruption */static void button_interrupt (int irq, void * dummy, struct pt_regs * FP) {input_report_key (& button_dev, BTN _!, INB (button_port), 1); input_sync (& button_dev);} static int _ init button_init (void) {/* request interruption */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.evbit [0] = bit (ev_key ); // supports ev_key event button_dev.keybit [long (bit_0)] = bit (btn_0); input_register_device (& button_dev); // registers the input device} static void _ exit button_exit (void) {input_unregister_device (& button_dev); free_irq (button_irq, button_interrupt );}