Commit 141e1faec2cd594dafb2edad6da8baa6a681cf37
Exists in
v2017.01-smarct4x
and in
40 other branches
Merge git://git.denx.de/u-boot-dm
Showing 3 changed files Side-by-side Diff
arch/sandbox/dts/sandbox.dts
common/cmd_gpio.c
| ... | ... | @@ -8,6 +8,7 @@ |
| 8 | 8 | |
| 9 | 9 | #include <common.h> |
| 10 | 10 | #include <command.h> |
| 11 | +#include <errno.h> | |
| 11 | 12 | #include <dm.h> |
| 12 | 13 | #include <asm/gpio.h> |
| 13 | 14 | |
| 14 | 15 | |
| 15 | 16 | |
| 16 | 17 | |
| 17 | 18 | |
| 18 | 19 | |
| ... | ... | @@ -24,18 +25,46 @@ |
| 24 | 25 | }; |
| 25 | 26 | |
| 26 | 27 | #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) |
| 27 | -static const char * const gpio_function[] = { | |
| 28 | +static const char * const gpio_function[GPIOF_COUNT] = { | |
| 28 | 29 | "input", |
| 29 | 30 | "output", |
| 31 | + "unused", | |
| 30 | 32 | "unknown", |
| 33 | + "func", | |
| 31 | 34 | }; |
| 32 | 35 | |
| 33 | -static void show_gpio(struct udevice *dev, const char *bank_name, int offset) | |
| 36 | +/* A few flags used by show_gpio() */ | |
| 37 | +enum { | |
| 38 | + FLAG_SHOW_ALL = 1 << 0, | |
| 39 | + FLAG_SHOW_BANK = 1 << 1, | |
| 40 | + FLAG_SHOW_NEWLINE = 1 << 2, | |
| 41 | +}; | |
| 42 | + | |
| 43 | +static void show_gpio(struct udevice *dev, const char *bank_name, int offset, | |
| 44 | + int *flagsp) | |
| 34 | 45 | { |
| 35 | 46 | struct dm_gpio_ops *ops = gpio_get_ops(dev); |
| 47 | + int func = GPIOF_UNKNOWN; | |
| 36 | 48 | char buf[80]; |
| 37 | 49 | int ret; |
| 38 | 50 | |
| 51 | + BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); | |
| 52 | + | |
| 53 | + if (ops->get_function) { | |
| 54 | + ret = ops->get_function(dev, offset); | |
| 55 | + if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) | |
| 56 | + func = ret; | |
| 57 | + } | |
| 58 | + if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED) | |
| 59 | + return; | |
| 60 | + if ((*flagsp & FLAG_SHOW_BANK) && bank_name) { | |
| 61 | + if (*flagsp & FLAG_SHOW_NEWLINE) { | |
| 62 | + putc('\n'); | |
| 63 | + *flagsp &= ~FLAG_SHOW_NEWLINE; | |
| 64 | + } | |
| 65 | + printf("Bank %s:\n", bank_name); | |
| 66 | + *flagsp &= ~FLAG_SHOW_BANK; | |
| 67 | + } | |
| 39 | 68 | *buf = '\0'; |
| 40 | 69 | if (ops->get_state) { |
| 41 | 70 | ret = ops->get_state(dev, offset, buf, sizeof(buf)); |
| ... | ... | @@ -44,14 +73,6 @@ |
| 44 | 73 | return; |
| 45 | 74 | } |
| 46 | 75 | } else { |
| 47 | - int func = GPIOF_UNKNOWN; | |
| 48 | - int ret; | |
| 49 | - | |
| 50 | - if (ops->get_function) { | |
| 51 | - ret = ops->get_function(dev, offset); | |
| 52 | - if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) | |
| 53 | - func = ret; | |
| 54 | - } | |
| 55 | 76 | sprintf(buf, "%s%u: %8s %d", bank_name, offset, |
| 56 | 77 | gpio_function[func], ops->get_value(dev, offset)); |
| 57 | 78 | } |
| 58 | 79 | |
| 59 | 80 | |
| ... | ... | @@ -60,12 +81,14 @@ |
| 60 | 81 | puts("\n"); |
| 61 | 82 | } |
| 62 | 83 | |
| 63 | -static int do_gpio_status(const char *gpio_name) | |
| 84 | +static int do_gpio_status(bool all, const char *gpio_name) | |
| 64 | 85 | { |
| 65 | 86 | struct udevice *dev; |
| 66 | - int newline = 0; | |
| 87 | + int banklen; | |
| 88 | + int flags; | |
| 67 | 89 | int ret; |
| 68 | 90 | |
| 91 | + flags = 0; | |
| 69 | 92 | if (gpio_name && !*gpio_name) |
| 70 | 93 | gpio_name = NULL; |
| 71 | 94 | for (ret = uclass_first_device(UCLASS_GPIO, &dev); |
| 72 | 95 | |
| 73 | 96 | |
| 74 | 97 | |
| 75 | 98 | |
| 76 | 99 | |
| 77 | 100 | |
| ... | ... | @@ -74,28 +97,33 @@ |
| 74 | 97 | const char *bank_name; |
| 75 | 98 | int num_bits; |
| 76 | 99 | |
| 100 | + flags |= FLAG_SHOW_BANK; | |
| 101 | + if (all) | |
| 102 | + flags |= FLAG_SHOW_ALL; | |
| 77 | 103 | bank_name = gpio_get_bank_info(dev, &num_bits); |
| 104 | + if (!num_bits) | |
| 105 | + continue; | |
| 106 | + banklen = bank_name ? strlen(bank_name) : 0; | |
| 78 | 107 | |
| 79 | 108 | if (!gpio_name || !bank_name || |
| 80 | - !strncmp(gpio_name, bank_name, strlen(bank_name))) { | |
| 109 | + !strncmp(gpio_name, bank_name, banklen)) { | |
| 81 | 110 | const char *p = NULL; |
| 82 | 111 | int offset; |
| 83 | 112 | |
| 84 | - if (bank_name) { | |
| 85 | - if (newline) | |
| 86 | - putc('\n'); | |
| 87 | - printf("Bank %s:\n", bank_name); | |
| 88 | - } | |
| 89 | - newline = 1; | |
| 90 | - if (gpio_name && bank_name) { | |
| 91 | - p = gpio_name + strlen(bank_name); | |
| 113 | + p = gpio_name + banklen; | |
| 114 | + if (gpio_name && *p) { | |
| 92 | 115 | offset = simple_strtoul(p, NULL, 10); |
| 93 | - show_gpio(dev, bank_name, offset); | |
| 116 | + show_gpio(dev, bank_name, offset, &flags); | |
| 94 | 117 | } else { |
| 95 | - for (offset = 0; offset < num_bits; offset++) | |
| 96 | - show_gpio(dev, bank_name, offset); | |
| 118 | + for (offset = 0; offset < num_bits; offset++) { | |
| 119 | + show_gpio(dev, bank_name, offset, | |
| 120 | + &flags); | |
| 121 | + } | |
| 97 | 122 | } |
| 98 | 123 | } |
| 124 | + /* Add a newline between bank names */ | |
| 125 | + if (!(flags & FLAG_SHOW_BANK)) | |
| 126 | + flags |= FLAG_SHOW_NEWLINE; | |
| 99 | 127 | } |
| 100 | 128 | |
| 101 | 129 | return ret; |
| 102 | 130 | |
| 103 | 131 | |
| 104 | 132 | |
| ... | ... | @@ -108,23 +136,33 @@ |
| 108 | 136 | enum gpio_cmd sub_cmd; |
| 109 | 137 | ulong value; |
| 110 | 138 | const char *str_cmd, *str_gpio = NULL; |
| 111 | -#ifdef CONFIG_DM_GPIO | |
| 112 | 139 | int ret; |
| 140 | +#ifdef CONFIG_DM_GPIO | |
| 141 | + bool all = false; | |
| 113 | 142 | #endif |
| 114 | 143 | |
| 115 | 144 | if (argc < 2) |
| 116 | 145 | show_usage: |
| 117 | 146 | return CMD_RET_USAGE; |
| 118 | 147 | str_cmd = argv[1]; |
| 119 | - if (argc > 2) | |
| 120 | - str_gpio = argv[2]; | |
| 148 | + argc -= 2; | |
| 149 | + argv += 2; | |
| 150 | +#ifdef CONFIG_DM_GPIO | |
| 151 | + if (argc > 0 && !strcmp(*argv, "-a")) { | |
| 152 | + all = true; | |
| 153 | + argc--; | |
| 154 | + argv++; | |
| 155 | + } | |
| 156 | +#endif | |
| 157 | + if (argc > 0) | |
| 158 | + str_gpio = *argv; | |
| 121 | 159 | if (!strcmp(str_cmd, "status")) { |
| 122 | 160 | /* Support deprecated gpio_status() */ |
| 123 | 161 | #ifdef gpio_status |
| 124 | 162 | gpio_status(); |
| 125 | 163 | return 0; |
| 126 | 164 | #elif defined(CONFIG_DM_GPIO) |
| 127 | - return cmd_process_error(cmdtp, do_gpio_status(str_gpio)); | |
| 165 | + return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio)); | |
| 128 | 166 | #else |
| 129 | 167 | goto show_usage; |
| 130 | 168 | #endif |
| ... | ... | @@ -160,7 +198,8 @@ |
| 160 | 198 | goto show_usage; |
| 161 | 199 | #endif |
| 162 | 200 | /* grab the pin before we tweak it */ |
| 163 | - if (gpio_request(gpio, "cmd_gpio")) { | |
| 201 | + ret = gpio_request(gpio, "cmd_gpio"); | |
| 202 | + if (ret && ret != -EBUSY) { | |
| 164 | 203 | printf("gpio: requesting pin %u failed\n", gpio); |
| 165 | 204 | return -1; |
| 166 | 205 | } |
| 167 | 206 | |
| ... | ... | @@ -181,14 +220,15 @@ |
| 181 | 220 | printf("gpio: pin %s (gpio %i) value is %lu\n", |
| 182 | 221 | str_gpio, gpio, value); |
| 183 | 222 | |
| 184 | - gpio_free(gpio); | |
| 223 | + if (ret != -EBUSY) | |
| 224 | + gpio_free(gpio); | |
| 185 | 225 | |
| 186 | 226 | return value; |
| 187 | 227 | } |
| 188 | 228 | |
| 189 | -U_BOOT_CMD(gpio, 3, 0, do_gpio, | |
| 190 | - "query and control gpio pins", | |
| 191 | - "<input|set|clear|toggle> <pin>\n" | |
| 192 | - " - input/set/clear/toggle the specified pin\n" | |
| 193 | - "gpio status [<bank> | <pin>]"); | |
| 229 | +U_BOOT_CMD(gpio, 4, 0, do_gpio, | |
| 230 | + "query and control gpio pins", | |
| 231 | + "<input|set|clear|toggle> <pin>\n" | |
| 232 | + " - input/set/clear/toggle the specified pin\n" | |
| 233 | + "gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs"); |
include/asm-generic/gpio.h
| ... | ... | @@ -79,11 +79,15 @@ |
| 79 | 79 | */ |
| 80 | 80 | int gpio_set_value(unsigned gpio, int value); |
| 81 | 81 | |
| 82 | -/* State of a GPIO, as reported by get_state() */ | |
| 82 | +/* State of a GPIO, as reported by get_function() */ | |
| 83 | 83 | enum { |
| 84 | 84 | GPIOF_INPUT = 0, |
| 85 | 85 | GPIOF_OUTPUT, |
| 86 | - GPIOF_UNKNOWN, | |
| 86 | + GPIOF_UNUSED, /* Not claimed */ | |
| 87 | + GPIOF_UNKNOWN, /* Not known */ | |
| 88 | + GPIOF_FUNC, /* Not used as a GPIO */ | |
| 89 | + | |
| 90 | + GPIOF_COUNT, | |
| 87 | 91 | }; |
| 88 | 92 | |
| 89 | 93 | struct udevice; |
| ... | ... | @@ -123,6 +127,13 @@ |
| 123 | 127 | int value); |
| 124 | 128 | int (*get_value)(struct udevice *dev, unsigned offset); |
| 125 | 129 | int (*set_value)(struct udevice *dev, unsigned offset, int value); |
| 130 | + /** | |
| 131 | + * get_function() Get the GPIO function | |
| 132 | + * | |
| 133 | + * @dev: Device to check | |
| 134 | + * @offset: GPIO offset within that device | |
| 135 | + * @return current function - GPIOF_... | |
| 136 | + */ | |
| 126 | 137 | int (*get_function)(struct udevice *dev, unsigned offset); |
| 127 | 138 | int (*get_state)(struct udevice *dev, unsigned offset, char *state, |
| 128 | 139 | int maxlen); |