十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FT6336触屏驱动调试实战:从I2C识别到坐标校准

FT6336触屏驱动调试实战:从I2C识别到坐标校准 简介FT6336触屏驱动是一份基于I2C接口的电容触摸屏控制器驱动程序面向嵌入式开发者和移动设备驱动调试人员旨在解决触控数据解析与上报、多点触控和手势识别等实际问题。压缩包共5个文件以C源文件和头文件为主并包含一个用于对比恢复的备份头文件整体体积仅19KB结构精简便于阅读、移植和二次开发。驱动主文件负责核心通信与设备探测扩展功能模块提供校准、手势等增强能力头文件则定义了寄存器映射与平台相关参数方便开发者按需适配。已有3276人学习下载适合具备一定驱动基础、希望深入理解FT6336寄存器操作与I2C通信机制的开发者。通过阅读这份驱动源码可以完整掌握触摸屏驱动的核心框架包括设备探测、中断处理、坐标映射等关键环节同时了解扩展功能模块中初始化、校准、事件处理的设计思路为后续驱动移植、调试或性能优化提供直接参考。 做小尺寸触屏设备特别是 UMPC、便携屏、开源掌机这类产品FT6336 是个绕不开的名字。它是 FocalTech 家族里很常见的电容触控方案I2C 接口工作在 3.3V 左右绝大多数场景下上报单点触摸功耗低、价格便宜所以从十年前的上网本到现在各种各样的袖珍 UMPC都能见到它的身影。但“把 FT6336 触屏驱动真正调通”往往比想象中麻烦不是拷一个 .ko 文件进去就完事。这篇文章我从实际调试一台 Villv S5 这样的小型 UMPC 触屏开始把整套排查、驱动选型、设备树配置、坐标校准和避坑经验整理出来适合正在给 UMPC、DIY 便携屏或 ARM 板子调触屏的人参考。1. 项目背景一台带 FT6336 的机器Linux 下为什么没触屏1.1 一颗“不折腾不舒服”的触控 ICFT6336 的公开资料不少但散、乱、旧不同版本的 datasheet 对寄存器地址的标注甚至对不上这导致很多人卡在第一关芯片在硬件上明明工作正常系统里却完全没有 touch 事件。这颗芯片的核心工作模式其实很简单主控通过 I2C 总线周期性读取触摸坐标触摸芯片通过 INT 引脚通知主控“有触摸发生”主控再读寄存器拿坐标数据最后上报给 input 子系统。听上去不复杂但实际干活时你会发现 I2C 地址、中断触发方式、寄存器格式都和具体固件版本强相关差一点都不动。对于 Villv S5 这类小尺寸 UMPCFT6336 基本上是“标配”级别的触控方案因为屏幕尺寸通常不超过 8 寸单点触控已经完全够用。问题在于这类产品出厂时多半只保证 Windows 下工作良好你装个 Linux 发行版进去触屏没反应是常态。这不是芯片坏了而是系统压根没把设备枚举出来或者枚举出来了但驱动没配对。1.2 Linux 认不到触摸屏的三种典型情况我调试过不少触屏设备总结下来 Linux 下触屏无外乎三种情况。第一种是内核根本没有编译对应驱动比如主线内核默认不带 FocalTech 的 I2C 触摸驱动只有 HID over I2C 的支持。第二种是设备枚举不到ARM 平台上设备树里没有描述这个 I2C 触摸屏节点或者 x86 平台上 ACPI 表没有把它暴露出来内核自然找不到设备。第三种最隐蔽设备枚举成功、驱动也加载了但中断引脚配置不对或者复位时序有问题导致驱动永远收不到触摸事件。所以拿到一台触摸失灵的 UMPC我从来不急着到处找驱动先做的事情是往下摸底把芯片“身份”确认清楚。这一步做得越细后面踩坑越少。2. 动手前先摸底判定 FT6336 的“身份三要素”2.1 用 i2cdetect 找设备地址无论什么平台第一步都是确认 I2C 总线上有没有这颗芯片。先看系统里有几条 I2C 总线i2cdetect -l然后逐条总线扫一遍。ARM 板子通常是 i2c-0、i2c-1、i2c-2 这种编号x86 UMPC 则可能是 i2c-i2c-0 之类数量更多。对每条总线执行i2cdetect -y 1如果某个地址显示38或39大概率就是 FT6336。默认情况下FT6336 的 7 位 I2C 地址是 0x38部分固件子版本或者硬件设计上拉了下拉脚不同也会出现 0x39。这里有一个容易踩的坑有些 I2C 触摸芯片会在系统运行时主动响应但 i2cdetect 扫描时跟其他设备地址冲突导致扫不出来所以扫描时看到 UU 也可能是已经被内核驱动占用了需要结合 dmesg 判断。2.2 读芯片 ID确认到底是不是 FT6336I2C 地址对上了还要进一步确认芯片型号。曾经有人把 FT5x06 当成 FT6336 来配设备树寄存器结构不一样结果触控完全没法用。用 i2cget 直接读两个关键寄存器可以快速确认i2cget -y 1 0x38 0xA3 i2cget -y 1 0x38 0xA50xA3 通常返回芯片 ID0xA5 通常返回固件版本。不同子版本会有差异比如 0x11、0x64 都很常见我的建议是别死记具体返回值而是确认“能读出来、且不是 0xFF”这已经能说明芯片基本通路正常。如果你还想看更详细的数据可以用 i2cdump 把整个寄存器空间拉出来看一遍。注意FT6336 和 FT6236 在很多驱动里是共用的因为它们的核心寄存器结构几乎一致所以设备树里写focaltech,ft6236也能正常驱动 FT6336这一点后面会细说。2.3 中断引脚决定驱动能不能省心FT6336 的 INT 引脚是驱动正常工作的关键。这颗芯片的 INT 通常在触摸时拉低所以设备树里要配成下降沿或者低电平触发并且外部最好有上拉电阻。如果硬件上 INT 接错了或者触发极性配反驱动加载成功也永远等不到中断表现为“触摸没反应”。我调试时会先看/proc/interrupts查看对应中断号有没有触发计数如果一直为零优先怀疑 INT 引脚和触发类型而不是驱动 bug。顺便提一个判断方法用手触摸屏幕同时用示波器或者万用表量 INT 引脚电平。有触摸时引脚电平发生变化说明硬件没问题问题在软件配置如果电平纹丝不动那先查排线、供电和触摸屏本身。3. 驱动选型三路线按设备类型选3.1 厂商 BSP 自带驱动最省事的一条路如果你用的是瑞芯微、全志这类 SoC 的 BSP 内核大概率已经在kernel/drivers/input/touchscreen/下带了 FocalTech 驱动目录比如focaltech_touch。这种驱动是厂商为自家平台适配过的设备树写法也比较固定。以瑞芯微平台为例I2C 节点下加一段i2c1 { status okay; focaltech38 { compatible focaltech,ft6236; reg 0x38; interrupt-parent gpio1; interrupts RK_PB4 IRQ_TYPE_LEVEL_LOW; reset-gpio gpio1 RK_PB5 GPIO_ACTIVE_LOW; focaltech,name ft6336; focaltech,max-touch-number 1; focaltech,display-coords 0 0 800 480; }; };这里compatible用focaltech,ft6236是故意的很多 BSP 驱动把 FT6x06 系列统一匹配FT6336 也能正常驱动。interrupts建议用IRQ_TYPE_LEVEL_LOW因为 FT6336 的 INT 是被拉低直到主控读取数据结束低电平触发比下降沿更可靠能避免漏掉中断。如果你找不到厂商驱动的设备树示例可以直接搜内核源码里的focaltech关键字一般都有 dts 参考。3.2 x86 UMPC 的 ACPI HID 路径Villv S5 最常见到了 Villv S5 这种 x86 UMPC 上情况就不太一样了。这类设备没有那么容易让你改设备树硬件信息都在 ACPI 表里。我遇到的大部分 x86 小屏设备触屏都以 HID over I2C 的方式暴露给系统ACPI 表里的硬件 ID 往往是FTC1001、FTE1001这类 FocalTech 触控设备名。Linux 主线内核有现成的i2c-hid-acpi驱动只要内核开了CONFIG_I2C_HID_ACPI和CONFIG_HID_MULTITOUCH触屏理论上能直接用。判断方法很简单先看系统枚举到了什么ls /sys/bus/i2c/devices/ dmesg | grep -i i2c如果看到i2c-FTC1001:00之类的目录说明 ACPI 已经把它枚举成 HID 设备只差驱动。确认一下模块有没有加载modprobe i2c-hid-acpi modprobe hid-multitouch加载完再看/dev/input/eventX是否多出设备用 evtest 测试触摸是否有事件。如果 ACPI 表里根本没有这个设备节点那就要么刷 BIOS、要么绕过 ACPI 自己写驱动难度会上升一个量级。所以我的建议是先走 HID 路径别一上来就想着自己写 I2C 驱动。3.3 自己写最小驱动兜底方案如果内核里既没有 BSP 驱动设备又没走 ACPI HID那你只能写一个最小 I2C 驱动来兜底。FT6336 的触摸上报逻辑其实很简单中断触发后用i2c_master_recv从 0x00 开始连续读 8 个字节其中第 3、4 字节是 X 坐标第 5、6 字节是 Y 坐标第 2 字节表示触摸点数。核心中断处理大概长这样static irqreturn_t ft6336_isr(int irq, void *data) { struct ft6336_data *ft data; u8 buf[8]; int x, y; if (i2c_master_recv(ft-client, buf, 8) 0) return IRQ_HANDLED; x ((buf[3] 0x0f) 8) | buf[4]; y ((buf[5] 0x0f) 8) | buf[6]; input_report_key(ft-input, BTN_TOUCH, buf[2] ? 1 : 0); input_report_abs(ft-input, ABS_X, x); input_report_abs(ft-input, ABS_Y, y); input_sync(ft-input); return IRQ_HANDLED; }这段代码只适合调试和学习用因为不同固件版本的数据格式可能有差异生产环境还是要用完整驱动。不过它足够验证一件事芯片通不通、中断好不好使、坐标对不对。我调过的很多板子最后都靠几百行这种“牙签驱动”先让触摸动起来再回头去搞正式方案。4. 设备树与参数调校从能用到好用4.1 一份可复制的设备树模板给 ARM 平台设备写设备树时我习惯用主线内核的标准 touchscreen 属性而不是 BSP 私有属性这样以后换内核少吃点亏。一个比较通用的节点长这样i2c2 { status okay; ft633638 { compatible focaltech,ft6336; reg 0x38; interrupt-parent gpio0; interrupts 20 IRQ_TYPE_EDGE_FALLING; reset-gpios gpio0 21 GPIO_ACTIVE_LOW; touchscreen-size-x 800; touchscreen-size-y 480; touchscreen-inverted-x; touchscreen-inverted-y; touchscreen-swapped-x-y; status okay; }; };touchscreen-size-x和touchscreen-size-y是触摸屏原始坐标最大值不是屏幕物理分辨率但通常等于屏幕分辨率。这个值如果写错触摸坐标会被内核错误换算导致触摸点和图标对不上这也是新手经常忽略的。reset-gpios不是必须的但如果硬件上有复位引脚最好接上驱动在初始化时会做复位时序能避免很多上电不稳定问题。4.2 坐标翻转与轴映射的实测调参流程坐标方向不对是最容易发现也最容易修的问题。我的调参流程是这样先用 evtest 看原始坐标手指从屏幕左上角滑到右下角观察 ABS_X、ABS_Y 的变化趋势。X 值从 0 到最大值说明方向正常如果从最大值到 0说明 X 轴反了需要加touchscreen-inverted-x。Y 轴同理。如果滑动时 X 在变但数值反映的是 Y 轴变化说明 X/Y 交换设置touchscreen-swapped-x-y。很多 BSP 驱动不用这套标准属性而是自己定义focaltech,swap-x2y、focaltech,invert-x、focaltech,invert-y。遇到这种情况要么在驱动里找这些属性的定义要么干脆改驱动源码在 input 上报前把坐标手动翻转一下。说实话改驱动源码比猜设备树属性名更直接因为 BSP 的私有属性命名混乱不同厂商的写法都可能不一样。4.3 灵敏度、扫描周期与功耗的平衡FT6336 的灵敏度受寄存器 0x80TH_GROUP控制数值越小越灵敏默认值一般在 0x22 附近。如果触摸屏贴了比较厚的保护膜或者冬天手比较干可以把阈值调低。反过来如果屏幕容易出现水渍误触或者充电时乱跳就适当调高。另外 0x85 和 0x86 分别控制主动模式和监测模式的扫描周期主动模式扫描越快触摸延迟越低但功耗更高监测模式扫描越快唤醒响应越快同样更耗电。对 UMPC 这种电池供电设备我建议把主动模式扫描周期保持在默认值把监测模式扫描周期稍微调短一点换取“从睡眠到触摸响应”的体验改善。如果你用的 BSP 驱动没有暴露这些参数的设备树属性大概率得改驱动代码用i2c_smbus_write_byte_data在 probe 里直接写寄存器。这个方法不优雅但有效我经常这么干。5. 实际调试中容易踩的坑5.1 i2cdetect 扫到了但驱动 probe 失败这是遇到最多的情况。驱动 probe 里读寄存器失败报 failed to read register 之类的错误大多数原因不是驱动问题而是芯片压根没正常工作。先检查有没有给触摸屏供电很多板子的触摸屏电源是独立 LDO 控制的系统起来后这个 LDO 没被打开。其次检查复位引脚如果复位脚一直拉低芯片会一直处于复位状态自然读不到任何寄存器。最后检查 I2C 地址是不是因为硬件跳线变了比如本来是 0x38某个电阻没贴变成 0x39导致驱动按 0x38 去匹配设备树一直配对失败。5.2 报点坐标乱跳、漂移严重触摸坐标乱跳先区分是硬件问题还是软件问题。最简单的方法是看触摸屏有没有贴膜膜太厚或者膜上有水汽电容触摸就会乱飘。排除掉外部因素后重点查屏幕电源纹波。FT6336 对电源噪声比较敏感电源不稳会出现“手指没碰屏幕但坐标乱跳”的现象。这种情况靠驱动调没用得从硬件上解决比如加大电容、换更干净的电源。如果纹波没问题再考虑把灵敏度阈值调高一点有时候触控面板本身质量一般阈值太低会把环境噪声也判定成触摸。5.3 睡眠唤醒后触控失效这类问题在 UMPC 上特别常见表现是系统 suspend 再 resume 之后触摸屏幕没有反应必须重启才能恢复。本质原因是驱动在 suspend 时没有把中断和芯片状态处理好。我一般会在 suspend 回调里disable_irq在 resume 回调里重新做一次芯片初始化然后enable_irq。如果只有中断关闭没有芯片复位FT6336 内部可能还停留在某个休眠状态唤醒后发出来的数据不完整表现为触摸没反应。另外要注意有些设备在 resume 后第一次触摸会触发一次“假中断”需要在上报逻辑里丢弃前几个事件否则会出现唤醒后第一次触摸一点就乱跳的情况。5.4 FT6336 和 FT6336U 别搞混这两个型号表面上看差不多但触控点数不一样。FT6336 基本是单点方案FT6336U 支持多点触控最多 5 点。如果你发现设备树里配了多点但实际只有一个触点有反应先确认芯片丝印到底是哪个型号。软件层面多点支持还需要内核的hid-multitouch或者驱动内部的TYPE_B协议支持不是光在设备树里写max-touch-number 5就完事的。我见过有人把 FT6336 硬配成 5 点结果上报数据混乱反而连单点都不准了。5.5 快速排查速查表症状可能原因处理方向i2cdetect 扫不到 0x38/0x39I2C 总线不对、设备电源没开、芯片复位中逐条总线扫描检查 LDO 上电和复位引脚电平驱动加载成功但无事件INT 引脚极性/触发方式不对用示波器量 INT核对触发类型和上拉触摸有反应但坐标不对坐标轴反向、尺寸参数错误evtest 实测修改 inverted / swapped / size 参数触摸乱跳、漂移电源纹波、膜厚、阈值过低检查电源调高 0x80 寄存器阈值睡眠唤醒后失效驱动 suspend/resume 处理不完整关闭中断、重新初始化芯片、忽略假中断只有单点多点不生效芯片型号不是 FT6336U、协议不匹配确认丝印型号确认内核 TYPE_B 协议支持我在实际调试这类触屏驱动时最大的体会是90% 的问题出在“确认芯片有没有被发现”和“中断引脚有没有配好”而不是驱动代码本身。很多人在 i2cdetect 还没扫到设备的情况下就开始改驱动源码改了半天也没结果白白浪费时间。正确顺序永远是先确认硬件通路再让系统枚举到设备最后才去调坐标和灵敏度。把 FT6336 这棵草拔掉之后你会发现在其他触摸芯片上也是一套差不多的路数I2C 触屏调试的逻辑是相通的。本文还有配套的精品资源点击获取
返回列表