问题:
由于升级了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
# getevent
getevent
add device 1: /dev/input/event1
name: "nexus ir input"
could not get driver version for /dev/input/mouse1, Not a typewriter
add device 2: /dev/input/event0
name: "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);
else
input_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分钟,哈哈。。。。