static irqreturn_t stylus_updown(int irq, void *dev_id, struct pt_regs *regs) { unsigned long data0; unsigned long data1; int updown; /* 读取ADCDAT0/1寄存器,判断Stylus的状态: 0 = Stylus down state 1 = Stylus up state */ data0 = readl(base_addr+S3C2410_ADCDAT0); data1 = readl(base_addr+S3C2410_ADCDAT1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT1_UPDOWN)); /* 更新stylus状态寄存器updown: 1 = down 0 = up */
/* 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. */
/* 判断出stylus down,调用touch_timer_fire函数 */ if (updown) touch_timer_fire(0);
adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { printk(KERN_ERR "failed to get adc clock source\n"); return -ENOENT; } clk_use(adc_clock);//这个在高版本下已经不需要了 clk_enable(adc_clock);
#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG printk(DEBUG_LVL "got and enabled clock\n"); #endif
base_addr=ioremap(S3C2410_PA_ADC,0x20);//映射触摸屏的控制寄存器,应该不需要解析了吧^_^ if (base_addr == NULL) { printk(KERN_ERR "Failed to remap register block\n"); return -ENOMEM; }
/* Configure GPIOs */ s3c2410_ts_connect();
/*以下根据我们提供的s3c2410_ts_mach_info结构,配置触摸屏的一些控制寄存器*/ /* Set the prscvl*/ if ((info->presc&0xff) > 0) writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\ base_addr+S3C2410_ADCCON); else writel(0,base_addr+S3C2410_ADCCON);
/* Initialise the adcdly registers */ if ((info->delay&0xffff) > 0) writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);
/* 进入s3c2410触摸屏提供的Waiting for Interrupt Mode,waits for Stylus down.The controller generates Interrupt (INT_TC) signals when the Stylus is down on Touch Screen Panel.*/
/* ADC转换中断,转换结束后触发 */ if (request_irq(IRQ_ADC, stylus_action, SA_SAMPLE_RANDOM, "s3c2410_action", &ts.dev)) { printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n"); iounmap(base_addr); return -EIO; } /* 检测stylus updown的中断,设置为Waiting for Interrupt Mode时, The controller generates Interrupt (INT_TC) signals when the Stylus is down on Touch Screen Panel,还记得吧^_^ */ if (request_irq(IRQ_TC, stylus_updown, SA_SAMPLE_RANDOM, "s3c2410_action", &ts.dev)) { printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n"); iounmap(base_addr); return -EIO; }