基于mini2440触摸屏驱动

驱动路径:drivers/input/touchscreen/s3c2410_ts.c

在static int __init s3c2410ts_init(void)函数中注册了两个中断

1.if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
  "s3c2410_action", dev))

2.if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
   "s3c2410_action", dev))

中断处理函数stylus_action和stylus_updown。当点击触摸屏时进入该函数,在该函数中启动ad转换,转换完成就触发中断进入stylus_action在stylus_action中读取数据。

首先来看一下stylus_updown函数 

 

static irqreturn_t stylus_updown(int irq, void *dev_id)    {        unsigned long data0;        unsigned long data1;        int updown;           if (down_trylock(&ADC_LOCK) == 0) {      //判断是否adc可用,down_trylock可以用来获取信号量,不会休眠            OwnADC = 1;            data0 = ioread32(base_addr+S3C2410_ADCDAT0);            data1 = ioread32(base_addr+S3C2410_ADCDAT1);               updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));               if (updown) {   //判断触摸屏是否按下                touch_timer_fire(0);  //启动adc            } else {                OwnADC = 0;                up(&ADC_LOCK);            }        }           return IRQ_HANDLED;    }  

下面开一下touch_timer_fire是怎么个玩法

static void touch_timer_fire(unsigned long data)    {        unsigned long data0;        unsigned long data1;        int updown;           data0 = ioread32(base_addr+S3C2410_ADCDAT0);        data1 = ioread32(base_addr+S3C2410_ADCDAT1);           updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));           if (updown) {  //判断现在是否还按下            if (count != 0) {   //采样完成,count的值我下面会讲解                long tmp;                                                                                            //应为是240×320,需要x,y调换一下                         tmp = xp;                xp = yp;                yp = tmp;                                                                                     //在stylus_action中取得是连续四次采样的结果需要处以4                                            xp >>= 2;                            yp >>= 2;                   input_report_abs(dev, ABS_X, xp); //x,y坐标报告                input_report_abs(dev, ABS_Y, yp);                   input_report_key(dev, BTN_TOUCH, 1);                input_report_abs(dev, ABS_PRESSURE, 1);                input_sync(dev);  //同步            }               xp = 0;   //否则开始采用            yp = 0;            count = 0;               iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);            iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);        } else {   //是否抬起            count = 0;               input_report_key(dev, BTN_TOUCH, 0);            input_report_abs(dev, ABS_PRESSURE, 0);            input_sync(dev);               iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);            if (OwnADC) {                OwnADC = 0;                up(&ADC_LOCK);            }        }    }  

注意:当第一次按下时,count==0,启动ad,当转换完成将触发中断,进入stylus_action中断处理函数,好家伙来看一下哦

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfwsx.html