ARM-Linux驱动-触摸屏驱动分析
时间:11-20
来源:互联网
点击:
- lude/linux/input.h,作用是报告事件
- staticinlinevoidinput_report_abs(structinput_dev*dev,unsignedintcode,intvalue)
- {
- input_event(dev,EV_ABS,code,value);
- }
- */
- //报告X,Y的绝对坐标
- input_report_abs(ts.dev,ABS_X,ts.xp);
- input_report_abs(ts.dev,ABS_Y,ts.yp);
- //报告事件,1代表光标被按下
- input_report_key(ts.dev,BTN_TOUCH,1);
- //报告触摸屏状态,1代表触摸屏被按下
- input_report_abs(ts.dev,ABS_PRESSURE,1);
- //等待接收方的确认,用于事件的同步
- input_sync(ts.dev);
- }
- //现在光标被按下,并且ADC转换没有启动
- ts.xp=0;
- ts.yp=0;
- ts.count=0;
- //设置触摸屏控制寄存器的值为0xdcB:11011100,设置控制寄存器上拉无效,自动转换X,Y坐标
- //printk("S3C2410_ADCTSC:0x%x\n",S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST);
- writel(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
- //启动ADC转换
- writel(readl(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
- }
- 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),base_addr+S3C2410_ADCTSC);
- }
- }
- staticirqreturn_tadc_irq(intirq,void*dev_id)
- {
- //用于存放数据寄存器的数据
- unsignedlongdata0;
- unsignedlongdata1;
- //读取数据,这次主要读取的是位置数据
- data0=readl(base_addr+S3C2410_ADCDAT0);
- data1=readl(base_addr+S3C2410_ADCDAT1);
- ts.xp+=data0&S3C2410_ADCDAT0_XPDATA_MASK;//累加四次准换结果的X坐标和
- ts.yp+=data1&S3C2410_ADCDAT1_YPDATA_MASK;//累加四次准换结果的Y坐标和
- ts.count++;//转换次数加一
- //如果转换次数小于4
- if(ts.count<(1
- {
- //再次设置触摸屏控制寄存器上拉不使能、自动X、Y转换模式
- writel(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
- //再次启动ADC转换
- writel(readl(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
- }
- else//这时,ADC转换四次完成,延迟一个系统滴答,执行touch_timer_fire()函数
- {
- mod_timer(&touch_timer,jiffies+1);
- writel(WAIT4INT(1),base_addr+S3C2410_ADCTSC);
- }
- returnIRQ_HANDLED;
- }
- /*
- *Thefunctionsforinserting/removingusasamodule.
- */
- /*
- 该结构体定义在/include/linux/platform_device.h
- structplatform_device{
- constchar*name;
- intid;
- structdevicedev;
- u32num_resources;
- structresource*resource;
- };
- */
- staticint__inits3c2440ts_probe(structplatform_device*pdev)
- {
- intrc;
- /*
- 下面结构体定义在/include/mach/s3c2410_ts.h
- structs3c2410_ts_mach_info{
- intdelay;
- intpresc;
- intoversampling_shift;
- };
- */
- structs3c2410_ts_mach_info*info;
- structinput_dev*input_dev;
- /*
- void*platform_data;//Platformspecificdata,devicecoredoesnttouchit
- */
- info=(structs3c2440_ts_mach_info*)pdev->dev.platform_data;
- if(!info)
- {
- printk(KERN_ERR"Hm...toobad:noplatformdataforts\n");
- return-EINVAL;
- }
- #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
- printk(DEBUG_LVL"Enterings3c2440ts_init\n");
- #endif
- //由于ADC转换需要时钟,这里获取时钟
- adc_clock=clk_get(NULL,"adc");
- if(!adc_clock){
- printk(KERN_ERR"failedtogetadcclocksource\n");
- return-ENOENT;
- }
- clk_enable(adc_clock);//使能时钟
- #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
- printk(DEBUG_LVL"gotandenabledclock\n");
- #endif
- //通过ioremap实现物理地址到虚拟地址的转换
- base_addr=ioremap(S3C2410_PA_ADC,0x20);
- if(base_addr==NULL){
- printk(KERN_ERR"Failedtoremapregisterblock\n");
- return-ENOMEM;
- }
- //设置ADCCON控制寄存器为0x4c40,设置预分频有效,预分频值为B:110001D:49
- //printk("ADCCONis0x%x\n",S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(info->presc&0xFF));
- 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);
- /*Initialiseregisters*/
- /*
- 设置ADC开始延时寄存器ADCDLY:0x4e20
- */
- //printk("ADCDLY:0x%x\n",info->delay&0xffff);
- if((info->delay&0xffff)>0)
- writel(info->delay&0xffff,base_addr+S3C2410_ADCDLY);
- /*
- 设置ADC触摸屏控制
ARMLinux驱动触摸屏驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
