RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526

一,FocalTech触摸屏简介

  1. FocalTech 的触控控制器常用于各种触摸屏,包括电容式和电阻式屏幕。支持多点触控,能够识别多个手指的输入。
    本文提到的 ft5526 支持多达 10 个触控点,能够同时识别多个手指的输入,适合需要复杂手势操作的应用。
  2. 工作电压:通常为 1.8V 或 3.3V,具体取决于设备设计。
  3. 通讯接口:支持 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

相关推荐
潜龙952737 分钟前
第3.2.3节 Android动态调用链路的获取
android·调用链路
追随远方1 小时前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
撰卢2 小时前
MySQL 1366 - Incorrect string value:错误
android·数据库·mysql
恋猫de小郭3 小时前
Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
android·flutter·ios
牛马程序小猿猴3 小时前
15.thinkphp的上传功能
android
林家凌宇3 小时前
Flutter 3.29.3 花屏问题记录
android·flutter·skia
时丶光4 小时前
Android 查看 Logcat (可纯手机方式 无需电脑)
android·logcat
血手人屠喵帕斯4 小时前
事务连接池
android·adb
恋猫de小郭5 小时前
React Native 前瞻式重大更新 Skia & WebGPU & ThreeJS,未来可期
android·javascript·flutter·react native·react.js·ios
一人一萧十只猫�6 小时前
MySQL 从入门到精通(三):日志管理详解 —— 从排错到恢复的核心利器
android·mysql·adb