前言
以前在移植Qt到開發板上時只知道在配置文件中需要指定觸摸屏的設備文件/dev/input/event0,僅此而已。直到一年半前突然想到用紅外遙控器控制Tiny6410開發板上的Android系統,從而代替物理按鍵。實現原理是很簡單的,就是首先解碼紅外信號,然后根據解碼出的鍵值模擬一個按鍵信號。既然要模擬按鍵信號,那得首先找到按鍵信號產生的地方,通過查看內核編譯生成的文件知道drivers/input/keyboard/gpio_keys.c文件是產生按鍵信號的源頭,這是一個通用的用IO口模擬鍵盤的驅動程序。別小看這樣一個功能,這是開發Android機頂盒、Android盒子必須要接觸到的。
雖說當時功能是實現了,但是對Linux的整個Input子系統的了解一點都不深入,本文就是來解決這個問題的。基於Linux-2.6.36版本,本文講解的Input子系統的主線是這樣的:和前面講SPI、IIC子系統的方法類似,先講Input核心的初始化,再從底層往上,分別是Input設備驅動程序(以drivers/input/keyboard/gpio_keys.c為例)、Input核心、Input事件驅動程序(以drivers/input/evdev.c為例)。按照輸入信號的產生以及在內核中的傳遞過程,最后到應用程序這條線路,從而深入理解Linux的Input子系統。
先給出Linux Input子系統的架構圖,如下圖所示。

