上一篇文章中介绍了input_dev和handler的匹配过程,input_dev的属性是在设备驱动程序中设定
的,调用input_device_register向input_core注册。那么对于handler的注册是发生在时间处理层的
,在input目录下有evdev.c,joydev.c,mousedev.c等事件驱动程序。下面介绍与触摸有关的evdev
事件处理源码;
static int __init evdev_init(void)
{
return input_register_handler(&evdev_handler);
源码中,首先就像input_core注册handler,先看看evdev_handler这个结构体是什么
}
evdev_handler源码:
static struct input_handler evdev_handler = {
.event = evdev_event, //当有event事件从底层上报到事件处理层中,会调用这个
//函数,将event投入到event_client中的链表中,
//等待读取,这个函数下一篇event上报流程中会分析
.connect = evdev_connect,//当handler和dev匹配成功后,会调用这个函数,在上面
//中分析了这个函数的源码
.disconnect = evdev_disconnect,
.fops = &evdev_fops, //操作函数
.minor = EVDEV_MINOR_BASE, //设备号的基值
.name = "evdev",
.id_table = evdev_ids, //这个就是用来和input_dev匹配的。下面
//定义了这个结构体,
};
static const struct input_device_id evdev_ids[] = {
{ .driver_info = 1 }, /* Matches all devices */可以匹配所有的设备
{ }, /* Terminating zero entry */
};
下面看input_register_handler这个函数的源码:
int input_register_handler(struct input_handler *handler)
{
struct input_dev *dev;
int retval;
retval = mutex_lock_interruptible(&input_mutex);
if (retval)
return retval;
INIT_LIST_HEAD(&handler->h_list);
if (handler->fops != NULL) {
if (input_table[handler->minor >> 5]) {
retval = -EBUSY;
goto out;
}
input_table[handler->minor >> 5] = handler;
}
//这里和input_dev_register一样也是搜索dev链表,将dev一一和handler进行匹配
list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node)
input_attach_handler(dev, handler);//这个函数和上一篇分析过了
//匹配成功后,在调用handler的connect函数,从而生成evdev这个结构体
input_wakeup_procfs_readers();
out:
mutex_unlock(&input_mutex);
return retval;
}
这个就是handler的注册过程,属于事件处理层驱动,事件处理层的驱动由内核实现的,
只需要找到合适的事件处理层的驱动为我所用即可。就常用evdev作为触摸屏的事件
处理层的驱动。