Linux Input子系统(中)--设备的注册和打开


这节结合even handler来分析设备的注册和打开的过程,在设备注册之前,必须先初始化INPUT子系统,由input_init()函数来完成

相关阅读:Linux Input子系统(上)--概述

  1. static int __init input_init(void)  
  2. {  
  3.     int err;  
  4.   
  5.     input_init_abs_bypass();  
  6.   
  7.     err = class_register(&input_class);//注册input类   
  8.     if (err) {  
  9.         printk(KERN_ERR "input: unable to register input_dev class\n");  
  10.         return err;  
  11.     }  
  12.   
  13.     err = input_proc_init();//创建/proc中的项   
  14.     if (err)  
  15.         goto fail1;  
  16.   
  17.     /*注册设备,设备号为INPUT_MAJOR(13),后面注册的输入设备都使用该主设备号*/  
  18.     err = register_chrdev(INPUT_MAJOR, "input", &input_fops);  
  19.     if (err) {  
  20.         printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);  
  21.         goto fail2;  
  22.     }  
  23.   
  24.     return 0;  
  25.   
  26.  fail2: input_proc_exit();  
  27.  fail1: class_unregister(&input_class);  
  28.     return err;  
  29. }  

input_fops中只定义了open函数。

  1. static const struct file_operations input_fops = {  
  2.     .owner = THIS_MODULE,  
  3.     .open = input_open_file,  
  4. };  

我们需要在设备驱动层中完成输入设备的注册,通过调用input_register_device()函数来完成,该函数的一个重要任务就是完成设备与事件驱动的匹配。

  1. int input_register_device(struct input_dev *dev)  
  2. {  
  3.     static atomic_t input_no = ATOMIC_INIT(0);  
  4.     struct input_handler *handler;  
  5.     const char *path;  
  6.     int error;  
  7.   
  8.     __set_bit(EV_SYN, dev->evbit);  
  9.   
  10.     /* 
  11.      * If delay and period are pre-set by the driver, then autorepeating 
  12.      * is handled by the driver itself and we don't do it in input.c. 
  13.      */  
  14.   
  15.     init_timer(&dev->timer);  
  16.     if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {  
  17.         dev->timer.data = (long) dev;  
  18.         dev->timer.function = input_repeat_key;  
  19.         dev->rep[REP_DELAY] = 250;  
  20.         dev->rep[REP_PERIOD] = 33;  
  21.     }  
  22.   
  23.     /*没有定义设备的getkeycode函数,则使用默认的获取键值函数*/  
  24.     if (!dev->getkeycode)  
  25.         dev->getkeycode = input_default_getkeycode;  
  26.   
  27.     /*没有定义设备的setkeycode函数,则使用默认的设定键值函数*/  
  28.     if (!dev->setkeycode)  
  29.         dev->setkeycode = input_default_setkeycode;  
  30.   
  31.     /*设定dev的名字*/  
  32.     dev_set_name(&dev->dev, "input%ld",  
  33.              (unsigned long) atomic_inc_return(&input_no) - 1);  
  34.   
  35.     /*添加设备*/  
  36.     error = device_add(&dev->dev);  
  37.     if (error)  
  38.         return error;  
  39.   
  40.     path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);  
  41.     printk(KERN_INFO "input: %s as %s\n",  
  42.         dev->name ? dev->name : "Unspecified device", path ? path : "N/A");  
  43.     kfree(path);  
  44.   
  45.     error = mutex_lock_interruptible(&input_mutex);  
  46.     if (error) {  
  47.         device_del(&dev->dev);  
  48.         return error;  
  49.     }  
  50.   
  51.     /*将设备添加到input_dev_list设备链表*/  
  52.     list_add_tail(&dev->node, &input_dev_list);  
  53.   
  54.     /*遍历input_handler_list,试图与每一个handler进行匹配*/  
  55.     list_for_each_entry(handler, &input_handler_list, node)  
  56.         input_attach_handler(dev, handler);  
  57.   
  58.     input_wakeup_procfs_readers();  
  59.   
  60.     mutex_unlock(&input_mutex);  
  61.   
  62.     return 0;  
  63. }

 

  1. static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)  
  2. {  
  3.     const struct input_device_id *id;  
  4.     int error;  
  5.   
  6.     /*如果定义了handler的黑名单,并且设备和黑名单中的id匹配了,则该设备不能和handler匹配*/  
  7.     if (handler->blacklist && input_match_device(handler->blacklist, dev))  
  8.         return -ENODEV;  
  9.   
  10.     id = input_match_device(handler->id_table, dev);  
  11.     if (!id)  
  12.         return -ENODEV;  
  13.   
  14.     /*执行handler的connect,建立handler与设备之间的联系*/  
  15.     error = handler->connect(handler, dev, id);  
  16.     if (error && error != -ENODEV)  
  17.         printk(KERN_ERR  
  18.             "input: failed to attach handler %s to device %s, "  
  19.             "error: %d\n",  
  20.             handler->name, kobject_name(&dev->dev.kobj), error);  
  21.   
  22.     return error;  
  23. }  
  • 1
  • 2
  • 3
  • 下一页

相关内容

    暂无相关文章