Linux/Android——輸入子系統input_event傳遞 (二)【轉】


本文轉載自:http://blog.csdn.net/jscese/article/details/42099381

 在前文 Linux/Android——usb觸摸屏驅動 - usbtouchscreen (一) 中記錄了如何在kernel中添加input device 類型為touchscreen的驅動,

這在整個輸入體系中是最下層的設備驅動部分,往上一層就是linux內核的管理驅動input系統,kernel中的源碼位置:/kernel/drivers/input/input.c

 

                                              撰寫不易,轉載需注明出處:http://blog.csdn.net/jscese/article/details/42099381

 

到目前已經完全調通,可以正常使用了,現在記錄一下這段時間接觸到的Android 輸入input 系統,先看一張網上的層次圖,蠻不錯的:
               

         

 

上一篇博客里面的 usbtouchscreen 就是對應上圖的I2c module的位置,而在kernel中input的核心就是input.c .

input_dev:

 這個結構體表述的是一個輸入設備的相關信息,在usbtouchscreen 驅動中的 usbtouch_probe 會初始化input_dev,作為usbtouch設備的一部分.

會對 input_dev  做一系列的初始化,設置參數之類的,具體可參考之前博客

input_dev 結構原型如下,/kernel/include/linux/input.h中定義:

 

[objc]  view plain  copy
 
  1. /** 
  2.  * struct input_dev - represents an input device 
  3.  * @name: name of the device 
  4.  * @phys: physical path to the device in the system hierarchy 
  5.  * @uniq: unique identification code for the device (if device has it) 
  6.  * @id: id of the device (struct input_id) 
  7.  * @propbit: bitmap of device properties and quirks 
  8.  * @evbit: bitmap of types of events supported by the device (EV_KEY, 
  9.  *  EV_REL, etc.) 
  10.  * @keybit: bitmap of keys/buttons this device has 
  11.  * @relbit: bitmap of relative axes for the device 
  12.  * @absbit: bitmap of absolute axes for the device 
  13.  * @mscbit: bitmap of miscellaneous events supported by the device 
  14.  * @ledbit: bitmap of leds present on the device 
  15.  * @sndbit: bitmap of sound effects supported by the device 
  16.  * @ffbit: bitmap of force feedback effects supported by the device 
  17.  * @swbit: bitmap of switches present on the device 
  18.  * @hint_events_per_packet: average number of events generated by the 
  19.  *  device in a packet (between EV_SYN/SYN_REPORT events). Used by 
  20.  *  event handlers to estimate size of the buffer needed to hold 
  21.  *  events. 
  22.  * @keycodemax: size of keycode table 
  23.  * @keycodesize: size of elements in keycode table 
  24.  * @keycode: map of scancodes to keycodes for this device 
  25.  * @getkeycode: optional legacy method to retrieve current keymap. 
  26.  * @setkeycode: optional method to alter current keymap, used to implement 
  27.  *  sparse keymaps. If not supplied default mechanism will be used. 
  28.  *  The method is being called while holding event_lock and thus must 
  29.  *  not sleep 
  30.  * @ff: force feedback structure associated with the device if device 
  31.  *  supports force feedback effects 
  32.  * @repeat_key: stores key code of the last key pressed; used to implement 
  33.  *  software autorepeat 
  34.  * @timer: timer for software autorepeat 
  35.  * @rep: current values for autorepeat parameters (delay, rate) 
  36.  * @mt: pointer to array of struct input_mt_slot holding current values 
  37.  *  of tracked contacts 
  38.  * @mtsize: number of MT slots the device uses 
  39.  * @slot: MT slot currently being transmitted 
  40.  * @trkid: stores MT tracking ID for the current contact 
  41.  * @absinfo: array of &struct input_absinfo elements holding information 
  42.  *  about absolute axes (current value, min, max, flat, fuzz, 
  43.  *  resolution) 
  44.  * @key: reflects current state of device's keys/buttons 
  45.  * @led: reflects current state of device's LEDs 
  46.  * @snd: reflects current state of sound effects 
  47.  * @sw: reflects current state of device's switches 
  48.  * @open: this method is called when the very first user calls 
  49.  *  input_open_device(). The driver must prepare the device 
  50.  *  to start generating events (start polling thread, 
  51.  *  request an IRQ, submit URB, etc.) 
  52.  * @close: this method is called when the very last user calls 
  53.  *  input_close_device(). 
  54.  * @flush: purges the device. Most commonly used to get rid of force 
  55.  *  feedback effects loaded into the device when disconnecting 
  56.  *  from it 
  57.  * @event: event handler for events sent _to_ the device, like EV_LED 
  58.  *  or EV_SND. The device is expected to carry out the requested 
  59.  *  action (turn on a LED, play sound, etc.) The call is protected 
  60.  *  by @event_lock and must not sleep 
  61.  * @grab: input handle that currently has the device grabbed (via 
  62.  *  EVIOCGRAB ioctl). When a handle grabs a device it becomes sole 
  63.  *  recipient for all input events coming from the device 
  64.  * @event_lock: this spinlock is is taken when input core receives 
  65.  *  and processes a new event for the device (in input_event()). 
  66.  *  Code that accesses and/or modifies parameters of a device 
  67.  *  (such as keymap or absmin, absmax, absfuzz, etc.) after device 
  68.  *  has been registered with input core must take this lock. 
  69.  * @mutex: serializes calls to open(), close() and flush() methods 
  70.  * @users: stores number of users (input handlers) that opened this 
  71.  *  device. It is used by input_open_device() and input_close_device() 
  72.  *  to make sure that dev->open() is only called when the first 
  73.  *  user opens device and dev->close() is called when the very 
  74.  *  last user closes the device 
  75.  * @going_away: marks devices that are in a middle of unregistering and 
  76.  *  causes input_open_device*() fail with -ENODEV. 
  77.  * @sync: set to %true when there were no new events since last EV_SYN 
  78.  * @dev: driver model's view of this device 
  79.  * @h_list: list of input handles associated with the device. When 
  80.  *  accessing the list dev->mutex must be held 
  81.  * @node: used to place the device onto input_dev_list 
  82.  */  
  83. struct input_dev {  
  84.     const charchar *name;  
  85.     const charchar *phys;  
  86.     const charchar *uniq;  
  87.     struct input_id id;  
  88.   
  89.     unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];  
  90.   
  91.     unsigned long evbit[BITS_TO_LONGS(EV_CNT)];  
  92.     unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];  
  93.     unsigned long relbit[BITS_TO_LONGS(REL_CNT)];  
  94.     unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];  
  95.     unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];  
  96.     unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];  
  97.     unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];  
  98.     unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];  
  99.     unsigned long swbit[BITS_TO_LONGS(SW_CNT)];  
  100.   
  101.     unsigned int hint_events_per_packet;  
  102.   
  103.     unsigned int keycodemax;  
  104.     unsigned int keycodesize;  
  105.     voidvoid *keycode;  
  106.   
  107.     int (*setkeycode)(struct input_dev *dev,  
  108.               const struct input_keymap_entry *ke,  
  109.               unsigned intint *old_keycode);  
  110.     int (*getkeycode)(struct input_dev *dev,  
  111.               struct input_keymap_entry *ke);  
  112.   
  113.     struct ff_device *ff;  
  114.   
  115.     unsigned int repeat_key;  
  116.     struct timer_list timer;  
  117.   
  118.     int rep[REP_CNT];  
  119.   
  120.     struct input_mt_slot *mt;  
  121.     int mtsize;  
  122.     int slot;  
  123.     int trkid;  
  124.   
  125.     struct input_absinfo *absinfo;  
  126.   
  127.     unsigned long key[BITS_TO_LONGS(KEY_CNT)];  
  128.     unsigned long led[BITS_TO_LONGS(LED_CNT)];  
  129.     unsigned long snd[BITS_TO_LONGS(SND_CNT)];  
  130.     unsigned long sw[BITS_TO_LONGS(SW_CNT)];  
  131.   
  132.     int (*open)(struct input_dev *dev);  
  133.     void (*close)(struct input_dev *dev);  
  134.     int (*flush)(struct input_dev *dev, struct file *file);  
  135.     int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);  
  136.   
  137.     struct input_handle __rcu *grab;  
  138.   
  139.     spinlock_t event_lock;  
  140.     struct mutex mutex;  
  141.   
  142.     unsigned int users;  
  143.     bool going_away;  
  144.   
  145.     bool sync;  
  146.   
  147.     struct device dev;  
  148.   
  149.     struct list_head    h_list;  
  150.     struct list_head    node;  
  151. };  


