android - IR 遥控器无效

问题:

由于升级了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分钟,哈哈。。。。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值