Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: tsc2005 - add DT support

This adds DT support to the tsc2005 touchscreen driver. It also adds
regulator support to the driver if booted via DT.

Reviewed-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Sebastian Reichel and committed by
Dmitry Torokhov
a38cfebb b98abe52

+146 -20
+42
Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt
··· 1 + * Texas Instruments tsc2005 touchscreen controller 2 + 3 + Required properties: 4 + - compatible : "ti,tsc2005" 5 + - reg : SPI device address 6 + - spi-max-frequency : Maximal SPI speed 7 + - interrupts : IRQ specifier 8 + - reset-gpios : GPIO specifier 9 + - vio-supply : Regulator specifier 10 + 11 + Optional properties: 12 + - ti,x-plate-ohms : integer, resistance of the touchscreen's X plates 13 + in ohm (defaults to 280) 14 + - ti,esd-recovery-timeout-ms : integer, if the touchscreen does not respond after 15 + the configured time (in milli seconds), the driver 16 + will reset it. This is disabled by default. 17 + - properties defined in touchscreen.txt 18 + 19 + Example: 20 + 21 + &mcspi1 { 22 + tsc2005@0 { 23 + compatible = "ti,tsc2005"; 24 + spi-max-frequency = <6000000>; 25 + reg = <0>; 26 + 27 + vio-supply = <&vio>; 28 + 29 + reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */ 30 + interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>; /* 100 */ 31 + 32 + touchscreen-fuzz-x = <4>; 33 + touchscreen-fuzz-y = <7>; 34 + touchscreen-fuzz-pressure = <2>; 35 + touchscreen-max-x = <4096>; 36 + touchscreen-max-y = <4096>; 37 + touchscreen-max-pressure = <2048>; 38 + 39 + ti,x-plate-ohms = <280>; 40 + ti,esd-recovery-timeout-ms = <8000>; 41 + }; 42 + }
+104 -20
drivers/input/touchscreen/tsc2005.c
··· 25 25 #include <linux/kernel.h> 26 26 #include <linux/module.h> 27 27 #include <linux/input.h> 28 + #include <linux/input/touchscreen.h> 28 29 #include <linux/interrupt.h> 29 30 #include <linux/delay.h> 30 31 #include <linux/pm.h> 32 + #include <linux/of.h> 33 + #include <linux/of_gpio.h> 31 34 #include <linux/spi/spi.h> 32 35 #include <linux/spi/tsc2005.h> 36 + #include <linux/regulator/consumer.h> 33 37 34 38 /* 35 39 * The touchscreen interface operates as follows: ··· 104 100 TSC2005_CFR2_AVG_7) 105 101 106 102 #define MAX_12BIT 0xfff 103 + #define TSC2005_DEF_X_FUZZ 4 104 + #define TSC2005_DEF_Y_FUZZ 8 105 + #define TSC2005_DEF_P_FUZZ 2 106 + #define TSC2005_DEF_RESISTOR 280 107 + 107 108 #define TSC2005_SPI_MAX_SPEED_HZ 10000000 108 109 #define TSC2005_PENUP_TIME_MS 40 109 110 ··· 152 143 153 144 bool pen_down; 154 145 146 + struct regulator *vio; 147 + 148 + int reset_gpio; 155 149 void (*set_reset)(bool enable); 156 150 }; 157 151 ··· 349 337 tsc2005_cmd(ts, TSC2005_CMD_STOP); 350 338 } 351 339 340 + static void tsc2005_set_reset(struct tsc2005 *ts, bool enable) 341 + { 342 + if (ts->reset_gpio >= 0) 343 + gpio_set_value(ts->reset_gpio, enable); 344 + else if (ts->set_reset) 345 + ts->set_reset(enable); 346 + } 347 + 352 348 /* must be called with ts->mutex held */ 353 349 static void __tsc2005_disable(struct tsc2005 *ts) 354 350 { ··· 375 355 { 376 356 tsc2005_start_scan(ts); 377 357 378 - if (ts->esd_timeout && ts->set_reset) { 358 + if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) { 379 359 ts->last_valid_interrupt = jiffies; 380 360 schedule_delayed_work(&ts->esd_work, 381 361 round_jiffies_relative( ··· 434 414 } 435 415 436 416 /* hardware reset */ 437 - ts->set_reset(false); 417 + tsc2005_set_reset(ts, false); 438 418 usleep_range(100, 500); /* only 10us required */ 439 - ts->set_reset(true); 419 + tsc2005_set_reset(ts, true); 440 420 441 421 if (!success) 442 422 goto out; ··· 479 459 umode_t mode = attr->mode; 480 460 481 461 if (attr == &dev_attr_selftest.attr) { 482 - if (!ts->set_reset) 462 + if (!ts->set_reset && !ts->reset_gpio) 483 463 mode = 0; 484 464 } 485 465 ··· 529 509 530 510 tsc2005_update_pen_state(ts, 0, 0, 0); 531 511 532 - ts->set_reset(false); 512 + tsc2005_set_reset(ts, false); 533 513 usleep_range(100, 500); /* only 10us required */ 534 - ts->set_reset(true); 514 + tsc2005_set_reset(ts, true); 535 515 536 516 enable_irq(ts->spi->irq); 537 517 tsc2005_start_scan(ts); ··· 592 572 static int tsc2005_probe(struct spi_device *spi) 593 573 { 594 574 const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev); 575 + struct device_node *np = spi->dev.of_node; 576 + 595 577 struct tsc2005 *ts; 596 578 struct input_dev *input_dev; 597 - unsigned int max_x, max_y, max_p; 598 - unsigned int fudge_x, fudge_y, fudge_p; 579 + unsigned int max_x = MAX_12BIT; 580 + unsigned int max_y = MAX_12BIT; 581 + unsigned int max_p = MAX_12BIT; 582 + unsigned int fudge_x = TSC2005_DEF_X_FUZZ; 583 + unsigned int fudge_y = TSC2005_DEF_Y_FUZZ; 584 + unsigned int fudge_p = TSC2005_DEF_P_FUZZ; 585 + unsigned int x_plate_ohm = TSC2005_DEF_RESISTOR; 586 + unsigned int esd_timeout; 599 587 int error; 600 588 601 - if (!pdata) { 589 + if (!np && !pdata) { 602 590 dev_err(&spi->dev, "no platform data\n"); 603 591 return -ENODEV; 604 592 } 605 593 606 - fudge_x = pdata->ts_x_fudge ? : 4; 607 - fudge_y = pdata->ts_y_fudge ? : 8; 608 - fudge_p = pdata->ts_pressure_fudge ? : 2; 609 - max_x = pdata->ts_x_max ? : MAX_12BIT; 610 - max_y = pdata->ts_y_max ? : MAX_12BIT; 611 - max_p = pdata->ts_pressure_max ? : MAX_12BIT; 612 - 613 594 if (spi->irq <= 0) { 614 595 dev_err(&spi->dev, "no irq\n"); 615 596 return -ENODEV; 597 + } 598 + 599 + if (pdata) { 600 + fudge_x = pdata->ts_x_fudge; 601 + fudge_y = pdata->ts_y_fudge; 602 + fudge_p = pdata->ts_pressure_fudge; 603 + max_x = pdata->ts_x_max; 604 + max_y = pdata->ts_y_max; 605 + max_p = pdata->ts_pressure_max; 606 + x_plate_ohm = pdata->ts_x_plate_ohm; 607 + esd_timeout = pdata->esd_timeout_ms; 608 + } else { 609 + x_plate_ohm = TSC2005_DEF_RESISTOR; 610 + of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm); 611 + esd_timeout = 0; 612 + of_property_read_u32(np, "ti,esd-recovery-timeout-ms", 613 + &esd_timeout); 616 614 } 617 615 618 616 spi->mode = SPI_MODE_0; ··· 653 615 ts->spi = spi; 654 616 ts->idev = input_dev; 655 617 656 - ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; 657 - ts->esd_timeout = pdata->esd_timeout_ms; 658 - ts->set_reset = pdata->set_reset; 618 + ts->x_plate_ohm = x_plate_ohm; 619 + ts->esd_timeout = esd_timeout; 620 + 621 + if (np) { 622 + ts->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); 623 + if (ts->reset_gpio == -EPROBE_DEFER) 624 + return ts->reset_gpio; 625 + if (ts->reset_gpio < 0) { 626 + dev_err(&spi->dev, "error acquiring reset gpio: %d\n", 627 + ts->reset_gpio); 628 + return ts->reset_gpio; 629 + } 630 + 631 + error = devm_gpio_request_one(&spi->dev, ts->reset_gpio, 0, 632 + "reset-gpios"); 633 + if (error) { 634 + dev_err(&spi->dev, "error requesting reset gpio: %d\n", 635 + error); 636 + return error; 637 + } 638 + 639 + ts->vio = devm_regulator_get(&spi->dev, "vio"); 640 + if (IS_ERR(ts->vio)) { 641 + error = PTR_ERR(ts->vio); 642 + dev_err(&spi->dev, "vio regulator missing (%d)", error); 643 + return error; 644 + } 645 + } else { 646 + ts->reset_gpio = -1; 647 + ts->set_reset = pdata->set_reset; 648 + } 659 649 660 650 mutex_init(&ts->mutex); 661 651 ··· 708 642 input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); 709 643 input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); 710 644 645 + if (np) 646 + touchscreen_parse_of_params(input_dev); 647 + 711 648 input_dev->open = tsc2005_open; 712 649 input_dev->close = tsc2005_close; 713 650 ··· 728 659 return error; 729 660 } 730 661 662 + /* enable regulator for DT */ 663 + if (ts->vio) { 664 + error = regulator_enable(ts->vio); 665 + if (error) 666 + return error; 667 + } 668 + 731 669 spi_set_drvdata(spi, ts); 732 670 error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group); 733 671 if (error) { 734 672 dev_err(&spi->dev, 735 673 "Failed to create sysfs attributes, err: %d\n", error); 736 - return error; 674 + goto disable_regulator; 737 675 } 738 676 739 677 error = input_register_device(ts->idev); ··· 755 679 756 680 err_remove_sysfs: 757 681 sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); 682 + disable_regulator: 683 + if (ts->vio) 684 + regulator_disable(ts->vio); 758 685 return error; 759 686 } 760 687 761 688 static int tsc2005_remove(struct spi_device *spi) 762 689 { 690 + struct tsc2005 *ts = spi_get_drvdata(spi); 691 + 763 692 sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); 693 + 694 + if (ts->vio) 695 + regulator_disable(ts->vio); 764 696 765 697 return 0; 766 698 }