android5.0输入系统添加自定义按键

xiaoxiao2021-02-28  182

申明:本按键添加没有用到全志sys_config.fex配置io。 Board:全志R16 SDK:Android KitKat 4.4.2、Linux-3.4 开发内容:自定义按键名为SOCHIP_EXT1,接在R16开发板的GPIOB7口。 1.先在linux-3.4/inlcude/linux/input.h添加自定义按键#define SOCHIP_EXT1 0x2e8 该键值最好不要跟系统的键值冲突,然后编写linux下的key driver代码。

#include <linux/module.h> #include <linux/init.h> #include <linux/input.h> #include <linux/irq.h> #include <mach/irqs.h> #include <linux/interrupt.h> #include <asm-generic/errno.h> #include <asm-generic/errno-base.h> #include <linux/gpio.h> #include <mach/gpio.h> #include <linux/slab.h> #include <linux/timer.h> #include <linux/param.h> #include <linux/jiffies.h> #include <linux/ioport.h> #include <linux/io.h> #define KEYDEV_NAME "mykey" #define MY_KEY KEY_SOCHIP_EXT1 #define KEY_GPIO GPIOB(7) static int key_irq; static struct timer_list *key_timer = NULL; static struct input_dev *key_dev = NULL; static void __iomem *key_reg; static irqreturn_t isr_key_func(int irq, void *arg) { printk(KERN_EMERG "key intretupt is comming ...\n"); mod_timer(key_timer, jiffies + (HZ / 5)); return IRQ_HANDLED; } static void timer_handler(unsigned long arg) { //printk("10ms is comming ... \n"); unsigned int val; val = gpio_get_value(KEY_GPIO); printk("val = %d\n", val); if(val == 0){ printk("key up ... \n"); input_report_key(key_dev, MY_KEY, 0); input_sync(key_dev); }else if(val == 1){ printk("key down ...\n"); input_report_key(key_dev, MY_KEY, 1); input_sync(key_dev); } } static int __init key_init(void) { int ret = 0; printk("hello key driver\n"); //初始化定时器 key_timer = kzalloc(sizeof(struct timer_list), GFP_KERNEL); if(!key_timer){ printk("kzalloc timer is failed!\n"); ret = -ENOMEM; goto ERR1; } init_timer(key_timer); key_timer->function = timer_handler;//定时服务函数 key_timer->expires = jiffies + (HZ / 10);//当前时间 + 定时时间 add_timer(key_timer);//添加定时器 //input结构体申请内存 key_dev = input_allocate_device(); if(!key_dev){ printk(KERN_EMERG "key: input_allocate_device failed!\n"); ret = -ENOMEM; goto ERR2; } #if 1 key_dev->name = KEYDEV_NAME; //输入设备名字 key_dev->phys = "input22"; //设备节点名称 key_dev->id.bustype = BUS_HOST; //设备标识ID属性 用于与事件处理层进行匹配 key_dev->id.vendor = 0x0001; key_dev->id.product = 0x0001; key_dev->id.version = 0x0100; #endif set_bit(EV_KEY, key_dev->evbit);//设置支持的事件类型为key set_bit(MY_KEY, key_dev->keybit);//设置设备支持按键类型为MYKEY //申请IO资源 第一种方式 ret = gpio_request(KEY_GPIO, NULL); if(ret < 0){ printk(KERN_EMERG "gpio request failed!\n"); ret = -EBUSY; return ret; } #if 0 //申请IO资源 第二种方式 if(!request_mem_region(KEY_GPIO, 4, "key")){ printk("requset_mem_region is failed!\n"); return -EBUSY; } #endif //映射 key_reg = ioremap(KEY_GPIO, 4); if(!key_reg){ printk("ioremap is failed!\n"); return -EIO; } //配置KEY_GPIO为中断模式 iowrite32(0x4, key_reg); //根据IO获取中断ID key_irq = gpio_to_irq(KEY_GPIO); if(key_irq == -ENXIO) { printk(KERN_EMERG "gpio_to_irq failed!\n"); ret = -ENXIO; goto ERR3; } //2.申请中断 if(request_irq(key_irq, isr_key_func, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "key", NULL)){ ret = -EBUSY; printk(KERN_EMERG "request irq failed!\n"); goto ERR4; } //3.向input子系统注册device ret = input_register_device(key_dev); if(ret){ printk(KERN_EMERG "input register device failed!\n"); goto ERR5; } return 0; ERR5: free_irq(key_irq, NULL); ERR4: gpio_free(KEY_GPIO); ERR3: input_free_device(key_dev); ERR2: kfree(key_timer); ERR1: return ret; } static void __exit key_exit(void) { del_timer(key_timer); //删除定时器 kfree(key_timer);//释放内存 free_irq(key_irq, NULL); //释放中断id iounmap(key_reg);//解映射 gpio_free(KEY_GPIO); //第二种方式释放申请的内存资源 // release_mem_region(KEY_GPIO, 4); //第一种方式释放申请的内存资源 input_unregister_device(key_dev);//解input注册 printk("goodbye key driver\n"); } module_init(key_init); module_exit(key_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("orange"); MODULE_DESCRIPTION("key driver");

