From 0757535a7eee3ae5603520fe4a0588a01a590ea7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:44 -0600 Subject: [PATCH] dm: Move the function for getting GPIO status into the uclass This function can be more easily tested if it is in the uclass. Signed-off-by: Simon Glass --- common/cmd_gpio.c | 57 ++++++++++++++------------------------ drivers/gpio/gpio-uclass.c | 39 ++++++++++++++++++++++++++ include/asm-generic/gpio.h | 18 ++++++++++++ 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 11f4e4031d..c0cdc5f6fd 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(""); - 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 04b7b16fd6..6367093210 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 71044549ba..693bb56f77 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -95,6 +95,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 * -- 2.39.5