diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-02-02 20:26:38 +0000 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-02-03 02:00:27 +0000 |
commit | a72b9cc07ea79a89bd08e3b80ac3e84136016ba2 (patch) | |
tree | 094550a9a7550bb0baa5e670159fcd334f2013d9 /common | |
parent | 54f36995a4b626280b868f1efe6049591f3fc53c (diff) | |
download | chrome-ec-a72b9cc07ea79a89bd08e3b80ac3e84136016ba2.tar.gz |
Split out GPIO console commands
The GPIO console commands are common to all platform, let's push them in
the common code.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=None
TEST=make BOARD=link && make BOARD=bds && make BOARD=discovery
on BDS console, try gpioget command.
Change-Id: I26e6d26b8d661e78b80d5d5f665e81f4daef0c11
Diffstat (limited to 'common')
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/gpio_commands.c | 129 |
2 files changed, 130 insertions, 0 deletions
diff --git a/common/build.mk b/common/build.mk index 2956407689..397188f255 100644 --- a/common/build.mk +++ b/common/build.mk @@ -7,6 +7,7 @@ common-y=main.o util.o console.o vboot.o uart_buffering.o common-y+=memory_commands.o shared_mem.o system.o usb_charge.o +common-y+=gpio_commands.o common-$(CONFIG_LPC)+=port80.o common-$(CONFIG_TASK_HOSTCMD)+=host_command.o common-$(CONFIG_TASK_I8042CMD)+=i8042.o keyboard.o diff --git a/common/gpio_commands.c b/common/gpio_commands.c new file mode 100644 index 0000000000..66bebb4b8d --- /dev/null +++ b/common/gpio_commands.c @@ -0,0 +1,129 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* GPIO console commands for Chrome EC */ + +#include "board.h" +#include "console.h" +#include "gpio.h" +#include "uart.h" +#include "util.h" + + +/* Signal information from board.c. Must match order from enum gpio_signal. */ +extern const struct gpio_info gpio_list[GPIO_COUNT]; + + +/* Find a GPIO signal by name. Returns the signal index, or GPIO_COUNT if + * no match. */ +static enum gpio_signal find_signal_by_name(const char *name) +{ + const struct gpio_info *g = gpio_list; + int i; + + if (!name || !*name) + return GPIO_COUNT; + + for (i = 0; i < GPIO_COUNT; i++, g++) { + if (!strcasecmp(name, g->name)) + return i; + } + + return GPIO_COUNT; +} + + +static uint8_t last_val[(GPIO_COUNT + 7) / 8]; + +/* If v is different from the last value for index i, updates the last value + * and returns 1; else returns 0. */ +static int last_val_changed(int i, int v) +{ + if (v && !(last_val[i / 8] & (1 << (i % 8)))) { + last_val[i / 8] |= 1 << (i % 8); + return 1; + } else if (!v && last_val[i / 8] & (1 << (i % 8))) { + last_val[i / 8] &= ~(1 << (i % 8)); + return 1; + } else { + return 0; + } +} + +static int command_gpio_get(int argc, char **argv) +{ + const struct gpio_info *g = gpio_list; + int changed, v, i; + + /* If a signal is specified, print only that one */ + if (argc == 2) { + i = find_signal_by_name(argv[1]); + if (i == GPIO_COUNT) { + uart_puts("Unknown signal name.\n"); + return EC_ERROR_UNKNOWN; + } + g = gpio_list + i; + v = gpio_get_level(i); + changed = last_val_changed(i, v); + uart_printf(" %d%c %s\n", v, (changed ? '*' : ' '), g->name); + + return EC_SUCCESS; + } + + /* Otherwise print them all */ + uart_puts("Current GPIO levels:\n"); + for (i = 0; i < GPIO_COUNT; i++, g++) { + if (!g->mask) + continue; /* Skip unsupported signals */ + + v = gpio_get_level(i); + changed = last_val_changed(i, v); + uart_printf(" %d%c %s\n", v, (changed ? '*' : ' '), g->name); + + /* We have enough GPIOs that we'll overflow the output buffer + * without flushing */ + uart_flush_output(); + } + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(gpioget, command_gpio_get); + + +static int command_gpio_set(int argc, char **argv) +{ + const struct gpio_info *g; + char *e; + int v, i; + + if (argc < 3) { + uart_puts("Usage: gpioset <signal_name> <0|1>\n"); + return EC_ERROR_UNKNOWN; + } + + i = find_signal_by_name(argv[1]); + if (i == GPIO_COUNT) { + uart_puts("Unknown signal name.\n"); + return EC_ERROR_UNKNOWN; + } + g = gpio_list + i; + + if (!g->mask) { + uart_puts("Signal is not implemented.\n"); + return EC_ERROR_UNKNOWN; + } + if (!(g->flags & GPIO_OUTPUT)) { + uart_puts("Signal is not an output.\n"); + return EC_ERROR_UNKNOWN; + } + + v = strtoi(argv[2], &e, 0); + if (*e) { + uart_puts("Invalid signal value.\n"); + return EC_ERROR_UNKNOWN; + } + + return gpio_set_level(i, v); +} +DECLARE_CONSOLE_COMMAND(gpioset, command_gpio_set); |