gpio: update dir_flags management
Update the flag management in GPIO uclass: the desc->flags is always
combined with the requested flags and the GPIO descriptor is updated
for further call.
Add a function dm_gpio_get_dir_flags to get dynamically
the current dir_flags (configuration and value).
This patch prepare introduction of the dir flags support with new ops.
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 29c8c0f..9550e45 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -141,8 +141,9 @@
if (args->args_count < 2)
return 0;
+ desc->flags = 0;
if (args->args[1] & GPIO_ACTIVE_LOW)
- desc->flags = GPIOD_ACTIVE_LOW;
+ desc->flags |= GPIOD_ACTIVE_LOW;
return 0;
}
@@ -559,6 +560,8 @@
if (ret)
return ret;
+ /* combine the requested flags (for IN/OUT) and the descriptor flags */
+ flags |= desc->flags;
ret = _dm_gpio_set_dir_flags(desc, flags);
/* update the descriptor flags */
@@ -579,6 +582,26 @@
return _dm_gpio_set_dir_flags(desc, desc->flags);
}
+int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
+{
+ int ret;
+ ulong dir_flags;
+
+ ret = check_reserved(desc, "get_dir_flags");
+ if (ret)
+ return ret;
+
+ dir_flags = desc->flags;
+ /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
+ dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
+ if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
+ dir_flags |= GPIOD_IS_OUT_ACTIVE;
+
+ *flags = dir_flags;
+
+ return 0;
+}
+
/**
* gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
* gpio: GPIO number
@@ -849,7 +872,7 @@
debug("%s: dm_gpio_requestf failed\n", __func__);
goto err;
}
- ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+ ret = dm_gpio_set_dir_flags(desc, flags);
if (ret) {
debug("%s: dm_gpio_set_dir failed\n", __func__);
goto err;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 5686df7..1329d02 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -592,8 +592,7 @@
/**
* dm_gpio_set_dir() - Set the direction for a GPIO
*
- * This sets up the direction according tot the provided flags. It will do
- * nothing unless the direction is actually specified.
+ * This sets up the direction according to the GPIO flags: desc->flags.
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
@@ -602,11 +601,10 @@
int dm_gpio_set_dir(struct gpio_desc *desc);
/**
- * dm_gpio_set_dir_flags() - Set direction using specific flags
+ * dm_gpio_set_dir_flags() - Set direction using description and added flags
*
- * This is like dm_gpio_set_dir() except that the flags value is provided
- * instead of being used from desc->flags. This is needed because in many
- * cases the GPIO description does not include direction information.
+ * This sets up the direction according to the provided flags and the GPIO
+ * description (desc->flags) which include direction information.
* Note that desc->flags is updated by this function.
*
* @desc: GPIO description containing device, offset and flags,
@@ -617,6 +615,18 @@
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
/**
+ * dm_gpio_get_dir_flags() - Get direction flags
+ *
+ * read the current direction flags
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @flags: place to put the used flags
+ * @return 0 if OK, -ve on error, in which case desc->flags is not updated
+ */
+int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
+
+/**
* gpio_get_number() - Get the global GPIO number of a GPIO
*
* This should only be used for debugging or interest. It returns the number