root/drivers/input/touchscreen/ti_am335x_tsc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. titsc_readl
  2. titsc_writel
  3. titsc_config_wires
  4. titsc_step_config
  5. titsc_cmp_coord
  6. titsc_read_coordinates
  7. titsc_irq
  8. titsc_parse_dt
  9. titsc_probe
  10. titsc_remove
  11. titsc_suspend
  12. titsc_resume

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

/* [<][>][^][v][top][bottom][index][help] */