安卓添加返回键+菜单键+HOME键--基于高通平台

2019-.4-22补充说明:

这两天又看了一下关于安卓按键的整个处理流程,现总结如下。

首先在linux驱动框架中按键值称为扫描码,而安卓应用中使用的按键值称为KeyCode其也是一个整数值,但是与linux中扫描码不同。linux扫描码需要经过两次转换才能转换为安卓层的KeyCode码,首先在Keylayout(按键布局)文件*.kl文件中把linux扫描码转化为KeycodeLabel字符串,在KEYCODE[]数组中把KeycodeLabel字符串转化为安卓KeyCode码。

frameworks/native/include/android/keycodes.h中定义了KeyCode码

enum {           
    AKEYCODE_UNKNOWN         = 0,
    AKEYCODE_SOFT_LEFT       = 1,
    AKEYCODE_SOFT_RIGHT      = 2,
    AKEYCODE_HOME            = 3,
    AKEYCODE_BACK            = 4,
    ... ...
    AKEYCODE_VOLUME_UP       = 24,
    AKEYCODE_VOLUME_DOWN     = 25,
    ... ...
    AKEYCODE_MENU            = 82,
    ... ...
    AKEYCODE_HELP            = 259
}; 

frameworks/native/include/input/InputEventLabels.h中定义了KeyCode码和KeycodeLabel字符串的对应关系

#define DEFINE_KEYCODE(key) {#key,AKEYCODE_##key}
static const InputEventLabel KEYCODES[] = {
    DEFINE_KEYCODE(UNKNOWN),             //    = {"UNKNOWN",0}
    DEFINE_KEYCODE(SOFT_LEFT),              //  = {"SOFT_LEFT",1}
    DEFINE_KEYCODE(SOFT_RIGHT),           //    = {"SOFT_RIGHT",2}
    DEFINE_KEYCODE(HOME),                    // = {"HOME",3}
    DEFINE_KEYCODE(BACK),                    // = {"BACK",4}
    ... ...
    DEFINE_KEYCODE(VOLUME_UP),           //  = {"VOLUME_UP",24}
    DEFINE_KEYCODE(VOLUME_DOWN),    //       = {"VOLUME_DOWN",25}
    ... ...
    DEFINE_KEYCODE(MENU),                     // = {"MENU",82}
    ... ...
    DEFINE_KEYCODE(HELP),                       // = {HELP",259}
    { NULL, 0 } 
};

在按键布局(Keylayout)文件中定义了linux扫描码和 KeycodeLabel字符串的对应关系

如在gpio-keys.kl文件中有

key 115   VOLUME_UP
key 114   VOLUME_DOWN
key 102   HOME
key 528   FOCUS

则linux扫描码115就对应KeycodeLabel字符串“VOLUME_UP”,而“VOLUME_UP”又对应到安卓KeyCode码24,故当linux的按键事件传递给安卓系统115键值最终会转换为安卓的KeyCode码24供安卓APP使用。

在安卓系统存在多个键盘布局文件(Keylayout),则具体某个驱动文件调用哪个kl文件是根据驱动的名字来确定的,如果找不到与驱动名字相同的文件,就会读取默认文件Generic.kl。如名字为gpio-keys的驱动就会读取gpio-keys.kl文件,如果该文件不存在,则读取Generic.kl文件。

2019-04-18 补充说明:

        原以为这个东西很简单,像我下面这样设置一下就可以了,今天自己重新编译系统然后烧录进去之后发现除了HOME按键能正常工作之外,MENU+BACk按键都不能正常工作,同样的方法在linux kernel源代码中寻找这三个IO使用区别,但是很遗憾没找到不同的地方,只能想着是安卓上层的原因了,于是看了一下安卓的源代码,发现确实是不一样的,在gpio-keys.kl有下面的代码

key 115   VOLUME_UP
key 114   VOLUME_DOWN
key 102   HOME
key 528   FOCUS

从代码可以看到这个文件中没有设置BACK和MENU按键的值,我想应该把BACK和MENU的值加上去之后就可以了(还没有亲自测试过,待测试之后再把结果告诉大家)。看来要想支持实体按键不仅需要linux源码层支持,还需要安卓层支持,这两者相互合作才能达到目的。

