gpio: f7188x: Implement get_direction.
authorplr.vincent@gmail.com <plr.vincent@gmail.com>
Mon, 6 Jun 2016 00:56:08 +0000 (00:56 +0000)
committerLinus Walleij <linus.walleij@linaro.org>
Tue, 14 Jun 2016 07:10:18 +0000 (09:10 +0200)
Avoids gpiolib assumptions on initial pin direction, allowing user to observe
power-on settings.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-f7188x.c

index 05aa538c3767a3b5e90cedd4eb95a5e89b04c4fa..600be84187073a211ad1db5fef6381670ad87be2 100644 (file)
@@ -125,6 +125,7 @@ static inline void superio_exit(int base)
  * GPIO chip.
  */
 
+static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset);
 static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset);
 static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset);
 static int f7188x_gpio_direction_out(struct gpio_chip *chip,
@@ -139,6 +140,7 @@ static int f7188x_gpio_set_single_ended(struct gpio_chip *gc,
                .chip = {                                               \
                        .label            = DRVNAME,                    \
                        .owner            = THIS_MODULE,                \
+                       .get_direction    = f7188x_gpio_get_direction,  \
                        .direction_input  = f7188x_gpio_direction_in,   \
                        .get              = f7188x_gpio_get,            \
                        .direction_output = f7188x_gpio_direction_out,  \
@@ -209,6 +211,26 @@ static struct f7188x_gpio_bank f81866_gpio_bank[] = {
        F7188X_GPIO_BANK(80, 8, 0x88),
 };
 
+static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+       int err;
+       struct f7188x_gpio_bank *bank =
+               container_of(chip, struct f7188x_gpio_bank, chip);
+       struct f7188x_sio *sio = bank->data->sio;
+       u8 dir;
+
+       err = superio_enter(sio->addr);
+       if (err)
+               return err;
+       superio_select(sio->addr, SIO_LD_GPIO);
+
+       dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
+
+       superio_exit(sio->addr);
+
+       return !(dir & 1 << offset);
+}
+
 static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 {
        int err;