我解釋可能還會誤導,源碼上面的注釋是最好的解釋,都是描述一個input 設備的相關信息.

 

每一個input設備,都需要初始化一個這樣的input_dev結構來描述記錄此設備的一些特性,然后通過input_register_device 注冊到設備總線上以供后續使用

可以到系統運行目錄的/proc/bus/input下 cat devices  查看總線上的已經注冊上的input device

 

 

input_event:

  設備驅動部分往上傳遞的就是觸發的event事件了,還以usbtouchscreen的為例,回調函數為:

[objc]  view plain  copy
 
  1. /***************************************************************************** 
  2.  * Generic Part 
  3.  */  
  4. static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,  
  5.                                  unsigned charchar *pkt, int len)  
  6. {  
  7.     struct usbtouch_device_info *type = usbtouch->type;   
  8.   
  9.     if (!type->read_data(usbtouch, pkt))  
  10.             return;  
  11.   
  12.     input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); // 上報觸摸類型 。touch為按下  
  13.   
  14.     if (swap_xy) {  
  15.         input_report_abs(usbtouch->input, ABS_X, usbtouch->y);  
  16.         input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);  
  17.     } else {  
  18.         input_report_abs(usbtouch->input, ABS_X, usbtouch->x);  
  19.         input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); // 上報絕對坐標值  
  20.     }  
  21.     if (type->max_press)  
  22.         input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);  
  23.     input_sync(usbtouch->input);   // 同步操作  
  24. }  



