微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动-触摸屏驱动分析

ARM-Linux驱动-触摸屏驱动分析

时间:11-20 来源:互联网 点击:

  1. lude/linux/input.h,作用是报告事件
  2. staticinlinevoidinput_report_abs(structinput_dev*dev,unsignedintcode,intvalue)
  3. {
  4. input_event(dev,EV_ABS,code,value);
  5. }
  6. */
  7. //报告X,Y的绝对坐标
  8. input_report_abs(ts.dev,ABS_X,ts.xp);
  9. input_report_abs(ts.dev,ABS_Y,ts.yp);
  10. //报告事件,1代表光标被按下
  11. input_report_key(ts.dev,BTN_TOUCH,1);
  12. //报告触摸屏状态,1代表触摸屏被按下
  13. input_report_abs(ts.dev,ABS_PRESSURE,1);
  14. //等待接收方的确认,用于事件的同步
  15. input_sync(ts.dev);
  16. }
  17. //现在光标被按下,并且ADC转换没有启动
  18. ts.xp=0;
  19. ts.yp=0;
  20. ts.count=0;
  21. //设置触摸屏控制寄存器的值为0xdcB:11011100,设置控制寄存器上拉无效,自动转换X,Y坐标
  22. //printk("S3C2410_ADCTSC:0x%x\n",S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST);
  23. writel(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
  24. //启动ADC转换
  25. writel(readl(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
  26. }
  27. else//光标没有被按下
  28. {
  29. ts.count=0;
  30. //报告事件及光标的位置状态
  31. input_report_key(ts.dev,BTN_TOUCH,0);
  32. input_report_abs(ts.dev,ABS_PRESSURE,0);
  33. //等待接收方的应答,用于同步
  34. input_sync(ts.dev);
  35. //设置触摸屏控制寄存器为等待中断模式
  36. writel(WAIT4INT(0),base_addr+S3C2410_ADCTSC);
  37. }
  38. }
  39. staticirqreturn_tadc_irq(intirq,void*dev_id)
  40. {
  41. //用于存放数据寄存器的数据
  42. unsignedlongdata0;
  43. unsignedlongdata1;
  44. //读取数据,这次主要读取的是位置数据
  45. data0=readl(base_addr+S3C2410_ADCDAT0);
  46. data1=readl(base_addr+S3C2410_ADCDAT1);
  47. ts.xp+=data0&S3C2410_ADCDAT0_XPDATA_MASK;//累加四次准换结果的X坐标和
  48. ts.yp+=data1&S3C2410_ADCDAT1_YPDATA_MASK;//累加四次准换结果的Y坐标和
  49. ts.count++;//转换次数加一
  50. //如果转换次数小于4
  51. if(ts.count<(1
  52. {
  53. //再次设置触摸屏控制寄存器上拉不使能、自动X、Y转换模式
  54. writel(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
  55. //再次启动ADC转换
  56. writel(readl(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
  57. }
  58. else//这时,ADC转换四次完成,延迟一个系统滴答,执行touch_timer_fire()函数
  59. {
  60. mod_timer(&touch_timer,jiffies+1);
  61. writel(WAIT4INT(1),base_addr+S3C2410_ADCTSC);
  62. }
  63. returnIRQ_HANDLED;
  64. }
  65. /*
  66. *Thefunctionsforinserting/removingusasamodule.
  67. */
  68. /*
  69. 该结构体定义在/include/linux/platform_device.h
  70. structplatform_device{
  71. constchar*name;
  72. intid;
  73. structdevicedev;
  74. u32num_resources;
  75. structresource*resource;
  76. };
  77. */
  78. staticint__inits3c2440ts_probe(structplatform_device*pdev)
  79. {
  80. intrc;
  81. /*
  82. 下面结构体定义在/include/mach/s3c2410_ts.h
  83. structs3c2410_ts_mach_info{
  84. intdelay;
  85. intpresc;
  86. intoversampling_shift;
  87. };
  88. */
  89. structs3c2410_ts_mach_info*info;
  90. structinput_dev*input_dev;
  91. /*
  92. void*platform_data;//Platformspecificdata,devicecoredoesnttouchit
  93. */
  94. info=(structs3c2440_ts_mach_info*)pdev->dev.platform_data;
  95. if(!info)
  96. {
  97. printk(KERN_ERR"Hm...toobad:noplatformdataforts\n");
  98. return-EINVAL;
  99. }
  100. #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
  101. printk(DEBUG_LVL"Enterings3c2440ts_init\n");
  102. #endif
  103. //由于ADC转换需要时钟,这里获取时钟
  104. adc_clock=clk_get(NULL,"adc");
  105. if(!adc_clock){
  106. printk(KERN_ERR"failedtogetadcclocksource\n");
  107. return-ENOENT;
  108. }
  109. clk_enable(adc_clock);//使能时钟
  110. #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
  111. printk(DEBUG_LVL"gotandenabledclock\n");
  112. #endif
  113. //通过ioremap实现物理地址到虚拟地址的转换
  114. base_addr=ioremap(S3C2410_PA_ADC,0x20);
  115. if(base_addr==NULL){
  116. printk(KERN_ERR"Failedtoremapregisterblock\n");
  117. return-ENOMEM;
  118. }
  119. //设置ADCCON控制寄存器为0x4c40,设置预分频有效,预分频值为B:110001D:49
  120. //printk("ADCCONis0x%x\n",S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(info->presc&0xFF));
  121. if((info->presc&0xff)>0)
  122. writel(S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
  123. base_addr+S3C2410_ADCCON);
  124. else
  125. writel(0,base_addr+S3C2410_ADCCON);
  126. /*Initialiseregisters*/
  127. /*
  128. 设置ADC开始延时寄存器ADCDLY:0x4e20
  129. */
  130. //printk("ADCDLY:0x%x\n",info->delay&0xffff);
  131. if((info->delay&0xffff)>0)
  132. writel(info->delay&0xffff,base_addr+S3C2410_ADCDLY);
  133. /*
  134. 设置ADC触摸屏控制

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top