一直以来都没有一个好的习惯,学过的东西用过之后不久就忘记了,最近决定开始把之前遇到的一些问题写到这里,一方面是自己备忘,另一方面也希望能够帮助到大家,起码给各位有一点参考的价值,吾心足矣,废话少说今天就从前段时间添加红外遥控器说起吧。
今天先说说驱动层的添加流程,正好前段时间写了一个技术分享的文档直接贴过来了。
一,说明:
通常遥控器都会用唯一的一个客户码来区分不同的客户,但是当一个遥控器的键不够用或者客户更换客户码的时候就需要添加客户码或者同时支持两个或更多客户码。
二,红外按键编码格式
遥控发射器的按键信息,一般采用红外光传输,其编码一般采用东芝TC9012编码规范:
载波:37.9KHz 占空比:1/3
头码(引导码):4.5ms(H)+ 4.5ms(L)
码0:0.56ms(H)+ 0.565ms(L)
码1:0.56ms(H)+ 1.69ms(L)
结束位:0.56ms(H)
单键码:引导码+8位客户码+8位客户码+8位数据码+8位数据码反码+结束位,长度:108ms
连续键码(发简码):4.5ms(H)+4.5ms(L)+ C0(码1反码)+结束位,简码重复周期:108ms。详见下图示:
三,添加驱动层
当遥控器的红外信号发出后,首先接到信号的是ir的驱动程序,ir设备对应的驱动程序kernellinuxlinux-3.10.0archarmsp-realtekmach-rtd294xirirrc.c
在这个文件的examine_ir_avail方法中检测收到的ir信号是否有效,这里会判断ir的协议和客户码是否支持,如果不是支持的协议和客户码就会直接将ir信号忽略。因此添加新的客户码时要在这里添加else if(ir_protocol == RAW_C03 && (*regValue & 0xffff) != 0xf1f1 && (*regValue & 0xffff) != 0xf5f5) {
return -ERESTARTSYS;
}其中0xf5f5是新添加的客户码。
下一步当ir设备驱动将信号有效性检测完成后会交给linux输入子系统中的input设备处理,因此在驱动程序kernellinuxlinux-3.10.0archarmsp-realtekmach-rtd294xirir_input.c中添加如下代码:
为了避免新添加客户码的键值对原来的遥控器按键造成干扰新建如下连个结构体:
static struct venus_key yk_54lu_keys_ex[] = {
{0x03fc, KEY_FACTORY_WLAN_SCAN}
};
static struct venus_key_table yk_54lu_key_table_ex = {
.keys = yk_54lu_keys_ex,
.size = ARRAY_SIZE(yk_54lu_keys_ex),
};
添加这个结构体后需要在初始化函数venus_ir_input_init中添加
for (i = 0; i < yk_54lu_key_table_ex.size; i++) {
set_bit(yk_54lu_key_table_ex.keys[i].keycode, data->input_dev->keybit);
}
完成对设备属性的初始化。
然后在venus_ir_scancode_to_keycode函数中将扫描码转化成linux层需要的keycode,在这个函数中添加
else if((value & 0x0000ffff) == YK_54LU_CUSTOMER_CODE_EX)
{
scancode = (value & 0xffff0000) >> 16;
for (i = 0; i < yk_54lu_key_table_ex.size; i++)
{
if (scancode == yk_54lu_key_table_ex.keys[i].scancode)
{
data->keycode = yk_54lu_key_table_ex.keys[i].keycode;
printk(KERN_ALERT "Venus IR: --YK_54LU report ex-key 0x%x %d
", scancode, data->keycode);
return data->keycode;
}
}
}
到这里就完成了驱动层的添加,实现了扫描码到keycode的转化,把按键的信号传递到了linux层,此时如果一切ok,在串口中getevent可以看到linux层收到的按键信息。
四,android 系统按键的添加
至此就是按照标准的android按键添加流程添加就ok了,因为添加的地方比较多这里只列出需要修改的文件及路径。
kernellinuxlinux-3.10.0includeuapilinuxinput.h
kernelandroidKKdevice
ealtek
td294x_tv010venus_IR_input.kl
kernelandroidKKframeworksasecore
es
esvaluesattrs.xml
kernelandroidKKframeworks
ativeincludeandroidkeycodes.h
kernelandroidKKframeworks
ativeincludeinputKeycodeLabels.h
kernelandroidKKframeworksase
td294x_tv010corejavaandroidviewKeyEvent.java
kernelandroidKKframeworksasepolicy
td294x_tv010srccomandroidinternalpolicyimplPhoneWindowManager.java
添加完上面8个文件后就完成了linux层keycode到framwork层keyevent的映射,这样上层的android控件就会收到新加遥控器的按键值。
五,总结
本文主要对遥控器红外信号的驱动层接收解码到传递给linux的input设备之间添加做了说明,从linux层到android层的按键映射只列出了需要修改的文件,如果需要可以参考android标准按键的添加流程进行添加。