gpio: twl4030: Implement .get_direction()
authorLinus Walleij <linus.walleij@linaro.org>
Mon, 3 Sep 2018 07:52:10 +0000 (09:52 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 10 Sep 2018 06:48:51 +0000 (08:48 +0200)
It's nice to be able to read back the direction of the GPIO
line from the hardware so implement .get_direction() for
twl4030.

Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-twl4030.c

index 1e47ddff33f6c244bcd596cc12ab2f31d7dc9973..fbfb648d350263426d0d5e00cc888d4e4baadb87 100644 (file)
@@ -154,6 +154,23 @@ static int twl4030_set_gpio_direction(int gpio, int is_input)
        return ret;
 }
 
+static int twl4030_get_gpio_direction(int gpio)
+{
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
+       u8 base = REG_GPIODATADIR1 + d_bnk;
+       int ret = 0;
+
+       ret = gpio_twl4030_read(base);
+       if (ret < 0)
+               return ret;
+
+       /* 1 = output, but gpiolib semantics are inverse so invert */
+       ret = !(ret & d_msk);
+
+       return ret;
+}
+
 static int twl4030_set_gpio_dataout(int gpio, int enable)
 {
        u8 d_bnk = gpio >> 3;
@@ -359,6 +376,28 @@ static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
        return ret;
 }
 
+static int twl_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+       struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
+       /*
+        * Default 0 = output
+        * LED GPIOs >= TWL4030_GPIO_MAX are always output
+        */
+       int ret = 0;
+
+       mutex_lock(&priv->mutex);
+       if (offset < TWL4030_GPIO_MAX) {
+               ret = twl4030_get_gpio_direction(offset);
+               if (ret) {
+                       mutex_unlock(&priv->mutex);
+                       return ret;
+               }
+       }
+       mutex_unlock(&priv->mutex);
+
+       return ret;
+}
+
 static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
@@ -374,8 +413,9 @@ static const struct gpio_chip template_chip = {
        .request                = twl_request,
        .free                   = twl_free,
        .direction_input        = twl_direction_in,
-       .get                    = twl_get,
        .direction_output       = twl_direction_out,
+       .get_direction          = twl_get_direction,
+       .get                    = twl_get,
        .set                    = twl_set,
        .to_irq                 = twl_to_irq,
        .can_sleep              = true,