fangxianghuamei 发表于 2013-12-16 11:22:57

Linux之触摸屏驱动-基于S3C6410

Linux之触摸屏驱动-基于S3C6410
这篇文章主要是关于linux中触摸屏驱动的,基于s3c6410处理器进行分析。这一篇主要是关于触摸屏设备作为平台设备的实现,还有对应的probe函数和remove函数的源码分析。
1、触摸屏模块的加载和卸载函数

万变不离其宗,还是熟悉的那个他,只不过每一次都是一番新的历程。对应的平台设备资源:在Dev-ts.c (linux2.6.28\arch\arm\plat-s3c)文件中:

在下面的数组中加入关于触摸屏的平台数据,这里我们加入上面的的s3c_device_ts:【在mach-smdk6410.c (linux2.6.28/arch/arm/mach-s3c6410/)文件中】

在触摸屏的平台数据结构中设置触摸屏信息,然后在smdk6410_machine_init函数中初始化触摸屏信息:【在mach-smdk6410.c (linux2.6.28/arch/arm/mach-s3c6410/)文件中】


对应的platform_driver结构体的定义如下:【在s3c-ts.c (linux2.6.28/drivers/input/touchscreen)文件中】
2、我想应该知道要做什么了,接着来看probe函数,源码如下:

结构s3c_ts_mach_info用于保存触摸屏的特定数据,里面存放的是触摸屏需要的一些设置参数,如如分频比和延时参数等:

默认值:

这里涉及到一个结构体s3c_ts_mach_info

其中有:

接着上面往下看:

这里主要和ADCCON寄存器的设置有关,而且有如下定义:

看下图:

接着往下看:
和上面差不多,主要和ADCDLY寄存器有关。直接看图:注:在两种模式下有不同的含义

接着往下看:

从datasheet可以看出,这里设置12位ADC:

接着往下看:

313行主要设置对ADCTSC寄存器进行操作,使触摸屏处于等待中断模式

315行用kzalloc申请s3c_ts_info内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0.
317行为申请并初始化一个输入设备。通过输入设备,驱动程序才能和用户交互。
接着往下看:

上面这一段代码都是初始化触摸屏设备的全局量ts,对应的结构体原型是:

接着往下看:

最后的这些是错误处理代码:

到这里,触摸屏设备驱动的probe函数就讲述完了。
3、当然,probe函数中几个重要的函数都没讲,就是关于输入子系统的,那不是我们现在关注的重点。接着看对应的remove函数,源码如下:

其实看懂了probe函数,remove函数就完全不用看了。
上面我们主要讲述了linux中触摸屏设备作为平台设备存在的模块加载和卸载函数,还有就是对应的probe函数和remove函数,下面我们主要介绍在probe函数中注册的两个中断处理函数:触摸屏中断函数和ADC中断函数。
4、先来说第一个中断处理函数——触摸屏中断,对应的中断处理函数是stylus_updown,当触摸屏被按下时,会产生中断信号IRQ_PENDUP。函数源码如下:

首先我们来分析161行,有如下定义:
#define S3C_ADCDAT0_UPDOWN        (1<<15)
#define S3C_ADCDAT1_UPDOWN        (1<<15)
从这里可知与这两个寄存器的第15位有关,而寄存器ADCDAT0和寄存器ADCDAT1分别表示X和Y方向检测到触摸屏是否被按下,也就是说只有当寄存器ADCDAT0和寄存器ADCDAT1两个寄存器的UPDOWN都等于0时,采表示触摸屏被按下。看下面这个图:


接下来我们分析175、176行,其中有如下定义:
#define S3C_ADCCLRINT                S3C_ADCREG(0x18)
#define S3C_ADCCLRWK                S3C_ADCREG(0x20)
直接看图:
















5、接下来来分析另外一个ADC中断,对应的中断函数是stylus_action。当触摸屏在自动X/Y位置转换模式和独立的X/Y位置转换模式时,当坐标数据转换之后会产生IRQ_ADC中断,进而调用stylus_action函数,此函数源码如下:

上图注释比较详细,所以我们直接来分析220行的touch_timer定时器指定的函数。这个定时器定义如下:

touch_timer定时器用来当缓冲区不为空时,不断地触发touch_timer_fire函数。此函数读取触摸屏的坐标信息,并传递给内核输入子系统。再说下上面的定时器定义函数的TIMER_INITIALIZER宏定义:看下面,可知触摸屏设备驱动程序将touch_timer定时器函数设置为touch_timer_fire,过期时间为0,数据为0.即加载完触摸屏驱动程序后,就会执行一次定时器数touch_timer_fire。

6、我们最后来分析触摸屏中断函数和ADC中断函数都调用过的一个重要函数:touch_timer_fire函数:
touch_timer_fire这个函数主要实现以下功能:
        stylus down的时候,在中断函数stylus_updown里面被调用,此时缓存区没有数据,ts.count为0,所以只是简单的设置ad转换的模式,然后开启ad转换。
        但ADC中断函数stylus_action把缓冲区填满的时候,作为中断后半段函数稍后被调用,此时ts.count为4,算出其平均值后,交给事件处理层(Event Handler)处理,主要是填写缓冲,然后唤醒等待输入数据的进程。
        stylus抬起,等到缓冲区填满后(可能会包含一些无用的数据)被调用,这时候判断出stylus up,报告stylus up事件,重新等待stylus down。


页: [1]
查看完整版本: Linux之触摸屏驱动-基于S3C6410