Linux2.6.22.6触摸屏移植到FL2440


2011-3-21 -- 2011-3-22*/

Kernel version :2.6.22.6
Crosstool      :arm-linux-gcc-3.4.1
Board          :FL2440
System         :Ubuntu 10.10
Source         :regs-adc.h, ts.h, s3c2410_ts.c

1.cp regs-adc.h include/asm-arm/arch-s3c2410/regs-adc.h

  1. /*regs-adc.h*/ 
  2.  
  3. #ifndef __ASM_ARCH_REGS_ADC_H  
  4. #define __ASM_ARCH_REGS_ADC_H "regs-adc.h"  
  5. #define S3C2410_ADCREG(x) (x)  
  6. #define S3C2410_ADCCON     S3C2410_ADCREG(0x00)  
  7. #define S3C2410_ADCTSC     S3C2410_ADCREG(0x04)  
  8. #define S3C2410_ADCDLY     S3C2410_ADCREG(0x08)  
  9. #define S3C2410_ADCDAT0    S3C2410_ADCREG(0x0C)  
  10. #define S3C2410_ADCDAT1    S3C2410_ADCREG(0x10)   
  11.   
  12. /* ADCCON Register Bits */ 
  13. #define S3C2410_ADCCON_ECFLG            (1<<15)  
  14. #define S3C2410_ADCCON_PRSCEN           (1<<14)  
  15. #define S3C2410_ADCCON_PRSCVL(x)        (((x)&0xFF)<<6)  
  16. #define S3C2410_ADCCON_PRSCVLMASK       (0xFF<<6)  
  17. #define S3C2410_ADCCON_SELMUX(x)        (((x)&0x7)<<3)  
  18. #define S3C2410_ADCCON_MUXMASK          (0x7<<3)  
  19. #define S3C2410_ADCCON_STDBM            (1<<2)  
  20. #define S3C2410_ADCCON_READ_START       (1<<1)  
  21. #define S3C2410_ADCCON_ENABLE_START     (1<<0)  
  22. #define S3C2410_ADCCON_STARTMASK        (0x3<<0)   
  23.   
  24. /* ADCTSC Register Bits */  

2.cp ts.h include/asm-arm/arch-s3c2410/ts.h

 

  1. /*ts.h*/  
  2.     
  3. *   
  4. * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>   
  5. *   
  6. *   
  7. * This program is free software; you can redistribute it and/or modify   
  8. * it under the terms of the GNU General Public License version 2 as  
  9. * published by the Free Software Foundation.   
  10. *   
  11. *   
  12. *  Changelog:   
  13. *     24-Mar-2005     RTP     Created file   
  14. *     03-Aug-2005     RTP     Renamed to ts.h   
  15. */  
  16. #ifndef __ASM_ARM_TS_H  
  17. #define __ASM_ARM_TS_H   
  18. struct s3c2410_ts_mach_info {   
  19.        int             delay;   
  20.        int             presc;   
  21.        int             oversampling_shift;   
  22. };   
  23. void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info);  
  24. #endif /* __ASM_ARM_TS_H */  

