aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorNeil Armstrong2020-05-05 10:43:17 +0200
committerNeil Armstrong2020-05-11 15:12:53 +0200
commit47bd533e9dd0f967ff7b62f3edfd6c97131e1501 (patch)
tree2454f95a2f6666d56fa3351f78fdad2cb435cda0 /drivers/gpio
parent375d79cdbb6bdeaa9bc10dd34c3b22dd6838d4f3 (diff)
gpio: emulate open drain & open source in dm_gpio_set_value()
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@baylibre.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-uclass.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 757ab7106ee..d3cea11f76e 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;
}