驱动之触摸屏驱动框架和实现
总览
- 嵌入式linux学习目录
- 驱动之input子系统
- 驱动之platform概念
- 驱动之RTC分析
- 驱动之LCD驱动框架和实现
- 驱动之触摸屏驱动框架和实现
- 驱动之USB基础概念和框架
- 驱动之USB设备驱动程序
本文使用 linux-2.6.22.6 内核, 使用jz2440开发板.
触摸屏驱动框架分析
回顾input子系统
在 驱动之input子系统 一文里, 已经介绍了input子系统的框架.
触摸驱动作为输入设备, 很自然的需要用到input子系统.
input子系统, 核心点如下:
- 软件抽象层,
/drivers/input/input.c
/drviers/input/*dev.c
- 初始化
input_handler
结构体变量, 负责软件抽象. - 提供
input_register_handler
函数 - 提供
input_register_handle(没有r)
函数 - 提供
input_register_device
函数
- 初始化
- 连接层,
/drviers/input/*dev.c
- 初始化
input_handle(没有r)
结构体变量, 负责input系统的软硬层对接 - 注册此变量
input_register_handle(没有r)
- 当注册handler或者device时, 会自动调用
handler->connect
, 匹配并关联软件抽象层和硬件设备层.
- 初始化
- 硬件设备层, 需要自己来实现
- 负责具体的硬件功能实现.
- 初始化
input_dev
结构体变量 - 注册此变量
input_register_device
- 实现硬件相关代码. 上报事件
input_event
s3c2410的触摸屏框架
s3c2410的触摸屏框架使用了input层. 硬件设备层又使用了platform框架来进一步隔离硬件上的通用代码和专用参数设置.
platform总线系统的详情可查看 驱动之platform概念
整个框架层次如下图:
platform 总线框架具体分析如下:
- platform_driver
/drivers/input/touchscreen/s3c2410_ts.c
- 调用
platform_driver_register(&s3c2410ts_driver);
- 匹配时, 执行
s3c2410ts_probe
- 和想的不一样, 用的
evbit
而不是absbit
ts.dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);
ts.dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- 然后向input系统注册device
input_register_device(ts.dev);
- 和想的不一样, 用的
- timer超时函数
touch_timer_fire
, 检测和发送触摸事件input_report_abs
input_report_key
- 调用
- platform_device
/arch/arm/plat-s3c24xx/common-smdk.c
- 调用
platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
smdk_devs
里面包含了s3c_device_ts
- 通过
set_s3c2410ts_info
函数来设置s3c_device_ts
- 调用
测试触摸屏驱动
这里用的开发板自带的触摸屏驱动, 先测试一下.
方法一 hexdump
# 开发板端 |
方法二 tslib
# Ubuntu 主机端, 需要先编译 tslib |
源码, 第一版
第一版源码, 让触摸屏工作起来即可
ts.c
|
Makefile
obj-m := ts.o |
测试
由于内核自带了驱动程序, 因此需要重新编译内核, 去掉触摸驱动
# Ubuntu 主机端 |
源码, 第二版
第一版的源码用于检测触摸屏的硬件设置是否正确, 触摸屏是否能正常工作.
但在实际情况下, 对触摸屏的ADC值还需要进行软件滤波等工作, 以提高可用性.
另外我们去掉了printk的打印信息, 改为 input_report_abs
input_report_key
ts.c
为方便理解, 减少代码量, 和源码第一版相同的部分删掉了.
譬如头文件, 小函数等.
static struct timer_list ts_timer; |
测试
# 先按照此文之前的测试步骤设置好tslib, 烧录无触摸屏驱动的内核文件. |
原创于 DRA&PHO