1. 项目概述
在嵌入式Linux开发中,触摸屏驱动移植是一个关键环节。本文将详细介绍如何在正点原子i.MX6ULL开发板上移植GT9147触摸屏驱动,使其在Linux 7.0内核下正常工作。GT9147是国产Goodix公司生产的一款高性能电容式触摸屏控制器,广泛应用于各类嵌入式设备。
2. 硬件连接分析
2.1 GT9147引脚功能
GT9147通过I2C接口与主控芯片通信,其典型硬件连接如下:
| 信号 | 引脚 | 功能描述 |
|---|---|---|
| SCL | UART5_TX (I2C2_SCL) | I2C时钟信号线 |
| SDA | UART5_RX (I2C2_SDA) | I2C数据信号线 |
| INT | GPIO1_IO09 | 触摸中断信号(低电平有效) |
| RST | GPIO1_IO05 | 复位信号(低电平有效) |
| VDD | 3.3V | 数字电源 |
| AVDD | 2.8V | 模拟电源 |
2.2 I2C地址说明
GT9147的I2C地址为0x5d(7位地址)。需要注意的是:
- 有些文档可能标注为0xba,这是包含读写位的8位地址
- 内核驱动中使用的是7位地址,因此配置为0x5d
- 可以通过i2cdetect工具验证设备是否被正确识别
3. 设备树配置详解
3.1 I2C总线配置
首先需要在设备树中配置I2C2总线节点:
dts复制&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
/* GT9147 触摸屏节点 */
gt9147: gt9147@5d {
compatible = "goodix,gt9147", "goodix,gt9xx";
reg = <0x5d>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc &pinctrl_tsc_reset>;
interrupt-parent = <&gpio1>;
interrupts = <9 0>;
reset-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
interrupt-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
status = "okay";
vdd-supply = <®_vddio>;
avdd-supply = <®_avdd28>;
};
};
3.2 关键属性解析
| 属性 | 说明 |
|---|---|
| compatible | 设备兼容字符串,"goodix,gt9147"优先匹配,失败则尝试"goodix,gt9xx" |
| reg | I2C设备地址(0x5d) |
| interrupt-parent | 中断控制器引用(这里是GPIO1控制器) |
| interrupts | 中断号配置(GPIO1_IO09对应<9 0>) |
| reset-gpios | 复位引脚配置(GPIO1_IO05,低电平有效) |
| interrupt-gpios | 中断引脚显式指定(某些驱动需要) |
| vdd-supply | 数字电源(3.3V) regulator引用 |
| avdd-supply | 模拟电源(2.8V) regulator引用 |
3.3 pinctrl配置
触摸屏需要配置两个pinctrl组:
dts复制&iomuxc {
pinctrl_tsc: tscgrp {
fsl,pins = <
/* TSC_INT */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x79
>;
};
pinctrl_tsc_reset: tsc_reset {
fsl,pins = <
/* TSC_RST */
MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x10B0
>;
};
};
注意:
- 0x79和0x10B0是引脚电气特性配置值
- 这些值根据具体硬件设计可能需要调整
- 配置不当可能导致信号完整性问题
3.4 电源管理配置
GT9147需要两个独立的电源:
dts复制/ {
reg_vddio: regulator-vddio {
compatible = "regulator-fixed";
regulator-name = "VDDIO";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-enable-high = <1>;
};
reg_avdd28: regulator-avdd28 {
compatible = "regulator-fixed";
regulator-name = "AVDD28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-high = <1>;
};
};
电源管理注意事项:
- 确保实际硬件能提供稳定的2.8V和3.3V电源
- 电源纹波过大会导致触摸性能下降
- 上电时序应符合GT9147规格书要求
4. GPIO冲突解决方案
4.1 冲突现象分析
在i.MX6ULL开发板上,GT9147的中断和复位引脚(GPIO1_IO09和GPIO1_IO05)与SD卡的引脚复用。当两个设备同时启用时,会产生GPIO冲突,典型错误如下:
code复制pin MX6UL_PAD_GPIO1_IO09 already requested by 1-005d; cannot claim for 2040000.touchscreen
pin MX6UL_PAD_GPIO1_IO05 already requested by 1-005d; cannot claim for 2190000.mmc
4.2 解决方案一:禁用SD卡冲突引脚
如果不需要使用SD卡,或SD卡通过其他接口连接,可以修改usdhc1的pinctrl配置:
dts复制pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
/* 注释掉下面两行冲突引脚 */
/* MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 */
/* MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 */
>;
};
4.3 解决方案二:调整设备加载顺序
通过设备树别名可以调整设备加载顺序:
dts复制/ {
aliases {
mmc0 = &usdhc1; // 确保SD卡先加载
mmc1 = &usdhc2;
};
};
注意事项:
- 这种方法不能从根本上解决硬件冲突
- 只适用于暂时性调试
- 长期解决方案应选择方案一或方案三
4.4 解决方案三:硬件修改
如果条件允许,可以考虑:
- 将触摸屏的中断/复位引脚改接到其他GPIO
- 修改PCB设计,彻底解决引脚冲突
- 使用I2C GPIO扩展芯片增加可用GPIO数量
5. 驱动验证与测试
5.1 驱动加载检查
系统启动后,检查内核日志:
bash复制dmesg | grep -E "goodix|gt9147|touch"
预期输出示例:
code复制[ 2.123456] goodix 1-005d: ID 0x9147
[ 2.234567] goodix 1-005d: irq 0, flags 0x0
[ 2.345678] goodix 1-005d: Touchscreen registered
[ 2.456789] input: Goodix Capacitive TouchScreen as /devices/soc0/soc/2100000.i2c/i2c-1/1-005d/input/input0
5.2 输入设备检查
查看系统输入设备:
bash复制ls /dev/input/
cat /proc/bus/input/devices
预期输出应包含类似内容:
code复制I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="Goodix Capacitive TouchScreen"
P: Phys=1-005d/input0
S: Sysfs=/devices/soc0/soc/2100000.i2c/i2c-1/1-005d/input/input0
U: Uniq=
H: Handlers=event0 mouse0
B: PROP=2
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
B: ABS=2650000 3
5.3 触摸功能测试
5.3.1 使用evtest测试
bash复制apt install evtest
evtest /dev/input/event0
正常触摸时应有类似输出:
code复制Event: time 1234567890.123456, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 1234567890.123456, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 512
Event: time 1234567890.123456, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 300
Event: time 1234567890.123456, -------------- SYN ------------
5.3.2 使用tslib测试
bash复制apt install tslib-tests
ts_test
测试界面应能正确响应触摸操作。
6. 常见问题排查
6.1 触摸无响应
排查步骤:
- 检查驱动是否加载成功
- 验证I2C通信是否正常:
bash复制
i2cdetect -y 1 - 测量中断引脚电平变化
- 检查电源电压是否稳定
6.2 触摸坐标偏移
可能原因:
- 屏幕分辨率与触摸报告分辨率不匹配
- 触摸屏安装位置偏移
- 校准参数错误
解决方案:
- 重新校准触摸屏
- 调整驱动中的resolution参数
- 检查硬件安装
6.3 触摸抖动
改善方法:
- 加强电源滤波
- 调整中断触发方式
- 启用驱动内置的软件滤波
- 检查接地是否良好
6.4 多点触摸失效
检查内核配置:
bash复制zcat /proc/config.gz | grep INPUT_MT
确保以下配置已启用:
code复制CONFIG_INPUT_MT=y
CONFIG_INPUT_TOUCHSCREEN=y
7. 性能优化建议
-
中断优化:
- 使用边沿触发代替电平触发
- 优化中断处理函数,减少耗时操作
-
电源管理:
- 合理配置睡眠模式
- 动态调整扫描频率
-
软件滤波:
- 启用驱动内置的滤波算法
- 调整滤波参数匹配具体应用场景
-
校准优化:
- 采用多点校准代替单点校准
- 定期自动校准
8. 开发心得
在实际移植过程中,有几点经验值得分享:
-
引脚冲突问题非常常见,需要仔细检查设备树中的每个引脚配置。我遇到过因为一个引脚的电气特性配置不当导致整个触摸屏无法工作的情况。
-
电源稳定性对触摸性能影响很大。曾经有一个项目因为电源纹波过大导致触摸坐标随机跳动,后来通过增加滤波电容解决了问题。
-
不同版本的GT9147固件可能有细微差异,如果遇到奇怪的问题,可以尝试更新触摸芯片的固件。
-
在调试阶段,建议先使用evtest工具验证基本功能,再集成到图形系统中,这样可以快速定位问题所在层。