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

相关推荐
恋猫de小郭36 分钟前
Flutter 官方多窗口体验 ,为什么 Flutter 推进那么慢,而 CMP 却支持那么快
android·前端·flutter
yan123686 小时前
Linux 驱动之设备树
android·linux·驱动开发·linux驱动
aningxiaoxixi8 小时前
android stdio 的布局属性
android
CYRUS STUDIO9 小时前
FART 自动化脱壳框架一些 bug 修复记录
android·bug·逆向·fart·脱壳
寻找优秀的自己10 小时前
Cocos 打包 APK 兼容环境表(Android API Level 10~15)
android·cocos2d
大胃粥11 小时前
WMS& SF& IMS: 焦点窗口更新框架
android
QING61811 小时前
Gradle 核心配置属性详解 - 新手指南(二)
android·前端·gradle
QING61811 小时前
Gradle 核心配置属性详解 - 新手指南(一)
android·前端·gradle
_一条咸鱼_14 小时前
Android Runtime内存管理子系统启动流程原理(13)
android·面试·android jetpack