]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Input: elants_i2c - properly handle the reset GPIO when power is off
authorDouglas Anderson <dianders@chromium.org>
Fri, 18 Nov 2022 05:49:19 +0000 (21:49 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jan 2023 10:41:03 +0000 (11:41 +0100)
[ Upstream commit a85fbd6498441694475716a4d5c65f9d3e073faf ]

As can be seen in elants_i2c_power_off(), we want the reset GPIO
asserted when power is off. The reset GPIO is active low so we need
the reset line logic low when power is off to avoid leakage.

We have a problem, though, at probe time. At probe time we haven't
powered the regulators on yet but we have:

  devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);

While that _looks_ right, it turns out that it's not. The
GPIOD_OUT_LOW doesn't mean to init the GPIO to low. It means init the
GPIO to "not asserted". Since this is an active low GPIO that inits it
to be high.

Let's fix this to properly init the GPIO. Now after both probe and
power off the state of the GPIO is consistent (it's "asserted" or
level low).

Once we fix this, we can see that at power on time we no longer to
assert the reset GPIO as the first thing. The reset GPIO is _always_
asserted before powering on. Let's fix powering on to account for
this.

Fixes: f7cae79c078e ("Input: elants_i2c - wire up regulator support")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20221117123805.1.I9959ac561dd6e1e8e1ce7085e4de6167b27c574f@changeid
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/input/touchscreen/elants_i2c.c

index a51e7c85f58197b2bba70793a30c81552468e847..4022816a4736f5e8e9c673d4eb8a2e7b1d0c2f2c 100644 (file)
@@ -1078,14 +1078,12 @@ static int elants_i2c_power_on(struct elants_data *ts)
        if (IS_ERR_OR_NULL(ts->reset_gpio))
                return 0;
 
-       gpiod_set_value_cansleep(ts->reset_gpio, 1);
-
        error = regulator_enable(ts->vcc33);
        if (error) {
                dev_err(&ts->client->dev,
                        "failed to enable vcc33 regulator: %d\n",
                        error);
-               goto release_reset_gpio;
+               return error;
        }
 
        error = regulator_enable(ts->vccio);
@@ -1094,7 +1092,7 @@ static int elants_i2c_power_on(struct elants_data *ts)
                        "failed to enable vccio regulator: %d\n",
                        error);
                regulator_disable(ts->vcc33);
-               goto release_reset_gpio;
+               return error;
        }
 
        /*
@@ -1103,7 +1101,6 @@ static int elants_i2c_power_on(struct elants_data *ts)
         */
        udelay(ELAN_POWERON_DELAY_USEC);
 
-release_reset_gpio:
        gpiod_set_value_cansleep(ts->reset_gpio, 0);
        if (error)
                return error;
@@ -1211,7 +1208,7 @@ static int elants_i2c_probe(struct i2c_client *client,
                return error;
        }
 
-       ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
+       ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
        if (IS_ERR(ts->reset_gpio)) {
                error = PTR_ERR(ts->reset_gpio);