您的位置:首页 > 运维架构 > Linux

linux中触摸屏驱动的实现(2)——基于s3c6410处理器

2012-05-26 20:12 357 查看


linux中触摸屏驱动的实现(1)——基于s3c6410处理器的链接地址

上一篇主要讲述了linux中触摸屏设备作为平台设备存在的模块加载和卸载函数,还有就是对应的probe函数和remove函数,这一篇说下在probe函数中注册的两个中断处理函数。

1、先来说第一个中断处理函数——触摸屏中断,对应的中断处理函数是stylus_updown,当触摸屏被按下时,会产生中断信号IRQ_PENDUP。函数源码如下:

static irqreturn_t stylus_updown(int irqno, void *param)

{

unsigned long data0;

unsigned long data1;

int updown;定义一个整型变量,用来表示触摸屏是否被按下,如果按下,这个值是1;如果没按下,这个值是0。

data0 = readl(ts_base+S3C_ADCDAT0);

data1 = readl(ts_base+S3C_ADCDAT1);读取寄存器ADCDAT0和寄存器ADCDAT1

updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

重点来分析,有如下定义:

#define S3C_ADCDAT0_UPDOWN(1<<15)

#define S3C_ADCDAT1_UPDOWN(1<<15)

从这里可知与这两个寄存器的第15位有关,而寄存器ADCDAT0和寄存器ADCDAT1分别表示X和Y方向检测到触摸屏是否被按下,也就是说只有当寄存器ADCDAT0和寄存器ADCDAT1两个寄存器的UPDOWN都等于0时,采表示触摸屏被按下。看下面这个图:





#ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG

printk(KERN_INFO " %c\n",updown ? 'D' : 'U');

#endif

/* TODO we should never get an interrupt with updown set while

* the timer is running, but maybe we ought to verify that the

* timer isn't running anyways. */

if (updown) updown 等于1,表示触摸屏按下

{

downflag=1;

//printk("touch_timer_fire(0)\n");

touch_timer_fire(0);调用此函数处理触摸屏的按下,这个函数下面再讲。

}

if(ts->s3c_adc_con==ADC_TYPE_2) {

__raw_writel(0x0, ts_base+S3C_ADCCLRWK);

__raw_writel(0x0, ts_base+S3C_ADCCLRINT);

}

其中有如下定义:

#define S3C_ADCCLRINTS3C_ADCREG(0x18)

#define S3C_ADCCLRWKS3C_ADCREG(0x20)

直接看图:







return IRQ_HANDLED;

}

好了现在可以分析我们上面没有分析的那一个函数了touch_timer_fire,源码如下:
static void touch_timer_fire(unsigned long data)

{

unsigned long data0;

unsigned long data1;

int updown;

data0 = readl(ts_base+S3C_ADCDAT0);

data1 = readl(ts_base+S3C_ADCDAT1);

updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

上面这些和刚才分析的一样,都是为了判断触摸屏是否被按下

if (updown) { 为1,触摸屏被按下

//printk("updown=1.\n");

if (ts->count) {

#ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG

........

#endif

if(downflag==0)

{

input_report_abs(ts->dev, ABS_X, ts->xp);

input_report_abs(ts->dev, ABS_Y, ts->yp);

input_report_key(ts->dev, BTN_TOUCH, 1);

input_report_abs(ts->dev, ABS_PRESSURE, 1);

input_sync(ts->dev);

} 上面这一段用来向输入子系统报告当前触摸笔的位置

else

{

// printk("downflag=1.ignore this data.\n");

downflag=0;

}

}

ts->xp = 0;

ts->yp = 0;

ts->count = 0;
表示缓冲区中没有数据,也就是没有触摸屏按下时间发生

writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC);主要是将AD转化模式设置在自动转化模式。
其中有如下定义:
#define S3C_ADCTSC_PULL_UP_DISABLE(1<<3)
#define AUTOPST (S3C_ADCTSC_YM_SEN | S3C_ADCTSC_YP_SEN
| S3C_ADCTSC_XP_SEN | \

S3C_ADCTSC_AUTO_PST | S3C_ADCTSC_XY_PST(0))

writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON);启动AD转化功能

}

else { 表示触摸屏没有被按下时的操作。

ts->count = 0;

input_report_key(ts->dev, BTN_TOUCH, 0);调用这个函数向输入子系统报告触摸屏被弹起事件,表示按键被释放。

input_report_abs(ts->dev, ABS_PRESSURE, 0); 发送触摸屏的一个绝对坐标

input_sync(ts->dev); 该函数通知事件发送者发送一个完整的报告。

writel(WAIT4INT(0), ts_base+S3C_ADCTSC); 把触摸屏的模式设为等待中断模式

}

}


linux中触摸屏驱动的实现(3)——基于s3c6410处理器的链接地址





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: