17.1.2 注册函数input_register_device()(1)

来源:互联网 发布:php autoload怎么用 编辑:程序博客网 时间:2024/05/23 00:31

button_init()函数中的28行调用了input_register_device()函数注册输入设备结构体。input_register_device()函数是输入子系统核心(input core)提供的函数。该函数将input_dev结构体注册到输入子系统核心中,input_dev结构体必须由前面讲的input_allocate_device()函数来分配。input_register_device()函数如果注册失败,必须调用input_free_device()函数释放分配的空间。如果该函数注册成功,在卸载函数中应该调用input_unregister_device()函数来注销输入设备结构体。

1.input_register_device()函数

input_register_device()函数的代码如下:

[cpp] view plaincopyprint?
  1. /** 
  2.  * input_register_device - register device with input core 
  3.  * @dev: device to be registered 
  4.  * 
  5.  * This function registers device with input core. The device must be 
  6.  * allocated with input_allocate_device() and all it's capabilities 
  7.  * set up before registering. 
  8.  * If function fails the device must be freed with input_free_device(). 
  9.  * Once device has been successfully registered it can be unregistered 
  10.  * with input_unregister_device(); input_free_device() should not be 
  11.  * called in this case. 
  12.  */  
  13. int input_register_device(struct input_dev *dev)  
  14. {  
  15.     static atomic_t input_no = ATOMIC_INIT(0);  
  16.     struct input_handler *handler;  
  17.     const char *path;  
  18.     int error;  
  19.   
  20.     /* Every input device generates EV_SYN/SYN_REPORT events. */  
  21.     __set_bit(EV_SYN, dev->evbit);  
  22.   
  23.     /* KEY_RESERVED is not supposed to be transmitted to userspace. */  
  24.     __clear_bit(KEY_RESERVED, dev->keybit);  
  25.   
  26.     /* Make sure that bitmasks not mentioned in dev->evbit are clean. */  
  27.     input_cleanse_bitmasks(dev);  
  28.   
  29.     /* 
  30.      * If delay and period are pre-set by the driver, then autorepeating 
  31.      * is handled by the driver itself and we don't do it in input.c. 
  32.      */  
  33.     init_timer(&dev->timer);  
  34.     if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {  
  35.         dev->timer.data = (long) dev;  
  36.         dev->timer.function = input_repeat_key;  
  37.         dev->rep[REP_DELAY] = 250;  
  38.         dev->rep[REP_PERIOD] = 33;  
  39.     }  
  40.   
  41.     if (!dev->getkeycode)  
  42.         dev->getkeycode = input_default_getkeycode;  
  43.   
  44.     if (!dev->setkeycode)  
  45.         dev->setkeycode = input_default_setkeycode;  
  46.   
  47.     dev_set_name(&dev->dev, "input%ld",  
  48.              (unsigned long) atomic_inc_return(&input_no) - 1);  
  49.   
  50.     error = device_add(&dev->dev);  
  51.     if (error)  
  52.         return error;  
  53.   
  54.     path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);  
  55.     printk(KERN_INFO "input: %s as %s\n",  
  56.         dev->name ? dev->name : "Unspecified device", path ? path : "N/A");  
  57.     kfree(path);  
  58.   
  59.     error = mutex_lock_interruptible(&input_mutex);  
  60.     if (error) {  
  61.         device_del(&dev->dev);  
  62.         return error;  
  63.     }  
  64.   
  65.     list_add_tail(&dev->node, &input_dev_list);  
  66.   
  67.     list_for_each_entry(handler, &input_handler_list, node)  
  68.         input_attach_handler(dev, handler);  
  69.   
  70.     input_wakeup_procfs_readers();  
  71.   
  72.     mutex_unlock(&input_mutex);  
  73.   
  74.     return 0;  
  75. }  


 

 

下面对该函数的主要代码进行分析。

第03~06行,定义了一些函数中将要用到的局部变量。

第07行,调用__set_bit()函数设置input_dev所支持的事件类型。事件类型由input_dev的evbit成员来表示,在这里将其EV_SYN置位,表示设备支持所有的事件。注意,一个设备可以支持一种或者多种事件类型。常用的事件类型如下:

  1. #define EV_SYN          0x00    /*表示设备支持所有的事件*/  
  2. #define EV_KEY          0x01    /*键盘或者按键,表示一个键码*/  
  3. #define EV_REL          0x02    /*鼠标设备,表示一个相对的光标位置结果*/  
  4. #define EV_ABS          0x03    /*手写板产生的值,其是一个绝对整数值*/  
  5. #define EV_MSC          0x04    /*其他类型*/  
  6. #define EV_LED          0x11    /*LED灯设备*/  
  7. #define EV_SND          0x12    /*蜂鸣器,输入声音*/  
  8. #define EV_REP          0x14    /*允许重复按键类型*/  
  9. #define EV_PWR          0x16    /*电源管理事件*/ 

dev_set_name设置input_dev中的device的名字,名字以input0、input1、input2、input3、input4等的形式出现在sysfs文件系统中。

使用device_add()函数将input_dev包含的device结构注册到Linux设备模型中,并可以在sysfs文件系统中表现出来。

打印设备的路径,输出调试信息。

调用list_add_tail()函数将input_dev加入input_dev_list链表中,input_dev_list链表中包含了系统中所有的input_dev设备。