Version:  2.0.40 2.2.26 2.4.37 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us