gpio: emulate open drain & open source in dm_gpio_set_value()
[oweals/u-boot.git] / drivers / gpio / gpio-uclass.c
index 757ab7106ee33d3fe03b9d3345fc4d9be8c60c52..d3cea11f76e5115513ed5661b45a578c4d2a705f 100644 (file)
@@ -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;
 }