GT9XX触摸屏驱动移植指南:从I2C寄存器到设备树配置

发布时间:2026/10/8 11:12:17
GT9XX触摸屏驱动移植指南:从I2C寄存器到设备树配置 简介汇顶GT9XX系列触摸屏驱动资料面向Android驱动工程师、BSP开发人员及触控方案调试者解决GT9XX系列在Android系统上的驱动适配与稳定运行问题。资源包共7个文件2.5MB以C源码与头文件为主覆盖核心驱动、固件更新与下载工具逻辑另提供PDF版《GT9XX驱动移植说明书》和调试工具APK便于从文档到真机完整对照。驱动遵循AOSP HAL架构用户空间通过JNI连接内核代码涵盖驱动注册、中断处理、I2C/SPI通信、电源管理和设备节点创建等移植关键点结合GT9157示例与规格书可快速掌握寄存器配置、触摸坐标上报和固件升级流程。作者还附带了goodix_tool调试程序与GT9XX调试工具APK支持在真机验证触摸坐标、寄存器读写、固件升级及参数配置。目前已有806人学习适合需要快速移植汇顶触摸屏的中高级Android开发者收藏使用。1. 一块 GT9XX 模组上电没反应问题通常不在硬件而在驱动代码一块新贴的 GT9XX 触摸模组上电后完全没有反应或者按下屏幕光标却在乱跳——这是 Android 驱动调试里最常遇到的场景。所谓 GT9XX 驱动代码就是汇顶Goodix电容触摸控制器在 Linux/Android 内核里的驱动实现配套的规格书说明寄存器、时序和配置表三者一起才能把一块触摸屏变成系统能识别的 input 设备。这篇文章按照一线移植流程把 GT9XX 驱动代码、规格书和 Android 内核怎么对上、怎么改、最容易翻车的地方讲清楚。适合正在做 Android BSP、车载或工控触摸屏适配的驱动工程师读完你至少能把一份 GT9XX 驱动从设备树到上报坐标完整跑通。2. 驱动代码从哪下手I2C 协议与 GT9XX 寄存器地图是移植前必须啃的硬骨头2.1 触摸屏驱动在 Linux 内核里的位置从 I2C 到 input 事件GT9XX 是一颗电容触摸控制芯片不是单纯的电平开关。手指靠近面板时芯片内部通过 ADC 采集电容变化计算出触摸点的坐标把结果放在自己的寄存器里。主控 SoC 通过 I2C 总线去读这些坐标寄存器再通过 GPIO 中断获知“有触摸”。所以带 GT9XX 的触摸屏驱动 Linux 内核代码本质是做了三件事初始化芯片、响应中断、把坐标变成 input 事件上报。理解这一点能避免一个常见误区很多人以为触摸屏驱动要直接读模拟信号。实际上 GT9XX 已经把坐标算好了驱动只是定期把坐标寄存器搬回内核。既然数据是数字化的接口就只是 I2C外加一根 INT 中断脚和一根 RST 复位脚。你在内核里看到的所有代码都是围绕这三根线展开的。2.2 GT9XX 寄存器地图先记住这三个地址就够了驱动代码里最频繁访问的是几个固定寄存器。0x8040 是命令寄存器写命令用来清中断或触发屏幕唤醒0x8047 开始是一段连续的坐标缓冲区前 6 个字节依次是触点状态、X 坐标高字节、X 坐标低字节、Y 坐标高字节、Y 坐标低字节0x8140 是模块版本寄存器初始化时驱动会先读它来确认 I2C 链路是否通畅。多指触控时数据从 0x8047 往后按 6 字节一组扩展第 2 组数据就是第二根手指的坐标。这里把坐标数据结构列出来你对照驱动代码里的读函数会非常直观寄存器偏移字节内容说明0x8047buffer status0 表示无触摸非 0 表示有几根手指0x8048 / 0x8049X 坐标高 8 位 / 低 8 位组合成 16 位 X 坐标0x804A / 0x804BY 坐标高 8 位 / 低 8 位组合成 16 位 Y 坐标0x804C / 0x804D第二指 X / Y 保留多指数据按 6 字节一组扩展驱动里常见做法是先用 i2c_transfer 一次性读取 0x8047 起的一段连续数据再在内存里做位运算拼出坐标。这里有个坑部分 GT9XX 寄存器地址是 16 位的发送地址时分成 0x80 和 0x47 两个字节不要按 8 位寄存器地址的方式去写。2.3 中断处理为什么要用线程化中断和 workqueueGT9XX 驱动代码里最核心的一段逻辑在中断处理函数。触摸发生时 INT 脚拉低主控进入中断然后驱动在中断上下文里通过 I2C 读坐标。I2C 传输本身是慢速操作如果直接写在硬中断上下文里会阻塞系统其他中断。所以大多数触摸屏驱动 Linux 内核实现都采用线程化中断加上 IRQF_ONESHOT 标志保证中断线程运行期间中断不会重复触发。驱动初始化主流程基本长这样源码包里的结构不会偏离这个框架static int gt9xx_probe(struct i2c_client *client, const struct i2c_device_id *id) { /* 1. 复位触摸IC时序参数参考规格书RST章节 */ gpio_set_value(reset_gpio, 0); mdelay(10); /* 拉低至少10ms让IC完成内部复位 */ gpio_set_value(reset_gpio, 1); mdelay(50); /* 拉高后等50ms等IC上电稳定 */ /* 2. 读版本寄存器确认I2C链路通畅 */ gt9xx_i2c_read(client, 0x8140, buf, 1); /* 3. 写配置表把坐标范围、通道数烧进芯片 */ gt9xx_send_config(client, config_data); /* 4. 注册input设备告诉内核坐标最大范围 */ input_set_abs_params(ts-input, ABS_MT_POSITION_X, 0, ts-max_x, 0, 0); input_set_abs_params(ts-input, ABS_MT_POSITION_Y, 0, ts-max_y, 0, 0); /* 5. 申请线程化中断触摸发生时到线程里读坐标 */ request_threaded_irq(client-irq, NULL, gt9xx_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client-name, ts); }这段逻辑说明了一个关键点probe 失败时不要只看中断有没有申请成功要先确认第 2 步的版本寄存器读出来没有。很多驱动代码在 I2C 读取失败后会直接返回 -ENODEV后续的 input 设备和中端全部不会注册。你在 dmesg 里看到 i2c transfer error 这类日志时问题基本都出在复位时序、I2C 地址或设备树节点上和中断代码没多大关系。3. 把驱动代码跑起来设备树节点、内核配置与模块加载3.1 设备树节点完整清单与属性解读拿到一份 GT9XX 驱动代码先别急着编译第一件事是核对平台设备树里有没有正确的 I2C 节点。节点通常挂在触摸屏所连接的 I2C 总线下我一般这样写i2c3 { gt9xx: gt9xx5d { compatible goodix,gt9xx; reg 0x5d; interrupt-parent gpio1; interrupts 13 IRQ_TYPE_EDGE_FALLING; reset-gpio gpio1 12 GPIO_ACTIVE_LOW; irq-gpio gpio1 13 GPIO_ACTIVE_LOW; touchscreen-max-x 720; touchscreen-max-y 1280; touchscreen-inverted-x 0; touchscreen-inverted-y 0; }; };reg 0x5d 用的是 7 位 I2C 地址。GT9XX 规格书里通常写的是 8 位读写地址 0xBA/0xBB很多新手直接把 0xBA 填进 reg导致 probe 时 i2c 匹配失败。inner 驱动代码用 client-addr 是 7 位地址所以必须把 0xBA 右移一位得到 0x5D。reset-gpio 和 irq-gpio 两个属性分别对应复位脚和中断脚GPIO 编号和 polarity 要跟硬件原理图严格一致interrupts 里的 IRQ_TYPE_EDGE_FALLING 说明中断是下降沿触发这个要和驱动里 request_threaded_irq 的触发标志一致否则中断可能只触发一次或者完全不触发。3.2 内核配置让 CONFIG_TOUCHSCREEN_GT9XX 正确打开设备树就位后还要确认内核里有对应的配置项。早期的 GT9XX 驱动代码常年以内核补丁形式提供编译配置路径在不同内核版本里有差异。Android 平台常见做法是在 defconfig 里直接打开或者用 menuconfig 选择后保存# 方式一menuconfig 图形化选择 make ARCHarm64 menuconfig # 进入 Device Drivers - Input device support - Touchscreens # 选中 Goodix GT9xx touchscreen然后 Save # 方式二直接改平台 defconfig # 在 arch/arm64/configs/xxx_defconfig 里加入一行 CONFIG_TOUCHSCREEN_GT9XXy # 重新生成配置文件并编译内核 make ARCHarm64 xxx_defconfig make ARCHarm64 -j$(nproc)这里建议优先编成模块而不是直接编进内核也就是把配置项改成 m。理由是 GT9XX 驱动经常要换配置表编成模块以后更新驱动只需要替换 .ko 文件再 insmod不用重编整个内核。如果平台要求开机就要用触摸才改成 y 编进内核。改了 defconfig 后务必重新生成配置文件不然 make 会沿用旧的 .config。3.3 模块化加载从 insmod 到 dmesg 确认驱动编译通过后先把 .ko 推到设备里手动加载确认基本功能再集成进系统镜像。常见做法是# 通过 adb 把驱动模块推到 /data/local/tmp adb push gt9xx.ko /data/local/tmp/ # 在设备上加载模块 adb shell su insmod /data/local/tmp/gt9xx.ko # 查看初始化日志确认probe是否成功 dmesg | grep -i goodix # 期望看到类似: gt9xx: GTP firmware version 0x10xx # 如果看到: gt9xx: i2c read failed -6说明I2C通信失败 # 确认中断是否注册成功 cat /proc/interrupts | grep gt9xxAndroid 内核驱动 ko 加载时insmod 不会自动处理模块依赖。如果驱动里用了 input 子系统的符号而 input 模块没加载insmod 会报 unknown symbol正常内核会把 input 编进内核很少遇到这个问题。dmesg 出现 firmware version 说明芯片已经响应触摸链路已经通了如果卡在 i2c read failed优先检查设备树 reg、reset 脚时序和 I2C 总线号。3.4 上报链路把寄存器坐标变成 input 事件驱动正常 probe 后坐标数据要从寄存器变成应用层能读到的事件。核心上报函数会做这几件事读坐标缓冲区、判断触点状态、上报 ABS_MT_POSITION_X/Y、上报 BTN_TOUCH、最后调用 input_sync 结束一次事件包。Android framework 层看到的就是 /dev/input/eventX 上源源不断的 input_event。驱动里还要把 max_x 和 max_y 填对Android 上层才能根据分辨率做坐标归一化填错会出现触摸点偏移到屏幕边缘的诡异问题。上报这段代码里坐标组装的写法值得多说一句。寄存器里的 X 是高字节在前驱动代码里常见的是x (buf[1] 8) | buf[2]不要写反。如果你在 getevent 里看到的 X 坐标一跳就是 256 的倍数八成就是高低字节拼反了。4. 规格书与驱动代码对照读时序、坐标寄存器与配置表别只看一样4.1 拿着原理图找关键信号I2C、INT、RST 与上电时序GT9XX 规格书的第一章通常就是引脚定义和芯片框图这部分必须在拿到驱动代码的同时打开对照看。驱动代码里操作的无非是 I2C 数据线、INT 中断脚、RST 复位脚、VDD 和 VDDIO 电源。RST 引脚在规格书里会给出低电平脉宽要求驱动代码里的 mdelay 参数就来自这里INT 引脚的默认电平和触发沿决定设备树里 interrupts 怎么配。两者一旦和硬件实际接法对不上probe 失败或中断不触发都是意料之中的事。我见过不少人在驱动代码里反复查问题最后发现是原理图上 INT 脚被上拉到 VDDIO而设备树里配了 IRQ_TYPE_EDGE_RISING。触摸按下时 INT 拉低上升沿只在手指抬起时才出现驱动每次上报都慢半拍。这种问题不看规格书和原理图只靠代码是查不出来的。4.2 从规格书里抄出这些参数I2C 地址、分辨率、通道数GT9XX 驱动代码不是一套配置走天下不同型号、不同面板尺寸对应的坐标最大值和触摸通道数都不一样。规格书里真正要抄进驱动代码的参数主要有这几项参数常见取值范围最终落点I2C 7 位从机地址0x5D / 0x14 等设备树 reg 属性触摸通道数10~20 通道配置表数组和输入通道初始化X / Y 最大坐标由面板分辨率决定常见 720/1280、1080/1920input_set_abs_params 的 max 参数INT 触发方式低有效或下降沿设备树 interrupts 和 request_threaded_irqRST 复位脉宽毫秒级驱动里 mdelay / usleep_range把这些参数从规格书抄到驱动代码后还要对照一个最容易忽视的地方坐标最大值。驱动代码里 input_set_abs_params 的 max 值不一定要等于屏幕分辨率它应该等于芯片实际能上报的坐标范围。比如 720×1280 的面板配 1024×1024 的坐标范围Android 上层会自己缩放此时驱动代码里如果硬填 720坐标就永远到不了屏幕边缘。4.3 配置表与固件更新驱动代码里最容易被忽略的“黑匣子”GT9XX 驱动代码包里通常会带一份配置表数组有的是 .h 头文件里的数组有的以独立固件文件形式存放。它决定了芯片扫描通道、上报范围、睡眠策略等一堆行为。拿到最新版本驱动资料包时先确认配置表对应的模组型号和面板尺寸不要拿开发板的配置表往量产模组上套。配置表的更新方式有几种常见路径。一种是驱动 probe 时直接把内置数组通过 I2C 写到芯片 RAM掉电丢失另一种是芯片带 EEPROM需要先进入编程模式把配置写死在外部 Flash 里。Android 平台量产时多数用前一种好处是换配置表只换驱动代码不用动硬件。更新配置表后要读回校验校验失败时芯片会停留在非工作状态触摸完全没反应。配置表里还有一个容易踩的隐藏项坐标方向。同样是 720×1280 的面板竖屏和横屏安装X 和 Y 的映射方向完全不同。如果驱动代码里读取到的触摸坐标和屏幕显示方向不一致不要急着改代码逻辑先看配置表里有没有翻转相关参数。很多情况下改配置表比改驱动代码更安全不影响其他功能。5. GT9XX 移植避坑清单中断极性、复位时序与坐标翻转5.1 中断触发模式不对导致触摸偶尔失效或坐标漂移现象大部分时间触摸正常但某个区域按下没反应或者触摸结束后坐标还在乱跳。原因设备树里配了 IRQ_TYPE_EDGE_RISING而 GT9XX 模组的 INT 脚默认低有效触摸开始是下降沿结束时才是上升沿。驱动在上升沿才读坐标漏掉了触摸开始的位置坐标自然偏移。解决先用示波器量 INT 脚在触摸按下时的电平变化确认是低有效还是高有效再把设备树 interrupts 和驱动里 request_threaded_irq 的触发方式统一改掉。血泪经验是两边都要改只改设备树不动驱动probe 阶段会以驱动里的参数为准问题依旧。5.2 复位时序太短导致首次 probe 失败现象开机 dmesg 偶尔报gt9xx: i2c read failed -6但不是每次都失败热重启后又能正常工作。原因RST 脚拉低时间只有几百微秒GT9XX 内部还没完成复位就开始跑 I2C版本寄存器读不到数据probe 直接返回失败。解决把复位拉低时间延长到 10ms拉高后再延时 50ms给芯片留足内部校准时间。驱动代码里常见的msleep(50)不是玄学是照着规格书时序写的。不要为了省开机时间改成 usleep_level芯片没有稳定前读 I2C 大概率翻车。5.3 配置表版本不对造成触摸完全无反应现象probe 成功、中断注册成功、dmesg 里也没有报错但触摸屏完全不上报坐标。原因驱动代码里内置的配置表与模组固件版本不匹配芯片在校验配置时发现不合法放弃了触摸处理通道。解决确认模组出厂时对应的配置表来源用同一型号的配置数组替换驱动里的默认数组。替换后重启并用 dmesg 查看配置表校验结果如果校验失败会有明显打印。这类问题排查起来最费时间因为它不报 I2C 错误也不报中断错误只能从配置表版本入手。5.4 坐标镜像或翻转手指往右滑光标往左走现象触摸坐标和显示内容的方向不一致出现左右镜像或上下颠倒。原因面板安装方向和驱动默认坐标轴不一致常见于横竖屏混用的产品。驱动代码读出的原始坐标是芯片视角显示层面如果做过旋转坐标也要跟着变。解决多数驱动代码支持设备树属性 touchscreen-inverted-x / touchscreen-inverted-y打开后驱动会在上报前做坐标换算。如果驱动版本不支持就在上报函数里对 X 或 Y 做max - x的变换。推荐优先用设备树属性因为这样不用动代码后续换面板方向只改 dts。5.5 睡眠唤醒后触摸失灵suspend 回调不是空函数现象系统休眠再唤醒后触摸屏第一次点击没反应或者要等两三秒才有响应。原因GT9XX 在 suspend 阶段进入低功耗模式唤醒后驱动没有重新初始化芯片芯片停在睡眠状态不输出坐标。解决在驱动 resume 回调里重新复位 IC、重新写配置表必要时重新申请中断。不要嫌麻烦只恢复 GPIO。Android 平台 bsp 里的触摸驱动resume 里做的初始化动作应该和 probe 里的主要步骤保持一致只是不需要每次重新注册 input 设备。这五条是 GT9XX 移植里最常踩的坑而它们有一个共同特点都不是靠读驱动代码本身能查出来的必须把设备树、规格书和模组硬件三个维度拉通才能定位。6. 调试 GT9XX 的高效手段寄存器、getevent 与中断计数三件事先做触摸屏驱动出问题时我习惯按“寄存器原始数据 → input 事件 → 中断计数”的顺序排查能省下大量瞎猜的时间。这几个手段不需要额外工具Android 机器上直接用 i2c-tools 和 getevent 就能完成。先读寄存器原始坐标确认芯片本身有没有算出坐标# 读取0x8047开始的一整块坐标缓冲区 i2ctransfer -y -f 0 w20x5d 0x80 0x47 r8前两个字节是写入地址 0x8047。返回的 8 个字节里第 1 字节是触点状态第 2 和第 3 字节拼成 X 坐标第 4 和第 5 字节拼成 Y 坐标。手指按下去时第 1 字节会变成非 0 值后面坐标跟着变。如果这里数据正常说明芯片和 I2C 链路没问题问题在驱动上报或上层。如果按下去数据纹丝不动则回到中断和配置表方向排查。接着用 getevent 确认驱动有没有往 input 子系统上报getevent -lt /dev/input/event1 # 触摸屏幕时应该看到 ABS_MT_POSITION_X 和 ABS_MT_POSITION_Y # 没有输出时先用 cat /proc/bus/input/devices 确认设备节点存在getevent 能看到坐标但方向不对说明驱动代码没问题改坐标映射连事件都没有则中断链路或数组拼装有问题。最后看 /proc/interrupts 里触摸中断的计数是否在递增递增说明 GPIO 和中断注册正常剩下的就是代码逻辑问题。这套组合拳打下来GT9XX 黑匣子基本也就拆开一半了。我自己带项目时还有一个习惯拿到任何新版本 GT9XX 驱动代码第一件事不是编译而是把设备树、配置表版本和规格书页码标注出来三样对照归档。移植工作大多数时候不是代码写不出来而是资料之间互相矛盾没被发现。这个习惯帮我少踩了很多无谓的坑希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询