一、常用命令介紹
在目前的機頂盒市場中,海思和Amlogic(之前還有Mstar)是主流的芯片方案。因此,在這幾種芯片上適配紅外和藍牙遙控器也就成爲了機頂盒廠家的常見工作,本篇文章簡單介紹下遙控器的適配方式。
使用"getevent -l"可以查看該機頂盒上適配的遙控器及對應的event,然後再隨便按個按鍵,串口輸出如下:
130|root@Hi3798MV300:/ # getevent -l
add device 1: /dev/input/event3
name: "YYYKQ"
could not get driver version for /dev/input/mouse2, Not a typewriter
could not get driver version for /dev/input/mouse1, Not a typewriter
add device 2: /dev/input/event2
name: "qwerty"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 3: /dev/input/event1
name: "Hi mouse"
add device 4: /dev/input/event0
name: "Hi keyboard"
could not get driver version for /dev/input/mice, Not a typewriter
/dev/input/event3: EV_MSC MSC_SCAN 00070051
/dev/input/event3: EV_KEY KEY_DOWN DOWN
/dev/input/event3: EV_SYN SYN_REPORT 00000000
/dev/input/event3: EV_MSC MSC_SCAN 00070051
/dev/input/event3: EV_KEY KEY_DOWN UP
/dev/input/event3: EV_SYN SYN_REPORT 00000000
以上內容表示適配了四套遙控器,名稱分別爲"YYYKQ"、“qwerty”、“Hi mouse”、“Hi keyboard”,目前使用的遙控器爲"YYYKQ"遙控器。下面的六行內容意思爲:前三行代表Usage ID爲0x51的按鍵被按下,後面的三行代表Usage ID爲0x51的按鍵彈起。
使用"dumpsys input"可以查看每套遙控器對應的kl文件,串口輸出如下:
130|root@Hi3798MV300:/ # dumpsys input
INPUT MANAGER (dumpsys input)
Event Hub State:
BuiltInKeyboardId: -2
Devices:
-1: Virtual
Classes: 0x40000023
Path: <virtual>
Descriptor: a718a782d34bc767f4689c232d64d527998ea7fd
Location:
ControllerNumber: 0
UniqueId: <virtual>
Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
KeyLayoutFile: /system/usr/keylayout/Generic.kl
KeyCharacterMapFile: /system/usr/keychars/Virtual.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
1: qwerty
Classes: 0x00000014
Path: /dev/input/event2
Descriptor: 0a920d0216027e6e2f378f49650573230b560922
Location:
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0100
KeyLayoutFile:
KeyCharacterMapFile:
ConfigurationFile: /system/usr/idc/qwerty.idc
HaveKeyboardLayoutOverlay: false
2: Hi mouse
Classes: 0x00000008
Path: /dev/input/event1
Descriptor: ddfb717d907e8defcc82f81ba273111db984c56a
Location:
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0001, product=0x0002, version=0x0100
KeyLayoutFile:
KeyCharacterMapFile:
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
3: Hi keyboard
Classes: 0x00000063
Path: /dev/input/event0
Descriptor: 485d69228e24f5e46da1598745890b214130dbc4
Location:
ControllerNumber: 1
UniqueId:
Identifier: bus=0x0000, vendor=0x0001, product=0x0001, version=0x0100
KeyLayoutFile: /system/usr/keylayout/Vendor_0001_Product_0001.kl
KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
5: YYYKQ
Classes: 0x8000016b
Path: /dev/input/event3
Descriptor: aef83b05c01603404d15b0155c07acee382a4de5
Location:
ControllerNumber: 2
UniqueId:
Identifier: bus=0x0005, vendor=0x0416, product=0x0300, version=0x0000
KeyLayoutFile: /system/usr/keylayout/Vendor_0416_Product_0300.kl
KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
由上面的輸出內容可知,"YYYKQ"對應的kl文件爲/system/usr/keylayout/Vendor_0416_Product_0300.kl。
除了上面兩個命令,還有一些遙控器方面常用命令,如禁用/啓用遙控器命令如下:
芯片 | 禁用紅外遙控器 | 啓動紅外遙控器 |
---|---|---|
Amlogic905L | remotecfg | ./system/bin/remotecfg.sh |
Hi3798MVxx | stop ir_user | start ir_user |
Mstar9380 | busybox devmem 0x1f007b00 16 0x0000 | busybox devmem 0x1f007b00 16 0x01bf |
二、紅外遙控器適配
按下遙控器的一個按鍵後,系統中的處理邏輯爲:物理鍵值——>Linux鍵值——>按鍵名稱——>Android鍵值。
2.1 海思紅外遙控器適配
可以先用"android_ir_user -D"命令查看一下機頂盒適配的所有紅外碼值,然後按下某個具體按鍵,如2014格式的上鍵,串口輸出如下:
Received key: 0xb9461420,linux_keycode =0x67,103,1, UP, protocol: .
該內容的意義如下:
1>1420爲遙控器頭碼
3>46爲遙控器物理鍵值
4>b9爲校驗值
5>0x67轉換爲實際值就是103,代表該按鍵對應的Linux鍵值
在device/hisilicon/bigfish/system/ir_user/key_pars/key.xml中尋找0xb9461420,可以查到該鍵值對應的按鍵名稱,如下:
<key value="0xb9461420" name="KEY_UP" /> <!--key up-->
以上內容表示0xb9461420對應的是上鍵。
然後在device/hisilicon/bigfish/system/ir_user/key_pars/linux_key.h中,可以查看該按鍵對應的Linux鍵值,如下:
{"KEY_UP", 103 },
以上內容表示的是上鍵對應的Linux鍵值是103。
接下來就是要尋找對應的kl文件,如上述的"dumpsys input"命令輸出的內容中,Vendor_0001_Product_0001.kl就是紅外遙控器對應的kl文件,在代碼中具體的文件爲:device/hisilicon/bigfish/prebuilts/Vendor_0001_Product_0001.kl,上鍵對應的內容如下:
key 103 DPAD_UP
按如上步驟,紅外遙控器底層鍵值就已經適配完成。接下來就要適配上層Android鍵值,上層鍵值的實現主要在framework代碼中實現,具體爲以下文件。
frameworks/base/core/java/android/view/KeyEvent.java中,內容如下:
public static final int KEYCODE_DPAD_UP = 19;
frameworks/native/include/input/KeycodeLabels.h中,內容如下:
{ "DPAD_UP", 19 },
frameworks/base/core/res/res/values/attrs.xml中,內容如下:
<enum name="KEYCODE_DPAD_UP" value="19" />
frameworks/native/include/android/keycodes.h中,內容如下:
AKEYCODE_DPAD_UP = 19,
海思上適配紅外遙控器的流程到此結束。
2.2 Amlogic紅外遙控器適配
Amlogic紅外遙控器的適配流程整體上與海思相似,不同的是海思上是key.xml,Amlogic上是remote*.conf。並且海思上的key.xml裏可以對應多套紅外遙控器鍵值,而一個remote*.conf只能對應一套紅外鍵值,並且代碼裏有多個remote*.conf,需要在device/amlogic/p201_iptv/p201_iptv.mk中查看對應的remote*.conf,如下:
ifeq ($(strip $(CHINA_MOBILE_ENABLE)),true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinamobile.conf:system/etc/remote.conf \
$(LOCAL_PATH)/remote_chinamobile1.conf:system/etc/remote1.conf \
$(LOCAL_PATH)/remote_chinamobile2.conf:system/etc/remote2.conf
else ifeq ($(strip $(CHINA_TELECOM_ENABLE)),true)
ifeq ($(strip $(BUILD_SH_TELECOM_APKS)),true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinatelecom_sh.conf:system/etc/remote.conf
else
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinatelecom.conf:system/etc/remote.conf
endif
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinatelecom1.conf:system/etc/remote1.conf
else ifeq ($(strip $(CHINA_UNICOM_ENABLE)),true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinaunicom.conf:system/etc/remote.conf \
$(LOCAL_PATH)/remote1.conf:system/etc/remote1.conf
else ifeq ($(strip $(BUILD_SD_MOBILE_APKS)),true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote_chinamobile2.conf:system/etc/remote2.conf
else
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/remote.conf:system/etc/remote.conf \
$(LOCAL_PATH)/remote1.conf:system/etc/remote1.conf
endif
Amlogic上沒有android_ir_user腳本,所以不能執行"android_ir_user"命令,要看某一按鍵的物理鍵值,可以按某一按鍵,然後使用"dmesg"命令來看,關鍵內容如下:
<6>[ 827.604760@0] remote: press ircode = 0x46,
<6>[ 827.604787@0] remote: scancode = 0x0067,maptable = 1,code:0xb9461420
以上內容表示該按鍵的物理鍵值是0x46,遙控器頭碼是1420,b9爲校驗值,0x67轉換爲實際值就是103,代表該按鍵對應的Linux鍵值。remote*.conf文件的內容如下:
factory_code = 0x14200001 //遙控器碼值類型,如該例子代表該文件是2014碼值類型的
work_mode = 0 //工作模式設置,1爲硬件,0位軟件,一般默認選擇0
repeat_enable = 1 //是否支持按下一直連發鍵
repeat_delay = 400 //按下按鍵到第一個連發鍵到時間間隔,單位爲ms
repeat_peroid = 120 //兩個連發鍵之間的時間間隔,單位爲ms
release_delay = 80 // 釋放按鍵時間間隔,單位爲 ms
debug_enable = 1 //是否打開驅動調試打印
factory_infcode = 2 //可簡單爲添加的第幾套碼值,從0開始,依次增加
key_begin
0x46 103
key_end
以上就是Amlogic的紅外遙控器適配與海思存在差異的地方,其餘均與海思一致,不再贅述。
2.3 Mstar紅外遙控器適配
Mstar紅外遙控器適配與海思相似,一個鍵值配置文件可以對應多套碼值,具體文件爲device/mstar/ponkan/preinstall32/irkey.cfg。如2014碼值格式的上鍵對應的內容如下:
{ 0x0246, KEY_UP },
三、藍牙遙控器適配
3.1 藍牙鍵值
不同芯片平臺對藍牙鍵值的適配方式是一樣的,有差異的是hid-input.c文件的位置,具體如下:
1>海思:device/hisilicon/bigfish/sdk/source/kernel/linux-3.18.y.patch/drivers/hid/hid-input.c
2>Amlogic:common/drivers/hid/hid-input.c
3>Mstar:vendor/mstar/kernel/drivers/hid/hid-input.c
先看一張藍牙遙控器的碼值表,如下:
按鍵名稱 | 紅外鍵值 | 藍牙鍵值 | Android鍵值 |
---|---|---|---|
電源 | DC | 0x66(07) | 179 |
確定 | CE | 0x41(0C) | 23 |
上 | CA | 0x52(07) | 19 |
下 | D2 | 0x51(07) | 20 |
左 | 99 | 0x50(07) | 21 |
右 | C1 | 0x4F(07) | 22 |
音量+ | 80 | 0xE9(0C) | 24 |
音量- | 81 | 0xEA(0C) | 25 |
頻道+ | 85 | 0x4B(07) | 166 |
頻道- | 86 | 0x4E(07) | 167 |
主頁 | 88 | 0x223(0C) | 3 |
菜單 | 82 | 0x65(07) | 82 |
設置 | 8D | 0xEB(0C) | 176 |
返回 | 95 | 0x224(0C) | 4 |
靜音 | 9C | 0xE2(0C) | 164 |
語音 | - | 0x3E(07) | 142 |
上面的鍵值表中第二列表示物理鍵值,第三列表示藍牙鍵,第四列代表上層Android鍵值。該表中不涉及按鍵的Linux鍵值,也就是說明某個按鍵的Linux鍵值是可以任意定義的(雖然可以任意定義,但不建議這樣做,接下來會詳細說明)。
上表的第三列中藍牙鍵值有不同的備註,"07"代表的普通藍牙鍵值,"0c"代表多媒體鍵值,這兩種類型鍵值的適配方式也不同,具體如下:
"07"類型鍵值的適配,就以上鍵爲例,由之前章節得知改建對應的Linux鍵值爲103,所以上鍵對應的藍牙鍵值在hid_keyboard數組中對應的值就是103。其位置由藍牙鍵值0x52決定,0x52轉換爲十進制爲82,所以其位置就是hid_keyboard[82]。綜合起來也就是hid_keyboard[82]位置的值爲103,如下:
static const unsigned char hid_keyboard[256] = {
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,240,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,250,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
};
如果某個"0c"類型鍵值在適配過程中,發現kl文件與hid_keyboard數組中的值不對應,建議修改kl文件。
"0c"類型鍵值的適配,以設置爲例,在HID_UP_CONSUMER中對應的代碼爲:
case 0x0eb: map_key_clear(KEY_SETUP); break;
case後面的值爲爲對應的藍牙鍵值,map_key_clear內的值爲對應的按鍵名稱。
3.2 kl
要明確藍牙鍵值對應哪個kl文件,仍可用上面提及的"dumpsys input",如frameworks/base/data/keyboards/Vendor_0416_Product_0300.kl。kl文件中的配置,與紅外適配時相同,不再贅述。
3.3 Android鍵值
映射到上層Android鍵值的部分,也與紅外就鍵值適配時相同,涉及以下幾個文件:
frameworks/base/core/java/android/view/KeyEvent.java
frameworks/base/core/res/res/values/attrs.xml
frameworks/native/include/android/keycodes.h
frameworks/native/include/input/KeycodeLabels.h
至此,Android TV上適配遙控器鍵值已全部完成。