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

相关推荐
帅次5 分钟前
Flutter ListView 详解
android·flutter·ios·iphone·webview
匹马夕阳1 小时前
(二十六)Java观察者模式在Android开发中的应用详解
android·java·观察者模式
百锦再2 小时前
Android Drawable 目录下的 XML 图形文件详解
android·xml·java·app·手机·安卓
百锦再2 小时前
Android ImageButton 使用详解
android·java·app·安卓·studio·mobile
顾林海3 小时前
深度解析CopyWriteArrayList工作原理
android·java·面试
pengyu3 小时前
【Flutter 状态管理 - 伍】 | 万字长文解锁你对观察者模式的认知
android·flutter·dart
Cachel wood4 小时前
大数据开发知识1:数据仓库
android·大数据·数据仓库·sql·mysql·算法·ab测试
灰色人生qwer4 小时前
idea中运行groovy程序报错
android·java·intellij-idea
Coffeeee4 小时前
面试官:说几个同步拿到异步操作结果的方式
android·面试·kotlin
小鱼人爱编程5 小时前
离职当晚,我删除了所有同事的微信
android·前端·后端