一、Linux 下电容触摸屏驱动框架简介
1 重要的知识点:
①、电容触摸屏是 IIC 接口的,需要触摸 IC,以正点原子的 ATK7016 为例,其所使用的触摸屏控制 IC 为 FT5426,因此所谓的电容触摸驱动就是 IIC 设备驱动。
②、触摸 IC 提供了中断信号引脚(INT),可以通过中断来获取触摸信息。
③、电容触摸屏得到的是触摸位置绝对信息以及触摸屏是否有按下。
④、电容触摸屏不需要校准。当然了,这只是理论上的,如果电容触摸屏质量比较差,或者触摸玻璃和 TFT 之间没有完全对齐,那么也是需要校准的。
2.可以得出电容触摸屏驱动其实就是以下几种 linux 驱动框架的组合:
①、 IIC 设备驱动,因为电容触摸 IC 基本都是 IIC 接口的,因此大框架就是 IIC 设备驱动。
②、通过中断引脚(INT)向 linux 内核上报触摸信息,因此需要用到 linux 中断驱动框架。坐标的上报在中断服务函数中完成。
③、触摸屏的坐标信息、屏幕按下和抬起信息都属于 linux 的 input 子系统,因此向 linux 内核上报触摸屏坐标信息就得使用 input 子系统。只是,我们得按照 linux 内核规定的规则来上报坐标信息
二、硬件原理图
使用gpio1_io05作为中断引脚。
三、设备树:
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
/* 电容屏触屏中断引脚 */
pinctrl_touchscreen_int: lcdif_tsc_int {
fsl,pins = <
MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x000010B0
>;
};
};
};
&iomuxc_snvs {
pinctrl-names = "default_snvs";
pinctrl-0 = <&pinctrl_hog_2>;
imx6ul-evk {
/* 电容屏复位引脚 */
pinctrl_tsc_reset: tscresetgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x000110A0
>;
};
};
};
&i2c2 {
clock_frequency = <100000>; /* i2c2通信频率 */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
gt9xx@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>; /* 设备地址0x5d */
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc_reset &pinctrl_touchscreen_int>;
/* 电容屏引脚中断相关配置 */
interrupt-parent = <&gpio1>;
interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
irq-gpios = <&gpio1 5 IRQ_TYPE_EDGE_FALLING>;
};
};
四、查找设备树中的i2c设备
五、驱动大纲:
1、主题I2C框架准备好
2、复位引脚和中断引脚,包括中断
3、初始化FT5426。
4、input子系统框架
5、在中断服务函数里面读取触摸坐标值,然后上报给系统
六、查看触摸屏原始数据方法:
使用手去点击屏幕,会输出数据。
七、原始数据分析:
第 1 行, type 为 0x3,说明是一个 EV_ABS 事件, code 为 0x2f,为 ABS_MT_SLOT,因此这一行就是 input_mt_slot 函数上报的 ABS_MT_SLOT 事件。 value=0,说明接下来上报的是第一个触摸点坐标。
第 2 行 , type 为 0x3 , 说 明 是 一 个 EV_ABS 事 件 , code 为 0x39 , 也 就 是ABS_MT_TRACKING_ID , 这 一 行 就 是 input_mt_report_slot_state 函 数 上 报ABS_MT_TRACKING_ID 事件。 value=5 说明给 SLOT0 分配的 ID 为 5。
第 3 行, type 为 0x3,是一个 EV_ABS 事件, code 为 0x35,为 ABS_MT_POSITION_X,这一行就是 input_report_abs 函数上报的 ABS_MT_POSITION_X 事件,也就是触摸点的 X 轴坐标。 value=0x03ec=1004,说明触摸点 X 轴坐标为 1004,属于屏幕右上角区域。
第 4 行, type 为 0x3,是一个 EV_ABS 事件, code 为 0x36,为 ABS_MT_POSITION_Y,这一行就是 input_mt_report_slot_state 函数上报的 ABS_MT_POSITION_Y 事件,也就是触摸点
的 Y 轴坐标。 value=0x17=23,说明 Y 轴坐标为 23,由此可以看出本次触摸的坐标为(1004,23),处于屏幕右上角区域。
第 5 行, type 为 0x1,是一个 EV_KEY 事件, code=0x14a,为 BTN_TOUCH, value=0x1 表示触摸屏被按下。
第 6 行, type 为 0x3,是一个 EV_ABS 事件, code 为 0x0,为 ABS_X,用于单点触摸的时候上报 X 轴坐标。在这里和 ABS_MT_POSITION_X 相同, value 也为 0x3f0=1008。 ABS_X 是由 input_mt_report_pointer_emulation 函数上报的。
第 7 行, type 为 0x3,是一个 EV_ABS 事件, code 为 0x1,为 ABS_Y,用于单点触摸的时候上报 Y 轴坐标。在这里和 ABS_MT_POSITION_Y 相同, value 也为 0x29=41。 ABS_Y 是由input_mt_report_pointer_emulation 函数上报的。
第 8 行, type 为 0x0,是一个 EV_SYN 事件,由 input_sync 函数上报。
第9行, type为0x3,是一个EV_ABS事件, code为0x39,也就是ABS_MT_TRACKING_ID,value=0xffffffff=-1,说明触摸点离开了屏幕。
第 10 行, type 为 0x1,是一个 EV_KEY 事件, code=0x14a,为 BTN_TOUCH, value=0x0表示手指离开触摸屏,也就是触摸屏没有被按下了。
第 11 行, type 为 0x0,是一个 EV_SYN 事件,由 input_sync 函数上报。
以上就是一个触摸点的坐标上报过程,和我们前面讲解的 Type B 类型设备一致。