input_report_abs(ts_dev, ABS_PRESSURE, 1);
input_report_key(ts_dev, BTN_TOUCH, 1);
input_sync(ts_dev);
}
xp = 0;
yp = 0;
count = 0;
writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, adc_base + S3C2410_ADCTSC);
writel(readl(adc_base + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, adc_base + S3C2410_ADCCON);
}
else
{
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), adc_base + S3C2410_ADCTSC);
if (OwnADC)
{
OwnADC = 0;
up(&ADC_LOCK);
}
}
}
static struct timer_list touch_timer = TIMER_INITIALIZER(touch_timer_fire, 0, 0);
static irqreturn_t adc_irq(int irq, void *dev_id)
{
unsigned long data0;
unsigned long data1;
if(OwnADC)
{
data0 = readl(adc_base + S3C2410_ADCDAT0);
data1 = readl(adc_base + S3C2410_ADCDAT1);
xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
count++;
if (count < (1<2))
{
writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, adc_base + S3C2410_ADCTSC);
writel(readl(adc_base + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, adc_base + S3C2410_ADCCON);
}
else
{
mod_timer(&touch_timer, jiffies + 1);
writel(WAIT4INT(1), adc_base + S3C2410_ADCTSC);
}
}
return IRQ_HANDLED;
}
我们从整体上描述转换这个的过程:
(1)如果触摸屏感觉到触摸,则触发触摸屏中断即进入tc_irq,获取ADC_LOCK后判断触摸屏状态为按下,则调用touch_timer_fire启动ADC转换;
(2)当ADC转换启动后,触发ADC中断即进入adc_irq,如果这一次转换的次数小于4,则重新启动ADC进行转换,如果4次完毕后,启动1个时间滴答的定时器,停止ADC转换,也就是说在这个时间滴答内,ADC转换是停止的;
(3)这里为什么要在1个时间滴答到来之前停止ADC的转换呢?这是为了防止屏幕抖动。
(4)如果1个时间滴答到来则进入定时器服务程序touch_timer_fire,判断触摸屏仍然处于按下状态则上报事件和转换的数据,并重启ADC转换,重复第(2)步;
(5)如果触摸抬起了,则上报释放事件,并将触摸屏重新设置为等待中断状态。