drivers/input/input.c
static LIST_HEAD(input_dev_list); static LIST_HEAD(input_handler_list);
关于LIST_HEAD的定义可参考misc类设备驱动开发详解
定义了input_dev_list链表用来记录所有内核中注册了的input类设备。当我们向内核注册一个input类设备时,内核就会向input_dev_list链表中insert一个节点。
定义了一个input_handler_list链表用来记录内核中注册了的handler。这些handler是在输入事件驱动层对应的源码中被注册进去的。可参考输入事件驱动层源码分析
struct input_dev
包含了一个input设备的相关数据和操作方法
成员:
- unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; 设备所支持的事件类型
- unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; EV_KEY事件类型所支持的code
- unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; EV_REL事件类型所支持的code
- 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)];
以上这些xxbit表示设备所支持的事件类型以及每种事件类型所支持的code值
数组结构的定义和划分方式,以evbit为例
EV_CNT表示内核中定义的支持的事件类型的种类,每一类放在一个bit位中表示,支持这个事件类型则在该位标记1,不支持则标记0。这里定义的是一个unsigned long类型的数组,对于32位系统每个unsigned long类型的变量中有32个bit,所以包含32种事件类型。那么EV_CNT种可以被多少个unsigned long所表示呢,答案就是BITS_TO_LONGS(EV_CNT)个
struct input_handler
包含了一个input handler的相关数据和操作方法
struct input_handle
struct input_handle { void *private; int open; const char *name; struct input_dev *dev; struct input_handler *handler; struct list_head d_node; struct list_head h_node; };
当一个device和一个handler匹配上之后就会在这里做一个记录
struct list_head d_node;和struct list_head h_node;分别用来记录device和handler的链表节点
input_init
(1)class_register。input类的注册,对应/sys/class/input文件夹
(2)input_proc_init。该函数内部主要就是创建了/proc/bus/input文件件和它下面的属性文件以及绑定操作方法
(3)register_chrdev。注册设备
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
#define INPUT_MAJOR 13
static const struct file_operations input_fops = { .owner = THIS_MODULE, .open = input_open_file, };
input_open_file函数中并不直接操作硬件,而是使用函数指针的方式间接调用操作硬件的函数
设备驱动层的接口函数
(1)input_allocate_device。struct input_dev类型变量的内存空间的申请和部分特定得泛型成员的初始化
(2)input_set_capability。为输入类设备上报的数据设置type和code
(3)input_register_device。向核心层注册设备
input_register_device
(1)添加了EV_SYN同步事件
__set_bit(EV_SYN, dev->evbit);
(2)设置设备对应文件夹名字,可以在/sys/class/input下看到inputx的文件夹(注意这里只是符号链接文件,真正的文件在/sys/device/...下)
dev_set_name(&dev->dev, "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
(3)调用了device_add添加设备
error = device_add(&dev->dev);
(4)将设备添加到管理所有input设备的链表
list_add_tail(&dev->node, &input_dev_list);
(5)遍历input_handler_list进行handler和device的匹配和连接
list_for_each_entry(handler, &input_handler_list, node) input_attach_handler(dev, handler);
input_attach_handler
(1) 匹配device和handler
id = input_match_device(handler, dev);
(2)连接
error = handler->connect(handler, dev, id);
input_match_device
static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { const struct input_device_id *id; int i; for (id = handler->id_table; id->flags || id->driver_info; id++) { if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) if (id->bustype != dev->id.bustype) continue; if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) if (id->vendor != dev->id.vendor) continue; if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) if (id->product != dev->id.product) continue; if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) if (id->version != dev->id.version) continue; MATCH_BIT(evbit, EV_MAX); MATCH_BIT(keybit, KEY_MAX); MATCH_BIT(relbit, REL_MAX); MATCH_BIT(absbit, ABS_MAX); MATCH_BIT(mscbit, MSC_MAX); MATCH_BIT(ledbit, LED_MAX); MATCH_BIT(sndbit, SND_MAX); MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(swbit, SW_MAX); if (!handler->match || handler->match(handler, dev)) return id; } return NULL; }
遍历handler的id_table数组中的每个struct input_device_id类型的成员,首先根据flags进行判断,接着进行xxbit的匹配,最后当handler中的match函数指针不为NULL时去执行它,匹配上后返回id
handler中的id_table中包含了该handler与device匹配时相关的值,主要用于匹配时判断device和handler是否能够匹配上
事件驱动层的接口函数
(1)input_register_handler。注册一个新的handler
(2)input_register_handle。用来处理device和handler之间的一些东西
input_table
static struct input_handler *input_table[8];
该数组中的每个元素都代表了一类input handler,最大可以有8个成员,所以内核中最大支持8类handler。
该数组中的每个成员实际上是一类handler的第一个handler
内核中可以有许多个handler,他们必须属于这8类中的一类。
每一类handler理论上最大能包含32个handler,每一类handler所对应的设备的次设备号范围分别是0-31,32-63,64-95,96-127,128-159,160-191,192-223,224-255。具体的原因见input_register_handler函数的内部实现
input_register_handler
int input_register_handler(struct input_handler *handler);
(1)
INIT_LIST_HEAD(&handler->h_list);
初始化链表节点
(2)
if (handler->fops != NULL) { if (input_table[handler->minor >> 5]) { retval = -EBUSY; goto out; } input_table[handler->minor >> 5] = handler; }
当handler的fops成员不是NULL时
当input_table[handler->minor >> 5]不为NULL时退出,否则设置input_table[handler->minor >> 5]为传入的handler
这里input_table数组下标中minor右移5位相当于除了一个32,所以每一类handler最大能包含32个handler,他们对应的设备次设备号范围也得到了
(3)
list_add_tail(&handler->node, &input_handler_list);
将这个handler节点加入到input_handler_list链表中
(4)
list_for_each_entry(dev, &input_dev_list, node) input_attach_handler(dev, handler);
遍历input_dev_list进行handler和device的匹配和连接,这里和input_register_device函数中十分相似。可以看出,不论是device先注册还是handler先注册,都会在最新注册的时候去匹配和连接。
(5)
input_wakeup_procfs_readers();
proc文件系统相关的
input_register_handle
int input_register_handle(struct input_handle *handle);
注册一个新的handle,应该是用来统筹管理device和handler的