真实面经题目 · 原创解析
Linux I2C 子系统和 input 子系统如何协作完成触摸屏驱动上报?
这题考触摸屏驱动架构,回答要把总线驱动负责寄存器访问、输入子系统负责事件上报、中断负责触发读取串起来。
真实面经题目 · 原创解析
这题考触摸屏驱动架构,回答要把总线驱动负责寄存器访问、输入子系统负责事件上报、中断负责触发读取串起来。
触摸屏驱动通常是总线子系统、输入子系统和中断子系统协作。设备树描述触摸芯片挂在哪个控制器、从地址、interrupt-gpios、reset-gpios、供电和 pinctrl。内核创建 client 后,驱动通过 i2c_driver 匹配,probe 中上电复位、读取 chip id、初始化寄存器,然后分配 input_dev,设置支持的 EV_ABS、ABS_MT_POSITION_X/Y、ABS_MT_TRACKING_ID 等多点触控能力并 input_register_device。触摸发生时,中断引脚触发,threaded IRQ 中通过总线读取触点数据,解析坐标、压力、触点 ID,再用 input_mt_slot、input_report_abs、input_mt_sync_frame、input_sync 上报。输入子系统把这些事件变成 /dev/input/eventX,用户态 evdev 或图形系统读取。总线层只负责通信,input 层负责统一事件 ABI,驱动负责把芯片私有数据转换成标准输入事件。
硬件描述让内核知道触摸芯片的地址和资源,i2c_driver probe 后使用 SMBus、i2c_transfer 或 regmap 访问寄存器。总线层不理解坐标语义。
驱动初始化芯片后创建 input_dev,声明支持的事件类型、坐标范围、多点触控槽数量和属性。注册后用户态才能看到标准输入设备节点。
触摸控制器检测到新数据后拉中断,驱动在线程化中断中读取触点寄存器。因为总线传输可能睡眠,通常不在硬中断顶半部直接读取大量数据。
驱动把芯片私有格式转换成标准 ABS/MT 事件并 sync。用户态不需要知道具体芯片协议,只消费 evdev 事件流。
还要处理复位时序、固件版本、坐标方向、噪声过滤、手势唤醒、挂起恢复和中断风暴等问题。
读取触摸数据需要总线事务,可能睡眠且耗时,放在线程化处理更合适,硬中断只做快速唤醒。
可以由设备树属性或驱动参数描述屏幕安装方向,驱动上报前转换坐标,也可由输入/显示栈进一步校正。
我会先看 dmesg 和返回码,再查 /sys 下设备、驱动和资源状态,必要时加 trace/ftrace 或最小日志,先证明问题出在设备生成、匹配、资源获取、回调路径还是用户态交互。