CSDN仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2017/12/26/Exynos4412——触摸屏驱动/#more
移植Exynos4412的I2C接口触摸屏驱动。
这应该是Exynos4412 LCD部分的最后一部分了。
为了去探索LCD驱动,前面做了一系列的准备工作,最后终于完成了LCD驱动,现在只剩下触摸屏这个最后的“尾巴”。
1.工作原理
前面LCD之backligth部分说了,友善之臂这个屏,为了改善大尺寸四线电阻触摸屏的性能,外加了一个低成本的MCU去控制专业的触控芯片,将滤波后的稳定数据通过GPIO传回到ARM上。
但我的板子LCD是电容屏,查阅相关资料后得知,是通过一个FT5406触摸屏芯片实现的电容触摸功能。
根据FT5x06.pdf手册可得知其工作的框架:
当触摸屏上发生触摸操作时,通过TXn(Transmit output pin)和RXn(Receiver input pins)传输给FT5406,FT5406经过处理后,将坐标信息通过Serial Interface(I2C or SPI)发给Host(开发板)。
查阅FT5x06.pdf,可以看到FT5x06对外有如下接口:
I2C/SPI:与主机进行数据交换的接口
INT:中断信号接口,通知主处理器触摸数据准备好读取
WAKE:主机将FT5x06从休眠模式切换到主动模式的中断信号
RST:外部低电平信号复位芯片
因此,开发板至少的有I2C/SPI和INT与FT5x06相连。
2.原理图
-
Tiny4412-1412-Schematic.pdf:
I2C使用I2C1,INT使用GPX1_6引脚。 -
Tiny4412SDK-1506-Schematic.pdf:
在底板上经过一次电平转换引出到LCD1接口上。 -
LCD-S702-1509.pdf:
LCD上并没有FT5x06的相关信息,只提供了一个CON5接口。
友善之臂封装好了LCD和触摸屏,对外只提供I2C接口。
对于驱动来说,触摸屏就是一个带中断的信号的I2C设备。
3. 设备树文件
ft5406 作为 i2c_1 的子节点。
&i2c_1 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <400000>;
status = "okay";
polytouch: edt-ft5x06@38 {
compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
reg = <0x38>;
interrupt-parent = <&gpx1>;
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
touchscreen-size-x = <800>;
touchscreen-size-y = <480>;
};
};
内核已经有了ft5x06驱动,所有对应的也会有设备树的描述文件:
linux-4.13.9/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
linux-4.13.9/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
详细介绍了设备树的必要参数和非必要参数。
4. 驱动程序
内核中ft5x06驱动所在路径:
linux-4.13.9/drivers/input/touchscreen/edt-ft5x06.c
这块的内容,暂时不想分析,涉及I2C子系统和输入子系统,回头再慢慢分析。
5. 测试程序
{% codeblock lang:c [app.c] https://github.com/hceng/learn/blob/master/tiny4412/03_touchscreen/app.c %}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
int main()
{
int keys_fd;
char ret[2];
struct input_event t;
keys_fd = open("/dev/input/event0", O_RDONLY); //打开TP设备
if(keys_fd<=0){
printf("open /dev/input/event0 device error!\n");
return 0;
}
while(1)
{
if(read(keys_fd, &t, sizeof(t))==sizeof(t))
{
if (t.type == EV_KEY)
{
printf(" type: EV_KEY, event = %s, value = %d \r\n",
t.code == BTN_TOUCH ? "BTN_TOUCH" : "Unkown", t.value);
}
else if(t.type == EV_ABS)
{
printf(" type: EV_ABS, event = %s, value = %d \r\n",
t.code == ABS_X ? "ABS_X" :
t.code == ABS_Y ? "ABS_Y" :
t.code == ABS_PRESSURE ? "ABS_PRESSURE" :"Unkown", t.value);
}
}
}
close(keys_fd);
return 0;
}
{% endcodeblock %}