Linux Input子系統架構圖
下面開始進入Input子系統的學習。
首先找到Input子系統的初始化函數,它是位於drivers/input/input.c中的input_init函數:
00002052 static int __init input_init(void) 00002053 { 00002054 int err; 00002055 00002056 err = class_register(&input_class); 00002057 if (err) { 00002058 printk(KERN_ERR "input: unable to register input_dev class\n"); 00002059 return err; 00002060 } 00002061 00002062 err = input_proc_init(); 00002063 if (err) 00002064 goto fail1; 00002065 00002066 err = register_chrdev(INPUT_MAJOR, "input", &input_fops); 00002067 if (err) { 00002068 printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); 00002069 goto fail2; 00002070 } 00002071 00002072 return 0; 00002073 00002074 fail2: input_proc_exit(); 00002075 fail1: class_unregister(&input_class); 00002076 return err; 00002077 }
2056行,向系統注冊input_class這么一個類,以后向Input子系統注冊設備時,所注冊的設備都會從屬於這個類。
2062行,proc文件系統相關的,不細講,但可以看下它的定義:
00001110 static int __init input_proc_init(void) 00001111 { 00001112 struct proc_dir_entry *entry; 00001113 00001114 proc_bus_input_dir = proc_mkdir("bus/input", NULL); 00001115 if (!proc_bus_input_dir) 00001116 return -ENOMEM; 00001117 00001118 entry = proc_create("devices", 0, proc_bus_input_dir, 00001119 &input_devices_fileops); 00001120 if (!entry) 00001121 goto fail1; 00001122 00001123 entry = proc_create("handlers", 0, proc_bus_input_dir, 00001124 &input_handlers_fileops); 00001125 if (!entry) 00001126 goto fail2; 00001127 00001128 return 0; 00001129 00001130 fail2: remove_proc_entry("devices", proc_bus_input_dir); 00001131 fail1: remove_proc_entry("bus/input", NULL); 00001132 return -ENOMEM; 00001133 }
1114行,很明顯,在/proc下創建一個目錄bus/input。
1118行,在/proc/bus/input目錄下創建proc文件,文件名為devices。
1123行,在/proc/bus/input目錄下創建proc文件,文件名為handlers。
回到input_init函數,2066行,注冊字符設備,主設備號為INPUT_MAJOR,它的值為13,該設備的文件操集作實例為input_fops,它的定義為:
00002047 static const struct file_operations input_fops = { 00002048 .owner = THIS_MODULE, 00002049 .open = input_open_file, 00002050 };
可以看到,里面只將open函數指針指向input_open_file函數,這個函數放到最后再說。
input_init函數說完了,下面進入Input設備驅動程序,也就是Input子系統的最底層部分。首先看drivers/input/keyboard/gpio_keys.c驅動程序的初始化函數gpio_keys_init的定義:
00000632 static int __init gpio_keys_init(void) 00000633 { 00000634 return platform_driver_register(&gpio_keys_device_driver); 00000635 }
這是一個平台驅動,關於平台設備和平台驅動綁定過程應該都很了解了吧,634行,platform_driver_register函數參數gpio_keys_device_driver的定義:
00000620 static struct platform_driver gpio_keys_device_driver = { 00000621 .probe = gpio_keys_probe, 00000622 .remove = __devexit_p(gpio_keys_remove), 00000623 .driver = { 00000624 .name = "gpio-keys", 00000625 .owner = THIS_MODULE, 00000626 #ifdef CONFIG_PM 00000627 .pm = &gpio_keys_pm_ops, 00000628 #endif 00000629 } 00000630 };
注意,該結構體實例里沒有為id_table變量賦值,因此寫平台設備結構體實例的時候name成員的值要設置為gpio-keys,這樣才能與該驅動匹配和綁定,從而該驅動中的probe函數才會被調用。下面看gpio_keys_probe函數的定義:
00000443 static int __devinit gpio_keys_probe(struct platform_device *pdev) 00000444 { 00000445 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 00000446 struct gpio_keys_drvdata *ddata; 00000447 struct device *dev = &pdev->dev; 00000448 struct input_dev *input; 00000449 int i, error; 00000450 int wakeup = 0; 00000451 00000452 ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + 00000453 pdata->nbuttons * sizeof(struct gpio_button_data), 00000454 GFP_KERNEL); 00000455 input = input_allocate_device(); 00000456 if (!ddata || !input) { 00000457 dev_err(dev, "failed to allocate state\n"); 00000458 error = -ENOMEM; 00000459 goto fail1; 00000460 } 00000461 00000462 ddata->input = input; 00000463 ddata->n_buttons = pdata->nbuttons; 00000464 ddata->enable = pdata->enable; 00000465 ddata->disable = pdata->disable; 00000466 mutex_init(&ddata->disable_lock); 00000467 00000468 platform_set_drvdata(pdev, ddata); 00000469 input_set_drvdata(input, ddata); 00000470 00000471 input->name = pdev->name; 00000472 input->phys = "gpio-keys/input0"; 00000473 input->dev.parent = &pdev->dev; 00000474 input->open = gpio_keys_open; 00000475 input->close = gpio_keys_close; 00000476 00000477 input->id.bustype = BUS_HOST; 00000478 input->id.vendor = 0x0001; 00000479 input->id.product = 0x0001; 00000480 input->id.version = 0x0100; 00000481 00000482 /* Enable auto repeat feature of Linux input subsystem */ 00000483 if (pdata->rep) 00000484 __set_bit(EV_REP, input->evbit); 00000485 00000486 for (i = 0; i < pdata->nbuttons; i++) { 00000487 struct gpio_keys_button *button = &pdata->buttons[i]; 00000488 struct gpio_button_data *bdata = &ddata->data[i]; 00000489 unsigned int type = button->type ?: EV_KEY; 00000490 00000491 bdata->input = input; 00000492 bdata->button = button; 00000493 00000494 error = gpio_keys_setup_key(pdev, bdata, button); 00000495 if (error) 00000496 goto fail2; 00000497 00000498 if (button->wakeup) 00000499 wakeup = 1; 00000500 00000501 input_set_capability(input, type, button->code); 00000502 } 00000503 00000504 error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); 00000505 if (error) { 00000506 dev_err(dev, "Unable to export keys/switches, error: %d\n", 00000507 error); 00000508 goto fail2; 00000509 } 00000510 00000511 error = input_register_device(input); 00000512 if (error) { 00000513 dev_err(dev, "Unable to register input device, error: %d\n", 00000514 error); 00000515 goto fail3; 00000516 } 00000517 00000518 /* get current state of buttons */ 00000519 for (i = 0; i < pdata->nbuttons; i++) 00000520 gpio_keys_report_event(&ddata->data[i]); 00000521 input_sync(input); 00000522 00000523 device_init_wakeup(&pdev->dev, wakeup); 00000524 00000525 return 0; 00000526 00000527 fail3: 00000528 sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); 00000529 fail2: 00000530 while (--i >= 0) { 00000531 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); 00000532 if (ddata->data[i].timer_debounce) 00000533 del_timer_sync(&ddata->data[i].timer); 00000534 cancel_work_sync(&ddata->data[i].work); 00000535 gpio_free(pdata->buttons[i].gpio); 00000536 } 00000537 00000538 platform_set_drvdata(pdev, NULL); 00000539 fail1: 00000540 input_free_device(input); 00000541 kfree(ddata); 00000542 00000543 return error; 00000544 }
445行,獲取平台設備數據。
452行,為struct gpio_keys_drvdata對象分配內存,注意,另外還分配pdata->nbuttons * sizeof(struct gpio_button_data)內存,pdata->nbuttons的值為按鍵的個數。struct gpio_keys_platform_data的定義在include/linux/gpio_keys.h:
00000016 struct gpio_keys_platform_data { 00000017 struct gpio_keys_button *buttons; 00000018 int nbuttons; 00000019 unsigned int rep:1; /* enable input subsystem auto repeat */ 00000020 int (*enable)(struct device *dev); 00000021 void (*disable)(struct device *dev); 00000022 };
17行,buttons,指向板文件中定義的struct gpio_keys_button數組。
18行,nbuttons,按鍵的個數。
19行,rep,是否支持按鍵自動重復。
20、21行,使能和失能按鍵的函數指針。
下面看一下struct gpio_keys_drvdata的定義:
00000038 struct gpio_keys_drvdata { 00000039 struct input_dev *input; 00000040 struct mutex disable_lock; 00000041 unsigned int n_buttons; 00000042 int (*enable)(struct device *dev); 00000043 void (*disable)(struct device *dev); 00000044 struct gpio_button_data data[0]; 00000045 };
39行,input,當前Input設備。
41行,n_buttons,按鍵的個數。
44行,是一個變長數組,當獲取到平台數據時才能確定該數組的長度。看下該數組類型struct gpio_button_data的定義:
00000029 struct gpio_button_data { 00000030 struct gpio_keys_button *button; 00000031 struct input_dev *input; 00000032 struct timer_list timer; 00000033 struct work_struct work; 00000034 int timer_debounce; /* in msecs */ 00000035 bool disabled; 00000036 };
先看31行,input,設備的指針。
32行,timer,用來延時的定時器。
33行,work,工作隊列。
34行,timer_debounce,定時器的定時時間,單位為ms。
35行,disabled,按鍵是否已經使能。
看回30行,struct gpio_keys_button的定義在include/linux/gpio_keys.h中:
00000004 struct gpio_keys_button { 00000005 /* Configuration parameters */ 00000006 int code; /* input event code (KEY_*, SW_*) */ 00000007 int gpio; 00000008 int active_low; 00000009 char *desc; 00000010 int type; /* input event type (EV_KEY, EV_SW) */ 00000011 int wakeup; /* configure the button as a wake-up source */ 00000012 int debounce_interval; /* debounce ticks interval in msecs */ 00000013 bool can_disable; 00000014 };
6行,code,鍵值。
7行,gpio,所使用的IO口。
8行,active_low,1表示低電平有效。
9行,desc,按鍵的名字。
10行,type,按鍵的事件類型。
11行,wakeup,1表示按鍵作為喚醒源。
12行,debounce_interval,延時消抖所需要的時間,單位為ms。
13行,can_disable,按鍵是否可以失能。
回到gpio_keys_probe函數,455行,分配Input設備,input_allocate_device函數在drivers/input/input.c里定義:
00001555 struct input_dev *input_allocate_device(void) 00001556 { 00001557 struct input_dev *dev; 00001558 00001559 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); 00001560 if (dev) { 00001561 dev->dev.type = &input_dev_type; 00001562 dev->dev.class = &input_class; 00001563 device_initialize(&dev->dev); 00001564 mutex_init(&dev->mutex); 00001565 spin_lock_init(&dev->event_lock); 00001566 INIT_LIST_HEAD(&dev->h_list); 00001567 INIT_LIST_HEAD(&dev->node); 00001568 00001569 __module_get(THIS_MODULE); 00001570 } 00001571 00001572 return dev; 00001573 }
1557行,看下struct input_dev結構體在include/linux/input.h中的定義:
00001150 struct input_dev { 00001151 const char *name; 00001152 const char *phys; 00001153 const char *uniq; 00001154 struct input_id id; 00001155 00001156 unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; 00001157 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; 00001158 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; 00001159 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; 00001160 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; 00001161 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; 00001162 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; 00001163 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; 00001164 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; 00001165 00001166 unsigned int hint_events_per_packet; 00001167 00001168 unsigned int keycodemax; 00001169 unsigned int keycodesize; 00001170 void *keycode; 00001171 int (*setkeycode)(struct input_dev *dev, 00001172 unsigned int scancode, unsigned int keycode); 00001173 int (*getkeycode)(struct input_dev *dev, 00001174 unsigned int scancode, unsigned int *keycode); 00001175 00001176 struct ff_device *ff; 00001177 00001178 unsigned int repeat_key; 00001179 struct timer_list timer; 00001180 00001181 int rep[REP_CNT]; 00001182 00001183 struct input_mt_slot *mt; 00001184 int mtsize; 00001185 int slot; 00001186 00001187 struct input_absinfo *absinfo; 00001188 00001189 unsigned long key[BITS_TO_LONGS(KEY_CNT)]; 00001190 unsigned long led[BITS_TO_LONGS(LED_CNT)]; 00001191 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; 00001192 unsigned long sw[BITS_TO_LONGS(SW_CNT)]; 00001193 00001194 int (*open)(struct input_dev *dev); 00001195 void (*close)(struct input_dev *dev); 00001196 int (*flush)(struct input_dev *dev, struct file *file); 00001197 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 00001198 00001199 struct input_handle *grab; 00001200 00001201 spinlock_t event_lock; 00001202 struct mutex mutex; 00001203 00001204 unsigned int users; 00001205 bool going_away; 00001206 00001207 bool sync; 00001208 00001209 struct device dev; 00001210 00001211 struct list_head h_list; 00001212 struct list_head node; 00001213 };
1151行,name,設備的名字。
1152行,phys,設備在系統層次結構中的路徑。
1153行,uniq,設備的識別碼。
1154行,id,還是ID,直接看它的定義更直接。
00000043 struct input_id { 00000044 __u16 bustype; 00000045 __u16 vendor; 00000046 __u16 product; 00000047 __u16 version; 00000048 };
