linux gpio key 實現方式

linux gpio key 實現方式

linux gpio key可以實現兩種方式,如果key比較少的話,(1)可以選擇單個的gpio作爲一個input event來上報,這樣的方式的優點是按鍵比較獨立,缺點是如果key比較多會生成比較的input event (2) 正常的話可以定義gpio key, 給不同的gpio選擇不同的鍵值,個人覺得這種方式比較正規,包括遙控按鍵的上報也是用這種方式。

gpio-key 實現原理

gpio-key是基於input架構實現的通用gpio按鍵驅動,該驅動是基於platform_driver架構,實現了驅動和設備的分離,符合linux設備驅動模型的基本思想。

代碼的驅動部分:
drivers/input/keyboard/gpio_keys.c
這裏基本不需要我們修改,只需要我們瞭解其中的實現流程就好。
代碼的dts部分:
主要修改的部分是dts部分,借用網上通用代碼。

 gpio-keys {                                                                                                                            
          compatible = "gpio-keys";                                                                                                          
          autorepeat;                                                                                                                        
                                                                                                                                             
          pinctrl-names = "default";                                                                                                         
          pinctrl-0 = <&s8_keys>;                                                                                                            
                                                                                                                                             
          power {                                                                                                                            
              gpios = <XXXXXX GPIO_ACTIVE_LOW>;                                                                                       
              linux,code = <KEY_POWER>;                                                                                                      
              label = "GPIO Key Power";                                                                                                      
              debounce-interval = <20>;                                                                                                      
          };                                                                                                                                 
                                                                                                                                             
         home {                                                                                                                             
              gpios = <YYYYY GPIO_ACTIVE_LOW>;                                                                                       
              linux,code = <KEY_HOME>;                                                                                                       
              label = "GPIO Key Home";                                                                                                       
              debounce-interval = <20>;                                                                                                      
          };                                                                                                                                 
      };

 &pinctrl {
     pinctrl-names = "default";    
     buttons {
         s8_keys: s8-keys {
             rockchip,pins = <XXXX &pcfg_pull_up>,                                                                         
                     <XXXXXXXX &pcfg_pull_up>;
         };
        }

1、節點名字爲“gpio-keys”。
2、gpio-keys 節點的 compatible 屬性值一定要設置爲“gpio-keys”。
3、所有的 KEY 都是 gpio-keys 的子節點,每個子節點可以用如下屬性描述自己:
gpios:KEY 所連接的 GPIO 信息。
interrupts:KEY 所使用 GPIO 中斷信息,不是必須的,可以不寫。
label:KEY 名字
linux,code:KEY 要模擬的按鍵可以直接填數字
可以直接填數字
gpio-key,wakeup:可以被喚醒
debounce-interval:消抖時間

以上就在linux driver端使能了key,接下來可以在hal層讀取/dev/
/dev/input/eventX 讀取key event的事件了

具體hal讀取按鍵的幾種方式,可看我的git源碼
網上的 應用代碼,沒有select

#define RECOVERY_KEY "/dev/input/event2"
#define RECOVERY_KEY_CODE 115
#define RECOVERY_KEY_PRESS 0
void recovery_key_press_timer(int sig)
{
 if(SIGALRM == sig)
 {
  printf("alarm 6s.\n");
 }
 return;
}
static void read_recovery_key_event()
{
 int fd = -1, ret = -1;
 struct input_event ev;
 fd = open(RECOVERY_KEY, O_RDONLY);
 if (fd < 0)
 {
  printf("open RECOVERY_KEY event failed.\n");
  return;
 }
 memset(&ev, 0, sizeof(struct input_event));
 ret = read(fd, &ev, sizeof(struct input_event));
 if (ret != sizeof(struct input_event))
 {
  printf("read RECOVERY_KEY event failed.\n");
  close(fd);
 }
 if( (RECOVERY_KEY_CODE == ev.code) && (RECOVERY_KEY_PRESS == ev.value) )
 {
  printf("recovery-key press.\n");
  alarm(6);
 }
 else
 {
  printf("recovery-key release.\n");
  alarm(0);
 }
 close(fd);
}
int main(int argc, char **argv)
{
    int rc = 0;
 signal(SIGALRM, recovery_key_press_timer);
 while(1)
 {
  read_recovery_key_event();
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章