Linux設備驅動剖析之Input(一)


前言

       以前在移植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 };

 

 


免責聲明!

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



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