|
楼主 |
发表于 2014-11-24 20:34:02
|
显示全部楼层
本帖最后由 unprince 于 2014-11-24 20:40 编辑
全志的源代码几乎是个半成品,关于这点,我们在用全志的方案开发产品时,有一部分时间都是在全志的"坑"里,例如现在讨论的红外遥控,最终的问题出现在./lichee/linux-3.0/drivers/input/keyboard/sun4i-ir.c文件中的ir_code_valid函数中(用于判断编码是否有效).由于高16位的遥控识别码是用宏定义给出的,因此在运行时是不可配置的.这表明仅当遥控的识别码与IR_ADDR_CODE(这里是0x9f00)一致时才可以使用.而问题的关键是我没有看到关于这个特定识别码的任何说明,假如你还困在这个红外遥控不能获得键值的问题中,那么一定是因为你的红外遥控识别码不是0x9f00.那么修改这个值就可以了
注意: 全志的全系列 sun5i-ir.c,sun7i-ir.c也存在同样的问题
相关的头文件- // vim ./lichee/linux-3.0/drivers/input/keyboard/ir-keymap.h +13
- #define IR_ADDR_CODE (0x9f00)
复制代码 相关源代码- // vim ./lichee/linux-3.0/drivers/input/keyboard/sun4i-ir.c +440
- static int ir_code_valid(unsigned long code)
- {
- unsigned long tmp1, tmp2;
- #ifdef IR_CHECK_ADDR_CODE
- /*Check Address Value*/
- if((code&0xffff) != (IR_ADDR_CODE&0xffff))
- return 0; /*Address Error*/
-
- tmp1 = code & 0x00ff0000;
- tmp2 = (code & 0xff000000)>>8;
-
- return ((tmp1^tmp2)==0x00ff0000); /*Check User Code*/
- #else
- /*Do Not Check Address Value*/
- tmp1 = code & 0x00ff00ff;
- tmp2 = (code & 0xff00ff00)>>8;
-
- //return ((tmp1^tmp2)==0x00ff00ff);
- return (((tmp1^tmp2) & 0x00ff0000)==0x00ff0000 );
- #endif /*#ifdef IR_CHECK_ADDR_CODE*/
- }
复制代码 最终的补丁方案(注意:是在A20的源码中修改的,实际是一样的)- diff --git a/drivers/input/keyboard/sun7i-ir.c b/drivers/input/keyboard/sun7i-ir.c
- index d4371aa..fb79734 100755
- --- a/drivers/input/keyboard/sun7i-ir.c
- +++ b/drivers/input/keyboard/sun7i-ir.c
- @@ -496,27 +496,39 @@ static unsigned long ir_packet_handler(unsigned char *buf, unsigned long dcnt)
- return code;
- }
-
- +static ushort ir_addr_code = 0;
- +module_param(ir_addr_code,ushort, 0644);
- +MODULE_PARM_DESC(ir_addr_code, "Valid IR addr code");
- +
- +static ushort cur_ir_addr_code = 0;
- +module_param(cur_ir_addr_code, ushort, 0644);
- +MODULE_PARM_DESC(cur_ir_addr_code, "Current IR addr code");
- +
- static int ir_code_valid(unsigned long code)
- {
- unsigned long tmp1, tmp2;
-
- -#ifdef IR_CHECK_ADDR_CODE
- - /* Check Address Value */
- - if ((code&0xffff) != (IR_ADDR_CODE&0xffff))
- - return 0; /* Address Error */
- +//#ifdef IR_CHECK_ADDR_CODE
- + cur_ir_addr_code = (code & 0xffff);
- +
- + if(ir_addr_code != 0){
- + /* Check Address Value */
- + if ((code&0xffff) != (ir_addr_code &0xffff))
- + return 0; /* Address Error */
-
- - tmp1 = code & 0x00ff0000;
- - tmp2 = (code & 0xff000000)>>8;
- + tmp1 = code & 0x00ff0000;
- + tmp2 = (code & 0xff000000)>>8;
-
- - return ((tmp1^tmp2)==0x00ff0000); /* Check User Code */
- -#else
- + return ((tmp1^tmp2)==0x00ff0000); /* Check User Code */
- + }
- +//#else
- /* Do Not Check Address Value */
- tmp1 = code & 0x00ff00ff;
- tmp2 = (code & 0xff00ff00)>>8;
-
- //return ((tmp1^tmp2)==0x00ff00ff);
- return (((tmp1^tmp2) & 0x00ff0000)==0x00ff0000 );
- -#endif /* #ifdef IR_CHECK_ADDR_CODE */
- +//#endif /* #ifdef IR_CHECK_ADDR_CODE */
- }
-
- static irqreturn_t ir_irq_service(int irqno, void *dev_id)
复制代码 说明:我们增加了两个变量(ir_addr_code和cur_ir_addr_code),并且导出到用户空间
通过下面的路径可以访问
/sys/module/sun7i_ir/parameters/ir_addr_code
/sys/module/sun7i_ir/parameters/cur_ir_addr_code
其中可以通过查看cur_ir_addr_code获得当前遥控识别码
通过向ir_addr_code写入新的遥控识别码过滤其他识别码的遥控,写0时不过滤任何识别码
|
|