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

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

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

  1. turn0;
  2. }
  3. */
  4. rc=input_register_device(ts.dev);
  5. if(rc){
  6. free_irq(IRQ_TC,ts.dev);
  7. free_irq(IRQ_ADC,ts.dev);
  8. clk_disable(adc_clock);
  9. iounmap(base_addr);
  10. return-EIO;
  11. }
  12. return0;
  13. }
  14. staticints3c2440ts_remove(structplatform_device*pdev)
  15. {
  16. disable_irq(IRQ_ADC);
  17. disable_irq(IRQ_TC);
  18. free_irq(IRQ_TC,ts.dev);
  19. free_irq(IRQ_ADC,ts.dev);
  20. if(adc_clock){
  21. clk_disable(adc_clock);
  22. clk_put(adc_clock);
  23. adc_clock=NULL;
  24. }
  25. input_unregister_device(ts.dev);
  26. iounmap(base_addr);
  27. return0;
  28. }
  29. #ifdefCONFIG_PM
  30. staticints3c2440ts_suspend(structplatform_device*pdev,pm_message_tstate)
  31. {
  32. writel(TSC_SLEEP,base_addr+S3C2410_ADCTSC);
  33. writel(readl(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_STDBM,
  34. base_addr+S3C2410_ADCCON);
  35. disable_irq(IRQ_ADC);
  36. disable_irq(IRQ_TC);
  37. clk_disable(adc_clock);
  38. return0;
  39. }
  40. staticints3c2440ts_resume(structplatform_device*pdev)
  41. {
  42. structs3c2440_ts_mach_info*info=
  43. (structs3c2440_ts_mach_info*)pdev->dev.platform_data;
  44. clk_enable(adc_clock);
  45. msleep(1);
  46. enable_irq(IRQ_ADC);
  47. enable_irq(IRQ_TC);
  48. if((info->presc&0xff)>0)
  49. writel(S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
  50. base_addr+S3C2410_ADCCON);
  51. else
  52. writel(0,base_addr+S3C2410_ADCCON);
  53. /*Initialiseregisters*/
  54. if((info->delay&0xffff)>0)
  55. writel(info->delay&0xffff,base_addr+S3C2410_ADCDLY);
  56. writel(WAIT4INT(0),base_addr+S3C2410_ADCTSC);
  57. return0;
  58. }
  59. #else
  60. #defines3c2440ts_suspendNULL
  61. #defines3c2440ts_resumeNULL
  62. #endif
  63. /*
  64. 下面是/linux/platform_device.h定义的platform_driver结构体
  65. structplatform_driver{
  66. int(*probe)(structplatform_device*);//设备的检测,所以需要先前的设备注册
  67. int(*remove)(structplatform_device*);//删除该设备
  68. void(*shutdown)(structplatform_device*);//关闭该设备
  69. int(*suspend)(structplatform_device*,pm_message_tstate);
  70. int(*suspend_late)(structplatform_device*,pm_message_tstate);
  71. int(*resume_early)(structplatform_device*);
  72. int(*resume)(structplatform_device*);
  73. structpm_ext_ops*pm;
  74. structdevice_driverdriver;//设备驱动,定义在include/linux/device.h中
  75. };
  76. 内核提供的platform_driver结构体的注册函数为platform_driver_register(),该函数定义在driver/base/platform.c中
  77. */
  78. staticstructplatform_drivers3c2440ts_driver={
  79. .driver={
  80. .name="s3c2440-ts",
  81. .owner=THIS_MODULE,
  82. },
  83. .probe=s3c2440ts_probe,
  84. .remove=s3c2440ts_remove,
  85. .suspend=s3c2440ts_suspend,
  86. .resume=s3c2440ts_resume,
  87. };
  88. staticint__inits3c2440ts_init(void)
  89. {
  90. intrc;
  91. rc=platform_driver_register(&s3c2440ts_driver);
  92. if(rc<0)
  93. printk(KERN_ERR"platform_driver_registererror!\n");
  94. returnrc;
  95. }
  96. staticvoid__exits3c2440ts_exit(void)
  97. {
  98. platform_driver_unregister(&s3c2440ts_driver);
  99. }
  100. module_init(s3c2440ts_init);
  101. module_exit(s3c2440ts_exit);
  102. MODULE_AUTHOR("YANMING");
  103. MODULE_DESCRIPTION("Mys3c2440touchscreendriver");
  104. MODULE_LICENSE("GPL");

4、分析完成后对触摸屏的工作过程就有了一个比较明确的认识

从触摸屏被按下到系统相应的过程如下:

(1) 当触摸屏感觉到触摸,触发IRQ_TC中断,然后读取触摸屏控制寄存器的值,判断是否被按下,如果被按下,启动定时器,执行touch_timer_fire()函数启动ADC转换。

(2) ADC转换完成后,会触发IRQ_ADC中断,执行相应的中断处理函数,如果ADC转换次数小于4,再次启动ADC转换;如果ADC转换次数为4,则启动一个系统滴答定时器,执行touch_timer_fire()函数

(3) 执行定时器服务程序时,如果此时触摸屏仍被按下,则上报事件和坐标数据,重复(2);如果没有被按下,上报时间和坐标数据,将触摸屏控制寄存器设置为中断等待状态
可见,触摸屏驱动的服务是一个封闭的循环过程。

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

网站地图

Top