summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_gpio.c57
-rw-r--r--drivers/gpio/gpio-uclass.c39
-rw-r--r--include/asm-generic/gpio.h18
3 files changed, 78 insertions, 36 deletions
diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c
index 11f4e40..c0cdc5f 100644
--- a/common/cmd_gpio.c
+++ b/common/cmd_gpio.c
@@ -25,13 +25,6 @@ enum gpio_cmd {
};
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
-static const char * const gpio_function[GPIOF_COUNT] = {
- "input",
- "output",
- "unused",
- "unknown",
- "func",
-};
/* A few flags used by show_gpio() */
enum {
@@ -40,22 +33,16 @@ enum {
FLAG_SHOW_NEWLINE = 1 << 2,
};
-static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
- int *flagsp)
+static void gpio_get_description(struct udevice *dev, const char *bank_name,
+ int offset, int *flagsp)
{
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
- int func = GPIOF_UNKNOWN;
char buf[80];
int ret;
- BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
-
- if (ops->get_function) {
- ret = ops->get_function(dev, offset);
- if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
- func = ret;
- }
- if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
+ ret = gpio_get_function(dev, offset, NULL);
+ if (ret < 0)
+ goto err;
+ if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
return;
if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
if (*flagsp & FLAG_SHOW_NEWLINE) {
@@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
printf("Bank %s:\n", bank_name);
*flagsp &= ~FLAG_SHOW_BANK;
}
- *buf = '\0';
- if (ops->get_state) {
- ret = ops->get_state(dev, offset, buf, sizeof(buf));
- if (ret) {
- puts("<unknown>");
- return;
- }
- } else {
- sprintf(buf, "%s%u: %8s %d", bank_name, offset,
- gpio_function[func], ops->get_value(dev, offset));
- }
- puts(buf);
- puts("\n");
+ ret = gpio_get_status(dev, offset, buf, sizeof(buf));
+ if (ret)
+ goto err;
+
+ printf("%s\n", buf);
+ return;
+err:
+ printf("Error %d\n", ret);
}
static int do_gpio_status(bool all, const char *gpio_name)
@@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name)
if (all)
flags |= FLAG_SHOW_ALL;
bank_name = gpio_get_bank_info(dev, &num_bits);
- if (!num_bits)
+ if (!num_bits) {
+ debug("GPIO device %s has no bits\n", dev->name);
continue;
+ }
banklen = bank_name ? strlen(bank_name) : 0;
if (!gpio_name || !bank_name ||
@@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name)
p = gpio_name + banklen;
if (gpio_name && *p) {
offset = simple_strtoul(p, NULL, 10);
- show_gpio(dev, bank_name, offset, &flags);
+ gpio_get_description(dev, bank_name, offset,
+ &flags);
} else {
for (offset = 0; offset < num_bits; offset++) {
- show_gpio(dev, bank_name, offset,
- &flags);
+ gpio_get_description(dev, bank_name,
+ offset, &flags);
}
}
}
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 04b7b16..6367093 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -330,6 +330,45 @@ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
return get_function(dev, offset, false, namep);
}
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
+{
+ struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ struct gpio_dev_priv *priv;
+ char *str = buf;
+ int func;
+ int ret;
+ int len;
+
+ BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+
+ *buf = 0;
+ priv = dev->uclass_priv;
+ ret = gpio_get_raw_function(dev, offset, NULL);
+ if (ret < 0)
+ return ret;
+ func = ret;
+ len = snprintf(str, buffsize, "%s%d: %s",
+ priv->bank_name ? priv->bank_name : "",
+ offset, gpio_function[func]);
+ if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
+ func == GPIOF_UNUSED) {
+ const char *label;
+ bool used;
+
+ ret = ops->get_value(dev, offset);
+ if (ret < 0)
+ return ret;
+ used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
+ snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
+ ret,
+ used ? 'x' : ' ',
+ used ? " " : "",
+ label ? label : "");
+ }
+
+ return 0;
+}
+
/* 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 7104454..693bb56 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -96,6 +96,24 @@ enum gpio_func_t {
struct udevice;
/**
+ * gpio_get_status() - get the current GPIO status as a string
+ *
+ * Obtain the current GPIO status as a string which can be presented to the
+ * user. A typical string is:
+ *
+ * "b4: in: 1 [x] sdmmc_cd"
+ *
+ * which means this is GPIO bank b, offset 4, currently set to input, current
+ * value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
+ *
+ * @dev: Device to check
+ * @offset: Offset of device GPIO to check
+ * @buf: Place to put string
+ * @buffsize: Size of string including \0
+ */
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
+
+/**
* gpio_get_function() - get the current function for a GPIO pin
*
* Note this returns GPIOF_UNUSED if the GPIO is not requested.