]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/input/touchscreen/ti_am335x_tsc.c
Merge tag 'riscv-for-linus-4.19-mw0' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-eoan-kernel.git] / drivers / input / touchscreen / ti_am335x_tsc.c
CommitLineData
1b8be32e
RP
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 */
15
16
1b8be32e
RP
17#include <linux/kernel.h>
18#include <linux/err.h>
19#include <linux/module.h>
20#include <linux/input.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
23#include <linux/clk.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
1b8be32e 26#include <linux/delay.h>
0396310b
PR
27#include <linux/of.h>
28#include <linux/of_device.h>
83edfdf3 29#include <linux/sort.h>
1b8be32e 30
2b99bafa 31#include <linux/mfd/ti_am335x_tscadc.h>
33f5cc60
PR
32
33#define ADCFSM_STEPID 0x10
1b8be32e 34#define SEQ_SETTLE 275
1b8be32e 35#define MAX_12BIT ((1 << 12) - 1)
1b8be32e 36
46850420
GS
37#define TSC_IRQENB_MASK (IRQENB_FIFO0THRES | IRQENB_EOS | IRQENB_HW_PEN)
38
bb76dc09
PR
39static const int config_pins[] = {
40 STEPCONFIG_XPP,
41 STEPCONFIG_XNN,
42 STEPCONFIG_YPP,
43 STEPCONFIG_YNN,
44};
45
55c04de5 46struct titsc {
1b8be32e 47 struct input_dev *input;
2b99bafa 48 struct ti_tscadc_dev *mfd_tscadc;
1b8be32e
RP
49 unsigned int irq;
50 unsigned int wires;
51 unsigned int x_plate_resistance;
52 bool pen_down;
0396310b 53 int coordinate_readouts;
bb76dc09
PR
54 u32 config_inp[4];
55 u32 bit_xp, bit_xn, bit_yp, bit_yn;
56 u32 inp_xp, inp_xn, inp_yp, inp_yn;
baee5399 57 u32 step_mask;
bf223612 58 u32 charge_delay;
1b8be32e
RP
59};
60
55c04de5 61static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
1b8be32e 62{
2b99bafa 63 return readl(ts->mfd_tscadc->tscadc_base + reg);
1b8be32e
RP
64}
65
55c04de5 66static void titsc_writel(struct titsc *tsc, unsigned int reg,
1b8be32e
RP
67 unsigned int val)
68{
2b99bafa 69 writel(val, tsc->mfd_tscadc->tscadc_base + reg);
1b8be32e
RP
70}
71
bb76dc09
PR
72static int titsc_config_wires(struct titsc *ts_dev)
73{
74 u32 analog_line[4];
75 u32 wire_order[4];
76 int i, bit_cfg;
77
78 for (i = 0; i < 4; i++) {
79 /*
80 * Get the order in which TSC wires are attached
81 * w.r.t. each of the analog input lines on the EVM.
82 */
83 analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4;
84 wire_order[i] = ts_dev->config_inp[i] & 0x0F;
85 if (WARN_ON(analog_line[i] > 7))
86 return -EINVAL;
87 if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins)))
88 return -EINVAL;
89 }
90
91 for (i = 0; i < 4; i++) {
92 int an_line;
93 int wi_order;
94
95 an_line = analog_line[i];
96 wi_order = wire_order[i];
97 bit_cfg = config_pins[wi_order];
98 if (bit_cfg == 0)
99 return -EINVAL;
100 switch (wi_order) {
101 case 0:
102 ts_dev->bit_xp = bit_cfg;
103 ts_dev->inp_xp = an_line;
104 break;
105
106 case 1:
107 ts_dev->bit_xn = bit_cfg;
108 ts_dev->inp_xn = an_line;
109 break;
110
111 case 2:
112 ts_dev->bit_yp = bit_cfg;
113 ts_dev->inp_yp = an_line;
114 break;
115 case 3:
116 ts_dev->bit_yn = bit_cfg;
117 ts_dev->inp_yn = an_line;
118 break;
119 }
120 }
121 return 0;
122}
123
55c04de5 124static void titsc_step_config(struct titsc *ts_dev)
1b8be32e
RP
125{
126 unsigned int config;
8c896308 127 int i;
3a59684c 128 int end_step, first_step, tsc_steps;
8c896308 129 u32 stepenable;
1b8be32e
RP
130
131 config = STEPCONFIG_MODE_HWSYNC |
bb76dc09 132 STEPCONFIG_AVG_16 | ts_dev->bit_xp;
1b8be32e
RP
133 switch (ts_dev->wires) {
134 case 4:
bb76dc09 135 config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
1b8be32e
RP
136 break;
137 case 5:
bb76dc09
PR
138 config |= ts_dev->bit_yn |
139 STEPCONFIG_INP_AN4 | ts_dev->bit_xn |
140 ts_dev->bit_yp;
1b8be32e
RP
141 break;
142 case 8:
bb76dc09 143 config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
1b8be32e
RP
144 break;
145 }
146
3a59684c
BG
147 tsc_steps = ts_dev->coordinate_readouts * 2 + 2;
148 first_step = TOTAL_STEPS - tsc_steps;
149 /* Steps 16 to 16-coordinate_readouts is for X */
150 end_step = first_step + tsc_steps;
151 for (i = end_step - ts_dev->coordinate_readouts; i < end_step; i++) {
55c04de5
PR
152 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
153 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
1b8be32e
RP
154 }
155
156 config = 0;
157 config = STEPCONFIG_MODE_HWSYNC |
bb76dc09 158 STEPCONFIG_AVG_16 | ts_dev->bit_yn |
8c896308 159 STEPCONFIG_INM_ADCREFM;
1b8be32e
RP
160 switch (ts_dev->wires) {
161 case 4:
bb76dc09 162 config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
1b8be32e
RP
163 break;
164 case 5:
bb76dc09 165 config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
cf5dd489 166 STEPCONFIG_XNP | STEPCONFIG_YPN;
1b8be32e
RP
167 break;
168 case 8:
bb76dc09 169 config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
1b8be32e
RP
170 break;
171 }
172
3a59684c
BG
173 /* 1 ... coordinate_readouts is for Y */
174 end_step = first_step + ts_dev->coordinate_readouts;
175 for (i = first_step; i < end_step; i++) {
55c04de5
PR
176 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
177 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
1b8be32e
RP
178 }
179
344d635b 180 /* Make CHARGECONFIG same as IDLECONFIG */
1b8be32e 181
344d635b 182 config = titsc_readl(ts_dev, REG_IDLECONFIG);
55c04de5 183 titsc_writel(ts_dev, REG_CHARGECONFIG, config);
bf223612 184 titsc_writel(ts_dev, REG_CHARGEDELAY, ts_dev->charge_delay);
1b8be32e 185
3a59684c 186 /* coordinate_readouts + 1 ... coordinate_readouts + 2 is for Z */
1b8be32e 187 config = STEPCONFIG_MODE_HWSYNC |
bb76dc09
PR
188 STEPCONFIG_AVG_16 | ts_dev->bit_yp |
189 ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
190 STEPCONFIG_INP(ts_dev->inp_xp);
8c896308
SAS
191 titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
192 titsc_writel(ts_dev, REG_STEPDELAY(end_step),
d1fb5743 193 STEPCONFIG_OPENDLY);
1b8be32e 194
8c896308
SAS
195 end_step++;
196 config |= STEPCONFIG_INP(ts_dev->inp_yn);
197 titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
198 titsc_writel(ts_dev, REG_STEPDELAY(end_step),
d1fb5743 199 STEPCONFIG_OPENDLY);
1b8be32e 200
3a59684c
BG
201 /* The steps end ... end - readouts * 2 + 2 and bit 0 for TS_Charge */
202 stepenable = 1;
203 for (i = 0; i < tsc_steps; i++)
204 stepenable |= 1 << (first_step + i + 1);
205
baee5399 206 ts_dev->step_mask = stepenable;
7e170c6e 207 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
1b8be32e
RP
208}
209
83edfdf3
V
210static int titsc_cmp_coord(const void *a, const void *b)
211{
212 return *(int *)a - *(int *)b;
213}
214
55c04de5 215static void titsc_read_coordinates(struct titsc *ts_dev,
8c896308 216 u32 *x, u32 *y, u32 *z1, u32 *z2)
1b8be32e 217{
83edfdf3
V
218 unsigned int yvals[7], xvals[7];
219 unsigned int i, xsum = 0, ysum = 0;
8c896308 220 unsigned int creads = ts_dev->coordinate_readouts;
1b8be32e 221
83edfdf3
V
222 for (i = 0; i < creads; i++) {
223 yvals[i] = titsc_readl(ts_dev, REG_FIFO0);
224 yvals[i] &= 0xfff;
225 }
1b8be32e 226
83edfdf3
V
227 *z1 = titsc_readl(ts_dev, REG_FIFO0);
228 *z1 &= 0xfff;
229 *z2 = titsc_readl(ts_dev, REG_FIFO0);
230 *z2 &= 0xfff;
3a59684c 231
83edfdf3
V
232 for (i = 0; i < creads; i++) {
233 xvals[i] = titsc_readl(ts_dev, REG_FIFO0);
234 xvals[i] &= 0xfff;
235 }
3a59684c 236
83edfdf3
V
237 /*
238 * If co-ordinates readouts is less than 4 then
239 * report the average. In case of 4 or more
240 * readouts, sort the co-ordinate samples, drop
241 * min and max values and report the average of
242 * remaining values.
243 */
244 if (creads <= 3) {
245 for (i = 0; i < creads; i++) {
246 ysum += yvals[i];
247 xsum += xvals[i];
1b8be32e 248 }
83edfdf3
V
249 ysum /= creads;
250 xsum /= creads;
251 } else {
252 sort(yvals, creads, sizeof(unsigned int),
253 titsc_cmp_coord, NULL);
254 sort(xvals, creads, sizeof(unsigned int),
255 titsc_cmp_coord, NULL);
256 for (i = 1; i < creads - 1; i++) {
257 ysum += yvals[i];
258 xsum += xvals[i];
259 }
260 ysum /= creads - 2;
261 xsum /= creads - 2;
1b8be32e 262 }
83edfdf3
V
263 *y = ysum;
264 *x = xsum;
1b8be32e
RP
265}
266
55c04de5 267static irqreturn_t titsc_irq(int irq, void *dev)
1b8be32e 268{
55c04de5 269 struct titsc *ts_dev = dev;
1b8be32e 270 struct input_dev *input_dev = ts_dev->input;
344d635b 271 unsigned int fsm, status, irqclr = 0;
1b8be32e
RP
272 unsigned int x = 0, y = 0;
273 unsigned int z1, z2, z;
1b8be32e 274
344d635b
BG
275 status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);
276 if (status & IRQENB_HW_PEN) {
277 ts_dev->pen_down = true;
344d635b 278 irqclr |= IRQENB_HW_PEN;
22a844b8 279 pm_stay_awake(ts_dev->mfd_tscadc->dev);
344d635b
BG
280 }
281
282 if (status & IRQENB_PENUP) {
283 fsm = titsc_readl(ts_dev, REG_ADCFSM);
284 if (fsm == ADCFSM_STEPID) {
285 ts_dev->pen_down = false;
286 input_report_key(input_dev, BTN_TOUCH, 0);
287 input_report_abs(input_dev, ABS_PRESSURE, 0);
288 input_sync(input_dev);
22a844b8 289 pm_relax(ts_dev->mfd_tscadc->dev);
344d635b
BG
290 } else {
291 ts_dev->pen_down = true;
292 }
293 irqclr |= IRQENB_PENUP;
294 }
295
296 if (status & IRQENB_EOS)
297 irqclr |= IRQENB_EOS;
298
baee5399
ZL
299 /*
300 * ADC and touchscreen share the IRQ line.
301 * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only
302 */
30af55f9 303 if (status & IRQENB_FIFO0THRES) {
1b8be32e 304
8c896308 305 titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
2b99bafa 306
1b8be32e
RP
307 if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
308 /*
309 * Calculate pressure using formula
310 * Resistance(touch) = x plate resistance *
311 * x postion/4096 * ((z2 / z1) - 1)
312 */
8c896308 313 z = z1 - z2;
1b8be32e
RP
314 z *= x;
315 z *= ts_dev->x_plate_resistance;
8c896308 316 z /= z2;
1b8be32e
RP
317 z = (z + 2047) >> 12;
318
319 if (z <= MAX_12BIT) {
320 input_report_abs(input_dev, ABS_X, x);
321 input_report_abs(input_dev, ABS_Y, y);
322 input_report_abs(input_dev, ABS_PRESSURE, z);
323 input_report_key(input_dev, BTN_TOUCH, 1);
324 input_sync(input_dev);
325 }
326 }
30af55f9 327 irqclr |= IRQENB_FIFO0THRES;
1b8be32e 328 }
9a28b883
SAS
329 if (irqclr) {
330 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
344d635b
BG
331 if (status & IRQENB_EOS)
332 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc,
333 ts_dev->step_mask);
9a28b883
SAS
334 return IRQ_HANDLED;
335 }
336 return IRQ_NONE;
1b8be32e
RP
337}
338
0396310b
PR
339static int titsc_parse_dt(struct platform_device *pdev,
340 struct titsc *ts_dev)
341{
342 struct device_node *node = pdev->dev.of_node;
343 int err;
344
345 if (!node)
346 return -EINVAL;
347
348 err = of_property_read_u32(node, "ti,wires", &ts_dev->wires);
349 if (err < 0)
350 return err;
351 switch (ts_dev->wires) {
352 case 4:
353 case 5:
354 case 8:
355 break;
356 default:
357 return -EINVAL;
358 }
359
360 err = of_property_read_u32(node, "ti,x-plate-resistance",
361 &ts_dev->x_plate_resistance);
362 if (err < 0)
363 return err;
364
c9aeb249
FB
365 /*
366 * Try with the new binding first. If it fails, try again with
367 * bogus, miss-spelled version.
368 */
369 err = of_property_read_u32(node, "ti,coordinate-readouts",
0396310b 370 &ts_dev->coordinate_readouts);
31972f6e
FB
371 if (err < 0) {
372 dev_warn(&pdev->dev, "please use 'ti,coordinate-readouts' instead\n");
c9aeb249
FB
373 err = of_property_read_u32(node, "ti,coordiante-readouts",
374 &ts_dev->coordinate_readouts);
31972f6e
FB
375 }
376
0396310b
PR
377 if (err < 0)
378 return err;
379
83edfdf3
V
380 if (ts_dev->coordinate_readouts <= 0) {
381 dev_warn(&pdev->dev,
382 "invalid co-ordinate readouts, resetting it to 5\n");
383 ts_dev->coordinate_readouts = 5;
384 }
385
bf223612
V
386 err = of_property_read_u32(node, "ti,charge-delay",
387 &ts_dev->charge_delay);
388 /*
389 * If ti,charge-delay value is not specified, then use
390 * CHARGEDLY_OPENDLY as the default value.
391 */
392 if (err < 0) {
393 ts_dev->charge_delay = CHARGEDLY_OPENDLY;
394 dev_warn(&pdev->dev, "ti,charge-delay not specified\n");
395 }
396
0396310b
PR
397 return of_property_read_u32_array(node, "ti,wire-config",
398 ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp));
1b8be32e
RP
399}
400
401/*
402 * The functions for inserting/removing driver as a module.
403 */
404
31564cbd 405static int titsc_probe(struct platform_device *pdev)
1b8be32e 406{
55c04de5 407 struct titsc *ts_dev;
1b8be32e 408 struct input_dev *input_dev;
a9bce1b0 409 struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
1b8be32e 410 int err;
1b8be32e 411
1b8be32e 412 /* Allocate memory for device */
520d8267 413 ts_dev = kzalloc(sizeof(*ts_dev), GFP_KERNEL);
1b8be32e
RP
414 input_dev = input_allocate_device();
415 if (!ts_dev || !input_dev) {
416 dev_err(&pdev->dev, "failed to allocate memory.\n");
417 err = -ENOMEM;
418 goto err_free_mem;
419 }
420
2b99bafa
PR
421 tscadc_dev->tsc = ts_dev;
422 ts_dev->mfd_tscadc = tscadc_dev;
1b8be32e 423 ts_dev->input = input_dev;
2b99bafa 424 ts_dev->irq = tscadc_dev->irq;
0396310b 425
b9194fdf 426 err = titsc_parse_dt(pdev, ts_dev);
0396310b
PR
427 if (err) {
428 dev_err(&pdev->dev, "Could not find valid DT data.\n");
429 goto err_free_mem;
430 }
1b8be32e 431
55c04de5 432 err = request_irq(ts_dev->irq, titsc_irq,
baee5399 433 IRQF_SHARED, pdev->dev.driver->name, ts_dev);
1b8be32e
RP
434 if (err) {
435 dev_err(&pdev->dev, "failed to allocate irq.\n");
2b99bafa 436 goto err_free_mem;
1b8be32e 437 }
1b8be32e 438
46850420 439 titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK);
55c04de5 440 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
344d635b 441 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS);
bb76dc09
PR
442 err = titsc_config_wires(ts_dev);
443 if (err) {
444 dev_err(&pdev->dev, "wrong i/p wire configuration\n");
445 goto err_free_irq;
446 }
55c04de5 447 titsc_step_config(ts_dev);
8c896308
SAS
448 titsc_writel(ts_dev, REG_FIFO0THR,
449 ts_dev->coordinate_readouts * 2 + 2 - 1);
1b8be32e 450
2b99bafa 451 input_dev->name = "ti-tsc";
1b8be32e
RP
452 input_dev->dev.parent = &pdev->dev;
453
454 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
455 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
456
457 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
458 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
459 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
460
461 /* register to the input system */
462 err = input_register_device(input_dev);
463 if (err)
2b99bafa 464 goto err_free_irq;
1b8be32e
RP
465
466 platform_set_drvdata(pdev, ts_dev);
467 return 0;
468
1b8be32e
RP
469err_free_irq:
470 free_irq(ts_dev->irq, ts_dev);
1b8be32e
RP
471err_free_mem:
472 input_free_device(input_dev);
473 kfree(ts_dev);
474 return err;
475}
476
31564cbd 477static int titsc_remove(struct platform_device *pdev)
1b8be32e 478{
a9bce1b0
SAS
479 struct titsc *ts_dev = platform_get_drvdata(pdev);
480 u32 steps;
1b8be32e
RP
481
482 free_irq(ts_dev->irq, ts_dev);
483
abeccee4 484 /* total steps followed by the enable mask */
0396310b 485 steps = 2 * ts_dev->coordinate_readouts + 2;
abeccee4
PR
486 steps = (1 << steps) - 1;
487 am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps);
488
1b8be32e
RP
489 input_unregister_device(ts_dev->input);
490
2b99bafa
PR
491 kfree(ts_dev);
492 return 0;
493}
1b8be32e 494
20aa787e 495static int __maybe_unused titsc_suspend(struct device *dev)
2b99bafa 496{
a9bce1b0
SAS
497 struct titsc *ts_dev = dev_get_drvdata(dev);
498 struct ti_tscadc_dev *tscadc_dev;
2b99bafa
PR
499 unsigned int idle;
500
a9bce1b0 501 tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
2b99bafa 502 if (device_may_wakeup(tscadc_dev->dev)) {
46850420 503 titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK);
2b99bafa
PR
504 idle = titsc_readl(ts_dev, REG_IRQENABLE);
505 titsc_writel(ts_dev, REG_IRQENABLE,
506 (idle | IRQENB_HW_PEN));
507 titsc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
508 }
509 return 0;
510}
1b8be32e 511
20aa787e 512static int __maybe_unused titsc_resume(struct device *dev)
2b99bafa 513{
a9bce1b0
SAS
514 struct titsc *ts_dev = dev_get_drvdata(dev);
515 struct ti_tscadc_dev *tscadc_dev;
1b8be32e 516
a9bce1b0 517 tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
2b99bafa
PR
518 if (device_may_wakeup(tscadc_dev->dev)) {
519 titsc_writel(ts_dev, REG_IRQWAKEUP,
520 0x00);
521 titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
22a844b8 522 pm_relax(ts_dev->mfd_tscadc->dev);
2b99bafa
PR
523 }
524 titsc_step_config(ts_dev);
525 titsc_writel(ts_dev, REG_FIFO0THR,
8c896308 526 ts_dev->coordinate_readouts * 2 + 2 - 1);
1b8be32e
RP
527 return 0;
528}
529
20aa787e 530static SIMPLE_DEV_PM_OPS(titsc_pm_ops, titsc_suspend, titsc_resume);
2b99bafa 531
0396310b
PR
532static const struct of_device_id ti_tsc_dt_ids[] = {
533 { .compatible = "ti,am3359-tsc", },
534 { }
535};
536MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids);
537
1b8be32e 538static struct platform_driver ti_tsc_driver = {
55c04de5 539 .probe = titsc_probe,
31564cbd 540 .remove = titsc_remove,
1b8be32e 541 .driver = {
5f184e63 542 .name = "TI-am335x-tsc",
20aa787e 543 .pm = &titsc_pm_ops,
8e6146bf 544 .of_match_table = ti_tsc_dt_ids,
1b8be32e
RP
545 },
546};
547module_platform_driver(ti_tsc_driver);
548
549MODULE_DESCRIPTION("TI touchscreen controller driver");
550MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
551MODULE_LICENSE("GPL");