2.修改xxx.kl安卓下的按键映射文件,R16平台SDK对应的kl文件在android/device/softwinner/xxx/configs/sunxi-keyboard.kl,也可通过cat /proc/bus/input/devices 可找到相应的驱动名。(其他kl文件可在frameworks//base/data/keyboards/中找到)添加key 744 SOCHIP_EXT1。 3.修改framework层的相关文件,R16平台SDK相关文件对应的路径如下:

=>android/frameworks/native/include/input/KeycodeLabels.h中添加如下对应的代码:

246 { "ASSIST", 219 }, 247 { "BRIGHTNESS_DOWN", 220 }, 248 { "BRIGHTNESS_UP", 221 }, 249 { "MEDIA_AUDIO_TRACK", 222 }, 250 { "SOCHIP_EXT1" , 223}, ==>此处添加

=>android/frameworks/native/include/android/keycodes.h中添加如下对应的代码:

265 AKEYCODE_ASSIST = 219, 266 AKEYCODE_BRIGHTNESS_DOWN = 220, 267 AKEYCODE_BRIGHTNESS_UP = 221, 268 AKEYCODE_MEDIA_AUDIO_TRACK = 222, 269 AKEYCODE_SOCHIP_EXT1 = 223, ==>此处添加

=>android/frameworks/base/core/res/res/values/attrs.xml中添加如下对应的代码:

1566 <enum name="KEYCODE_ASSIST" value="219" /> 1567 <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" /> 1568 <enum name="KEYCODE_BRIGHTNESS_UP" value="221" /> 1569 <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" /> 1570 <enum name="KEYCODE_SOCHIP_EXT1" value="223" /> ==>此处添加

=>android/frameworks/base/core/Java/android/view/KeyEvent.java 此文件有两处修改,分别如下: 第一处修改:

631 public static final int KEYCODE_BRIGHTNESS_UP = 221; 632 /** Key code constant: Audio Track key 633 * Switches the audio tracks. */ 634 public static final int KEYCODE_MEDIA_AUDIO_TRACK = 222; 635 636 public static final int KEYCODE_SOCHIP_EXT1 = 223; ==>此处添加 637 638 private static final int LAST_KEYCODE = KEYCODE_SOCHIP_EXT1;==>此处若LAST_KEYCODE对应的上一行是什么按键就赋值什么。

第二处修改:

879 names.append(KEYCODE_ASSIST, "KEYCODE_ASSIST"); 880 names.append(KEYCODE_BRIGHTNESS_DOWN, "KEYCODE_BRIGHTNESS_DOWN"); 881 names.append(KEYCODE_BRIGHTNESS_UP, "KEYCODE_BRIGHTNESS_UP"); 882 names.append(KEYCODE_MEDIA_AUDIO_TRACK, "KEYCODE_MEDIA_AUDIO_TRACK"); 883 names.append(KEYCODE_SOCHIP_EXT1, "KEYCODE_SOCHIP_EXT1");==>此处添加

=>android/device/softwinner/astar-evb/configs/sunxi-keyboard.kl中添加如下

1 key 102 HOME WAKE 2 key 28 BACK WAKE 3 key 139 MENU WAKE_DROPPED 4 key 114 VOLUME_UP 5 key 115 VOLUME_DOWN 6 key 744 SOCHIP_EXT1 ==>此处添加

=>android/frameworks/native/libs/input/Input.cpp =>修改 bool KeyEvent::isSystemKey(int32_t keyCode) ,添加AKEYCODE_SOCHIP_EXT1 ,如添加了代表此按键为系统按键。

109 case AKEYCODE_SEARCH: 110 case AKEYCODE_BRIGHTNESS_DOWN: 111 case AKEYCODE_BRIGHTNESS_UP: 112 case AKEYCODE_MEDIA_AUDIO_TRACK: 113 case AKEYCODE_SOCHIP_EXT1:

最后切记执行make update-api 把刚刚修改的内容更新,可在frameworks/base/api/current.txt找到更新后添加到里面的按键内容,如本文,我们可以搜索SOCHIP_EXT1,找到的内容如下:

27284 field public static final int KEYCODE_SLASH = 76; // 0x4c 27285 field public static final int KEYCODE_SOCHIP_EXT1 = 223; // 0xdf ==>此处 27286 field public static final int KEYCODE_SOFT_LEFT = 1; // 0x1 27287 field public static final int KEYCODE_SOFT_RIGHT = 2; // 0x2

若没有执行make update-api是找不到你所添加的按键对应的内容,最后编译、打包、烧录,至此添加自定义按键成功,相关解析按键布局的kl文件可在frameworks/base/services/input/EventHub.cpp。

转载请注明原文地址: https://www.6miu.com/read-23021.html

最新回复(0)