背景移植矩阵键盘。 矩阵键盘的原理不说明。
设备树evm上的主板具有2×3矩阵键盘,也显示在设备树中。 请参考这个独特的矩阵键盘设备树。
matrix _ keypad : matrix _ keypad @0{ compatible=’ gpio-matrix-keypad ‘; debounce-delay-ms=5; col-scan-delay-us=2; 原始gpios=gpio 315 gpio _ active _ high/* bank 1,pin 15 */gpio 321 gpio _ active _ high/* bank 1,pin 21 */gpio 127 g pin 25 */col-gpios=gpio 123 gpio _ active _ high/* bank 1,pin 23 */gpio 121 gpio _ active _ high/* bank pin 21 */gpio pin 26 */gpio 124 gpio _ active _ high/* bank 1,pin 24 */gpio 122 gpio pin 22 */GPI o120 gpio _ active _ high/* bank 1,Pio pin 19 */gpio 117 gpio pin 17 */gpio 118g Pio _ active _ high/* bank 1,pin18 */gpio1 16 GPIO_ACTIVE_HIGH; /*银行1,pin16 */linux, ky map=0x 0000003 b/* f1 */0x 00010010/* q */0x 0002001 e/* a*/0x 0003002 c/* z */0x 00040002/*0x 00005 000000000x0x 0100003 c/* F2 */0x 01010011/* w */0x 0102001 f0x 01040003/*2*/0x 01050006/*0x 01060009/*8/0x 01070000 b
* 3 */ 0x02050007 /* 6 */ 0x0206000a /* 9 */ 0x02070026 /* L */ 0x02080069 /* LEFT */ 0x02090041 /* F7 */ 0x0300003e /* F4 */ 0x03010013 /* R */ 0x03020021 /* F */ 0x0303002f /* V */ 0x0304001d /* LEFTCTRL */ 0x0305002a /* LEFTSHIFT */ 0x03060067 /* UP */ 0x0307006c /* DOWN */ 0x0308006a /* RIGHT */ 0x03090042>; /* F8 */ };&am33xx_pinmux { pinctrl-names = “default”; pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>; matrix_keypad_s0: matrix_keypad_s0 { pinctrl-single,pins = < 0x64 PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */ 0x6c PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio1_27 */ 0x194 PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio3_15 */ 0x1AC PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio3_21 */ 0x40 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_16 */ 0x44 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_17 */ 0x48 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_18 */ 0x4c PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_19 */ 0x50 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_20 */ 0x54 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ 0x58 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */ 0x5c PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_23 */ 0x60 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_24 */ 0x68 PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */ >; }; … …};
第一部分是设置按键的keymap;第二部分是设置管脚。
keymap
keymap的设置可以参考Documentation/devicetree/bindings/input/matrix-keymap.tx
在这里面可以看到keymap值的计算方式:
row << 24 | column << 16 | key-code
那么key-code又怎么看呢?可以参考Documentation/input/event-codes.txt文档
EV_KEY:———-EV_KEY events take the form KEY_<name> or BTN_<name>. For example, KEY_A is usedto represent the ‘A’ key on a keyboard. When a key is depressed, an event withthe key’s code is emitted with value 1. When the key is released, an event isemitted with value 0. Some hardware send events when a key is repeated. Theseevents have a value of 2. In general, KEY_<name> is used for keyboard keys, andBTN_<name> is used for other types of momentary switch events.
可以在内核源码中搜索KEY_A,找到对应的宏定义。可以参看arch/arm/boot/dts/include/dt-bindings/input/input.h。
小工具
知道了keymap的是如何计算的,但是这么多按键,一个个的算,太麻烦,写个小程序。
#include <stdio.h>#include “input.h”typedef struct { char *name; int key_val;}key_map_t;key_map_t keys[] = { {“F1”, KEY_F1}, {“F2”, KEY_F2}, {“F3”, KEY_F3}, {“F4”, KEY_F4}, {“Q”, KEY_Q}, {“W”, KEY_W}, {“E”, KEY_E}, {“R”, KEY_R}, {“A”, KEY_A}, {“S”, KEY_S}, {“D”, KEY_D}, {“F”, KEY_F}, {“Z”, KEY_Z}, {“X”, KEY_X}, {“C”, KEY_C}, {“V”, KEY_V}, {“1”, KEY_1}, {“2”, KEY_2}, {“3”, KEY_3}, {“LEFTCTRL”, KEY_LEFTCTRL}, {“4”, KEY_4}, {“5”, KEY_5}, {“6”, KEY_6}, {“LEFTSHIFT”, KEY_LEFTSHIFT}, {“7”, KEY_7}, {“8”, KEY_8}, {“9”, KEY_9}, {“UP”, KEY_UP}, {“MINUS”, KEY_MINUS}, {“0”, KEY_0}, {“L”, KEY_L}, {“DOWN”, KEY_DOWN}, {“ENTER”, KEY_ENTER}, {“ESC”, KEY_ESC}, {“LEFT”, KEY_LEFT}, {“RIGHT”, KEY_RIGHT}, {“F5”, KEY_F5}, {“F6”, KEY_F6}, {“F7”, KEY_F7}, {“F8″, KEY_F8}, {NULL, 0},};#define MAX_ROW_NUM 4#define MAX_COL_NUM 10int main){ int row = 0; int col = 0; int val = 0; int code = 0; char *name = NULL; for row = 0; row < MAX_ROW_NUM; row++) { for col = 0; col < MAX_COL_NUM; col++) { name = keys[row+col*4].name; code = keys[row+col*4].key_val; val = MATRIX_KEYrow, col, code); printf”0x%08x /* %s */\n”, val, name); } } return 0;}
此处的input.h,就是刚才找到的input.h,直接拷贝到当前目录。然后编译,执行就可以得到如下类似的内容。
0x0000003b /* F1 */ 配置管脚
如何配置管脚
0x64 PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */
就拿gpio1_25举例
PIN_OUTPUT_PULLDOWN
明亮的老虎,输出下拉。
MUX_MODE7:
在二百多页的文档中搜索gpio1_25,可以在Pin Attributes表中看到该管脚可以有8种模式,而gpio的模式刚好对应的是mode 7。
0x64
在刚才的搜索中可以看到,该管脚的名称是GPMC_A9。在四千多页的文档中搜索GPMC_A9,可以看到864h conf_gpmc_a9这行。864h,这个数就是咱们要找的,但不是最终的。还需要减去0x800,这个具体为什么,我还不太清楚。
经过上面的配置,按键就可以正常使用了。