前面在介绍中断时以按键为例,我们要检测按键输入,需要做如下工作
(1) 从设备树获取到按键节点、初始化gpio节点、获取中断号、注册中断
(2) 注册设备号、初始化字符设备、自动创建驱动节点
(3) 实现文件操作函数逻辑(read、open、release)
Linux内核为了处理输入事件(按键、鼠标、键盘、触摸屏),专门设计了input子系统,使用 input 子系统后无需执行上面的步骤 (2)、(3),大大节省了编写驱动的时间。
(1) 从设备树获取到按键节点、初始化 gpio 节点、获取中断号、注册中断
(2) 为按键注册 input 子系统(事件注册、按键注册)
一、input 设备类型
注册到 input 子系统中的设备称为 input 设备,Linux 内核专门提供了一种数据类型 input_dev 用来表示 input 设备,该结构体定义在 <linux/input.h> 文件中。
struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; /* 按键值的位图 */
unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; /* 相对坐标的位图 */
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; /* 绝对坐标的位图 */
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; /* 杂项事件的位图 */
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; /*LED 相关的位图 */
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; /* sound 有关的位图 */
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; /* 压力反馈的位图 */
unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; /*开关状态的位图 */
...
}
① name 成员
input_dev 的name成员用于标识输入设备的名称,当 input 设备注册成功后,输入 lsinput 命令可以看到当前 Linux 内核管理的 input 设备,
(a) /dev/input/event0:表示当前 input 设备对应的驱动文件是 /dev/input/event0
(b) name:表示当前input 设备的名字
(c) bits ev:表示当前input设备监听的事件类型
② evbit 成员
input 设备支持多种输入事件,evbit 成员的作用便是管理当前 input 设备需要监听的事件,假设我们要把一个按键注册为 input 设备,那么我们就需要向这个成员中添加按键事件,若考虑到按键会被重复按下,我们还可以添加重复事件。各种事件的定义在 <linux/input.h> 文件中。
#define EV_SYN 0x00 /* 同步事件 */
#define EV_KEY 0x01 /* 按键事件 */
#define EV_REL 0x02 /* 相对坐标事件 */
#define EV_ABS 0x03 /* 绝对坐标事件 */
#define EV_MSC 0x04 /* 杂项(其他)事件 */
#define EV_SW 0x05 /* 开关事件 */
#define EV_LED 0x11 /* LED */
#define EV_SND 0x12 /* sound(声音) */
#define EV_REP 0x14 /* 重复事件 */
#define EV_F