我们之前已经说过,input_register_device 的作用就是注册一个 input_device。
在分析 input_register_device 之前 ,我们先搜索一下,究竟哪里会调用这个函数你呢。可以看到很多文件都调用了,我们看到一个熟悉的文件ft5x.c。可以想象到,是在设
备初始化时候,要向input子系统注册一个input_dev,因为只有这样才能用input子系统里面的东西啊,不然怎么用input子系统呢。关于ft5x.c这个文件,是一个典型的触
摸屏驱动程序,我们最后会分析它。
好了,我们将精力集中回到 input_register_device 这个函数分析里面来。
如上面所示,会把dev挂入
input_dev_list链表,
然后会遍历
input_handler_list链表
,对链表里面的每个handler 进行匹配,如果匹配成功就调用到
input_attach_handler函数,
这个该函数之前分析过,就不再次分析了。由此可见,无论是先注册驱动,还是先注册设备,最后都会调用的匹配函数。
在分析 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;
- }
这个该函数之前分析过,就不再次分析了。由此可见,无论是先注册驱动,还是先注册设备,最后都会调用的匹配函数。