• Linux设备驱动剖析之Input(二)


    分别是总线类型、厂商号、产品号和版本号。

    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
    ",
    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
    ",
    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
    ",
    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
    ",
    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)
    ",
    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
    ",
    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
    ",
    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函数,这里把剩下的代码贴出来,省得再回去看。

  • 相关阅读:
    .Net Core 微服务学习一
    微服务学习一
    软件开发基本接口学习二
    浏览器根对象window之操作方法
    浏览器根对象window之caches
    Angular面试题三
    浏览器根对象window之performance
    Angular面试题二
    浏览器根对象window之screen
    浏览器根对象window之history
  • 原文地址:https://www.cnblogs.com/lknlfy/p/3275814.html
Copyright © 2020-2023  润新知