gt11触摸屏驱动probe函数解析
函数概述
gt1x_ts_probe 是 Goodix GT1X 触摸屏驱动的探测函数,在 I2C 设备匹配时由内核调用,负责初始化触摸屏驱动并注册到系统。
整体结构
初始化流程:
1. 基础检查 → 2. 设备树解析 → 3. IO端口请求 →
4. 触摸屏初始化 → 5. 工作队列创建 → 6. 输入设备注册 →
7. 中断请求 → 8. 电源管理注册
关键步骤详解
1. 基础设置与检查
gt1x_i2c_client = client; // 保存 I2C 客户端指针
spin_lock_init(&irq_lock); // 初始化中断自旋锁
- 保存
i2c_client供全局使用 - 检查 I2C 适配器是否支持标准 I2C 功能
设计要点: 自旋锁保护中断相关的临界区,避免竞态条件。
2. 设备树解析
#ifdef GTP_CONFIG_OF
if (client->dev.of_node) {
gt1x_parse_dt(&client->dev);
}
#endif
- 从设备树读取硬件配置(如中断引脚、复位引脚、电源管理等)
- 仅在支持设备树的平台编译
3. 硬件初始化序列
gt1x_request_io_port() // 请求 GPIO 引脚(中断、复位等)
gt1x_init() // 触摸屏芯片初始化(读取固件版本、配置等)
- 按依赖顺序初始化:先配置硬件引脚,再初始化芯片
- 任一步骤失败都会终止整个初始化流程
4. 工作队列与工作项初始化
gt1x_wq = create_singlethread_workqueue("gt1x_wq");
INIT_WORK(>1x_work, gt1x_ts_work_func);
重要设计决策:
- 使用单线程工作队列而非标准工作队列
- 保证触摸事件处理顺序性
- 避免多线程竞争导致的数据错乱
gt1x_work用于在中断上下文中将触摸数据移到工作队列处理
5. 输入设备注册
gt1x_request_input_dev() // 注册 Linux 输入子系统设备
- 创建
/dev/input/eventX设备节点 - 配置输入事件类型(EV_ABS 绝对坐标、EV_SYN 同步等)
6. 中断请求与工作模式
ret = gt1x_request_irq();
if (ret < 0) {
GTP_DEBUG("GTP works in polling mode.");
} else {
GTP_DEBUG("GTP works in interrupt mode.");
}
优雅设计:
- 优先尝试中断模式(节能、响应快)
- 如果中断请求失败,自动降级为轮询模式
- 保证驱动在各种硬件环境下都能工作
7. 特殊功能模块
ESD 静电保护
#if GTP_ESD_PROTECT
gt1x_init_esd_protect();
gt1x_esd_switch(SWITCH_ON);
#endif
- 监测触摸屏芯片是否因静电冲击而死锁
- 定期检测芯片状态,必要时复位恢复
固件自动更新
#if GTP_AUTO_UPDATE
thread = kthread_run(gt1x_auto_update_proc, ...);
#endif
- 创建内核线程检查并更新固件
- 在后台运行,不阻塞 probe 流程
8. 电源管理注册
gt1x_register_powermanger();
- 注册系统休眠/唤醒回调
- 确保设备在系统睡眠时正确进入低功耗状态
编程模式与最佳实践
1. 条件编译宏设计
#if GTP_AUTO_UPDATE
#if GTP_ESD_PROTECT
#if GTP_GESTURE_WAKEUP
- 通过宏开关控制功能模块
- 支持裁剪驱动以适应不同产品需求
- 减小最终内核镜像大小
2. 错误处理策略
- 每个关键步骤都有返回值检查
- 失败时立即返回错误码,清理已分配资源
- 错误信息使用
GTP_ERROR宏记录
3. 日志分级
GTP_INFO() // 信息日志(版本号、I2C地址)
GTP_DEBUG() // 调试日志(工作模式)
GTP_ERROR() // 错误日志(初始化失败)
4. 模块化设计
- 每个初始化步骤封装为独立函数
- 职责清晰:
gt1x_request_io_port只管 GPIO,gt1x_init只管芯片初始化 - 便于测试和维护









