双击亮屏这个很常见的功能:需要注意的关键的点
(1)首先得保证灭屏后不断电
注意suspend的流程中是否有关电源的操作函数,通过示波器去量是否有reset,vdd输出供电正常,中断INT信号再摁下后反应
(2)不断电并且触摸屏并未进入stop模式
这个就要具体分析对应的驱动,mxt中suspend->mxt_stop/resume->mxt_start,其中还包含了一些状态标志位,这一步需要确保在灭屏的时候getevnet有键值上报
suspend:
enable_irq_wake(data->irq);
resume:
disable_irq_wake(data->irq);
(3)上报后添加单击亮屏流程
input_report_key(input_dev, KEY_POWER, 1);
input_sync(input_dev);
input_report_key(input_dev, KEY_POWER, 0);
input_sync(input_dev);
问题一: ? ? ? ? key_power getevent没有任何反应 分析: ? ? ? ? check input.c的流程,打印log,去查哪里把这个过滤点,总结下来就是需要注意 ? ? ? ? is_event_supported(type, dev->evbit, EV_MAX) ? ? ? ? is_event_supported(code, dev->keybit, KEY_MAX) ? ? ? ? keybit evbit如果还不清楚的话,需要去搜一下input的流程 解决: ? ? ? ? 添加设置keybit/evbit来实现对应支持的input
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(KEY_POWER, input_dev->keybit);
or
input_set_capability(input_dev, EV_KEY, KEY_POWER);
(4)以上完成单击亮屏后添加双击亮屏
依赖于mxt驱动的流程,发现单击摁下和抬起后触发的type/x/y/a/p/v值都是一样, 问题二: ? ? ? ? 想通过count每两次记录算一次单击,概率性出现count=4被丢掉 分析: ? ? ? ? 原本以为pressure是代表压力的意思但实际并未有压力检测的功能, 解决: ? ? ? ? 在irq触发的方式上使用上升沿触发IRQF_TRIGGER_RISING
error = request_threaded_irq(data->irq, NULL, mxt_interrupt,
data->pdata->irqflags | IRQF_ONESHOT | IRQF_TRIGGER_RISING,
client->name, data);
(5)双击亮屏后自测多次发现的问题
问题三: ? ? ? ? 两次单击时间过程没有恢复的机制 分析: ? ? ? ? 每次时间的记录都依赖于中断去触发,所以即使单击一次超时后, ? ? ? ? 再下一次双击任然不会亮屏,1 + 2 = 1(count = 1) 解决: ? ? ? ? 在count = 1的时候调度500ms queue_delayed_work,其中用于超时500ms count恢复为0 ? ? ? ? (如果要实现循环实行任务,可以在在delayed_work中将delayed_workqueue再次添加到queue中)
probe:
data->mxt_workqueue = create_singlethread_workqueue("mxt_wq");
if(NULL == data->mxt_workqueue)
dev_info(&client->dev,"failed to create mxt_workqueue ");
INIT_DELAYED_WORK(&data->mxt_work, mxtcount_func);
process
if(type == 1 && suspended){
count ++;
dev_info(dev, "trigger into suspend double touch detect count = %d", count);
if(count == 1){
firsttouch = current_kernel_time();
if(NULL != data->mxt_workqueue)
queue_delayed_work(data->mxt_workqueue, &data->mxt_work, msecs_to_jiffies(500));
}
else if(count == 2){
secondtouch = current_kernel_time();
ts_delta = timespec_sub(secondtouch, firsttouch);
dev_info(dev, "get the time ts_delta = %ld",timespec_to_ns(&ts_delta)/1000000);
if((timespec_to_ns(&ts_delta)/1000000) < 500 && false == triggerOnce){
input_report_key(input_dev, KEY_POWER, 1);
input_sync(input_dev);
input_report_key(input_dev, KEY_POWER, 0);
input_sync(input_dev);
}
count = 0;
}
return;
}else if(!suspended)
count = 0;
resume:
if(NULL != data->mxt_workqueue)
cancel_delayed_work(&data->mxt_work);
以上就是我遇到的一些问题,当然不同的IC的特性还是不同的,但通用流程上应该就上面这些吧。
|