3.cp s3c2410_ts.c drivers/input/touchscreen/s3c2440_ts.c

 

  1. /*s3c2410_ts.c*/  
  2.   
  3. /* By dean adapted from original driver of linux-2.6.13.4 for mini2440 */ 
  4. #include <linux/errno.h>  
  5. #include <linux/kernel.h>  
  6. #include <linux/module.h>  
  7. #include <linux/slab.h>  
  8. #include <linux/input.h>  
  9. #include <linux/init.h>  
  10. #include <linux/serio.h>  
  11. #include <linux/delay.h>  
  12. #include <linux/clk.h>  
  13. #include <linux/platform_device.h>  
  14. #include <asm/io.h>  
  15. #include <asm/irq.h>  
  16.  
  17.  
  18. #include <asm/arch/regs-adc.h>  
  19. #include <asm/arch/regs-gpio.h>  
  20. #include <asm/arch/ts.h>   
  21.   
  22. /* For ts.dev.id.version */ 
  23. #define S3C2410TSVERSION 0x0101  
  24. #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))  
  25. #define WAIT4INT(x) (((x)<<8) | S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | \   
  26. S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3))  
  27.  
  28. #define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN |\   
  29. S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))  
  30. #define DEBUG_LVL KERN_DEBUG   
  31.   
  32. MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");   
  33. MODULE_DESCRIPTION("s3c2410 touchscreen driver");   
  34. MODULE_LICENSE("GPL");   
  35.   
  36. /*  
  37. * Definitions & global arrays.  
  38. */  
  39.   
  40.   
  41. static char *s3c2410ts_name = "s3c2410 TouchScreen";   
  42.   
  43. /*  
  44. * Per-touchscreen data.  
  45. */  
  46.   
  47. struct s3c2410ts {   
  48. struct input_dev *dev;   
  49. long xp;   
  50. long yp;   
  51. int count;   
  52. int shift;   
  53. char phys[32];   
  54. };   
  55.   
  56. static struct s3c2410ts ts;   
  57. static void __iomem *base_addr;   
  58. static inline void s3c2410_ts_connect(void)   
  59. {   
  60. s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);   
  61. s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);   
  62. s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);   
  63. s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);   
  64. }   
  65.   
  66. static void touch_timer_fire(unsigned long data)   
  67. {   
  68. unsigned long data0;   
  69. unsigned long data1;   
  70. int updown;   
  71. //printk("touch_timer_fire 1:%d\n",updown);   
  72.   
  73. data0 = readl(base_addr+S3C2410_ADCDAT0);   
  74. data1 = readl(base_addr+S3C2410_ADCDAT1);   
  75. //printk("touch time fire: 2:data0:%d:data1:%d.\n",data0,data1);   
  76. updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));   
  77. //printk("touch_timer_fire 3:%d\n",updown);   
  78. if (updown)    
  79. {   
  80. if (ts.count != 0)    
  81. {   
  82. long tmp;   
  83. tmp = ts.xp;   
  84. ts.xp = ts.yp;   
  85. ts.yp = tmp;   
  86. //printk("touch time fire:4:xp:%d:yp:%d.\n",ts.xp,ts.yp);   
  87. ts.xp >>= ts.shift;   
  88. ts.yp >>= ts.shift;   
  89. //printk("func 2");  
  90. #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG   
  91. {   
  92. struct timeval tv;   
  93. do_gettimeofday(&tv);   
  94. printk(DEBUG_LVL "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts.xp, ts.yp);   
  95. }  
  96. #endif   
  97.   
  98. input_report_abs(ts.dev, ABS_X, ts.xp);   
  99. input_report_abs(ts.dev, ABS_Y, ts.yp);   
  100. //printk("touch time fire:reportsbs:xp:%d:yp:%d.\n",ts.xp,ts.yp);   
  101. input_report_key(ts.dev, BTN_TOUCH, 1);   
  102. input_report_abs(ts.dev, ABS_PRESSURE, 1);   
  103. input_sync(ts.dev);   
  104. }   
  105.   
  106. ts.xp = 0;   
  107. ts.yp = 0;   
  108. ts.count = 0;   
  109. //printk("func 1");   
  110.   
  111. writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);   
  112. writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);   
  113. }    
  114. else    
  115. {   
  116. ts.count = 0;   
  117. //printk("func 3");   
  118. input_report_key(ts.dev, BTN_TOUCH, 0);   
  119. input_report_abs(ts.dev, ABS_PRESSURE, 0);   
  120. input_sync(ts.dev);   
  121.   
  122. writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);   
  123. }   
  124. }   
  125.   
  126. static struct timer_list touch_timer =   
  127. TIMER_INITIALIZER(touch_timer_fire, 0, 0);   
  128.   
  129. static irqreturn_t stylus_updown(int irq, void *dev_id)   
  130. {   
  131. unsigned long data0;   
  132. unsigned long data1;   
  133. int updown;   
  134. data0 = readl(base_addr+S3C2410_ADCDAT0);   
  135. data1 = readl(base_addr+S3C2410_ADCDAT1);   
  136. updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));   
  137.   
  138. /* TODO we should never get an interrupt with updown set while  
  139. * the timer is running, but maybe we ought to verify that the  
  140. * timer isn't running anyways. */  
  141. if (updown)   
  142. touch_timer_fire(0);   
  143.   
  144. return IRQ_HANDLED;   
  145. }   
  146.   
  147.   
  148. static irqreturn_t stylus_action(int irq, void *dev_id)   
  149. {   
  150. //printk("action\n");   
  151. unsigned long data0;   
  152. unsigned long data1;   
  153.   
  154. data0 = readl(base_addr+S3C2410_ADCDAT0);   
  155. data1 = readl(base_addr+S3C2410_ADCDAT1);   
  156.   
  157. ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;   
  158. ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;   
  159. ts.count++;   
  160.   
  161. if (ts.count < (1<<ts.shift)) {   
  162. writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);   
  163. writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);   
  164. else {   
  165. mod_timer(&touch_timer, jiffies+1);   
  166. writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);   
  167. }   
  168.   
  169. return IRQ_HANDLED;   
  170. }   
  171. static struct clk *adc_clock;   
  172.   
  173. static int __init s3c2410ts_probe(struct platform_device *pdev)   
  174. {   
  175. int rc;   
  176. struct s3c2410_ts_mach_info *info;   
  177. struct input_dev *input_dev;   
  178.   
  179. info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;   
  180.   
  181. if (!info)   
  182. {   
  183. printk(KERN_ERR "Hm... too bad : no platform data for ts\n");   
  184. return -EINVAL;   
  185. }  
  186.  
  187. #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG   
  188. printk(DEBUG_LVL "Entering s3c2410ts_init\n");  
  189. #endif   
  190.   
  191. adc_clock = clk_get(NULL, "adc");   
  192. if (!adc_clock) {   
  193. printk(KERN_ERR "failed to get adc clock source\n");   
  194. return -ENOENT;   
  195. }   
  196. clk_enable(adc_clock);  
  197.  
  198. #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG   
  199. printk(DEBUG_LVL "got and enabled clock\n");  
  200. #endif   
  201.   
  202. base_addr=ioremap(S3C2410_PA_ADC,0x20);   
  203. if (base_addr == NULL) {   
  204. printk(KERN_ERR "Failed to remap register block\n");   
  205. return -ENOMEM;   
  206. }   
  207.   
  208.   
  209. /* Configure GPIOs */  
  210. s3c2410_ts_connect();   
  211.   
  212. if ((info->presc&0xff) > 0)   
  213. writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\   
  214. base_addr+S3C2410_ADCCON);   
  215. else  
  216. writel(0,base_addr+S3C2410_ADCCON);   
  217.   
  218.   
  219. /* Initialise registers */  
  220. if ((info->delay&0xffff) > 0)   
  221. writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);   
  222.   
  223. writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);   
  224.   
  225. /* Initialise input stuff */  
  226. memset(&ts, 0, sizeof(struct s3c2410ts));   
  227. input_dev = input_allocate_device();   
  228. if (!input_dev) {   
  229. printk(KERN_ERR "Unable to allocate the input device !!\n");   
  230. return -ENOMEM;   
  231. }   
  232. sprintf(ts.phys, "ts0");   
  233. ts.dev=input_dev;   
  234.   
  235. ts.dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);     
  236. ts.dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);     
  237. input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);   
  238. input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);   
  239. input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);   
  240.   
  241. ts.dev->name = s3c2410ts_name;   
  242. ts.dev->id.bustype = BUS_RS232;   
  243. ts.dev->id.vendor = 0xDEAD;   
  244. ts.dev->id.product = 0xBEEF;   
  245. ts.dev->id.version = S3C2410TSVERSION;   
  246.   
  247. ts.shift = info->oversampling_shift;   
  248.   
  249. /* Get irqs */  
  250. if (request_irq(IRQ_ADC, stylus_action,IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev))   
  251. {   
  252. printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");   
  253. iounmap(base_addr);   
  254. return -EIO;   
  255. }   
  256. if (request_irq(IRQ_TC, stylus_updown,IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev))   
  257. {   
  258. printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");   
  259. iounmap(base_addr);   
  260. return -EIO;   
  261. }   
  262.   
  263. printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);   
  264.   
  265. /* All went ok, so register to the input system */  
  266. rc=input_register_device(ts.dev);   
  267. if (rc)   
  268. {   
  269. free_irq(IRQ_TC, ts.dev);   
  270. free_irq(IRQ_ADC, ts.dev);   
  271. clk_disable(adc_clock);   
  272. iounmap(base_addr);   
  273. return -EIO;   
  274. }   
  275. return 0;   
  276. }   
  277.   
  278. static int s3c2410ts_remove(struct platform_device *pdev)   
  279. {   
  280. disable_irq(IRQ_ADC);   
  281. disable_irq(IRQ_TC);   
  282. free_irq(IRQ_TC,ts.dev);   
  283. free_irq(IRQ_ADC,ts.dev);   
  284.   
  285. if (adc_clock) {   
  286. clk_disable(adc_clock);   
  287. clk_put(adc_clock);   
  288. adc_clock = NULL;   
  289. }   
  290.   
  291. input_unregister_device(ts.dev);   
  292. iounmap(base_addr);   
  293.   
  294. return 0;   
  295. }  
  296.  
  297. #ifdef CONFIG_PM   
  298. static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state)   
  299. {   
  300. writel(TSC_SLEEP, base_addr+S3C2410_ADCTSC);   
  301. writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_STDBM,base_addr+S3C2410_ADCCON);   
  302. disable_irq(IRQ_ADC);   
  303. disable_irq(IRQ_TC);   
  304. clk_disable(adc_clock);   
  305. return 0;   
  306. }   
  307.   
  308. static int s3c2410ts_resume(struct platform_device *pdev)   
  309. {   
  310. struct s3c2410_ts_mach_info *info =   
  311. struct s3c2410_ts_mach_info *)pdev->dev.platform_data;   
  312.   
  313. clk_enable(adc_clock);   
  314. msleep(1);   
  315.   
  316. enable_irq(IRQ_ADC);   
  317. enable_irq(IRQ_TC);   
  318.   
  319. if ((info->presc&0xff) > 0)   
  320. writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),base_addr+S3C2410_ADCCON);   
  321. else  
  322. writel(0,base_addr+S3C2410_ADCCON);   
  323.   
  324. /* Initialise registers */  
  325. if ((info->delay&0xffff) > 0)   
  326. writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);   
  327.   
  328. writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);   
  329.   
  330. return 0;   
  331. }  
  332.  
  333. #else  
  334. #define s3c2410ts_suspend NULL  
  335. #define s3c2410ts_resume NULL  
  336. #endif   
  337.   
  338.   
  339. static struct platform_driver s3c2410ts_driver = {   
  340. .driver ={   
  341. .name = "s3c2410-ts",   
  342. .owner = THIS_MODULE,   
  343. },   
  344. .probe = s3c2410ts_probe,   
  345. .remove = s3c2410ts_remove,   
  346. .suspend = s3c2410ts_suspend,   
  347. .resume = s3c2410ts_resume,   
  348.   
  349. };   
  350.   
  351.   
  352.   
  353. int __init s3c2410ts_init(void)    
  354. {   
  355.   
  356. return platform_driver_register(&s3c2410ts_driver);   
  357. }   
  358.   
  359. void __exit s3c2410ts_exit(void)   
  360. {   
  361.   
  362. platform_driver_unregister(&s3c2410ts_driver);   
  363. }   
  364.   
  365. module_init(s3c2410ts_init);   
  366. module_exit(s3c2410ts_exit);  
  • 1
  • 2
  • 下一页

相关内容