1 /*
2 * TI Touch Screen driver
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/err.h>
20 #include <linux/module.h>
21 #include <linux/input.h>
22 #include <linux/slab.h>
23 #include <linux/interrupt.h>
24 #include <linux/clk.h>
25 #include <linux/platform_device.h>
26 #include <linux/io.h>
27 #include <linux/input/ti_tscadc.h>
28 #include <linux/delay.h>
29 #include <linux/pm_runtime.h>
31 #define TSCADC_REG_IRQEOI 0x020
32 #define TSCADC_REG_RAWIRQSTATUS 0x024
33 #define TSCADC_REG_IRQSTATUS 0x028
34 #define TSCADC_REG_IRQENABLE 0x02C
35 #define TSCADC_REG_IRQCLR 0x030
36 #define TSCADC_REG_IRQWAKEUP 0x034
37 #define TSCADC_REG_CTRL 0x040
38 #define TSCADC_REG_ADCFSM 0x044
39 #define TSCADC_REG_CLKDIV 0x04C
40 #define TSCADC_REG_SE 0x054
41 #define TSCADC_REG_IDLECONFIG 0x058
42 #define TSCADC_REG_CHARGECONFIG 0x05C
43 #define TSCADC_REG_CHARGEDELAY 0x060
44 #define TSCADC_REG_STEPCONFIG(n) (0x64 + ((n-1) * 8))
45 #define TSCADC_REG_STEPDELAY(n) (0x68 + ((n-1) * 8))
46 #define TSCADC_REG_STEPCONFIG13 0x0C4
47 #define TSCADC_REG_STEPDELAY13 0x0C8
48 #define TSCADC_REG_STEPCONFIG14 0x0CC
49 #define TSCADC_REG_STEPDELAY14 0x0D0
50 #define TSCADC_REG_FIFO0CNT 0xE4
51 #define TSCADC_REG_FIFO0THR 0xE8
52 #define TSCADC_REG_FIFO1CNT 0xF0
53 #define TSCADC_REG_FIFO1THR 0xF4
54 #define TSCADC_REG_FIFO0 0x100
55 #define TSCADC_REG_FIFO1 0x200
57 /* Register Bitfields */
58 #define TSCADC_IRQWKUP_ENB BIT(0)
59 #define TSCADC_IRQWKUP_DISABLE 0x00
60 #define TSCADC_STPENB_STEPENB 0x7FFF
61 #define TSCADC_IRQENB_FIFO0THRES BIT(2)
62 #define TSCADC_IRQENB_FIFO1THRES BIT(5)
63 #define TSCADC_IRQENB_PENUP BIT(9)
64 #define TSCADC_IRQENB_HW_PEN BIT(0)
65 #define TSCADC_STEPCONFIG_MODE_HWSYNC 0x2
66 #define TSCADC_STEPCONFIG_2SAMPLES_AVG (1 << 4)
67 #define TSCADC_STEPCONFIG_XPP BIT(5)
68 #define TSCADC_STEPCONFIG_XNN BIT(6)
69 #define TSCADC_STEPCONFIG_YPP BIT(7)
70 #define TSCADC_STEPCONFIG_YNN BIT(8)
71 #define TSCADC_STEPCONFIG_XNP BIT(9)
72 #define TSCADC_STEPCONFIG_YPN BIT(10)
73 #define TSCADC_STEPCONFIG_RFP (1 << 12)
74 #define TSCADC_STEPCONFIG_INM (1 << 18)
75 #define TSCADC_STEPCONFIG_INP_4 (1 << 19)
76 #define TSCADC_STEPCONFIG_INP (1 << 20)
77 #define TSCADC_STEPCONFIG_INP_5 (1 << 21)
78 #define TSCADC_STEPCONFIG_FIFO1 (1 << 26)
79 #define TSCADC_STEPCONFIG_IDLE_INP (1 << 22)
80 #define TSCADC_STEPCONFIG_OPENDLY 0x018
81 #define TSCADC_STEPCONFIG_SAMPLEDLY 0x88
82 #define TSCADC_STEPCONFIG_Z1 (3 << 19)
83 #define TSCADC_STEPCHARGE_INM_SWAP BIT(16)
84 #define TSCADC_STEPCHARGE_INM BIT(15)
85 #define TSCADC_STEPCHARGE_INP_SWAP BIT(20)
86 #define TSCADC_STEPCHARGE_INP BIT(19)
87 #define TSCADC_STEPCHARGE_RFM (1 << 23)
88 #define TSCADC_STEPCHARGE_DELAY 0x1
89 #define TSCADC_CNTRLREG_TSCSSENB BIT(0)
90 #define TSCADC_CNTRLREG_STEPID BIT(1)
91 #define TSCADC_CNTRLREG_STEPCONFIGWRT BIT(2)
92 #define TSCADC_CNTRLREG_POWERDOWN BIT(4)
93 #define TSCADC_CNTRLREG_TSCENB BIT(7)
94 #define TSCADC_CNTRLREG_4WIRE (0x1 << 5)
95 #define TSCADC_CNTRLREG_5WIRE (0x1 << 6)
96 #define TSCADC_CNTRLREG_8WIRE (0x3 << 5)
97 #define TSCADC_ADCFSM_STEPID 0x10
98 #define TSCADC_ADCFSM_FSM BIT(5)
100 #define ADC_CLK 3000000
102 #define MAX_12BIT ((1 << 12) - 1)
104 int pen = 1;
105 unsigned int bckup_x = 0, bckup_y = 0;
107 struct tscadc {
108 struct input_dev *input;
109 int wires;
110 int x_plate_resistance;
111 int irq;
112 void __iomem *tsc_base;
113 unsigned int ctrl;
114 };
116 static unsigned int tscadc_readl(struct tscadc *ts, unsigned int reg)
117 {
118 return readl(ts->tsc_base + reg);
119 }
121 static void tscadc_writel(struct tscadc *tsc, unsigned int reg,
122 unsigned int val)
123 {
124 writel(val, tsc->tsc_base + reg);
125 }
127 static void tsc_step_config(struct tscadc *ts_dev)
128 {
129 unsigned int stepconfigx = 0, stepconfigy = 0;
130 unsigned int delay, chargeconfig = 0;
131 unsigned int stepconfigz1 = 0, stepconfigz2 = 0;
132 int i;
134 /* Configure the Step registers */
136 delay = TSCADC_STEPCONFIG_SAMPLEDLY | TSCADC_STEPCONFIG_OPENDLY;
138 stepconfigx = TSCADC_STEPCONFIG_MODE_HWSYNC |
139 TSCADC_STEPCONFIG_2SAMPLES_AVG | TSCADC_STEPCONFIG_XPP;
141 switch (ts_dev->wires) {
142 case 4:
143 stepconfigx |= TSCADC_STEPCONFIG_INP |
144 TSCADC_STEPCONFIG_XNN;
145 break;
146 case 5:
147 stepconfigx |= TSCADC_STEPCONFIG_YNN |
148 TSCADC_STEPCONFIG_INP_5 | TSCADC_STEPCONFIG_XNN |
149 TSCADC_STEPCONFIG_YPP;
150 break;
151 case 8:
152 stepconfigx |= TSCADC_STEPCONFIG_INP |
153 TSCADC_STEPCONFIG_XNN;
154 break;
155 }
157 for (i = 1; i < 7; i++) {
158 tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG(i), stepconfigx);
159 tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY(i), delay);
160 }
162 stepconfigy = TSCADC_STEPCONFIG_MODE_HWSYNC |
163 TSCADC_STEPCONFIG_2SAMPLES_AVG | TSCADC_STEPCONFIG_YNN |
164 TSCADC_STEPCONFIG_INM | TSCADC_STEPCONFIG_FIFO1;
165 switch (ts_dev->wires) {
166 case 4:
167 stepconfigy |= TSCADC_STEPCONFIG_YPP;
168 break;
169 case 5:
170 stepconfigy |= TSCADC_STEPCONFIG_XPP | TSCADC_STEPCONFIG_INP_5 |
171 TSCADC_STEPCONFIG_XNP | TSCADC_STEPCONFIG_YPN;
172 break;
173 case 8:
174 stepconfigy |= TSCADC_STEPCONFIG_YPP;
175 break;
176 }
178 for (i = 7; i < 13; i++) {
179 tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG(i), stepconfigy);
180 tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY(i), delay);
181 }
183 chargeconfig = TSCADC_STEPCONFIG_XPP | TSCADC_STEPCONFIG_YNN |
184 TSCADC_STEPCONFIG_RFP | TSCADC_STEPCHARGE_RFM |
185 TSCADC_STEPCHARGE_INM | TSCADC_STEPCHARGE_INP;
186 tscadc_writel(ts_dev, TSCADC_REG_CHARGECONFIG, chargeconfig);
187 tscadc_writel(ts_dev, TSCADC_REG_CHARGEDELAY, TSCADC_STEPCHARGE_DELAY);
189 /* Configure to calculate pressure */
190 stepconfigz1 = TSCADC_STEPCONFIG_MODE_HWSYNC |
191 TSCADC_STEPCONFIG_2SAMPLES_AVG |
192 TSCADC_STEPCONFIG_XNP |
193 TSCADC_STEPCONFIG_YPN | TSCADC_STEPCONFIG_INM;
194 stepconfigz2 = stepconfigz1 | TSCADC_STEPCONFIG_Z1 |
195 TSCADC_STEPCONFIG_FIFO1;
196 tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG13, stepconfigz1);
197 tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY13, delay);
198 tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG14, stepconfigz2);
199 tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY14, delay);
201 tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
202 }
204 static void tsc_idle_config(struct tscadc *ts_config)
205 {
206 /* Idle mode touch screen config */
207 unsigned int idleconfig;
209 idleconfig = TSCADC_STEPCONFIG_YNN | TSCADC_STEPCONFIG_INM |
210 TSCADC_STEPCONFIG_IDLE_INP | TSCADC_STEPCONFIG_YPN;
212 tscadc_writel(ts_config, TSCADC_REG_IDLECONFIG, idleconfig);
213 }
215 static irqreturn_t tscadc_interrupt(int irq, void *dev)
216 {
217 struct tscadc *ts_dev = (struct tscadc *)dev;
218 struct input_dev *input_dev = ts_dev->input;
219 unsigned int status, irqclr = 0;
220 int i;
221 int fsm = 0, fifo0count = 0, fifo1count = 0;
222 unsigned int readx1 = 0, ready1 = 0;
223 unsigned int prev_val_x = ~0, prev_val_y = ~0;
224 unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
225 unsigned int cur_diff_x = 0, cur_diff_y = 0;
226 unsigned int val_x = 0, val_y = 0, diffx = 0, diffy = 0;
227 unsigned int z1 = 0, z2 = 0, z = 0;
229 status = tscadc_readl(ts_dev, TSCADC_REG_IRQSTATUS);
231 if (status & TSCADC_IRQENB_FIFO1THRES) {
232 fifo0count = tscadc_readl(ts_dev, TSCADC_REG_FIFO0CNT);
233 fifo1count = tscadc_readl(ts_dev, TSCADC_REG_FIFO1CNT);
234 for (i = 0; i < (fifo0count-1); i++) {
235 readx1 = tscadc_readl(ts_dev, TSCADC_REG_FIFO0);
236 readx1 = readx1 & 0xfff;
237 if (readx1 > prev_val_x)
238 cur_diff_x = readx1 - prev_val_x;
239 else
240 cur_diff_x = prev_val_x - readx1;
242 if (cur_diff_x < prev_diff_x) {
243 prev_diff_x = cur_diff_x;
244 val_x = readx1;
245 }
247 prev_val_x = readx1;
248 ready1 = tscadc_readl(ts_dev, TSCADC_REG_FIFO1);
249 ready1 &= 0xfff;
250 if (ready1 > prev_val_y)
251 cur_diff_y = ready1 - prev_val_y;
252 else
253 cur_diff_y = prev_val_y - ready1;
255 if (cur_diff_y < prev_diff_y) {
256 prev_diff_y = cur_diff_y;
257 val_y = ready1;
258 }
260 prev_val_y = ready1;
261 }
263 if (val_x > bckup_x) {
264 diffx = val_x - bckup_x;
265 diffy = val_y - bckup_y;
266 } else {
267 diffx = bckup_x - val_x;
268 diffy = bckup_y - val_y;
269 }
270 bckup_x = val_x;
271 bckup_y = val_y;
273 z1 = ((tscadc_readl(ts_dev, TSCADC_REG_FIFO0)) & 0xfff);
274 z2 = ((tscadc_readl(ts_dev, TSCADC_REG_FIFO1)) & 0xfff);
276 if ((z1 != 0) && (z2 != 0)) {
277 /*
278 * cal pressure using formula
279 * Resistance(touch) = x plate resistance *
280 * x postion/4096 * ((z2 / z1) - 1)
281 */
282 z = z2 - z1;
283 z *= val_x;
284 z *= ts_dev->x_plate_resistance;
285 z /= z1;
286 z = (z + 2047) >> 12;
288 /*
289 * Sample found inconsistent by debouncing
290 * or pressure is beyond the maximum.
291 * Don't report it to user space.
292 */
293 if (pen == 0) {
294 if ((diffx < 15) && (diffy < 15)
295 && (z <= MAX_12BIT)) {
296 input_report_abs(input_dev, ABS_X,
297 val_x);
298 input_report_abs(input_dev, ABS_Y,
299 val_y);
300 input_report_abs(input_dev, ABS_PRESSURE,
301 z);
302 input_report_key(input_dev, BTN_TOUCH,
303 1);
304 input_sync(input_dev);
305 }
306 }
307 }
308 irqclr |= TSCADC_IRQENB_FIFO1THRES;
309 }
311 udelay(315);
313 status = tscadc_readl(ts_dev, TSCADC_REG_RAWIRQSTATUS);
314 if (status & TSCADC_IRQENB_PENUP) {
315 /* Pen up event */
316 fsm = tscadc_readl(ts_dev, TSCADC_REG_ADCFSM);
317 if (fsm == 0x10) {
318 pen = 1;
319 bckup_x = 0;
320 bckup_y = 0;
321 input_report_key(input_dev, BTN_TOUCH, 0);
322 input_report_abs(input_dev, ABS_PRESSURE, 0);
323 input_sync(input_dev);
324 } else {
325 pen = 0;
326 }
327 irqclr |= TSCADC_IRQENB_PENUP;
328 }
329 irqclr |= TSCADC_IRQENB_HW_PEN;
331 tscadc_writel(ts_dev, TSCADC_REG_IRQSTATUS, irqclr);
333 /* check pending interrupts */
334 tscadc_writel(ts_dev, TSCADC_REG_IRQEOI, 0x0);
336 tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
337 return IRQ_HANDLED;
338 }
340 /*
341 * The functions for inserting/removing driver as a module.
342 */
344 static int __devinit tscadc_probe(struct platform_device *pdev)
345 {
346 struct tscadc *ts_dev;
347 struct input_dev *input_dev;
348 int err;
349 int clk_value;
350 int clock_rate, irqenable, ctrl;
351 struct tsc_data *pdata = pdev->dev.platform_data;
352 struct resource *res;
353 struct clk *clk;
355 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
356 if (!res) {
357 dev_err(&pdev->dev, "no memory resource defined.\n");
358 return -EINVAL;
359 }
361 /* Allocate memory for device */
362 ts_dev = kzalloc(sizeof(struct tscadc), GFP_KERNEL);
363 if (!ts_dev) {
364 dev_err(&pdev->dev, "failed to allocate memory.\n");
365 return -ENOMEM;
366 }
368 ts_dev->irq = platform_get_irq(pdev, 0);
369 if (ts_dev->irq < 0) {
370 dev_err(&pdev->dev, "no irq ID is specified.\n");
371 return -ENODEV;
372 }
374 input_dev = input_allocate_device();
375 if (!input_dev) {
376 dev_err(&pdev->dev, "failed to allocate input device.\n");
377 err = -ENOMEM;
378 goto err_free_mem;
379 }
380 ts_dev->input = input_dev;
382 res = request_mem_region(res->start, resource_size(res), pdev->name);
383 if (!res) {
384 dev_err(&pdev->dev, "failed to reserve registers.\n");
385 err = -EBUSY;
386 goto err_free_mem;
387 }
389 ts_dev->tsc_base = ioremap(res->start, resource_size(res));
390 if (!ts_dev->tsc_base) {
391 dev_err(&pdev->dev, "failed to map registers.\n");
392 err = -ENOMEM;
393 goto err_release_mem;
394 }
396 err = request_irq(ts_dev->irq, tscadc_interrupt, IRQF_DISABLED,
397 pdev->dev.driver->name, ts_dev);
398 if (err) {
399 dev_err(&pdev->dev, "failed to allocate irq.\n");
400 goto err_unmap_regs;
401 }
403 pm_runtime_enable(&pdev->dev);
404 pm_runtime_get_sync(&pdev->dev);
406 clk = clk_get(&pdev->dev, "adc_tsc_fck");
407 if (IS_ERR(clk)) {
408 dev_err(&pdev->dev, "failed to get TSC fck\n");
409 err = PTR_ERR(clk);
410 goto err_free_irq;
411 }
412 clock_rate = clk_get_rate(clk);
413 clk_put(clk);
414 clk_value = clock_rate / ADC_CLK;
415 if (clk_value < 7) {
416 dev_err(&pdev->dev, "clock input less than min clock requirement\n");
417 err = -EINVAL;
418 goto err_fail;
419 }
420 /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
421 clk_value = clk_value - 1;
422 tscadc_writel(ts_dev, TSCADC_REG_CLKDIV, clk_value);
424 ts_dev->wires = pdata->wires;
425 ts_dev->x_plate_resistance = pdata->x_plate_resistance;
427 /* Set the control register bits */
428 ctrl = TSCADC_CNTRLREG_STEPCONFIGWRT |
429 TSCADC_CNTRLREG_TSCENB |
430 TSCADC_CNTRLREG_STEPID;
431 switch (ts_dev->wires) {
432 case 4:
433 ctrl |= TSCADC_CNTRLREG_4WIRE;
434 break;
435 case 5:
436 ctrl |= TSCADC_CNTRLREG_5WIRE;
437 break;
438 case 8:
439 ctrl |= TSCADC_CNTRLREG_8WIRE;
440 break;
441 }
442 tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
443 ts_dev->ctrl = ctrl;
445 /* Set register bits for Idel Config Mode */
446 tsc_idle_config(ts_dev);
448 /* IRQ Enable */
449 irqenable = TSCADC_IRQENB_FIFO1THRES;
450 tscadc_writel(ts_dev, TSCADC_REG_IRQENABLE, irqenable);
452 tsc_step_config(ts_dev);
454 tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
456 ctrl |= TSCADC_CNTRLREG_TSCSSENB;
457 tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
459 input_dev->name = "ti-tsc-adcc";
460 input_dev->dev.parent = &pdev->dev;
462 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
463 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
465 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
466 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
467 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
469 /* register to the input system */
470 err = input_register_device(input_dev);
471 if (err)
472 goto err_fail;
474 device_init_wakeup(&pdev->dev, true);
475 platform_set_drvdata(pdev, ts_dev);
476 return 0;
478 err_fail:
479 pm_runtime_put_sync(&pdev->dev);
480 pm_runtime_disable(&pdev->dev);
481 err_free_irq:
482 free_irq(ts_dev->irq, ts_dev);
483 err_unmap_regs:
484 iounmap(ts_dev->tsc_base);
485 err_release_mem:
486 release_mem_region(res->start, resource_size(res));
487 input_free_device(ts_dev->input);
488 err_free_mem:
489 platform_set_drvdata(pdev, NULL);
490 kfree(ts_dev);
491 return err;
492 }
494 static int __devexit tscadc_remove(struct platform_device *pdev)
495 {
496 struct tscadc *ts_dev = platform_get_drvdata(pdev);
497 struct resource *res;
499 tscadc_writel(ts_dev, TSCADC_REG_SE, 0x00);
500 free_irq(ts_dev->irq, ts_dev);
502 input_unregister_device(ts_dev->input);
504 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
505 iounmap(ts_dev->tsc_base);
506 release_mem_region(res->start, resource_size(res));
508 pm_runtime_put_sync(&pdev->dev);
509 pm_runtime_disable(&pdev->dev);
511 kfree(ts_dev);
513 device_init_wakeup(&pdev->dev, 0);
514 platform_set_drvdata(pdev, NULL);
515 return 0;
516 }
518 static int tscadc_suspend(struct platform_device *pdev, pm_message_t state)
519 {
520 struct tscadc *ts_dev = platform_get_drvdata(pdev);
521 unsigned int idle;
523 if (device_may_wakeup(&pdev->dev)) {
524 idle = tscadc_readl(ts_dev, TSCADC_REG_IRQENABLE);
525 tscadc_writel(ts_dev, TSCADC_REG_IRQENABLE,
526 (idle | TSCADC_IRQENB_HW_PEN));
527 tscadc_writel(ts_dev, TSCADC_REG_SE, 0x00);
528 tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP, TSCADC_IRQWKUP_ENB);
529 } else {
530 /* module disable */
531 idle = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
532 idle &= ~(TSCADC_CNTRLREG_TSCSSENB);
533 tscadc_writel(ts_dev, TSCADC_REG_CTRL, (idle |
534 TSCADC_CNTRLREG_POWERDOWN));
535 }
537 pm_runtime_put_sync(&pdev->dev);
539 return 0;
541 }
543 static int tscadc_resume(struct platform_device *pdev)
544 {
545 struct tscadc *ts_dev = platform_get_drvdata(pdev);
546 unsigned int restore;
548 pm_runtime_get_sync(&pdev->dev);
550 if (device_may_wakeup(&pdev->dev)) {
551 tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP,
552 TSCADC_IRQWKUP_DISABLE);
553 tscadc_writel(ts_dev, TSCADC_REG_IRQCLR, TSCADC_IRQENB_HW_PEN);
554 }
556 /* context restore */
557 tscadc_writel(ts_dev, TSCADC_REG_CTRL, ts_dev->ctrl);
558 /* Make sure ADC is powered up */
559 restore = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
560 restore &= ~(TSCADC_CNTRLREG_POWERDOWN);
561 tscadc_writel(ts_dev, TSCADC_REG_CTRL, restore);
562 tsc_idle_config(ts_dev);
563 tsc_step_config(ts_dev);
564 tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
565 restore = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
566 tscadc_writel(ts_dev, TSCADC_REG_CTRL,
567 (restore | TSCADC_CNTRLREG_TSCSSENB));
569 return 0;
570 }
572 static struct platform_driver ti_tsc_driver = {
573 .probe = tscadc_probe,
574 .remove = __devexit_p(tscadc_remove),
575 .driver = {
576 .name = "tsc",
577 .owner = THIS_MODULE,
578 },
579 .suspend = tscadc_suspend,
580 .resume = tscadc_resume,
581 };
583 static int __init ti_tsc_init(void)
584 {
585 return platform_driver_register(&ti_tsc_driver);
586 }
587 module_init(ti_tsc_init);
589 static void __exit ti_tsc_exit(void)
590 {
591 platform_driver_unregister(&ti_tsc_driver);
592 }
593 module_exit(ti_tsc_exit);
595 MODULE_DESCRIPTION("TI touchscreen controller driver");
596 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
597 MODULE_LICENSE("GPL");