android - IR 遥控器无效

来源:互联网 发布:天翼网络对讲机 编辑:程序博客网 时间:2024/04/29 23:22

问题:

由于升级了SDK导致遥控器无法使用,对于ir驱动的代码没有进行修改,完全一致,升级前遥控器可以使用,但升级使用不了。

问题分析:

1、驱动加打印,确认按键消息是否有发送

void ir_input_event_irCallback(void *pParam, int iParam)

        调用了input_report_key及input_sync进行按键发送了,这块应该没有问题 


2、上层利用android系统自带的 getevent 获取键值 

D:\hisi-tools\sdk-tools>adb shell

# geteventgeteventadd device 1: /dev/input/event1name: "nexus ir input"could not get driver version for /dev/input/mouse1, Not a typewriteradd device 2: /dev/input/event0name: "Darfon USB Optical Mouse"

logcat 打印:

I/EventHub( 1794): New keyboard: device->id=0x10000 devname='nexus ir input' propName='hw.keyboards.65536.devname'keylayout='/system/usr/keylayout/qwerty.kl'
I/EventHub( 1794): New device: path=/dev/input/event1 name=nexus ir input id=0x10000 (of 0x1) index=1 fd=102 classes=0x1


说明设备创建成功,不存在没有设备结点的问题,基本上可确认发送端及接收端的设备注册没有问题

   

 3、确认struct input_dev结构中关于key的相关设定

unsigned long evbit[BITS_TO_LONGS(EV_CNT)];

unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

key_dev->evbit[0] = BIT_MASK(EV_KEY);
for (i = 0; nexus_ir_input_inputkeys[i].inputev; i++)

set_bit(nexus_ir_input_inputkeys[i].inputev, key_dev->keybit);

没有问题。。。这到低是哪里的问题呢???


4、在linux kernel发送流程中加打印

看看 input_sync 及 input_report_key 的执行流程

代码路径:

drivers/input/input.c 

static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{

input_event(dev, EV_KEY, code, !!value);

}


static inline void input_sync(struct input_dev *dev)
{

input_event(dev, EV_SYN, SYN_REPORT, 0);

}


都是调用 input_event --> input_handle_event() --> 这里需要重点关注,这就是真正处理键case点:

static void input_handle_event(struct input_dev *dev,       unsigned int type, unsigned int code, int value){int disposition = INPUT_IGNORE_EVENT;printk(KERN_ERR "input_handle_event call..(type=%d,code=%d) \n",type,code);switch (type) {case EV_SYN:switch (code) {case SYN_CONFIG:disposition = INPUT_PASS_TO_ALL;break;case SYN_REPORT:if (!dev->sync) {dev->sync = 1;disposition = INPUT_PASS_TO_HANDLERS;}break;case SYN_MT_REPORT:dev->sync = 0;disposition = INPUT_PASS_TO_HANDLERS;break;}break;case EV_KEY:if (is_event_supported(code, dev->keybit, KEY_MAX) &&    !!test_bit(code, dev->key) != value) {if (value != 2) {__change_bit(code, dev->key);if (value)input_start_autorepeat(dev, code);elseinput_stop_autorepeat(dev);}disposition = INPUT_PASS_TO_HANDLERS;}break;...if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN){printk(KERN_ERR "input_handle_event INPUT_IGNORE_EVENT");dev->sync = 0;}if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event){printk(KERN_ERR "input_handle_event INPUT_PASS_TO_DEVICE");dev->event(dev, type, code, value);}if (disposition & INPUT_PASS_TO_HANDLERS){printk(KERN_ERR "input_handle_event INPUT_PASS_TO_HANDLERS");input_pass_event(dev, type, code, value);}}


在 EV_KEY 及 最后面的三个if条件加打印,即可找到问题所在了。

原因:

input_report_key(nexus_ir_input_event_device.input_key_dev, nexus_ir_input_inputkeys[i].inputev, irEvent.repeat);
input_sync(nexus_ir_input_event_device.input_key_dev);
input_report_key(nexus_ir_input_event_device.input_key_dev, nexus_ir_input_inputkeys[i].inputev, 0);
input_sync(nexus_ir_input_event_device.input_key_dev);


irEvent.repeat 这个值为false即0,导致 

case EV_KEY:
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
    !!test_bit(code, dev->key) != value) {

里判定失败,不会进入,,,,从而引发后面三个if条件全部错了。。


正确流程:

<3>input_handle_event call..(type=2,code=0) 
<3>input_handle_event INPUT_IGNORE_EVENT
<3>input_handle_event INPUT_PASS_TO_HANDLERS
<3>input_handle_event call..(type=2,code=1) 
<3>input_handle_event call..(type=2,code=8) 
<3>input_handle_event call..(type=0,code=0) 
<3>input_handle_event INPUT_PASS_TO_HANDLERS


问题解决:

input_report_key(nexus_ir_input_event_device.input_key_dev, nexus_ir_input_inputkeys[i].inputev,1); 

非常容易撒,,,,哈哈,可这个问题花了我1个小时过10分钟,再记录下这个问题记录20分钟,哈哈。。。。


原创粉丝点击