input: ti_am33x_tsc: Order of TSC wires, made configurable
[pandora-kernel.git] / drivers / input / touchscreen / ti_am335x_tsc.c
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
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_am335x_tsc.h>
28 #include <linux/delay.h>
29
30 #include <linux/mfd/ti_am335x_tscadc.h>
31
32 #define ADCFSM_STEPID           0x10
33 #define SEQ_SETTLE              275
34 #define MAX_12BIT               ((1 << 12) - 1)
35
36 static const int config_pins[] = {
37         STEPCONFIG_XPP,
38         STEPCONFIG_XNN,
39         STEPCONFIG_YPP,
40         STEPCONFIG_YNN,
41 };
42
43 struct titsc {
44         struct input_dev        *input;
45         struct ti_tscadc_dev    *mfd_tscadc;
46         unsigned int            irq;
47         unsigned int            wires;
48         unsigned int            x_plate_resistance;
49         bool                    pen_down;
50         int                     steps_to_configure;
51         u32                     config_inp[4];
52         u32                     bit_xp, bit_xn, bit_yp, bit_yn;
53         u32                     inp_xp, inp_xn, inp_yp, inp_yn;
54 };
55
56 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
57 {
58         return readl(ts->mfd_tscadc->tscadc_base + reg);
59 }
60
61 static void titsc_writel(struct titsc *tsc, unsigned int reg,
62                                         unsigned int val)
63 {
64         writel(val, tsc->mfd_tscadc->tscadc_base + reg);
65 }
66
67 static int titsc_config_wires(struct titsc *ts_dev)
68 {
69         u32 analog_line[4];
70         u32 wire_order[4];
71         int i, bit_cfg;
72
73         for (i = 0; i < 4; i++) {
74                 /*
75                  * Get the order in which TSC wires are attached
76                  * w.r.t. each of the analog input lines on the EVM.
77                  */
78                 analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4;
79                 wire_order[i] = ts_dev->config_inp[i] & 0x0F;
80                 if (WARN_ON(analog_line[i] > 7))
81                         return -EINVAL;
82                 if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins)))
83                         return -EINVAL;
84         }
85
86         for (i = 0; i < 4; i++) {
87                 int an_line;
88                 int wi_order;
89
90                 an_line = analog_line[i];
91                 wi_order = wire_order[i];
92                 bit_cfg = config_pins[wi_order];
93                 if (bit_cfg == 0)
94                         return -EINVAL;
95                 switch (wi_order) {
96                 case 0:
97                         ts_dev->bit_xp = bit_cfg;
98                         ts_dev->inp_xp = an_line;
99                         break;
100
101                 case 1:
102                         ts_dev->bit_xn = bit_cfg;
103                         ts_dev->inp_xn = an_line;
104                         break;
105
106                 case 2:
107                         ts_dev->bit_yp = bit_cfg;
108                         ts_dev->inp_yp = an_line;
109                         break;
110                 case 3:
111                         ts_dev->bit_yn = bit_cfg;
112                         ts_dev->inp_yn = an_line;
113                         break;
114                 }
115         }
116         return 0;
117 }
118
119 static void titsc_step_config(struct titsc *ts_dev)
120 {
121         unsigned int    config;
122         unsigned int    stepenable = 0;
123         int i, total_steps;
124
125         /* Configure the Step registers */
126         total_steps = 2 * ts_dev->steps_to_configure;
127
128         config = STEPCONFIG_MODE_HWSYNC |
129                         STEPCONFIG_AVG_16 | ts_dev->bit_xp;
130         switch (ts_dev->wires) {
131         case 4:
132                 config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
133                 break;
134         case 5:
135                 config |= ts_dev->bit_yn |
136                                 STEPCONFIG_INP_AN4 | ts_dev->bit_xn |
137                                 ts_dev->bit_yp;
138                 break;
139         case 8:
140                 config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
141                 break;
142         }
143
144         for (i = 1; i <= ts_dev->steps_to_configure; i++) {
145                 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
146                 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
147         }
148
149         config = 0;
150         config = STEPCONFIG_MODE_HWSYNC |
151                         STEPCONFIG_AVG_16 | ts_dev->bit_yn |
152                         STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
153         switch (ts_dev->wires) {
154         case 4:
155                 config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
156                 break;
157         case 5:
158                 config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
159                                 ts_dev->bit_xn | ts_dev->bit_yp;
160                 break;
161         case 8:
162                 config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
163                 break;
164         }
165
166         for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) {
167                 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
168                 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
169         }
170
171         config = 0;
172         /* Charge step configuration */
173         config = ts_dev->bit_xp | ts_dev->bit_yn |
174                         STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
175                         STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp);
176
177         titsc_writel(ts_dev, REG_CHARGECONFIG, config);
178         titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
179
180         config = 0;
181         /* Configure to calculate pressure */
182         config = STEPCONFIG_MODE_HWSYNC |
183                         STEPCONFIG_AVG_16 | ts_dev->bit_yp |
184                         ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
185                         STEPCONFIG_INP(ts_dev->inp_xp);
186         titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
187         titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
188                         STEPCONFIG_OPENDLY);
189
190         config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1;
191         titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
192         titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
193                         STEPCONFIG_OPENDLY);
194
195         /* The steps1 … end and bit 0 for TS_Charge */
196         stepenable = (1 << (total_steps + 2)) - 1;
197         am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
198 }
199
200 static void titsc_read_coordinates(struct titsc *ts_dev,
201                                     unsigned int *x, unsigned int *y)
202 {
203         unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
204         unsigned int prev_val_x = ~0, prev_val_y = ~0;
205         unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
206         unsigned int read, diff;
207         unsigned int i, channel;
208
209         /*
210          * Delta filter is used to remove large variations in sampled
211          * values from ADC. The filter tries to predict where the next
212          * coordinate could be. This is done by taking a previous
213          * coordinate and subtracting it form current one. Further the
214          * algorithm compares the difference with that of a present value,
215          * if true the value is reported to the sub system.
216          */
217         for (i = 0; i < fifocount - 1; i++) {
218                 read = titsc_readl(ts_dev, REG_FIFO0);
219                 channel = read & 0xf0000;
220                 channel = channel >> 0x10;
221                 if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) {
222                         read &= 0xfff;
223                         diff = abs(read - prev_val_x);
224                         if (diff < prev_diff_x) {
225                                 prev_diff_x = diff;
226                                 *x = read;
227                         }
228                         prev_val_x = read;
229                 }
230
231                 read = titsc_readl(ts_dev, REG_FIFO1);
232                 channel = read & 0xf0000;
233                 channel = channel >> 0x10;
234                 if ((channel >= ts_dev->steps_to_configure) &&
235                         (channel < (2 * ts_dev->steps_to_configure - 1))) {
236                         read &= 0xfff;
237                         diff = abs(read - prev_val_y);
238                         if (diff < prev_diff_y) {
239                                 prev_diff_y = diff;
240                                 *y = read;
241                         }
242                         prev_val_y = read;
243                 }
244         }
245 }
246
247 static irqreturn_t titsc_irq(int irq, void *dev)
248 {
249         struct titsc *ts_dev = dev;
250         struct input_dev *input_dev = ts_dev->input;
251         unsigned int status, irqclr = 0;
252         unsigned int x = 0, y = 0;
253         unsigned int z1, z2, z;
254         unsigned int fsm;
255         unsigned int fifo1count, fifo0count;
256         int i;
257
258         status = titsc_readl(ts_dev, REG_IRQSTATUS);
259         if (status & IRQENB_FIFO0THRES) {
260                 titsc_read_coordinates(ts_dev, &x, &y);
261
262                 z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
263                 z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
264
265                 fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT);
266                 for (i = 0; i < fifo1count; i++)
267                         titsc_readl(ts_dev, REG_FIFO1);
268
269                 fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT);
270                 for (i = 0; i < fifo0count; i++)
271                         titsc_readl(ts_dev, REG_FIFO0);
272
273                 if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
274                         /*
275                          * Calculate pressure using formula
276                          * Resistance(touch) = x plate resistance *
277                          * x postion/4096 * ((z2 / z1) - 1)
278                          */
279                         z = z2 - z1;
280                         z *= x;
281                         z *= ts_dev->x_plate_resistance;
282                         z /= z1;
283                         z = (z + 2047) >> 12;
284
285                         if (z <= MAX_12BIT) {
286                                 input_report_abs(input_dev, ABS_X, x);
287                                 input_report_abs(input_dev, ABS_Y, y);
288                                 input_report_abs(input_dev, ABS_PRESSURE, z);
289                                 input_report_key(input_dev, BTN_TOUCH, 1);
290                                 input_sync(input_dev);
291                         }
292                 }
293                 irqclr |= IRQENB_FIFO0THRES;
294         }
295
296         /*
297          * Time for sequencer to settle, to read
298          * correct state of the sequencer.
299          */
300         udelay(SEQ_SETTLE);
301
302         status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);
303         if (status & IRQENB_PENUP) {
304                 /* Pen up event */
305                 fsm = titsc_readl(ts_dev, REG_ADCFSM);
306                 if (fsm == ADCFSM_STEPID) {
307                         ts_dev->pen_down = false;
308                         input_report_key(input_dev, BTN_TOUCH, 0);
309                         input_report_abs(input_dev, ABS_PRESSURE, 0);
310                         input_sync(input_dev);
311                 } else {
312                         ts_dev->pen_down = true;
313                 }
314                 irqclr |= IRQENB_PENUP;
315         }
316
317         titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
318
319         am335x_tsc_se_update(ts_dev->mfd_tscadc);
320         return IRQ_HANDLED;
321 }
322
323 /*
324  * The functions for inserting/removing driver as a module.
325  */
326
327 static int titsc_probe(struct platform_device *pdev)
328 {
329         struct titsc *ts_dev;
330         struct input_dev *input_dev;
331         struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
332         struct mfd_tscadc_board *pdata;
333         int err;
334
335         pdata = tscadc_dev->dev->platform_data;
336
337         if (!pdata) {
338                 dev_err(&pdev->dev, "Could not find platform data\n");
339                 return -EINVAL;
340         }
341
342         /* Allocate memory for device */
343         ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
344         input_dev = input_allocate_device();
345         if (!ts_dev || !input_dev) {
346                 dev_err(&pdev->dev, "failed to allocate memory.\n");
347                 err = -ENOMEM;
348                 goto err_free_mem;
349         }
350
351         tscadc_dev->tsc = ts_dev;
352         ts_dev->mfd_tscadc = tscadc_dev;
353         ts_dev->input = input_dev;
354         ts_dev->irq = tscadc_dev->irq;
355         ts_dev->wires = pdata->tsc_init->wires;
356         ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
357         ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
358         memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
359                         sizeof(pdata->tsc_init->wire_config));
360
361         err = request_irq(ts_dev->irq, titsc_irq,
362                           0, pdev->dev.driver->name, ts_dev);
363         if (err) {
364                 dev_err(&pdev->dev, "failed to allocate irq.\n");
365                 goto err_free_mem;
366         }
367
368         titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
369         err = titsc_config_wires(ts_dev);
370         if (err) {
371                 dev_err(&pdev->dev, "wrong i/p wire configuration\n");
372                 goto err_free_irq;
373         }
374         titsc_step_config(ts_dev);
375         titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
376
377         input_dev->name = "ti-tsc";
378         input_dev->dev.parent = &pdev->dev;
379
380         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
381         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
382
383         input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
384         input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
385         input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
386
387         /* register to the input system */
388         err = input_register_device(input_dev);
389         if (err)
390                 goto err_free_irq;
391
392         platform_set_drvdata(pdev, ts_dev);
393         return 0;
394
395 err_free_irq:
396         free_irq(ts_dev->irq, ts_dev);
397 err_free_mem:
398         input_free_device(input_dev);
399         kfree(ts_dev);
400         return err;
401 }
402
403 static int titsc_remove(struct platform_device *pdev)
404 {
405         struct titsc *ts_dev = platform_get_drvdata(pdev);
406         u32 steps;
407
408         free_irq(ts_dev->irq, ts_dev);
409
410         /* total steps followed by the enable mask */
411         steps = 2 * ts_dev->steps_to_configure + 2;
412         steps = (1 << steps) - 1;
413         am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps);
414
415         input_unregister_device(ts_dev->input);
416
417         platform_set_drvdata(pdev, NULL);
418         kfree(ts_dev);
419         return 0;
420 }
421
422 #ifdef CONFIG_PM
423 static int titsc_suspend(struct device *dev)
424 {
425         struct titsc *ts_dev = dev_get_drvdata(dev);
426         struct ti_tscadc_dev *tscadc_dev;
427         unsigned int idle;
428
429         tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
430         if (device_may_wakeup(tscadc_dev->dev)) {
431                 idle = titsc_readl(ts_dev, REG_IRQENABLE);
432                 titsc_writel(ts_dev, REG_IRQENABLE,
433                                 (idle | IRQENB_HW_PEN));
434                 titsc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
435         }
436         return 0;
437 }
438
439 static int titsc_resume(struct device *dev)
440 {
441         struct titsc *ts_dev = dev_get_drvdata(dev);
442         struct ti_tscadc_dev *tscadc_dev;
443
444         tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
445         if (device_may_wakeup(tscadc_dev->dev)) {
446                 titsc_writel(ts_dev, REG_IRQWAKEUP,
447                                 0x00);
448                 titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
449         }
450         titsc_step_config(ts_dev);
451         titsc_writel(ts_dev, REG_FIFO0THR,
452                         ts_dev->steps_to_configure);
453         return 0;
454 }
455
456 static const struct dev_pm_ops titsc_pm_ops = {
457         .suspend = titsc_suspend,
458         .resume  = titsc_resume,
459 };
460 #define TITSC_PM_OPS (&titsc_pm_ops)
461 #else
462 #define TITSC_PM_OPS NULL
463 #endif
464
465 static struct platform_driver ti_tsc_driver = {
466         .probe  = titsc_probe,
467         .remove = titsc_remove,
468         .driver = {
469                 .name   = "tsc",
470                 .owner  = THIS_MODULE,
471                 .pm     = TITSC_PM_OPS,
472         },
473 };
474 module_platform_driver(ti_tsc_driver);
475
476 MODULE_DESCRIPTION("TI touchscreen controller driver");
477 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
478 MODULE_LICENSE("GPL");