在海思、Amlogic、Mstar平台上适配蓝牙或者红外遥控器,可以按照以下的步骤进行排查和修改。
无论是蓝牙遥控器还是红外遥控器,都需要确定其使用的kl (KeyLayoutFile)文件。在安卓shell 环境执行命令确认kl 文件:getevent -l (getevent -v)。下图是按蓝牙遥控器方向下键和菜单键串口的打印:
由上图可知,该蓝牙遥控器对应/dev/input/event3。以下三行表示按键(HID键值码 0x0051)被按下
/dev/input/event3: EV_MSC MSC_SCAN 00070051
/dev/input/event3: EV_KEY KEY_UP DOWN
/dev/input/event3: EV_SYN SYN_REPORT 00000000
以下三行表示按键(HID键值码 0x0051)被释放
/dev/input/event3: EV_MSC MSC_SCAN 00070051
/dev/input/event3: EV_KEY KEY_UP UP
/dev/input/event3: EV_SYN SYN_REPORT 00000000
在安卓shell 环境下执行 dumpsys input ,可以根据所连接的遥控器的名称找到遥控器对应的kl文件。
这里所用到的Android层映射文件为/system/usr/keylayout/Generic.kl(各个项目使用的kl文件可能不一样,Generic.kl为默认的;.kl文件代码路径:/framework/base/data/keyboards;盒子路径:/system/usr/keylayout)。
查看单板该路径下文件,找到108对应的键值,为DPAD_DOWN,与按键需要的功能一致。
如果hid-input.c中获取到的值为unk,从Generic.kl(项目具体使用的kl文件)下找到对应功能的值,填到hid-input.c中对应的位置。
Android IR实现原理可参考:https://blog.csdn.net/zhanxingshan007/article/details/81096124
按下遥控器的一个按键后,在系统中的逻辑过程:遥控器的物理键值——>Linux的标准键值——>自定义的字符串——>定义这个字符串——>android标准键值——>android键值上报——>所有上报表中键值判断是否为全局——>(上报成功)。
Amlogic平台执行remotecfg可以屏蔽红外遥控器,执行remotecfg.sh 可以打开红外遥控器。uboot模式,输入如下命令可以得到遥控器的物理键值: irkey 12 12 122 30000000
海思平台可以直接运行 android_ir_user -D 命令,运行后操作遥控器,看是否能获取到物理键值, 能够正常获取到说明驱动层功能正常。
红外遥控器与蓝牙遥控器的流程仅仅驱动内核层配置不一样,框架层的kl文件配置以及android应用层完全相同。而海思、Amlogic、Mstar的驱动层红外配置也不相同。
1)直接运行 android_ir_user -D 命令,运行后操作遥控器,看是否能获取到物理键值, 能够正常获取到说明驱动层功能正常。
2)处理红外遥控物理键值与 linux 标准键值的映射关系。
涉及到的目录和文件:
device\hisilicon\bigfish\system\ir_user\key_pars
遥控器物理键值与linux标准键值之前的映射: device\hisilicon\bigfish\system\ir_user\key_pars/key.xml
linux 键值字符型与整形转换关系: device/hisilicon/bigfish/system/ir_user/key_pars/linux_key.h
海思红外遥控器需要在device\hisilicon\bigfish\system\ir_user\key_pars\key.xml中配置,且可以配置多个不同的遥控器。
0xee115da0:5da0为遥控器头码,11为遥控器物理键值,ee为校验值。
3)getevent -v 或者dumpsys input 确认设备使用的 kl 文件,该命令显示值代表内核中的值。
该款红外遥控使用 kl 文件名称为 Vendor_0001_Product_0001.kl,海思平台上,该配置文件位于 device\hisilicon\bigfish\prebuilts目录。
4)最终映射到 android 键值层
Android应用层在onKeyUp,onKeyDown 中识别的就是keyCode。android 键值定义文件如下:
android5.1 版 本 及 以 上 :
frameworks\native\include\android\keycodes.h
frameworks\native\include\input\InputEventLabels.h
frameworks\base\core\java\android\view\KeyEvent.java
frameworks\base\core\res\res\values\attrs.xml
android4.4 版 本 :
frameworks\base\include\androidfw\KeycodeLabels.h
frameworks\base\core\java\android\view\KeyEvent.java
frameworks\base\core\res\res\values\attrs.xml
android4.0 版 本 :
frameworks\base\include\ui\KeycodeLabels.h
frameworks\base\core\java\android\view\KeyEvent.java
frameworks\base\core\res\res\values\attrs.xml
1)进入uboot模式,输入如下命令: irkey 12 12 122 30000000 ,运行后操作遥控器,看是否能获取到物理键值, 能够正常获取到说明驱动层功能正常。
2)处理红外遥控物理键值与 linux 标准键值的映射关系。
涉及到的目录和文件:
遥控器物理键值与linux标准键值之前的映射:device\amlogic\p201_iptv\remote.conf
linux 中所支持的按键 linux 键值字符型与整形转换关系:common/arch/arm/boot/dts/include/dt-bindings/input/input.h
Amlogic红外遥控器需要在device\amlogic\p201_iptv\remote_*.conf中配置,每个remote_*.conf中只能配置一款遥控器, 最终需要在device\amlogic\p201_iptv \p201_iptv.mk中决定使用哪款遥控器配置。
3)getevent -v或者dumpsys input 确认设备使用的 kl 文件,该命令显示值代表内核中的值。
4)最终映射到 android 键值层。
涉及到的目录和文件:
遥控器物理键值与linux标准键值之前的映射:vendor/mstar/mi/MI_project/project/board/c2p/MSO9385-BGA-DDR4/ir_config.ini
linux 中所支持的按键 linux 键值字符型与整形转换关系:vendor/mstar/kernel/tegra/include/dt-bindings/input/input.h
Mstar红外遥控器需要在MI_project/project/board/c2p/xxx/ir_config.ini中配置,且可以配置多个不同的遥控器。
Hisi 、Amlogic以及Mstar的蓝牙遥控器是同样的流程。
1)确认各个按键 HID 值。可以找遥控器厂家或者局方咨询。
2)按键 HID 值与 linux 键值之间映射关系。
Hisi:device/hisilicon/bigfish/sdk/…/drivers/hid/hid-input.c
AMLOGIC:common/drivers/hid/hid-input.c
Mstar:platform/android/vendor/mstar/kernel/tegra/drivers/hid/hid-input.c
HID键码值表即为蓝牙键值,其中usage page为键值类型(07代表普通键值、0c代表多媒体键值)、usage ID为蓝牙键值。我们需要根据键值类型来修改hid-input.c。
对于普通类型键值(07),只需要修改hid_keyboard数组相应的值即可,其中数组序号代表蓝牙键值,数组里面的值代表对应的linux键值。
hid有256个键值保存在device\hisilicon\bigfish\sdk\source\kernel\linux-3.18.y\drivers\hid\hid-input.c定义的数组中,如下图所示,可以看到hid_keyboard[74] = 102,而在linux_key.h(不是在此处定义的)中键值102对应的按键字符串为KEY_HOME。比如确定键,HID键值类型为0x07,键值为0x28(即40,hid_keyboard数组的第3行第9个),则hid_keyboard[40]的值应该为确定键对应的linux键值。
对于多媒体类型键值(0c),修改在case HID_UP_CONSUMER部分进行添加。以设置键为例,0XF6代表蓝牙键值,KEY_BACK(158)代表对应的linux键值(input.h中定义),因此需要在switch (usage->hid & HID_USAGE)语句中添加case 0x224: map_key_clear(KEY_BACK)。
3)确认设备使用的 kl 文件并修改。
确定遥控器(android:/framework/base/data/keyboards)使用哪一个kl文件,可以通过指令getevent-l或者getevent –v,或者在/system/usr/keylayout通过cat /proc/bus/input/devices,根据Vendor,Product,Version确认该遥控器是哪个event事件。
若对应 vendor 和 product 的 kl 文件不存在,如果要新增 kl 配置文件,新增的 kl 文件要添加到frameworks/base/data/keyboards 目录下,命名规则根据查询到的VendorID 和 ProductID。特殊说明:如果不新增设备对应的 kl 文件的话,系统默认会使用 Generic.kl 进行映射处理(frameworks/base/data/keyboards/Generic.kl), 建议尽量不要改动默认的Generic.kl 文件,以免对其他设备产生影响。
确定好遥控器使用哪个kl文件后,需要检查上一步配置的linux键值是否在该kl文件中配置。如果没有,则需要添加到android键值的映射。
4)最终映射到 android 键值层,同红外遥控器。
下面以返回键和设置键蓝牙适配来详细了解流程。
根据遥控器厂商提供的HID键值表,0x0007对应键盘码区。
海思代码路径:.../ kernel/linux-3.18.y/drivers/hid/hid-input.c,0x0029就是第3行第10列,对应为1。
再查看蓝牙遥控器连接所用的.kl文件, Generic.kl,发现1对应的是ESCAPE
而能实现back功能对应的为158
所以,在修改键码前,按遥控器实现的功能为ESCAPE,而不是返回。为了减少内核代码的修改,我们不要将hid-input.c中的1修改为158,而是将 key 1 对应的ESCAPE改为BACK。
当然,不会直接在Generic.kl文件中进行修改,可以将Generic.kl复制一份,并将文件名改为与遥控器VID,PID相对应的名字,例如电信BLE语音遥控器的VID,PID为060a,1000,所以将复制出来的kl文件改名为Vendor_060a_Product_1000.kl。遥控器连接后会自动根据其VID,PID加载对应的kl文件。
根据遥控器厂商提供的HID键值表,0x0c对应的是HID_UP_CONSUMER区域
从…/kernel/linux-3.18.y/include/uapi/linux/input.h中查到,设置按键对应的key code为
在(代码路径:.../ kernel/linux-3.18.y/drivers/hid/hid-input.c)如下图框中添加代码
烧录内核代码后,再次从串口通过getevent获取操作设置键的打印,如果有打印,检查功能是否正常,如果无打印,请重新检查修改是否正确。
综上,蓝牙遥控器按键值适配简要流程如下:由getevent蓝牙按键打印确认是蓝牙键盘类型(0x7)还是自定义类型(0xC),根据不同的类型修改内核和kl文件。