我们之前已经说过,input_register_device 的作用就是注册一个 input_device。
在分析
input_register_device 之前,我们先搜索一下,究竟哪里会调用这个函数你呢。可以看到很多文件都调用了,我们看到一个熟悉的文件ft5x.c。可以想象到,是在设
备初始化时候,要向input子系统注册一个input_dev,因为只有这样才能用input子系统里面的东西啊,不然怎么用input子系统呢。关于ft5x.c这个文件,是一个典型的触
摸屏驱动程序,我们最后会分析它。
好了,我们将精力集中回到
input_register_device 这个函数分析里面来。
-
/**
-
* input_register_device - register device with input core
-
* @dev: device to be registered
-
*
-
* This function registers device with input core. The device must be
-
* allocated with input_allocate_device() and all it's capabilities
-
* set up before registering.
-
* If function fails the device must be freed with input_free_device().
-
* Once device has been successfully registered it can be unregistered
-
* with input_unregister_device(); input_free_device() should not be
-
* called in this case.
-
*/
-
int input_register_device(struct input_dev *dev)
-
{
-
static atomic_t input_no = ATOMIC_INIT(0);
-
struct input_handler *handler;
-
const char *path;
-
int error;
-
//解析说的很明白,因为每个input device 都会产生EV_SYN/SYN_REPORT 时间,所以就放在一起去设置了。
-
/* Every input device generates EV_SYN/SYN_REPORT events. */
-
__set_bit(EV_SYN, dev->evbit);
-
-
/* KEY_RESERVED is not supposed to be transmitted to userspace. */
-
__clear_bit(KEY_RESERVED, dev->keybit);
-
//没有设置的位,保证被清零
-
/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
-
input_cleanse_bitmasks(dev);
-
//这个函数的意义是,获取每个包有多少个event,不太明白
-
if (!dev->hint_events_per_packet)
-
dev->hint_events_per_packet =
-
input_estimate_events_per_packet(dev);
-
//下面这段,不太明白
-
/*
-
* If delay and period are pre-set by the driver, then autorepeating
-
* is handled by the driver itself and we don't do it in input.c.
-
*/
-
init_timer(&dev->timer);
-
if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
-
dev->timer.data = (long) dev;
-
dev->timer.function = input_repeat_key;
-
dev->rep[REP_DELAY] = 250;
-
dev->rep[REP_PERIOD] = 33;
-
}
-
//获取按键值默认函数
-
if (!dev->getkeycode)
-
dev->getkeycode = input_default_getkeycode;
-
//设置按键值默认函数
-
if (!dev->setkeycode)
-
dev->setkeycode = input_default_setkeycode;
-
-
dev_set_name(&dev->dev, "input%ld",
-
(unsigned long) atomic_inc_return(&input_no) - 1);
-
//其实不太明白,这里创建了什么,因为和自己想像的不一样
-
error = device_add(&dev->dev);
-
if (error)
-
return error;
-
-
path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
-
pr_info("%s as %s\n",
-
dev->name ? dev->name : "Unspecified device",
-
path ? path : "N/A");
-
kfree(path);
-
-
error = mutex_lock_interruptible(&input_mutex);
-
if (error) {
-
device_del(&dev->dev);
-
return error;
-
}
-
//将dev挂入input_dev_list设备链表
-
list_add_tail(&dev->node, &input_dev_list);
-
//遍历驱动链表input_handler_list,对立面的每一个handler,看是否匹配
-
list_for_each_entry(handler, &input_handler_list, node)
-
input_attach_handler(dev, handler);
-
-
input_wakeup_procfs_readers();
-
-
mutex_unlock(&input_mutex);
-
-
return 0;
-
}
如上面所示,会把dev挂入
input_dev_list链表,然后会遍历
input_handler_list链表,对链表里面的每个handler 进行匹配,如果匹配成功就调用到
input_attach_handler函数,
这个该函数之前分析过,就不再次分析了。由此可见,无论是先注册驱动,还是先注册设备,最后都会调用的匹配函数。
阅读(3324) | 评论(0) | 转发(0) |