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

相关推荐
安东尼肉店6 小时前
Android compose屏幕适配终极解决方案
android
2501_916007476 小时前
HTTPS 抓包乱码怎么办?原因剖析、排查步骤与实战工具对策(HTTPS 抓包乱码、gzipbrotli、TLS 解密、iOS 抓包)
android·ios·小程序·https·uni-app·iphone·webview
feiyangqingyun8 小时前
基于Qt和FFmpeg的安卓监控模拟器/手机摄像头模拟成onvif和28181设备
android·qt·ffmpeg
用户20187928316712 小时前
ANR之RenderThread不可中断睡眠state=D
android
煤球王子12 小时前
简单学:Android14中的Bluetooth—PBAP下载
android
小趴菜822712 小时前
安卓接入Max广告源
android
齊家治國平天下12 小时前
Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
android·anr
ZHANG13HAO12 小时前
Android 13.0 Framework 实现应用通知使用权默认开启的技术指南
android
【ql君】qlexcel12 小时前
Android 安卓RIL介绍
android·安卓·ril
写点啥呢12 小时前
android12解决非CarProperty接口深色模式设置后开机无法保持
android·车机·aosp·深色模式·座舱