X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=common%2Fcmd_gpio.c;h=58d8125f84dac75a7ea0db3099c04d838ea9064d;hp=4634f914e66d97a0bc9fe0f244fb957cf4b544d1;hb=867e58744bc55c8ba8235109cf3fc12a1bc0756e;hpb=f23adc9f219977e603cf057a2704605349f02d36 diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 4634f914e6..58d8125f84 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -8,10 +8,11 @@ #include #include +#include #include #include -int __weak name_to_gpio(const char *name) +__weak int name_to_gpio(const char *name) { return simple_strtoul(name, NULL, 10); } @@ -24,48 +25,52 @@ enum gpio_cmd { }; #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) -static const char * const gpio_function[] = { - "input", - "output", - "unknown", + +/* A few flags used by show_gpio() */ +enum { + FLAG_SHOW_ALL = 1 << 0, + FLAG_SHOW_BANK = 1 << 1, + FLAG_SHOW_NEWLINE = 1 << 2, }; -static void show_gpio(struct udevice *dev, const char *bank_name, int offset) +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); char buf[80]; int ret; - *buf = '\0'; - if (ops->get_state) { - ret = ops->get_state(dev, offset, buf, sizeof(buf)); - if (ret) { - puts(""); - return; - } - } else { - int func = GPIOF_UNKNOWN; - int ret; - - if (ops->get_function) { - ret = ops->get_function(dev, offset); - if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) - func = ret; + 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) { + putc('\n'); + *flagsp &= ~FLAG_SHOW_NEWLINE; } - sprintf(buf, "%s%u: %8s %d", bank_name, offset, - gpio_function[func], ops->get_value(dev, offset)); + printf("Bank %s:\n", bank_name); + *flagsp &= ~FLAG_SHOW_BANK; } - 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(const char *gpio_name) +static int do_gpio_status(bool all, const char *gpio_name) { struct udevice *dev; - int newline = 0; + int banklen; + int flags; int ret; + flags = 0; if (gpio_name && !*gpio_name) gpio_name = NULL; for (ret = uclass_first_device(UCLASS_GPIO, &dev); @@ -74,28 +79,36 @@ static int do_gpio_status(const char *gpio_name) const char *bank_name; int num_bits; + flags |= FLAG_SHOW_BANK; + if (all) + flags |= FLAG_SHOW_ALL; bank_name = gpio_get_bank_info(dev, &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 || - !strncmp(gpio_name, bank_name, strlen(bank_name))) { + !strncmp(gpio_name, bank_name, banklen)) { const char *p = NULL; int offset; - if (bank_name) { - if (newline) - putc('\n'); - printf("Bank %s:\n", bank_name); - } - newline = 1; - if (gpio_name && bank_name) { - p = gpio_name + strlen(bank_name); + p = gpio_name + banklen; + if (gpio_name && *p) { offset = simple_strtoul(p, NULL, 10); - show_gpio(dev, bank_name, offset); + gpio_get_description(dev, bank_name, offset, + &flags); } else { - for (offset = 0; offset < num_bits; offset++) - show_gpio(dev, bank_name, offset); + for (offset = 0; offset < num_bits; offset++) { + gpio_get_description(dev, bank_name, + offset, &flags); + } } } + /* Add a newline between bank names */ + if (!(flags & FLAG_SHOW_BANK)) + flags |= FLAG_SHOW_NEWLINE; } return ret; @@ -108,23 +121,33 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) enum gpio_cmd sub_cmd; ulong value; const char *str_cmd, *str_gpio = NULL; -#ifdef CONFIG_DM_GPIO int ret; +#ifdef CONFIG_DM_GPIO + bool all = false; #endif if (argc < 2) show_usage: return CMD_RET_USAGE; str_cmd = argv[1]; - if (argc > 2) - str_gpio = argv[2]; + argc -= 2; + argv += 2; +#ifdef CONFIG_DM_GPIO + if (argc > 0 && !strcmp(*argv, "-a")) { + all = true; + argc--; + argv++; + } +#endif + if (argc > 0) + str_gpio = *argv; if (!strcmp(str_cmd, "status")) { /* Support deprecated gpio_status() */ #ifdef gpio_status gpio_status(); return 0; #elif defined(CONFIG_DM_GPIO) - return cmd_process_error(cmdtp, do_gpio_status(str_gpio)); + return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio)); #else goto show_usage; #endif @@ -160,9 +183,10 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto show_usage; #endif /* grab the pin before we tweak it */ - if (gpio_request(gpio, "cmd_gpio")) { + ret = gpio_request(gpio, "cmd_gpio"); + if (ret && ret != -EBUSY) { printf("gpio: requesting pin %u failed\n", gpio); - return -1; + return CMD_RET_FAILURE; } /* finally, let's do it: set direction and exec command */ @@ -181,13 +205,14 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("gpio: pin %s (gpio %i) value is %lu\n", str_gpio, gpio, value); - gpio_free(gpio); + if (ret != -EBUSY) + gpio_free(gpio); - return value; + return (ret && ret != -EBUSY) ? CMD_RET_FAILURE : CMD_RET_SUCCESS; } -U_BOOT_CMD(gpio, 3, 0, do_gpio, - "query and control gpio pins", - " \n" - " - input/set/clear/toggle the specified pin\n" - "gpio status [ | ]"); +U_BOOT_CMD(gpio, 4, 0, do_gpio, + "query and control gpio pins", + " \n" + " - input/set/clear/toggle the specified pin\n" + "gpio status [-a] [ | ] - show [all/claimed] GPIOs");