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

Input: atmel_mxt_ts - fix up inverted RESET handler

This driver uses GPIO descriptors to drive the touchscreen RESET line. In
the existing device trees this has in conflict with intution been flagged
as GPIO_ACTIVE_HIGH and the driver then applies the reverse action by
driving the line low (setting to 0) to enter reset state and driving the
line high (setting to 1) to get out of reset state.

The correct way to handle active low GPIO lines is to provide the
GPIO_ACTIVE_LOW in the device tree (thus properly describing the hardware)
and letting the GPIO framework invert the assertion (driving high) to a
low level and vice versa.

This is considered a bug since the device trees are incorrectly
mis-specifying the line as active high.

Fix the driver and all device trees specifying a reset line.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Philippe Schenker <philippe.schenker@toradex.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Link: https://lore.kernel.org/r/20201104153032.1387747-1-linus.walleij@linaro.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Linus Walleij and committed by
Dmitry Torokhov
feedaacd 05909cd9

+14 -12
+1 -1
arch/arm/boot/dts/imx53-ppd.dts
··· 589 589 590 590 touchscreen@4b { 591 591 compatible = "atmel,maxtouch"; 592 - reset-gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>; 592 + reset-gpio = <&gpio5 19 GPIO_ACTIVE_LOW>; 593 593 reg = <0x4b>; 594 594 interrupt-parent = <&gpio5>; 595 595 interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+1 -1
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
··· 143 143 reg = <0x4a>; 144 144 interrupt-parent = <&gpio1>; 145 145 interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28 */ 146 - reset-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; /* SODIMM 30 */ 146 + reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; /* SODIMM 30 */ 147 147 status = "disabled"; 148 148 }; 149 149
+1 -1
arch/arm/boot/dts/imx6q-apalis-eval.dts
··· 140 140 reg = <0x4a>; 141 141 interrupt-parent = <&gpio6>; 142 142 interrupts = <10 IRQ_TYPE_EDGE_FALLING>; 143 - reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */ 143 + reset-gpios = <&gpio6 9 GPIO_ACTIVE_LOW>; /* SODIMM 13 */ 144 144 status = "disabled"; 145 145 }; 146 146
+1 -1
arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
··· 145 145 reg = <0x4a>; 146 146 interrupt-parent = <&gpio6>; 147 147 interrupts = <10 IRQ_TYPE_EDGE_FALLING>; 148 - reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */ 148 + reset-gpios = <&gpio6 9 GPIO_ACTIVE_LOW>; /* SODIMM 13 */ 149 149 status = "disabled"; 150 150 }; 151 151
+1 -1
arch/arm/boot/dts/imx6q-apalis-ixora.dts
··· 144 144 reg = <0x4a>; 145 145 interrupt-parent = <&gpio6>; 146 146 interrupts = <10 IRQ_TYPE_EDGE_FALLING>; 147 - reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */ 147 + reset-gpios = <&gpio6 9 GPIO_ACTIVE_LOW>; /* SODIMM 13 */ 148 148 status = "disabled"; 149 149 }; 150 150
+1 -1
arch/arm/boot/dts/imx7-colibri-aster.dtsi
··· 99 99 reg = <0x4a>; 100 100 interrupt-parent = <&gpio2>; 101 101 interrupts = <15 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 */ 102 - reset-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* SODIMM 106 */ 102 + reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* SODIMM 106 */ 103 103 }; 104 104 105 105 /* M41T0M6 real time clock on carrier board */
+1 -1
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
··· 124 124 reg = <0x4a>; 125 125 interrupt-parent = <&gpio1>; 126 126 interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28 */ 127 - reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; /* SODIMM 30 */ 127 + reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* SODIMM 30 */ 128 128 status = "disabled"; 129 129 }; 130 130
+1 -1
arch/arm/boot/dts/motorola-mapphone-common.dtsi
··· 428 428 pinctrl-names = "default"; 429 429 pinctrl-0 = <&touchscreen_pins>; 430 430 431 - reset-gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; /* gpio173 */ 431 + reset-gpios = <&gpio6 13 GPIO_ACTIVE_LOW>; /* gpio173 */ 432 432 433 433 /* gpio_183 with sys_nirq2 pad as wakeup */ 434 434 interrupts-extended = <&gpio6 23 IRQ_TYPE_LEVEL_LOW>,
+1 -1
arch/arm/boot/dts/s5pv210-aries.dtsi
··· 620 620 interrupts = <5 IRQ_TYPE_EDGE_FALLING>; 621 621 pinctrl-names = "default"; 622 622 pinctrl-0 = <&ts_irq>; 623 - reset-gpios = <&gpj1 3 GPIO_ACTIVE_HIGH>; 623 + reset-gpios = <&gpj1 3 GPIO_ACTIVE_LOW>; 624 624 }; 625 625 }; 626 626
+1 -1
arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
··· 436 436 interrupt-parent = <&gpio>; 437 437 interrupts = <TEGRA_GPIO(V, 6) IRQ_TYPE_LEVEL_LOW>; 438 438 439 - reset-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_HIGH>; 439 + reset-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_LOW>; 440 440 441 441 avdd-supply = <&vdd_3v3_sys>; 442 442 vdd-supply = <&vdd_3v3_sys>;
+4 -2
drivers/input/touchscreen/atmel_mxt_ts.c
··· 3134 3134 if (error) 3135 3135 return error; 3136 3136 3137 + /* Request the RESET line as asserted so we go into reset */ 3137 3138 data->reset_gpio = devm_gpiod_get_optional(&client->dev, 3138 - "reset", GPIOD_OUT_LOW); 3139 + "reset", GPIOD_OUT_HIGH); 3139 3140 if (IS_ERR(data->reset_gpio)) { 3140 3141 error = PTR_ERR(data->reset_gpio); 3141 3142 dev_err(&client->dev, "Failed to get reset gpio: %d\n", error); ··· 3154 3153 disable_irq(client->irq); 3155 3154 3156 3155 if (data->reset_gpio) { 3156 + /* Wait a while and then de-assert the RESET GPIO line */ 3157 3157 msleep(MXT_RESET_GPIO_TIME); 3158 - gpiod_set_value(data->reset_gpio, 1); 3158 + gpiod_set_value(data->reset_gpio, 0); 3159 3159 msleep(MXT_RESET_INVALID_CHG); 3160 3160 } 3161 3161