先说一下背景:

       新入手了一个开发板,开发板带有BACK+HOME+MENU实体按键,还有两个实体的音量加减按键。但是开机后发现音量键都是可以正常使用的,另外三个按键无法正常使用,在按键没有按下时测量这几个按键的电压发现音量键的电压是1.8V,另外三个按键的电压则是0V。根据电压值可推测,应该是在系统内部没有对这三个IO设置导致这几个IO不能体现其正常的功能。

        既然要使用这几个实体按键,就只能老老实实的查看代码把功能添加上去了,这里我先说明一下,其实把按键对应的功能添加上非常容易,但是由于自己第一次做这样的工作,因此记录一下自己的想法和方法。

        首先,这5个按键都是通过GPIO和soc链接的,既然音量键能正常工作就看这几个按键和音量键的GPIO设置有哪些区别呗,首先查看dtsi中设备树中这几个GPIO有哪些区别,发现在某个文件中有以下代码。

      
gpio_keys {
        compatible = "gpio-keys";
        input-name = "gpio-keys";
        pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
        pinctrl-0 = <&gpio_key_active>;
        pinctrl-1 = <&gpio_key_suspend>;
        vol_up {
            label = "volume_up";
            gpios = <&msm_gpio 15 0x1>;
            linux,input-type = <1>;
            linux,code = <115>;
            gpio-key,wakeup;
            debounce-interval = <15>;
        };  
        vol_down {
            label = "volume_down";
            gpios = <&msm_gpio 8 0x1>;
            linux,input-type = <1>;
            linux,code = <114>;
            gpio-key,wakeup;
            debounce-interval = <15>;
        };
};

根据硬件链接可以知道音量“+”使用的时GPIO15,音量“-”使用的是GPIO8刚好和设备树中的gpios对应,故感觉这个就是音量相关的设备树的配置,那就尝试这找driver中的代码吧,看看驱动中是如何使用这些属性的。根据compatible = "gpio-keys"在找到了对应的驱动文件,翻阅了一下驱动文件好像也并没有对vol_up和vol_down做特别的处理,只是读取了设备树的属性,然后根据这些属性进行设置。既然这样,那直接把HOME+MENU+BACK按键的属性添加上去不就大功告成了,这样想着就把BACK+MENU+HOME对应的按键添加到了

gpio_keys {
    ......
    ......
    vol_up{
        ......
        ......
    };

    vol_down{
        ......
        ......
    };
    home_key {
        label = "home_key";
        gpios = <&msm_gpio 9 0x1>;
        linux,input-type = <1>;
        linux,code = <102>;
        gpio-key,wakeup;
        debounce-interval = <15>;
    };  
    back_button {           
        label = "back_button";          
        gpios = <&msm_gpio 10 0x1>;         
        linux,code = <158>;         
        linux,input-type = <1>;         
        gpio-key,wakeup;            
        debounce-interval = <15>;           
    };  
    menu_button {
        label = "list_button";
        gpios = <&msm_gpio 13 0x1>;
        linux,code = <139>;
        linux,input-type = <1>;
        gpio-key,wakeup;
        debounce-interval = <15>;
   };  

};
    

然后编译系统,下载进去之后测试,发现另外三个按键不能正常工作,但是不应该啊,因为驱动中没有特别针对音量键,想着是不是设备树中的设置有问题啊,于是又仔细看了一下设备树中gpio_keys的属性,发现有pinctrl-0 = <&gpio_key_active>;
        pinctrl-1 = <&gpio_key_suspend>;这两个属性,于是就搜索了一下gpio_key_active和gpio_key_suspend,发现这两个属性在另外一个文件中定义,该文件中代码如下

tlmm_gpio_key {                                                                             
            qcom,pins = <&gp 15>, <&gp 8>;
            qcom,pin-func = <0>; 
            qcom,num-grp-pins = <2>;
            label = "tlmm_gpio_key";
            gpio_key_active: gpio_key_active {
                drive-strength = <2>; 
                bias-pull-up;
            };   
            gpio_key_suspend: gpio_key_suspend {
                drive-strength = <2>; 
                bias-pull-up;
            };
};

看到这里就只有把BACK+MENU+HOME对应的gpio加入到这里了,代码如下

tlmm_gpio_key {                                                                             
            qcom,pins = <&gp 15>, <&gp 8>, <&gp 9>, <&gp 10>, <&gp 13>; 
            qcom,pin-func = <0>; 
            qcom,num-grp-pins = <5>;
            label = "tlmm_gpio_key";
            gpio_key_active: gpio_key_active {
                drive-strength = <2>; 
                bias-pull-up;
            };   
            gpio_key_suspend: gpio_key_suspend {
                drive-strength = <2>; 
                bias-pull-up;
            };
};

再次编译,下载。按键就全部可以使用了。

总体上说,做过一次之后这个东西很简单,只是在设备树中添加相应的属性即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值