Android input touchpanel双击灭屏

双击亮屏这个很常见的功能:需要注意的关键的点

(1)首先得保证灭屏后不断电

注意suspend的流程中是否有关电源的操作函数,通过示波器去量是否有reset,vdd输出供电正常,中断INT信号再摁下后反应

(2)不断电并且触摸屏并未进入stop模式

这个就要具体分析对应的驱动,mxt中suspend->mxt_stop/resume->mxt_start,其中还包含了一些状态标志位,这一步需要确保在灭屏的时候getevnet有键值上报

suspend:
	enable_irq_wake(data->irq);
	//pm_stay_awake(&data->client->dev);
resume:
	disable_irq_wake(data->irq);
	//pm_relax(&data->client->dev);

(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的特性还是不同的,但通用流程上应该就上面这些吧。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Linux Touch Panel驱动的demo: ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> #include <linux/i2c.h> #include <linux/delay.h> #define DEVICE_NAME "touchpanel" static struct i2c_device_id touchpanel_id_table[] = { {DEVICE_NAME, 0}, {} }; MODULE_DEVICE_TABLE(i2c, touchpanel_id_table); static int touchpanel_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct input_dev *input; int error = 0; input = input_allocate_device(); if (!input) { dev_err(&client->dev, "input_allocate_device failed\n"); error = -ENOMEM; goto err_free_mem; } input->name = "Touch Panel"; input->id.bustype = BUS_I2C; input->dev.parent = &client->dev; input_set_capability(input, EV_KEY, BTN_TOUCH); error = input_register_device(input); if (error) { dev_err(&client->dev, "input_register_device failed\n"); goto err_free_mem; } return 0; err_free_mem: input_free_device(input); return error; } static int touchpanel_remove(struct i2c_client *client) { struct input_dev *input = i2c_get_clientdata(client); input_unregister_device(input); input_free_device(input); return 0; } static const struct of_device_id touchpanel_of_match[] = { { .compatible = "linux,touchpanel", }, {} }; MODULE_DEVICE_TABLE(of, touchpanel_of_match); static struct i2c_driver touchpanel_driver = { .probe = touchpanel_probe, .remove = touchpanel_remove, .id_table = touchpanel_id_table, .driver = { .name = DEVICE_NAME, .of_match_table = touchpanel_of_match, }, }; module_i2c_driver(touchpanel_driver); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("Touch Panel Driver"); MODULE_LICENSE("GPL"); ``` 这个驱动程序使用I2C总线与触摸屏进行通信,并向输入子系统注册输入设备。在`probe`函数中,它分配了一个新的输入设备并配置其名称、总线类型和父设备。它还设置了该设备支持BTN_TOUCH事件。在`remove`函数中,它注销了输入设备并释放了分配的内存。这个驱动程序还包含了一些必要的Linux模块元数据,如作者、描述和许可证信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值