diff options
author | Nick Sanders <nsanders@chromium.org> | 2016-04-13 22:15:02 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-27 14:04:07 -0700 |
commit | 4e52ae607c569e9d240e3ce3363659c840f1aa87 (patch) | |
tree | 6824faac11c4b35ebce8599f41e39c28351eb816 /common/gpio_commands.c | |
parent | d18cb0e81f2ba3c71349d17c7d84e7e10066711e (diff) | |
download | chrome-ec-4e52ae607c569e9d240e3ce3363659c840f1aa87.tar.gz |
servo_micro: add gpio mode get and set
GPIO console commands currently only show input voltage level,
and can only set level on predefined outputs.
This change allows GPIOs to be cycled between output, input,
and alternate function, as well as displaying the mode and
asserted level (if any) in gpioget.
This change creates CONFIG_CMD_GPIO_EXTENDED
as the internal gpio interface needs to be changed to support
this, and I can't test the other architectures. It may be
worthwhile to add this for all, or not.
This change is also necessary also for servo micro JTAG and PD
UART support, as several pins are tied together on the flex
and stm32 outputs need to be variously active or in high-z
depending on mode.
BUG=chromium:571477
TEST=gpioget <0|1|IN|A|ALT>; gpioget;
BRANCH=None
Change-Id: Iba32992db6244ee1e654db840d1c9c11dd2a0993
Signed-off-by: Nick Sanders <nsanders@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/338885
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'common/gpio_commands.c')
-rw-r--r-- | common/gpio_commands.c | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/common/gpio_commands.c b/common/gpio_commands.c index 25185597ea..e3ce1d046d 100644 --- a/common/gpio_commands.c +++ b/common/gpio_commands.c @@ -77,19 +77,47 @@ static enum ec_error_list set(const char *name, int value) /*****************************************************************************/ /* Console commands */ +static void print_gpio_info(int gpio) +{ + int changed, v, flags; + + if (!gpio_is_implemented(gpio)) + return; /* Skip unsupported signals */ + + v = gpio_get_level(gpio); +#ifdef CONFIG_CMD_GPIO_EXTENDED + flags = gpio_get_flags(gpio); +#else + flags = 0; +#endif + changed = last_val_changed(gpio, v); + + ccprintf(" %d%c %s%s%s%s%s%s%s%s%s%s\n", v, (changed ? '*' : ' '), + (flags & GPIO_INPUT ? "I " : ""), + (flags & GPIO_OUTPUT ? "O " : ""), + (flags & GPIO_LOW ? "L " : ""), + (flags & GPIO_HIGH ? "H " : ""), + (flags & GPIO_ANALOG ? "A " : ""), + (flags & GPIO_OPEN_DRAIN ? "ODR " : ""), + (flags & GPIO_PULL_UP ? "PU " : ""), + (flags & GPIO_PULL_DOWN ? "PD " : ""), + (flags & GPIO_ALTERNATE ? "ALT " : ""), + gpio_get_name(gpio)); + + /* Flush console to avoid truncating output */ + cflush(); +} + static int command_gpio_get(int argc, char **argv) { - int changed, v, i; + int i; /* If a signal is specified, print only that one */ if (argc == 2) { i = find_signal_by_name(argv[1]); if (i == GPIO_COUNT) return EC_ERROR_PARAM1; - v = gpio_get_level(i); - changed = last_val_changed(i, v); - ccprintf(" %d%c %s\n", v, (changed ? '*' : ' '), - gpio_get_name(i)); + print_gpio_info(i); return EC_SUCCESS; } @@ -99,13 +127,7 @@ static int command_gpio_get(int argc, char **argv) if (!gpio_is_implemented(i)) continue; /* Skip unsupported signals */ - v = gpio_get_level(i); - changed = last_val_changed(i, v); - ccprintf(" %d%c %s\n", v, (changed ? '*' : ' '), - gpio_get_name(i)); - - /* Flush console to avoid truncating output */ - cflush(); + print_gpio_info(i); } return EC_SUCCESS; @@ -117,6 +139,46 @@ DECLARE_CONSOLE_COMMAND(gpioget, command_gpio_get, static int command_gpio_set(int argc, char **argv) { +#ifdef CONFIG_CMD_GPIO_EXTENDED + int gpio; + int flags = 0; + int af = -1; + char *e; + + if (argc < 3) + return EC_ERROR_PARAM_COUNT; + + gpio = find_signal_by_name(argv[1]); + if (gpio == GPIO_COUNT) + return EC_ERROR_PARAM1; + + if (strcasecmp(argv[2], "IN") == 0) + flags = GPIO_INPUT; + else if (strcasecmp(argv[2], "1") == 0) + flags = GPIO_OUT_HIGH; + else if (strcasecmp(argv[2], "0") == 0) + flags = GPIO_OUT_LOW; + else if (strcasecmp(argv[2], "A") == 0) + flags = GPIO_ANALOG; + else if (strcasecmp(argv[2], "ALT") == 0) { + if (argc >= 4) { + af = strtoi(argv[3], &e, 0); + if (*e || af < 0 || af > 5) + return EC_ERROR_PARAM2; + } + flags = GPIO_ALTERNATE; + } else + return EC_ERROR_PARAM2; + + /* Update alt function if requested. */ + if (af >= 0) { + const struct gpio_info *g = gpio_list + gpio; + + gpio_set_alternate_function(g->port, g->mask, af); + } + /* Update GPIO flags. */ + gpio_set_flags(gpio, flags); +#else char *e; int v; @@ -129,11 +191,15 @@ static int command_gpio_set(int argc, char **argv) if (set(argv[1], v) != EC_SUCCESS) return EC_ERROR_PARAM1; - +#endif return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(gpioset, command_gpio_set, +#ifdef CONFIG_CMD_GPIO_EXTENDED + "name <0 | 1 | IN | A | ALT [func]>", +#else "name <0 | 1>", +#endif "Set a GPIO", NULL); |