In some Tegra SoC (like e.g. T30) there is a possibility that one will configure at early boot state a pin as GPIO (to use it for e.g. carrier board detection). However, afterwards (i.e. in Linux) the same pin will be used as the special function one.
Current Tegra gpio driver doesn't allow this, so callback for set_flags() has been defined to properly setup the GPIO when required. For now following flags are supported: - GPIOD_IS_AF (i.e. "alternate function"). - GPIOD_IS_IN - GPIOD_IS_OUT In long term the tegra_gpio_set_flags() is going to replace direction_{input|output} callbacks. Signed-off-by: Lukasz Majewski <lu...@nabladev.com> --- drivers/gpio/tegra_gpio.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 3d1e18854f2..1e8bd051875 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -258,6 +258,29 @@ 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 = %d\n", + gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), flags); + + if (flags & GPIOD_IS_AF) { + set_config(gpio, CFG_SFIO); + return 0; + } 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 -EINVAL; +} + static const struct dm_gpio_ops gpio_tegra_ops = { .direction_input = tegra_gpio_direction_input, .direction_output = tegra_gpio_direction_output, @@ -266,6 +289,7 @@ static const struct dm_gpio_ops gpio_tegra_ops = { .get_function = tegra_gpio_get_function, .xlate = tegra_gpio_xlate, .rfree = tegra_gpio_rfree, + .set_flags = tegra_gpio_set_flags, }; /* -- 2.39.5