[PATCH v2 1/2] gpio: emulate open drain & open source in dm_gpio_set_value()

Neil Armstrong narmstrong at baylibre.com
Tue May 5 10:43:17 CEST 2020


Handle the GPIOD_OPEN_DRAIN & GPIOD_OPEN_SOURCE flags to emulate open drain
and open source by setting the GPIO line as input depending on the
requested value.

The behaviour is taken from the Linux gpiolib.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpio/gpio-uclass.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 757ab7106e..d3cea11f76 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -526,6 +526,21 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value)
 
 	if (desc->flags & GPIOD_ACTIVE_LOW)
 		value = !value;
+
+	/*
+	 * Emulate open drain by not actively driving the line high or
+	 * Emulate open source by not actively driving the line low
+	 */
+	if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
+	    (desc->flags & GPIOD_OPEN_SOURCE && !value))
+		return gpio_get_ops(desc->dev)->direction_input(desc->dev,
+								desc->offset);
+	else if (desc->flags & GPIOD_OPEN_DRAIN ||
+		 desc->flags & GPIOD_OPEN_SOURCE)
+		return gpio_get_ops(desc->dev)->direction_output(desc->dev,
+								desc->offset,
+								value);
+
 	gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
 	return 0;
 }
-- 
2.22.0



More information about the U-Boot mailing list