歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux Input子系統(中)--設備的注冊和打開

這節結合even handler來分析設備的注冊和打開的過程,在設備注冊之前,必須先初始化INPUT子系統,由input_init()函數來完成

相關閱讀:Linux Input子系統(上)--概述 http://www.linuxidc.com/Linux/2012-07/64419.htm

  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. }  
Copyright © Linux教程網 All Rights Reserved