Linux驅動開發十六.input系統——3.系統自帶的input驅動

2022-08-29 06:01:26

前面兩章我們通過input子系統構建了一個按鍵型別的輸入裝置的驅動,其實Linux的核心還提供了一套基於GPIO的按鍵驅動程式,和LED裝置一樣,我們只需要在編譯核心的過程中進行設定然後在裝置樹中定義好裝置節點就可以直接使用了。

設定核心

在使用核心提供的input子系統驅動前要將驅動使能,可以按照下面說明中的路徑進行設定

 從上面的介紹可以看到,這個設定在.config裡時CONFIG_KEYBOARD_GPIO,在該設定被使能以後,.config檔案下的這個設定值就會變成y

並且可以從定位下面哪行Defined看到具體的設定(drivers/input/keyboard/Kconfig)

 

 並且在drivers/input/keyboard路徑下的Makefile裡,可以看到我們設定的CONFIG_KEYBOARD_GPIO對應的規則檔案

 

 也就是說我們需要關注的就是gpio_keys.c這個檔案。

從這個gpio_keys.c檔案裡,我們可以看出來,其實這個驅動也是一個platform驅動,和platform_dev裝置的匹配規則也可以在檔案中找到

 

上面就是platform_driver的定義,在沒有裝置樹的情況下我們可以直接定義一個platform裝置,裝置的name屬性的值就是gpio-keys。如果在裝置樹下,匹配的規則要去找of_match_table裡面的gpio_keys_of_match變數

 

也就是說,我們這個裝置樹的節點必須是gpio-keys。

裝置樹設定

裝置樹的設定我們可以先看下參考檔案Documentation/devicetree/bindings/input/gpio-keys.txt

Device-Tree bindings for input/gpio_keys.c keyboard driver

Required properties:
    - compatible = "gpio-keys";

Optional properties:
    - autorepeat: Boolean, Enable auto repeat feature of Linux input
      subsystem.

Each button (key) is represented as a sub-node of "gpio-keys":
Subnode properties:

    - gpios: OF device-tree gpio specification.
    - interrupts: the interrupt line for that input.
    - label: Descriptive name of the key.
    - linux,code: Keycode to emit.

Note that either "interrupts" or "gpios" properties can be omitted, but not
both at the same time. Specifying both properties is allowed.

Optional subnode-properties:
    - linux,input-type: Specify event type this button/key generates.
      If not specified defaults to <1> == EV_KEY.
    - debounce-interval: Debouncing interval time in milliseconds.
      If not specified defaults to 5.
    - gpio-key,wakeup: Boolean, button can wake-up the system.
    - linux,can-disable: Boolean, indicates that button is connected
      to dedicated (not shared) interrupt which can be disabled to
      suppress events from the button.

Example nodes:

    gpio_keys {
            compatible = "gpio-keys";
            #address-cells = <1>;
            #size-cells = <0>;
            autorepeat;
            button@21 {
                label = "GPIO Key UP";
                linux,code = <v103>;
                gpios = <&gpio1 0 1>;
            };
            button@22 {
                label = "GPIO Key DOWN";
                linux,code = <108>;
                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
            };
            ...

上面的範例已經給的很清楚了,我們只需要按照上面的套路,去完善裝置樹就可以了。                                                                                                                                                                                                                                                                                                         

gpio_keys {
    compatible = "gpio-keys";
    #address-cells = <1>;
    #cell-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_key>;

    key0 {
        label = "GPIO KEY Enter";
        linux,code = <KEY_ENTER>;
        gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
    };
};

我們把按鍵的鍵值模擬成確認鍵,因為在下面我們要做的驅動是LCD螢幕,但是螢幕在一定時間後會熄屏,在沒有鍵盤的時候就需要用到按鍵模仿確認鍵去重新點亮螢幕。

編譯裝置樹,用新的裝置樹檔案啟動開發板,可以在dev/input路徑下看到有兩個event檔案,具體哪個檔案是咱們的按鍵裝置不一定,只能通過hexdump挨個試驗一下

 

執行指令以後按下按鍵,看看有沒有資訊列印出來。如果有資料列印,就是這個檔案。KEY_ENTER的值是28

#define KEY_ENTER        28

換算下來就是0x1C,和列印出來的資料一致(倒數第3列)。

這樣就用到了核心自帶的按鍵驅動。但是現在還不能像確認鍵一樣使用按鍵,後面再看看吧!