触摸屏驱动

本文档使用驱动为gt9xx,使用I2c通信。

设备树配置

通讯地址为0x14,挂载在i2c5总线上。中断引脚和复位引脚为gpio3的PC0和PC1,根据硬件方案修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&i2c5 {
status = "okay";

/*********************** GT 方案**********************/
gt9xx: gt9xx@14 {
status = "okay";
compatible = "goodix,gt9xx";
reg = <0x14>;
touch-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; //中断IO
reset-gpio = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>; //复位IO
max-x = <1920>;
max-y = <1200>;
tp-size = <911>;
};
};

设备树解释:
touch-gpio : 触摸中断引脚,根据原理图设定
reset-gpio : 触摸复位引脚,根据原理图设定
max-x:触摸屏x轴最大坐标
max-y:触摸屏y轴最大坐标
tp-size:用来驱动区分型号,加载不同的cfg文件

驱动源码

目前使用的是gt9xx v2.2版本驱动,驱动版本前后存在差异,使用时需要详细对比

  • 代码路径

kernel/drivers/input/touchscreen/gt9xx

  • 文件更改

kernel/drivers/input/touchscreen/Makefile

1
2
# add
obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/

kernel/drivers/input/touchscreen/Kconfig

1
2
3
4
5
6
7
8
9
config TOUCHSCREEN_GT9XX
tristate "Goodix gt9xx support for rockchip platform"
depends on I2C && ARCH_ROCKCHIP
help
Say Y here if you have a touchscreen interface using the gt9xx
on Rockchip platform, and your board-specific initialization
code includes that in its table of IIC devices.
If unsure, say N.

如果是单独编译内核,需要make menuconfig 中设置 “TOUCHSCREEN_GT9XX”

瑞芯微平台,在deconfig中增加

1
2
CONFIG_TOUCHSCREEN_GT9XX=y

  • 执行流程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
* goodix_ts_probe 起始入口
* GTP_DEBUG_FUNC 打印函数头和所在行数,需要开关打开
* i2c_check_functionality 检查I2c 功能是否支持,否则返回错误
* devm_regulator_get 获取“tp”对应电源管理调节器
* regulator_enable 启动电源管理调节器
* of_get_named_gpio_flags 获取中断引脚和复位引脚
* of_property_read_u32 获取最大触摸点数
* INIT_WORK 初始化一个工作队列
* i2c_set_clientdata 设置i2c_client的私有数据
* gtp_request_io_port
* GTP_DEBUG_FUNC 打印函数头和所在行
* GTP_GPIO_REQUEST 注册中断引脚和复位引脚
* gtp_reset_guitar 复位触摸屏
* i2c_get_clientdata 获取i2c_client的私有数据
* GTP_DEBUG_FUNC 打印函数头和所在行
* GTP_GPIO_OUTPUT 设置复位引脚为低电平,并在后续模拟复位信号
* gtp_int_sync 将中断引脚设置成低电平输出、延迟和设置成输入模式
* gtp_get_chip_type 获取触摸屏芯片类型(暂未执行)
* gtp_i2c_test 测试i2c通信
* gtp_read_version 读取触摸屏版本号
* gtp_init_panel 初始化触摸屏面板,加载cfg文件以及一些校验
* proc_create 创建触摸屏 proc 文件,名为gt91xx_config(现读取会崩溃)
* gtp_request_input_dev 申请触摸屏设备
* GTP_DEBUG_FUNC 打印函数头和所在行
* devm_input_allocate_device 分配输入设备
* input_set_abs_params 设置触摸屏绝对坐标
* input_register_device 注册触摸屏设备
* gtp_request_irq 请求中断的处理
* gpio_to_irq 获取中断号
* devm_request_threaded_irq 申请中断
* gtp_irq_enable 启用中断
* of_property_read_bool 读取设备树属性,如果使能了触摸屏作为唤醒源,则执行
* device_init_wakeup 设置设备是否支持唤醒
* enable_irq_wake 设置中断支持唤醒

2.2版本还是会加载cfg文件,如果发现触摸不准,可能原因与cfg有关
修改gt9xx_cfg.h 中对应位置,不同tp-size 对应不同的配置文件

1
2
3
4
u8 gtp_dat_gt11[] = {
/* <1200, 1920>*/
#include "DT101M.5371_IIC_Pen_GT9110_3003_20230926_V92.cfg"
};

触摸原点定位

调试触摸屏时,可能会遇到原点位置和软件对应位置不一致。需要按照以下步骤修改。
1、通过调试工具和屏幕鼠标位置,确定系统规定的原点位置
evtest

1
2
3
4
5
6
7
8
9
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: rk805 pwrkey
/dev/input/event1: goodix-ts
/dev/input/event2: headset-keys
/dev/input/event3: rockchip-es8388 Headset
/dev/input/event4: adc-keys
/dev/input/event5: adc-vin2-keys
/dev/input/event6: adc-vin6-keys

找到对应触摸屏,根据上报的坐标值,确定x、y轴的原点和最大点

1
2
3
4
5
Event: time 1679941692.863173, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 70
Event: time 1679941692.863173, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 1130
Event: time 1679941692.863173, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 111
Event: time 1679941692.863173, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 111

2、修改驱动或者设备树,使驱动上报的值符合,符合实际情况的原点
gt9xx驱动对应位置

1
2
3
4
5
6
# x、y轴翻转 
gtp_change_x2y = FALSE;
# x 轴翻转
gtp_x_reverse = FALSE;
# y 轴翻转
gtp_y_reverse = FALSE;

注意问题

1、中断事件未获取到
需要根据确认电路,设计的是高电平中断还是低电平中断。假如配置的低电平中断,那芯片默认引脚应当初始值为in 高。反之,高电平触发中断,中断引脚默认电平应当为in 低。
配合kernel debug指令排查

  • 查看gpio电平

    1
    2
    3
    4
    5
    # 查看当前引脚电平状态
    cat /sys/kernel/debug/gpio

    gpio-112 ( |GTP_INT_IRQ ) in hi
    gpio-113 ( |GTP_RST_PORT ) out hi

    本处使用的低电平中断,中断引脚为in hi

  • 查看中断事件

    1
    2
    3
    4
    5
    # 过滤gt9xx 事件打印
    cat /proc/interrupts |grep gt9x

    116: 784 0 0 0 0 0 0 0 rockchip_gpio_irq 16 Edge gt9xx

    如果中断事件一直为0,则需要定位该问题

2、设置驱动修改翻转不生效
查看驱动代码发现,原先代码仅在非911和970配置x、y翻转才生效,注释判断即可。

1
2
3
4
5
6
7
8
// if (!bgt911 && !bgt970) {
if (gtp_x_reverse)
x = ts->abs_x_max - x;

if (gtp_y_reverse)
y = ts->abs_y_max - y;
// }