一,FocalTech触摸屏简介
- FocalTech 的触控控制器常用于各种触摸屏,包括电容式和电阻式屏幕。支持多点触控,能够识别多个手指的输入。
本文提到的 ft5526 支持多达 10 个触控点,能够同时识别多个手指的输入,适合需要复杂手势操作的应用。 - 工作电压:通常为
1.8V 或 3.3V
,具体取决于设备设计。 - 通讯接口:支持 I2C 或 SPI 通信接口,方便与主控芯片连接。
二,DTS配置
查看原理图TP是挂在i2c1节点下:
注:不同主板节点以及GPIO引脚是不同的,可查看对应原理图确定。
bash
&i2c1 {
status = "okay";
focaltech@38 {
status = "okay";
compatible = "focaltech,fts";
reg = <0x38>;
focaltech,irq-gpio = <&gpio0 RK_PB5 IRQ_TYPE_LEVEL_LOW>; //中断脚
focaltech,reset-gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; //复位脚
focaltech,max-touch-number = <5>; //最大触摸数支持
focaltech,display-coords = <0 0 1280 800>; //以像素为单位的显示分辨率。一个由minX, minY, maxX和maxY组成的四元数组
};
};
属性解析:
focaltech,irq-gpio :中断脚
focaltech,reset-gpio :复位脚
focaltech,max-touch-number :最大触摸数支持
focaltech,display-coords :以像素为单位的显示分辨率。一个由minX, minY, maxX和maxY组成的四元数组
三,驱动文件配置
主要驱动文件如上图所示。
1. focaltech_core.c
bash
static int fts_gpio_configure(struct fts_ts_data *data) //用于配置 FocalTech 触摸屏 GPIO(通用输入输出)引脚
在这个函数中,可以看到读取dts中配置的GPIO引脚信息:
c
static int fts_gpio_configure(struct fts_ts_data *data)
{
int ret = 0;
FTS_FUNC_ENTER();
/* request irq gpio */
if (gpio_is_valid(data->pdata->irq_gpio)) {
ret = gpio_request(data->pdata->irq_gpio, "fts_irq_gpio");
if (ret) {
FTS_ERROR("[GPIO]irq gpio request failed");
goto err_irq_gpio_req;
}
ret = gpio_direction_input(data->pdata->irq_gpio);
if (ret) {
FTS_ERROR("[GPIO]set_direction for irq gpio failed");
goto err_irq_gpio_dir;
}
}
/* request reset gpio */
if (gpio_is_valid(data->pdata->reset_gpio)) {
ret = gpio_request(data->pdata->reset_gpio, "fts_reset_gpio");
if (ret) {
FTS_ERROR("[GPIO]reset gpio request failed");
goto err_irq_gpio_dir;
}
ret = gpio_direction_output(data->pdata->reset_gpio, 1);
if (ret) {
FTS_ERROR("[GPIO]set_direction for reset gpio failed");
goto err_reset_gpio_dir;
}
}
FTS_FUNC_EXIT();
return 0;
err_reset_gpio_dir:
if (gpio_is_valid(data->pdata->reset_gpio))
gpio_free(data->pdata->reset_gpio);
err_irq_gpio_dir:
if (gpio_is_valid(data->pdata->irq_gpio))
gpio_free(data->pdata->irq_gpio);
err_irq_gpio_req:
FTS_FUNC_EXIT();
return ret;
}
2. focaltech_core.h
头文件用来定义TP驱动程序的功能。使用#define定义私有常量和宏;
截取部分定义代码:
bash
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define FTS_MAX_POINTS_SUPPORT 10 /* constant value, can't be changed */
#define FTS_MAX_KEYS 4
#define FTS_KEY_DIM 10
#define FTS_COORDS_ARR_SIZE 4
#define FTS_ONE_TCH_LEN 6
3. 移植驱动
驱动包资源链接附在文末。
a. 将驱动包解压后整个拷贝到以下目录
bash
./kernel/drivers/input/touchscreen
b. 修改 touchscreen 目录下的 Makefile以及Kconfig
bash
kernel/drivers/input/touchscreen/Makefile中添加:
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
------------------------------------------------------------------------
kernel/drivers/input/touchscreen/Kconfig中添加:
source "drivers/input/touchscreen/focaltech_touch/Kconfig"
c. 内核中加载驱动
bash
kernel/arch/arm64/configs/rockchip_defconfig中添加:
CONFIG_TOUCHSCREEN_FTS=y
CONFIG_TOUCHSCREEN_FTS_DIRECTORY="focaltech_touch"
四,调试
1. 上电时的内核打印日志
和触摸屏相关的打印都是 [FTS_TS]
开头的:
2. 查看I2C设备
可以在目录下看到i2c挂载点。
3. 报点问题
源码路径:kernel/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
fts_input_report_b函数是触摸屏驱动中处理触摸事件的一个部分,特别是处理触摸按下(DOWN)事件的逻辑。
c
static int fts_input_report_b(struct fts_ts_data *ts_data, struct ts_event *events)
{
int i = 0;
int touch_down_point_cur = 0;
int touch_point_pre = ts_data->touch_points;
u32 max_touch_num = ts_data->pdata->max_touch_number;
bool touch_event_coordinate = false;
struct input_dev *input_dev = ts_data->input_dev;
for (i = 0; i < ts_data->touch_event_num; i++) {
if (fts_input_report_key(ts_data, &events[i]) == 0) {
continue;
}
touch_event_coordinate = true;
if (EVENT_DOWN(events[i].flag)) { //EVENT_DOWN(events[i].flag) 检查当前事件标志是否表示触控按下.
input_mt_slot(input_dev, events[i].id); //input_mt_slot(input_dev, events[i].id);指定当前活动的触控点 ID,为以下的多点触控报告做准备.
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true); //报告当前插槽中的触控工具(例如手指)处于按下状态.
#if FTS_REPORT_PRESSURE_EN
input_report_abs(input_dev, ABS_MT_PRESSURE, events[i].p);
#endif
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, events[i].area); //触摸的主要面积.
input_report_abs(input_dev, ABS_MT_POSITION_X, events[i].x); //触摸点的 x 坐标
input_report_abs(input_dev, ABS_MT_POSITION_Y, events[i].y); //触摸点的 y 坐标
touch_down_point_cur |= (1 << events[i].id); //用位运算更新当前和之前的触控点记录,标记按下的触控 ID.
touch_point_pre |= (1 << events[i].id);
if ((ts_data->log_level >= 2) ||
((1 == ts_data->log_level) && (FTS_TOUCH_DOWN == events[i].flag))) {
FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
events[i].id, events[i].x, events[i].y,
events[i].p, events[i].area);
}
} else {
input_mt_slot(input_dev, events[i].id);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
touch_point_pre &= ~(1 << events[i].id);
if (ts_data->log_level >= 1) FTS_DEBUG("[B]P%d UP!", events[i].id);
}
}
if (unlikely(touch_point_pre ^ touch_down_point_cur)) {
for (i = 0; i < max_touch_num; i++) {
if ((1 << i) & (touch_point_pre ^ touch_down_point_cur)) {
if (ts_data->log_level >= 1) FTS_DEBUG("[B]P%d UP!", i);
input_mt_slot(input_dev, i);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
}
}
}
if (touch_down_point_cur)
input_report_key(input_dev, BTN_TOUCH, 1);
else if (touch_event_coordinate || ts_data->touch_points) {
if (ts_data->touch_points && (ts_data->log_level >= 1))
FTS_DEBUG("[B]Points All Up!");
input_report_key(input_dev, BTN_TOUCH, 0);
}
ts_data->touch_points = touch_down_point_cur;
input_sync(input_dev);
return 0;
}
a. x,y轴坐标需要更换
在触摸事件的处理过程中,发现触摸事件的 x 坐标和 y 坐标被颠倒, 可以交换这两个函数调用的参数:
c
input_report_abs(input_dev, ABS_MT_POSITION_X, events[i].y); // 将 y 赋值给 x
input_report_abs(input_dev, ABS_MT_POSITION_Y, events[i].x); // 将 x 赋值给 y
b. x,y轴需要镜像变换
c
int screen_width = 800; // 假设屏幕的宽
int screen_length = 1280; // 假设屏幕的长
input_report_abs(input_dev, ABS_MT_POSITION_X, screen_width - events[i].x);
input_report_abs(input_dev, ABS_MT_POSITION_Y, screen_length - events[i].y);
screen_width 为触摸屏的实际宽度,以保证 X 轴的值在报告时被镜像翻转。
screen_length 为触摸屏的实际长度,以保证 Y 轴的值在报告时被镜像翻转。
TP驱动包资源链接:
https://download.csdn.net/download/weixin_45639314/90020237?spm=1001.2014.3001.5503