我是靠谱客的博主 凶狠白羊,最近开发中收集的这篇文章主要介绍LINUX GPIO独立按键 和 GPIO矩阵键盘,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

http://blog.chinaunix.net/uid-20768928-id-5084287.html

 

    这两种情况,内核中都有考虑,都在drivers/input/keyboard/ 下面。

 

GPIO 独立按键是 gpio_keys.c

 

GPIO 矩阵键盘是 matrix_keypad.c

 

具体也没有什么好分析的,主要就是采用platform 方式注册input 子系统,往应用层报键值。

 

在此基础上,添加相关的驱动,格式很固有化。直接上自己整理的模板吧。

 

GPIO 独立按键

 

点击(此处)折叠或打开

  1. #define SABRESD_VOLUME_UP    IMX_GPIO_NR(1, 4) //得到gpio number 号
  2. #define SABRESD_VOLUME_DN    IMX_GPIO_NR(1, 5)
  3.  
  4. //定义宏
  5. #ifdefined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
  6. #define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce)    
  7. {                                
  8.     .gpio        = gpio_num,                
  9.     .type        = EV_KEY,                
  10.     .code        = ev_code,                
  11.     .active_low    = act_low,                
  12.     .desc        = "btn " descr,                
  13.     .wakeup        = wake,                    
  14.     .debounce_interval = debounce,                
  15. }
  16. //上面宏定义的数组
  17. static struct gpio_keys_button CPU_NAME_buttons[] = {
  18.     GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1),
  19.     GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 0, 1),
  20.     GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1, 1),
  21. };
  22.  
  23. static struct gpio_keys_platform_data CPU_NAME_button_data = {
  24.     .buttons    = CPU_NAME_buttons,
  25.     .nbuttons    = ARRAY_SIZE(CPU_NAME_buttons),
  26. };
  27. //platform device  与driver 中对应的
  28. static struct platform_device CPU_NAME_button_device = {
  29.     .name        = "gpio-keys",
  30.     .id        = -1,
  31.     .num_resources = 0,
  32.     .dev        = {
  33.         .platform_data = &CPU_NAME_button_data,
  34.     }
  35. };
  36. //注册设备的函数
  37. static void __init CPU_NAME_add_device_buttons(void)
  38. {
  39.     platform_device_register(&CPU_NAME_button_device);
  40. }
  41. #else
  42. static void __init CPU_NAME_add_device_buttons(void) {}
  43. #endif

 

    有些时候因不同CPU BSP 的GPIO 封装,在driver 中会出现一些问题。比如 gpio_request   可能会重复(imx287,
得到GPIO号的时候就已经request 了,太TMD超前了)  如下这段代码要屏蔽。

 

点击(此处)折叠或打开

  1. #if 0
  2.                 error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
  3.                 if (error < 0) {
  4.                         pr_err("gpio-keys: failed to request GPIO %d,"
  5.                                 " error %dn", button->gpio, error);
  6.                         goto fail2;
  7.                 }
  8. #endif

 

GPIO 矩阵键盘

 

点击(此处)折叠或打开

  1. #if 1 
  2. /*
  3.  * Tosa Keyboard
  4.  */
  5.  #include <linux/input/matrix_keypad.h>
  6. //矩阵键盘按下时对应的键码表
  7. static const uint32_t tosakbd_keymap[] = {
  8.     KEY(0, 0, KEY_1),
  9.     KEY(0, 1, KEY_2),
  10.     KEY(0, 2, KEY_3),
  11.  
  12.  
  13.     KEY(1, 0, KEY_4),
  14.     KEY(1, 1, KEY_5),
  15.     KEY(1, 2, KEY_6),
  16.  
  17.  
  18.     KEY(2, 0, KEY_7),
  19.     KEY(2, 1, KEY_8),
  20.     KEY(2, 2, KEY_9),
  21.  
  22.  
  23.     KEY(3, 0, KEY_UP),
  24.     KEY(3, 1, KEY_0),
  25.     KEY(3, 2, KEY_DOWN),
  26.  
  27.     KEY(4, 0, KEY_BACK),
  28.     KEY(4, 1, KEY_ENTER),
  29.     KEY(4, 2, KEY_ESC),
  30.     
  31.  
  32. };
  33.  
  34. static struct  matrix_keymap_data   tosakbd_keymap_data = {
  35.     .keymap        = tosakbd_keymap,
  36.     .keymap_size    = ARRAY_SIZE(tosakbd_keymap),
  37. };
  38.  
  39. //列选  得到GPIO 口number 号
  40. static const int tosakbd_col_gpios[] =
  41.             { 
  42.                 // MXS_PIN_TO_GPIO( PINID_SSP0_DATA5), // 4
  43.                 MXS_PIN_TO_GPIO(PINID_LCD_D08), // 5
  44.                 MXS_PIN_TO_GPIO(PINID_LCD_D09), // 6
  45.                 MXS_PIN_TO_GPIO(PINID_LCD_D10) // 7
  46.             };
  47. //行选  得到GPIO 口number 号            
  48. static const int tosakbd_row_gpios[] =
  49.             { 
  50.                 MXS_PIN_TO_GPIO(PINID_LCD_D11), // 2
  51.                 MXS_PIN_TO_GPIO(PINID_LCD_D12), // 2
  52.                 MXS_PIN_TO_GPIO(PINID_LCD_D13), // 3
  53.                 MXS_PIN_TO_GPIO(PINID_LCD_D14),              // 1
  54.                 MXS_PIN_TO_GPIO(PINID_LCD_D15) // 0
  55.             };
  56. //driver 中的需要的data
  57. static struct matrix_keypad_platform_data CPU_NAMEkbd_pdata = {
  58.     .keymap_data        = &tosakbd_keymap_data,
  59.     .row_gpios        = tosakbd_row_gpios,
  60.     .col_gpios        = tosakbd_col_gpios,
  61.     .num_row_gpios        = ARRAY_SIZE(tosakbd_row_gpios),
  62.     .num_col_gpios        = ARRAY_SIZE(tosakbd_col_gpios),
  63.     .col_scan_delay_us    = 10,
  64.     .debounce_ms        = 10,
  65.     .wakeup            = 1,
  66.  
  67.     .active_low =,
  68. };
  69.  
  70. static struct platform_device CPU_NAMEkbd_device = {
  71.     .name        = "matrix-keypad",
  72.     .id        = -1,
  73.     .dev        = {
  74.         .platform_data = &CPU_NAMEkbd_pdata,
  75.     },
  76. };
  77.  
  78. #endif

 

 上面的两种方式,有些时候因不同CPU BSP 的GPIO 封装,在driver 中会出现一些问题。由于不同CPU GPIO口
产生中断的触发方式不同,这里出现问题的更多。

 

 

 

点击(此处)折叠或打开

  1. err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
  2.                 matrix_keypad_interrupt,
  3.                 IRQF_DISABLED |
  4.                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  5.                 "matrix-keypad", keypad);

 

 

 

  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING   很多CPU无法同时支持上升延与下降延触发。只能选择其中一个,要么FALLING ,要么RISING。
 这两种方式,内核都已经封装成足够简单的方式了,用不着自己去写一个驱动,类似于填空就好了。

最后

以上就是凶狠白羊为你收集整理的LINUX GPIO独立按键 和 GPIO矩阵键盘的全部内容,希望文章能够帮你解决LINUX GPIO独立按键 和 GPIO矩阵键盘所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(94)

评论列表共有 0 条评论

立即
投稿
返回
顶部