可以看到通過 input_report_* 上報事件到input.c中,這也就是上面層次圖中的箭頭 9 ,初始在/kernel/include/linux/input.h:

 

[objc]  view plain  copy
 
  1. static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)  
  2. {  
  3.     input_event(dev, EV_KEY, code, !!value);  
  4. }  
  5.   
  6. static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)  
  7. {  
  8.     input_event(dev, EV_REL, code, value);  
  9. }  
  10.   
  11. static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)  
  12. {  
  13.     input_event(dev, EV_ABS, code, value);  
  14. }  

 

 

可以看到不同的report 都調用進了input_event,只是傳參不同,接下來的事就全交由input.c 來做了!

 

[objc]  view plain  copy
 
  1. /** 
  2.  * input_event() - report new input event 
  3.  * @dev: device that generated the event 
  4.  * @type: type of the event 
  5.  * @code: event code 
  6.  * @value: value of the event 
  7.  * 
  8.  * This function should be used by drivers implementing various input 
  9.  * devices to report input events. See also input_inject_event(). 
  10.  * 
  11.  * NOTE: input_event() may be safely used right after input device was 
  12.  * allocated with input_allocate_device(), even before it is registered 
  13.  * with input_register_device(), but the event will not reach any of the 
  14.  * input handlers. Such early invocation of input_event() may be used 
  15.  * to 'seed' initial state of a switch or initial position of absolute 
  16.  * axis, etc. 
  17.  */  
  18. void input_event(struct input_dev *dev,  
  19.          unsigned int type, unsigned int code, int value)  
  20. {  
  21.     unsigned long flags;  
  22.   
  23.     if (is_event_supported(type, dev->evbit, EV_MAX)) {  //判斷是否是注冊時的event類型,驅動probe時注冊input_dev時設置了能響應的event類型  
  24.   
  25.         spin_lock_irqsave(&dev->event_lock, flags); //自旋鎖枷鎖  
  26.   
  27.        add_input_randomness(type, code, value);  
  28.         input_handle_event(dev, type, code, value);  //進一步處理傳上來的這個 event  
  29.         spin_unlock_irqrestore(&dev->event_lock, flags);//解鎖  
  30.     }  
  31. }  


