This patch adds support for the .set_flags callback.
For now following flags are supported:
- GPIOD_IS_AF (i.e. "alternate function").
- GPIOD_IS_IN
- GPIOD_IS_OUT

Currently, the .set_flags in gpio-uclass.c (function dm_gpio_set_value())
is used before .set_value callback, so functionally replaces it.
As a result the corresponding tegra_gpio_set_value() can be removed.

Signed-off-by: Lukasz Majewski <[email protected]>
---

Changes for v2:
- Fix the format specifier for flags in debug() function
- Update commit message
- Remove tegra_gpio_set_value() method (as it is functionally replaced by
  set_value()
- Prevent from returning errors when flags = 0 (problem with e.g. I2C GPIO
  support)
---
 drivers/gpio/tegra_gpio.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 3d1e18854f2..85f2d28ee73 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -182,21 +182,6 @@ static int tegra_gpio_get_value(struct udevice *dev, 
unsigned offset)
        return (val >> GPIO_BIT(gpio)) & 1;
 }
 
-/* write GPIO OUT value to pin 'gpio' */
-static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int 
value)
-{
-       struct tegra_port_info *state = dev_get_priv(dev);
-       int gpio = state->base_gpio + offset;
-
-       debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
-             gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
-
-       /* Configure GPIO output value. */
-       set_level(gpio, value);
-
-       return 0;
-}
-
 void gpio_config_table(const struct tegra_gpio_config *config, int len)
 {
        int i;
@@ -258,14 +243,36 @@ static int tegra_gpio_rfree(struct udevice *dev, unsigned 
int offset)
        return 0;
 }
 
+static int tegra_gpio_set_flags(struct udevice *dev, unsigned int offset,
+                               ulong flags)
+{
+       struct tegra_port_info *state = dev_get_priv(dev);
+       int gpio = state->base_gpio + offset;
+
+       debug("gpio_set_flags: pin = %d (port %d:bit %d), flag = 0x%lx\n",
+             gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), flags);
+
+       if (flags & GPIOD_IS_AF) {
+               set_config(gpio, CFG_SFIO);
+       } else if (flags & GPIOD_IS_IN) {
+               return tegra_gpio_direction_input(dev, offset);
+       } else if (flags & GPIOD_IS_OUT) {
+               bool value = flags & GPIOD_IS_OUT_ACTIVE;
+
+               return tegra_gpio_direction_output(dev, offset, value);
+       }
+
+       return 0;
+}
+
 static const struct dm_gpio_ops gpio_tegra_ops = {
        .direction_input        = tegra_gpio_direction_input,
        .direction_output       = tegra_gpio_direction_output,
        .get_value              = tegra_gpio_get_value,
-       .set_value              = tegra_gpio_set_value,
        .get_function           = tegra_gpio_get_function,
        .xlate                  = tegra_gpio_xlate,
        .rfree                  = tegra_gpio_rfree,
+       .set_flags              = tegra_gpio_set_flags,
 };
 
 /*
-- 
2.39.5

Reply via email to