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

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


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

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

static irqreturn_t stylus_action(int irqno, void *param)
{
unsigned long data0;
unsigned long data1;

//printk("stylus_action.\n");

data0 = readl(ts_base+S3C_ADCDAT0);
data1 = readl(ts_base+S3C_ADCDAT1);  读两个寄存器的值

if(ts->resol_bit==12) {    12位分辨率
#if defined(CONFIG_TOUCHSCREEN_NEW)
ts->yp += S3C_ADCDAT0_XPDATA_MASK_12BIT - (data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT);
ts->xp += S3C_ADCDAT1_YPDATA_MASK_12BIT - (data1 & S3C_ADCDAT1_YPDATA_MASK_12BIT);
#else 
ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT;获得触摸点的X坐标,把它加到ts->xp上。

其中:#define S3C_ADCDAT0_XPDATA_MASK_12BIT (0x0FFF)  也就是屏蔽位
ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK_12BIT;和上面一样,获得触摸点Y坐标,加到ts->yp上。
#endif
}
else {   10位分频率
#if defined(CONFIG_TOUCHSCREEN_NEW)
ts->yp += S3C_ADCDAT0_XPDATA_MASK - (data0 & S3C_ADCDAT0_XPDATA_MASK);
ts->xp += S3C_ADCDAT1_YPDATA_MASK - (data1 & S3C_ADCDAT1_YPDATA_MASK);
#else
ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK;
ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK;
#endif
}


ts->count++;  


if (ts->count < (1<<ts->shift)) {     如果缓冲区未满,再次激活ADC转化器。
writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC);
writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON);
} else {
mod_timer(&touch_timer, jiffies+1);  修改touch_timer定时器,将其时间延后一个单位。在下一个定时器时刻将调用touch_timer定时器指定的函数。这个定时器的定义如下:

static struct timer_list touch_timer =
TIMER_INITIALIZER(touch_timer_fire, 0, 0);

writel(WAIT4INT(1), ts_base+S3C_ADCTSC);    将触摸屏设为等待中断模式
}


if(ts->s3c_adc_con==ADC_TYPE_2) {    清中断
        __raw_writel(0x0, ts_base+S3C_ADCCLRWK);
        __raw_writel(0x0, ts_base+S3C_ADCCLRINT);
}

return IRQ_HANDLED;
}

touch_timer定时器用来当缓冲区不为空时,不断地触发touch_timer_fire函数。此函数读取触摸屏的坐标信息,并传递给内核输入子系统。还记得吗?touch_timer_fire这个函数的源码在上一篇博客中已经分析了。

2、再说下上面的定时器定义函数。

static struct timer_list touch_timer =
TIMER_INITIALIZER(touch_timer_fire, 0, 0);看下面,可知触摸屏设备驱动程序将touch_timer定时器函数设置为touch_timer_fire,过期时间为0,数据为0.即加载完触摸屏驱动程序后,就会执行一次定时器数touch_timer_fire。

#define TIMER_INITIALIZER(_function, _expires, _data) { \
.entry = { .prev = TIMER_ENTRY_STATIC }, \
.function = (_function), \
.expires = (_expires), \
.data = (_data), \
.base = &boot_tvec_bases, \
}



你可能感兴趣的:(c,linux,timer,function,struct,action)