可以看到在這里首先就是過濾了事件類型,這個也是在usbtouchscreen中的probe中初始化過的!

 

類型有如下幾種:

 

[objc]  view plain  copy
 
  1. /* 
  2.  * Event types 
  3.  */  
  4.   
  5. #define EV_SYN          0x00  
  6. #define EV_KEY          0x01  
  7. #define EV_REL          0x02  
  8. #define EV_ABS          0x03  
  9. #define EV_MSC          0x04  
  10. #define EV_SW           0x05  
  11. #define EV_LED          0x11  
  12. #define EV_SND          0x12  
  13. #define EV_REP          0x14  
  14. #define EV_FF           0x15  
  15. #define EV_PWR          0x16  
  16. #define EV_FF_STATUS        0x17  
  17. #define EV_MAX          0x1f  
  18. #define EV_CNT          (EV_MAX+1)  



 

 

input_handle_event:

 由上面的input_event 調入進這個handle處理。這里會根據type進行分類處理:

[objc]  view plain  copy
 
  1. static void input_handle_event(struct input_dev *dev,  
  2.                    unsigned int type, unsigned int code, int value)  
  3. {  
  4.     int disposition = INPUT_IGNORE_EVENT; //初始為不做處理  
  5.   
  6.     switch (type) {  
  7.   
  8.     case EV_SYN:  
  9.         switch (code) {  
  10.         case SYN_CONFIG:  
  11.             disposition = INPUT_PASS_TO_ALL;  
  12.             break;  
  13.   
  14.         case SYN_REPORT:  
  15.             if (!dev->sync) {  
  16.                 dev->sync = true;  
  17.                 disposition = INPUT_PASS_TO_HANDLERS;  
  18.             }  
  19.             break;  
  20.   
  21. ...  
  22.   
  23.     case EV_KEY:  
  24.   
  25.         if (is_event_supported(code, dev->keybit, KEY_MAX) &&  //按鍵code是否被keybit支持  
  26.             !!test_bit(code, dev->key) != value) {  //key是鍵盤當前所有鍵狀態,測試code對應鍵狀態,value傳來事件的按鍵狀態。此句表示按鍵狀態應有變化  
  27.   
  28.             if (value != 2) {  
  29.                 __change_bit(code, dev->key);  //改變key的值以改變按鍵狀態。  
  30.                 if (value)  
  31.                     input_start_autorepeat(dev, code);  //如果按鍵值為按下,則開始重復按鍵操作。具體會不會重復,input_start_autorepeat還會根據evbit中有沒有置位重復事件等判斷。  
  32.                 else  
  33.                     input_stop_autorepeat(dev); //如果是松開按鍵則應停止重復按鍵相關操作。  
  34.             }  
  35.   
  36.             disposition = INPUT_PASS_TO_HANDLERS;  
  37.         }  
  38.         break;  
  39.   
  40. ...  
  41.   
  42.     case EV_ABS:  
  43.         if (is_event_supported(code, dev->absbit, ABS_MAX))  //同上面一樣看是否支持  
  44.             disposition = input_handle_abs_event(dev, code, &value);  //這個函數可以跟進去看,是做為篩選的,第一次是不會返回INPUT_IGNORE_EVENT ,后面如果有跟上次相同的ABS坐標就會被過濾掉,返回IGNORE  
  45. //        err("jscese display disposition vlue ==0x%x,code==0x%x, value== 0x%x\n",disposition,code,value);  
  46.         break;  
  47.   
  48. ...  
  49.   
  50.    }  
  51.   
  52.     if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)  
  53.         dev->sync = false;  
  54.   
  55.     if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)  
  56.         dev->event(dev, type, code, value);   
  57.   
  58.     if (disposition & INPUT_PASS_TO_HANDLERS)  
  59.         input_pass_event(dev, type, code, value);  //更深一步調用 ,最終都是 調用到 event(**)方法  
  60.   
  61. }  



這里先記錄整個輸入系統從設備驅動到上層的關系,以及從kernel中的驅動調用到input系統中的傳遞過程,雖然看到調用了input.c中的一些函數傳遞,但是對input核心還是沒多少概念,

下篇解析記錄一下input這個核心模塊~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM