一、 多点触摸协议(MT)
input子系统下的多点触摸协议称为MT本协议的文件为:Documentation/input/multitouch-protocol.txt。
MT根据硬件的兼容性,协议分为两种类型:
- Type A:适用于无法区分或跟踪触摸点的原始数据。
- Type B:适用于具有硬件跟踪和区分触摸点的触摸设备。这类设备是通过的slot更新某一个触摸点的信息
通过一系列的触摸点信息ABS_MT事件上报给Linux在文件中定义内核include/uapi/linux/input.h
中:
#define ABS_MT_SLOT 0x2f /* MT slot being modified */ #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ #define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */ #define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */ #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ #define ABS_MT_POSITION_X 0x35 /* Center X touch position */ #define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */ #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ #define ABS_MT_DISTANCE
0x3b
/* Contact hover distance */
#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
其中最常用的是:
- ABS_MT_SLOT:用来上报触摸点ID
- ABS_MT_POSITION_X和ABS_MT_POSITION_Y:用来上报触摸点的 (X, Y) 坐标信息
- ABS_MT_TRACKING_ID:对于Type B类型的设备,需要用该事件来区分触摸点
二、FT5426触摸芯片
FT5x06系列是单芯片电容触摸板控制器IC,内部带有一个8bit的MCU,支持2.8’‘到8.9’‘的触摸屏,区别如下: 其内部框图如下: 与主控制器的连接示意图如下: 串行接口支持I2C(最大400KHz)和SPI,I2C的通信格式如下: 本文使用的是正点原子7’'RGB屏幕,分辨率1024*600,触摸屏及其驱动IC集成在屏幕上,通过FPC排线与imx6ull开发板相连: imx6ull底板的排线连接情况如下: 可以看出:。
三、使用内核自带的驱动
1. 驱动源码
Linux内核已经集成了很多电容触摸IC的驱动文件,针对FT5426触摸IC,驱动文件为:drivers/input/touchscreen/edt-ft5x06.c。
此驱动源码在正点原子的开发板上不能直接使用,正点原子官方对其进行了修改,修改的地方如下。
(1)edt_ft5x06_i2c_ts_probe_dt 设备树解析函数
增加触摸IC中断引脚使用的gpio: (2)edt_ft5x06_ts_probe 挂载函数
看上去像是600不是64的倍数,所以选择在驱动里写死: 驱动ic的中断引脚需要设置gpio: (3)edt_ft5x06_ts_isr 触摸中断处理函数
此函数修改的地方有点多,截取部分: (4)EDT_RAW_DATA_RETRIES
2. 使能驱动
查看该文件下的makefile: 需要开启该宏来使能驱动,进入menuconfig界面,按/
,搜索该宏定义位置: 按照帮助文档给出,使能该驱动: 配置修改后保存退出,生成新的.config文件,重新编译内核后,将修改同步到开发板配置文件 。
3. 添加设备树节点
。
驱动添加完成后,还需要添加与之匹配的设备树节点,根据兼容性查找对应的绑定文档: 找到绑定文档为:Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt,其中给出的i2c示例节点为:
polytouch: edt-ft5x06@38 {
compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
reg = <0x38>;
pinctrl-names = "default";
pinctrl-0 = <&edt_ft5x06_pins>;
interrupt-parent = <&gpio2>;
interrupts = <5 0>;
reset-gpios = <&gpio2 6 1>;
wake-gpios = <&gpio4 9 0>;
};
根据绑定文档,在开发板的设备树中 节点下,添加自己的节点:
polytouch: edt-ft5x06@38 {
compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
reg = <0x38>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ft5x06>;
interrupt-parent = <&gpio1>;
interrupts = <9 0>;
reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
interrupt-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
在pinctrl节点下,添加edt_ft5x06_pins描述:
pinctrl_ft5x06: ft5x06grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0xF080
MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x10B0
>;
};
修改完成,重新编译设备树。
4. 测试
使用新的内核和设备树启动,查看启动日志input子系统相关: 查看input输入设备的节点: 这里我另外还注册了按键为回车键,所以会有三个输入设备,根据启动顺序,触摸屏应该是event1。
查看触摸屏数据:
hexdump /dev/input/event1
执行此命令后,开始点击触摸屏,就会输出数据。如果无数据,则表示驱动有问题。
5. 过程中遇到的问题记录
(1)问题1 分析:GPIO1_IO09引脚已被使用。
解决: (2)问题2 问题分析:gpio1-09已被申请,肯定是没有屏蔽干净。
问题解决:
四、FT5x06驱动浅析
1. i2c驱动框架
FT5x06的核心是一个i2c设备,所以整个驱动都是基于i2c驱动框架所写: 兼容性如下:
2. 挂载函数的流程
static int edt_ft5x06_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
}
(1)
获取设备树节点中的gpio引脚信息: 该函数中会调用gpio子系统,操作上一步拿到的复位引脚,复位ic,实现如下: 接下来申请中断引脚对应的gpio: (2)I2C设备操作
检测ft5x06版本号: 该函数实现如下: i2c读写函数封装为edt_ft5x06_ts_readwrite,实现如下: (3)input子系统操作 (4)注册gpio引脚中断 中断函数为edt_ft5x06_ts_isr,在该函数中完成触摸事件的上报。 (5)注册输入设备