summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpio/gpio-uclass.c47
-rw-r--r--include/asm-generic/gpio.h34
2 files changed, 80 insertions, 1 deletions
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index e11c5a6..04b7b16 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -283,6 +283,53 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
return priv->bank_name;
}
+static const char * const gpio_function[GPIOF_COUNT] = {
+ "input",
+ "output",
+ "unused",
+ "unknown",
+ "func",
+};
+
+int get_function(struct udevice *dev, int offset, bool skip_unused,
+ const char **namep)
+{
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct dm_gpio_ops *ops = gpio_get_ops(dev);
+
+ BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+ if (!device_active(dev))
+ return -ENODEV;
+ if (offset < 0 || offset >= uc_priv->gpio_count)
+ return -EINVAL;
+ if (namep)
+ *namep = uc_priv->name[offset];
+ if (skip_unused && !uc_priv->name[offset])
+ return GPIOF_UNUSED;
+ if (ops->get_function) {
+ int ret;
+
+ ret = ops->get_function(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret >= ARRAY_SIZE(gpio_function))
+ return -ENODATA;
+ return ret;
+ }
+
+ return GPIOF_UNKNOWN;
+}
+
+int gpio_get_function(struct udevice *dev, int offset, const char **namep)
+{
+ return get_function(dev, offset, true, namep);
+}
+
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
+{
+ return get_function(dev, offset, false, namep);
+}
+
/* We need to renumber the GPIOs when any driver is probed/removed */
static int gpio_renumber(struct udevice *removed_dev)
{
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 128249e..7104454 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -83,7 +83,7 @@ int gpio_get_value(unsigned gpio);
int gpio_set_value(unsigned gpio, int value);
/* State of a GPIO, as reported by get_function() */
-enum {
+enum gpio_func_t {
GPIOF_INPUT = 0,
GPIOF_OUTPUT,
GPIOF_UNUSED, /* Not claimed */
@@ -96,6 +96,38 @@ enum {
struct udevice;
/**
+ * gpio_get_function() - get the current function for a GPIO pin
+ *
+ * Note this returns GPIOF_UNUSED if the GPIO is not requested.
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @namep: If non-NULL, this is set to the nane given when the GPIO
+ * was requested, or -1 if it has not been requested
+ * @return -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the
+ * function from enum gpio_func_t.
+ */
+int gpio_get_function(struct udevice *dev, int offset, const char **namep);
+
+/**
+ * gpio_get_raw_function() - get the current raw function for a GPIO pin
+ *
+ * Note this does not return GPIOF_UNUSED - it will always return the GPIO
+ * driver's view of a pin function, even if it is not correctly set up.
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @namep: If non-NULL, this is set to the nane given when the GPIO
+ * was requested, or -1 if it has not been requested
+ * @return -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * Otherwise returns the function from enum gpio_func_t.
+ */
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep);
+
+/**
* struct struct dm_gpio_ops - Driver model GPIO operations
*
* Refer to functions above for description. These function largely copy