分别是总线类型、厂商号、产品号和版本号。
1156行,evbit,设备支持的事件类型的位图,每一位代表一种事件,比如EV_KEY、EV_REL事件等等。BITS_TO_LONGS(nr)是一个宏,假设long型变量为32位,1位可以表示一种事件,那么这个宏的意思就是nr种事件需要用多少个long型变量来表示。EV_CNT的值为0x1f+1,因此BITS_TO_LONGS(0x1f+1)的值就为1。
1157行,keybit,设备拥有的按键的位图,每一位代表一个按键。
1158行,relbit,设备拥有的相对轴的位图,每一位代表一个相对轴。
1159行,absbit,设备拥有的绝对轴的位图,每一位代表一个绝对轴。
1160行,mscbit,设备支持的杂项事件位图。
1161行,ledbit,设备拥有的LED位图。
1162行,sndbit,设备支持的音效位图。
1163行,ffbit,1164行,swbit,不说了,对于本文只需要关注evbit和keybit即可,其他那些只需要有个印象,等用到的时候自然就明白了。
1166行,hint_events_per_packet,输入事件到达事件驱动程序的时候会存放在一个缓冲区里,这里表示这个缓冲区的大小。
1168行,keycodemax,键码表的大小。
1169行,keycodesize,键码表元素的大小。
1170行,扫描码到键码的映射。
1171、1173行,设置和获取键码的函数指针。
1176至1187行,与本文没什么关系,略过吧。
1189至1192行,表示当前状态的位图。
1194至1197行,一些函数指针,用到再说。
1199行,grab,这有点意思,表示设备拥有的input handle,当输入事件准备传递给事件驱动程序时会input core会先判断设备是否拥有了input handle,如果有,则把事件投递给该handle来处理,否则,遍历所有已经注册了的handle,每遍历到一个handle,就把事件投递给它。
1204行,users,计数,每打开设备一次,计数加1,关闭设备,计数减1。
1207行,sync,当为true时表示自从上一次同步以来再也没有新的输入事件产生。
1209行,dev,嵌入到设备模型中用的。
1211行,设备拥有的handle,这些handle以链表的形式连接在一起。从这可以看出,一个设备是可以拥有多个handle的。
1212行,node,作为input_dev_list这个全局链表的节点使用,从而把系统中的所有Input设备连成一个链表。
回到input_allocate_device函数,1559行,为Input设备分配内存。
1561行,指定设备的类型为input_dev_type。
1562行,还记得Input子系统初始化时注册的那个input_class没?就是这么用的。
1563行,用设备模型的函数初始化设备。
1564至1567行,锁和链表的初始化。
1569行,啥也没做,是一个空函数。
回到gpio_keys_probe函数,456至460行,如果申请内存失败或者分配设备失败,那么就释放之前申请的内存,返回出错。
462至480行,一些赋值,不细说了。
483行,如果支持按键自动重复,则设置evbit位图中的相应位为1。
486行,循环的次数等于按键的个数。
489行,事件类型默认为按键类型(EV_KEY)。
494行,gpio_keys_setup_key函数的定义:
00000362 static int __devinit gpio_keys_setup_key(struct platform_device *pdev, 00000363 struct gpio_button_data *bdata, 00000364 struct gpio_keys_button *button) 00000365 { 00000366 char *desc = button->desc ? button->desc : "gpio_keys"; 00000367 struct device *dev = &pdev->dev; 00000368 unsigned long irqflags; 00000369 int irq, error; 00000370 00000371 setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); 00000372 INIT_WORK(&bdata->work, gpio_keys_work_func); 00000373 00000374 error = gpio_request(button->gpio, desc); 00000375 if (error < 0) { 00000376 dev_err(dev, "failed to request GPIO %d, error %d\n", 00000377 button->gpio, error); 00000378 goto fail2; 00000379 } 00000380 00000381 error = gpio_direction_input(button->gpio); 00000382 if (error < 0) { 00000383 dev_err(dev, "failed to configure" 00000384 " direction for GPIO %d, error %d\n", 00000385 button->gpio, error); 00000386 goto fail3; 00000387 } 00000388 00000389 if (button->debounce_interval) { 00000390 error = gpio_set_debounce(button->gpio, 00000391 button->debounce_interval * 1000); 00000392 /* use timer if gpiolib doesn't provide debounce */ 00000393 if (error < 0) 00000394 bdata->timer_debounce = button->debounce_interval; 00000395 } 00000396 00000397 irq = gpio_to_irq(button->gpio); 00000398 if (irq < 0) { 00000399 error = irq; 00000400 dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", 00000401 button->gpio, error); 00000402 goto fail3; 00000403 } 00000404 00000405 irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 00000406 /* 00000407 * If platform has specified that the button can be disabled, 00000408 * we don't want it to share the interrupt line. 00000409 */ 00000410 if (!button->can_disable) 00000411 irqflags |= IRQF_SHARED; 00000412 00000413 error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); 00000414 if (error) { 00000415 dev_err(dev, "Unable to claim irq %d; error %d\n", 00000416 irq, error); 00000417 goto fail3; 00000418 } 00000419 00000420 return 0; 00000421 00000422 fail3: 00000423 gpio_free(button->gpio); 00000424 fail2: 00000425 return error; 00000426 }
371行,初始化按键定时器,定时器超时处理函数为gpio_keys_timer,函数的参数为bdata。之前说了,该定时器是用到延时消抖的。所谓延时消抖就是说当按键按下时,由于按键的机械特性会存在抖动,造成多次按下和抬起,因此当延时适当的时间后,如果按键仍然处于按下状态,那么就认为按键真的按下了,这是一种软件消抖的方法,当然,还有硬件消抖的方法。
372行,初始化按键的工作节点,使用系统默认的工作队列。
374至379行,申请IO口,如果IO口被占用,那么该IO口就不能用作按键的输入。
381至387行,设置IO口为输入功能。
389行,如果按键有设置延时的话那么就执行390行通过gpiolib的gpio_set_debounce函数来设置延时,如果有些平台不支持gpiolib,那么执行394行,通过定时器来实现延时。
397至403行,获取IO口对应的中断号。
405行,设置上升沿和下降沿都将触发中断的标志。
410、411行,如果IO口(按键)可以被失能的话,那么就不要设置共享中断标志,即此IO口独占一条中断线。
413至418行,申请中断,中断处理函数为gpio_keys_isr,函数的其中一个参数为bdata。
至此,gpio_keys_setup_key函数说完了,回到gpio_keys_probe函数,498、491行,如果按键可以作为唤醒源,那么设置wakeup变量为1,马上就会用到。
501行,调用drivers/input/input.c中的input_set_capability函数,定义如下:
00001652 void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) 00001653 { 00001654 switch (type) { 00001655 case EV_KEY: 00001656 __set_bit(code, dev->keybit); 00001657 break; 00001658 00001659 case EV_REL: 00001660 __set_bit(code, dev->relbit); 00001661 break; 00001662 00001663 case EV_ABS: 00001664 __set_bit(code, dev->absbit); 00001665 break; 00001666 00001667 case EV_MSC: 00001668 __set_bit(code, dev->mscbit); 00001669 break; 00001670 00001671 case EV_SW: 00001672 __set_bit(code, dev->swbit); 00001673 break; 00001674 00001675 case EV_LED: 00001676 __set_bit(code, dev->ledbit); 00001677 break; 00001678 00001679 case EV_SND: 00001680 __set_bit(code, dev->sndbit); 00001681 break; 00001682 00001683 case EV_FF: 00001684 __set_bit(code, dev->ffbit); 00001685 break; 00001686 00001687 case EV_PWR: 00001688 /* do nothing */ 00001689 break; 00001690 00001691 default: 00001692 printk(KERN_ERR 00001693 "input_set_capability: unknown type %u (code %u)\n", 00001694 type, code); 00001695 dump_stack(); 00001696 return; 00001697 } 00001698 00001699 __set_bit(type, dev->evbit); 00001700 }
很明显的排比句,根据按键支持的事件设置按键表示的键值,最后再设置按键支持的事件。通俗地说,按键产生的是按键事件(EV_KEY),一个按键只能代表一个键值,比如键盘上的F1、F2等等。
回到gpio_keys_probe函数,504至509行,sysfs文件系统相关的,简单地说,sysfs_create_group函数就是在/sys相应的目录下创建一些文件,这样就可以在用户空间通过echo或cat来设置或者读取驱动中的一些参数。
511至516行,调用input_register_device函数注册Input设备,定义如下:
00001734 int input_register_device(struct input_dev *dev) 00001735 { 00001736 static atomic_t input_no = ATOMIC_INIT(0); 00001737 struct input_handler *handler; 00001738 const char *path; 00001739 int error; 00001740 00001741 /* Every input device generates EV_SYN/SYN_REPORT events. */ 00001742 __set_bit(EV_SYN, dev->evbit); 00001743 00001744 /* KEY_RESERVED is not supposed to be transmitted to userspace. */ 00001745 __clear_bit(KEY_RESERVED, dev->keybit); 00001746 00001747 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ 00001748 input_cleanse_bitmasks(dev); 00001749 00001750 /* 00001751 * If delay and period are pre-set by the driver, then autorepeating 00001752 * is handled by the driver itself and we don't do it in input.c. 00001753 */ 00001754 init_timer(&dev->timer); 00001755 if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { 00001756 dev->timer.data = (long) dev; 00001757 dev->timer.function = input_repeat_key; 00001758 dev->rep[REP_DELAY] = 250; 00001759 dev->rep[REP_PERIOD] = 33; 00001760 } 00001761 00001762 if (!dev->getkeycode) 00001763 dev->getkeycode = input_default_getkeycode; 00001764 00001765 if (!dev->setkeycode) 00001766 dev->setkeycode = input_default_setkeycode; 00001767 00001768 dev_set_name(&dev->dev, "input%ld", 00001769 (unsigned long) atomic_inc_return(&input_no) - 1); 00001770 00001771 error = device_add(&dev->dev); 00001772 if (error) 00001773 return error; 00001774 00001775 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); 00001776 printk(KERN_INFO "input: %s as %s\n", 00001777 dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); 00001778 kfree(path); 00001779 00001780 error = mutex_lock_interruptible(&input_mutex); 00001781 if (error) { 00001782 device_del(&dev->dev); 00001783 return error; 00001784 } 00001785 00001786 list_add_tail(&dev->node, &input_dev_list); 00001787 00001788 list_for_each_entry(handler, &input_handler_list, node) 00001789 input_attach_handler(dev, handler); 00001790 00001791 input_wakeup_procfs_readers(); 00001792 00001793 mutex_unlock(&input_mutex); 00001794 00001795 return 0; 00001796 }
1736行,注意,这是一个static型变量,就是说当函数返回时它所占用的内存不会释放,它的值会维持不变,并且只会被初始化一次,第一次进该函数时input_no=0,第二次进时input_no=1,以此类推。
1737行,遇到了一个新的结构体struct input_handler,它定义了输入设备的接口,主要用在事件驱动程序中,它的定义在include/linux/input.h中:
00001304 struct input_handler { 00001305 00001306 void *private; 00001307 00001308 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 00001309 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 00001310 bool (*match)(struct input_handler *handler, struct input_dev *dev); 00001311 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); 00001312 void (*disconnect)(struct input_handle *handle); 00001313 void (*start)(struct input_handle *handle); 00001314 00001315 const struct file_operations *fops; 00001316 int minor; 00001317 const char *name; 00001318 00001319 const struct input_device_id *id_table; 00001320 00001321 struct list_head h_list; 00001322 struct list_head node; 00001323 };
1306行,private,驱动的私有数据指针。
1308至1313行,一些函数指针,其中,event是Input core向事件驱动程序传递消息时调用的函数。
1315行,fops,事件驱动实现的文件操作集。
1316行,minor,次设备号的起始值。
1317行,name,handler的名字,会出现在/proc/bus/input/handlers。
1319行,id_table,事件驱动支持的id table。
1321行,h_list,将所有handle连接起来。
1322行,node,作为全局链表input_handler_list的节点,input_handler_list将所有handler节点连成一个双向循环链表。
容易被这里的链表弄晕,索性一次把它讲清楚,下面看struct input_handle的定义,注意,是handle,不是handler。
00001337 struct input_handle { 00001338 00001339 void *private; 00001340 00001341 int open; 00001342 const char *name; 00001343 00001344 struct input_dev *dev; 00001345 struct input_handler *handler; 00001346 00001347 struct list_head d_node; 00001348 struct list_head h_node; 00001349 };
1339行,private,handler的私有数据指针。
1341行,open,handle的打开计数。
1342行,name,handle的名字。
1344行,dev,此handle依附的Input设备。
1345行,handler,通过此handle与设备进行交互的handler。
1347,d_node,1348,h_node,细心的话可以发现在说struct input_dev时也有两个关于链表的成员,而struct input_handler和struct input_handle也有两个关于链表的成员,它们三者形成的关系如下图所示:
应该很清楚了吧,这里只以其中的一个input_dev和handler为例画出来的图,其他的以此类推。其中input_dev_list和input_handler_list是两条全局的链表,每当调用input_register_device函数时会将Input设备加入到input_dev_list链表的尾部;每当调用input_register_handler函数时会将handler加入到input_handler_list链表的尾部;每当调用input_register_handle函数时会将handle加入到其对应的Input设备的h_list链表的尾部,并且还会该handle加入到其对应的handler的h_list链表的尾部。
回到input_register_device函数,1742行,设置事件位图的同步事件位为1,表示设备支持同步事件。
1745行,清0保留的键值,该键值不会被发送到用户空间。
1748行,清0事件位图中没有设置的位。
1754行,初始化设备的定时器。
1755至1760行,如果dev->rep[REP_DELAY]和dev->rep[REP_PERIOD]的值都为0,那么就给他们和定时器设置一些默认值,具体的函数和变量等用到的时候再说。
1762至1766行,如果dev->getkeycode和dev->setkeycode这两个函数指针没有设置,就为它们赋默认值。
1771行,将设备加入到设备模型中,关于设备模型的就略过了,下文也如此。
1786行,看到了吧,将Input设备加入到input_dev_list链表的尾部。
1788、1789行,遍历input_handler_list链表,每找到一个节点就调用input_attach_handler函数,它的定义如下:
00000840 static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) 00000841 { 00000842 const struct input_device_id *id; 00000843 int error; 00000844 00000845 id = input_match_device(handler, dev); 00000846 if (!id) 00000847 return -ENODEV; 00000848 00000849 error = handler->connect(handler, dev, id); 00000850 if (error && error != -ENODEV) 00000851 printk(KERN_ERR 00000852 "input: failed to attach handler %s to device %s, " 00000853 "error: %d\n", 00000854 handler->name, kobject_name(&dev->dev.kobj), error); 00000855 00000856 return error; 00000857 }
842行,struct input_device_id,关于这个结构体这里就不说了,不过可以看下它的定义,在include/input/mod_devicetable.h中:
00000312 struct input_device_id { 00000313 00000314 kernel_ulong_t flags; 00000315 00000316 __u16 bustype; 00000317 __u16 vendor; 00000318 __u16 product; 00000319 __u16 version; 00000320 00000321 kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; 00000322 kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; 00000323 kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; 00000324 kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; 00000325 kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; 00000326 kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; 00000327 kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; 00000328 kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; 00000329 kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; 00000330 00000331 kernel_ulong_t driver_info; 00000332 };
845行,调用input_match_device函数,定义如下:
00000799 static const struct input_device_id *input_match_device(struct input_handler *handler, 00000800 struct input_dev *dev) 00000801 { 00000802 const struct input_device_id *id; 00000803 int i; 00000804 00000805 for (id = handler->id_table; id->flags || id->driver_info; id++) { 00000806 00000807 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) 00000808 if (id->bustype != dev->id.bustype) 00000809 continue; 00000810 00000811 if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) 00000812 if (id->vendor != dev->id.vendor) 00000813 continue; 00000814 00000815 if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) 00000816 if (id->product != dev->id.product) 00000817 continue; 00000818 00000819 if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) 00000820 if (id->version != dev->id.version) 00000821 continue; 00000822 00000823 MATCH_BIT(evbit, EV_MAX); 00000824 MATCH_BIT(keybit, KEY_MAX); 00000825 MATCH_BIT(relbit, REL_MAX); 00000826 MATCH_BIT(absbit, ABS_MAX); 00000827 MATCH_BIT(mscbit, MSC_MAX); 00000828 MATCH_BIT(ledbit, LED_MAX); 00000829 MATCH_BIT(sndbit, SND_MAX); 00000830 MATCH_BIT(ffbit, FF_MAX); 00000831 MATCH_BIT(swbit, SW_MAX); 00000832 00000833 if (!handler->match || handler->match(handler, dev)) 00000834 return id; 00000835 } 00000836 00000837 return NULL; 00000838 }
805行,循环handler的id_table数组的每一项。
807至821行,都是检查handler的flags标志的,意思也很明显,不多说了。
823至831行,只要弄懂第一个就行了,其他的都是一样的,下面看MATCH_BIT这个宏的定义:
00000792 #define MATCH_BIT(bit, max) \ 00000793 for (i = 0; i < BITS_TO_LONGS(max); i++) \ 00000794 if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ 00000795 break; \ 00000796 if (i != BITS_TO_LONGS(max)) \ 00000797 continue;
以MATCH_BIT(evbit, EV_MAX);为例,把宏展开后是这样的:
00000793 for (i = 0; i < BITS_TO_LONGS(EV_MAX); i++) 00000794 if ((id->evbit [i] & dev->evbit [i]) != id->evbit [i]) 00000795 break; 00000796 if (i != BITS_TO_LONGS(EV_MAX)) 00000797 continue;
以id->evbit[i]的值为准,如果id-evbit[i]不等于dev-evbit[i],那么跳出793行的for循环,接着判断796行,如果条件不成立,那么后面的就不用比较了,直接进行id_table数组的下一个元素的比较。
824至831行,和上面相同。
833行,至少要满足其中一个条件,否则Input设备就不能与handler匹配。
回到input_attach_handler函数,849行,调用handler的connect函数,等讲事件驱动程序evdev.c的时候再讲。
回到input_register_device函数,1791行,proc文件系统相关的,略过。至此,input_register_device函数讲完了,回到gpio_keys_probe函数,这里把剩下的代码贴出来,省得再回去看。