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