linux随笔记 - 电容触屏

该笔记是在学习电容触摸相关知识的时候说记录的笔记,总的来说,这是这个相对比较综合的时候,会设计到IIC驱动设备,中断驱动,input子系统。这些在前面的已经进行学习过了,因为笔者有一款传感器需要些,也是需要设计到上述相关的知识。而本实验中除此之外还需要补充一个触摸协议MT协议。

Type A:适用于触摸点不能被区分或者追踪,此类型的设备上报原始数据(这种现在用的很少)。
Type B:适用于有硬件追踪并能区分触摸点的触摸设备,此类型设备通过 slot 更新某一个
触摸点的信息,FT5426 就属于此类型,一般的多点电容触摸屏 IC 都有此能力。

在产生中断后,一般是通过中断的的处理上报(耗时的操作放到下半部或者是通过中断线程化处理)

typeA

该模式不能识别多指滑动轨迹,只能将点上报,所以现在已经用得不多叻,就只简单介绍一下。

//通过input子系统进行上报,一个点一个点的上报
static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
{
	.....
	ret = st1232_ts_read_data(ts);
	if (ret < 0)
	goto end;
	/* multi touch protocol */
	for (i = 0; i < MAX_FINGERS; i++) 
	{
	if (!finger[i].is_valid)
		continue;
		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
		input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
		input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
		input_mt_sync(input_dev);
		count++;
	}
	.....
	/* SYN_REPORT */
	input_sync(input_dev);
	end:
	return IRQ_HANDLED;
}

typeB

该模式的上报可以理解为分组上报,每一组会关联一个ID,通过这个ID去区分当前有几条触摸的线。上报的方式如下:

1 ABS_MT_SLOT 0                        //上报 ABS_MT_SLOT 事件
2 ABS_MT_TRACKING_ID 45        //关联的ID 来完成对触摸点的添加、替换或删除

                                                      input_mt_report_slot_state
3 ABS_MT_POSITION_X x[0]        //上报触摸点 0 的 X-Y 轴坐标,使input_report_abs
4 ABS_MT_POSITION_Y y[0]
5 ABS_MT_SLOT 1
6 ABS_MT_TRACKING_ID 46
7 ABS_MT_POSITION_X x[1]
8 ABS_MT_POSITION_Y y[1]
9 SYN_REPORT

 

static void ili210x_report_events(struct input_dev *input, const struct touchdata *touchdata)
{
	int i;
	bool touch;
	unsigned int x, y;
	const struct finger *finger;

	for (i = 0; i < MAX_TOUCHES; i++) 
	{
		input_mt_slot(input, i);	//上报事件
		finger = &touchdata->finger[i];
		touch = touchdata->status & (1 << i);
		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);	//上报关联触摸ID,区分不同ID组的
		if (touch) 
		{
			x = finger->x_low | (finger->x_high << 8);
			y = finger->y_low | (finger->y_high << 8);
			input_report_abs(input, ABS_MT_POSITION_X, x);	//上报
			input_report_abs(input, ABS_MT_POSITION_Y, y);
		}
	}
	input_mt_report_pointer_emulation(input, false);
	input_sync(input);	//上报处理
}

接下来就是抄一套软件框架,写的时候好有个参考,其实也就是和IIC总线设备差不多,在probe和remove多了部分input和MT相关的初始化注册/注销。

/* 设备树匹配表 */
static const struct i2c_device_id xxx_ts_id[] = 
{
	{ "xxx", 0, },
	{ /* sentinel */ }
};

/* 设备树匹配表 */
static const struct of_device_id xxx_of_match[] = 
{
	{ .compatible = "xxx", },
	{ /* sentinel */ }
};

/* i2c 驱动结构体 */
static struct i2c_driver ft5x06_ts_driver = 
{
	.driver = {
	.owner = THIS_MODULE,
	.name = "edt_ft5x06",
	.of_match_table = of_match_ptr(xxx_of_match),
	},
	.id_table = xxx_ts_id,
	.probe = xxx_ts_probe,
	.remove = xxx_ts_remove,
};

/*
* @description : 驱动入口函数
* @param : 无
* @return : 无
*/
static int __init xxx_init(void)
{
	int ret = 0;
	ret = i2c_add_driver(&xxx_ts_driver);
	return ret;
}

 /*
 * @description : 驱动出口函数
 * @param : 无
 * @return : 无
 */
static void __exit xxx_exit(void)
{
	i2c_del_driver(&ft5x06_ts_driver);
}
module_init(xxx_init);
module_exit(xxx_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("your name");
static int xxx_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct input_dev *input;
	/* 1、初始化 I2C */
	......
	/* 2,申请中断, */
	devm_request_threaded_irq(&client->dev, client->irq, NULL,
	xxx_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
	client->name, &xxx);
	......
	/* 3,input 设备申请与初始化 */
	input = devm_input_allocate_device(&client->dev);
	input->name = client->name;
	input->id.bustype = BUS_I2C;
	input->dev.parent = &client->dev;
	......

	/* 4,初始化 input 和 MT */
	__set_bit(EV_ABS, input->evbit);
	__set_bit(BTN_TOUCH, input->keybit);

	input_set_abs_params(input, ABS_X, 0, width, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, height, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_X,0, width, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y,0, height, 0, 0);
	input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0);
	......
	/* 5,注册 input_dev */
	input_register_device(input);
	......
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值