From a767d9b22b248095b609a4751ca46ec2b18dbb13 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Wed, 11 Jan 2012 10:59:59 -0800 Subject: [PATCH] Add GPIO get/set commands Signed-off-by: Randall Spangler BUG=chrome-os-partner:7528 TEST=from debug console, gpioget --> prints current level. Run a few times to see DEBUG_LED value toggle. gpioset debug_led 1 --> turns debug LED on. Run repeatedly to override the idle task toggling it off. Change-Id: I7c64044228697e052a9c20eb052d37a1f640f6e7 --- chip/lm4/gpio.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++--- include/gpio.h | 8 +++-- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c index 50216106e3..974f849d8e 100644 --- a/chip/lm4/gpio.c +++ b/chip/lm4/gpio.c @@ -5,6 +5,7 @@ /* GPIO module for Chrome EC */ +#include "console.h" #include "gpio.h" #include "power_button.h" #include "registers.h" @@ -15,20 +16,47 @@ struct gpio_info { + const char *name; int port; /* Port (LM4_GPIO_*) */ int mask; /* Bitmask on that port (0x01 - 0x80) */ void (*irq_handler)(enum gpio_signal signal); }; +/* Macro for signals which don't exist */ +#define SIGNAL_NOT_IMPLEMENTED(name) {name, LM4_GPIO_A, 0x00, NULL} +/* Signal information. Must match order from enum gpio_signal. */ const struct gpio_info signal_info[EC_GPIO_COUNT] = { - {LM4_GPIO_A, 0x80, NULL}, /* DEBUG_LED */ - {LM4_GPIO_C, 0x20, power_button_interrupt}, /* POWER_BUTTON */ - {LM4_GPIO_C, 0x00, NULL}, /* POWER_BUTTON_OUT */ - {LM4_GPIO_D, 0x01, power_button_interrupt}, /* LID_SWITCH */ - {LM4_GPIO_D, 0x00, NULL}, /* LID_SWITCH_OUT */ + /* Signals with interrupt handlers */ + {"POWER_BUTTON", LM4_GPIO_C, 0x20, power_button_interrupt}, + {"LID_SWITCH", LM4_GPIO_D, 0x01, power_button_interrupt}, + /* Other signals */ + {"DEBUG_LED", LM4_GPIO_A, 0x80, NULL}, + SIGNAL_NOT_IMPLEMENTED("POWER_BUTTON_OUT"), + SIGNAL_NOT_IMPLEMENTED("LID_SWITCH_OUT"), }; +#undef SIGNAL_NOT_IMPLEMENTED + + +/* Find a GPIO signal by name. Returns the signal index, or EC_GPIO_COUNT if + * no match. */ +static enum gpio_signal find_signal_by_name(const char *name) +{ + const struct gpio_info *g = signal_info; + int i; + + if (!name || !*name) + return EC_GPIO_COUNT; + + for (i = 0; i < EC_GPIO_COUNT; i++, g++) { + if (!strcasecmp(name, g->name)) + return i; + } + + return EC_GPIO_COUNT; +} + int gpio_pre_init(void) { @@ -112,6 +140,8 @@ int gpio_set_level(enum gpio_signal signal, int value) return EC_SUCCESS; } +/*****************************************************************************/ +/* Interrupt handlers */ static void gpio_interrupt(int port, uint32_t mis) { @@ -136,8 +166,64 @@ static void __gpio_c_interrupt(void) } DECLARE_IRQ(LM4_IRQ_GPIOC, __gpio_c_interrupt, 1); +/*****************************************************************************/ +/* Console commands */ + +static int command_gpio_get(int argc, char **argv) +{ + const struct gpio_info *g = signal_info; + int i; + + uart_puts("Current GPIO levels:\n"); + for (i = 0; i < EC_GPIO_COUNT; i++, g++) { + if (g->mask) + uart_printf(" %d %s\n", gpio_get_level(i), g->name); + else + uart_printf(" - %s\n", g->name); + } + return EC_SUCCESS; +} + + +static int command_gpio_set(int argc, char **argv) +{ + char *e; + int v, i; + + if (argc < 3) { + uart_puts("Usage: gpioset <0|1>\n"); + return EC_ERROR_UNKNOWN; + } + + i = find_signal_by_name(argv[1]); + if (i == EC_GPIO_COUNT) { + uart_puts("Unknown signal name.\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); +} + + +static const struct console_command console_commands[] = { + {"gpioget", command_gpio_get}, + {"gpioset", command_gpio_set}, +}; +static const struct console_group command_group = { + "GPIO", console_commands, ARRAY_SIZE(console_commands) +}; + +/*****************************************************************************/ +/* Initialization */ int gpio_init(void) { + console_register_commands(&command_group); return EC_SUCCESS; } diff --git a/include/gpio.h b/include/gpio.h index 54ea231dba..0d307b8b95 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -12,10 +12,12 @@ /* GPIO signal definitions. */ enum gpio_signal { - EC_GPIO_DEBUG_LED = 0, /* Debug LED */ - EC_GPIO_POWER_BUTTON, /* Power button */ - EC_GPIO_POWER_BUTTON_OUT, /* Power button output to PCH */ + /* Signals with interrupt handlers are first for efficiency */ + EC_GPIO_POWER_BUTTON = 0, /* Power button */ EC_GPIO_LID_SWITCH, /* Lid switch */ + /* Other signals */ + EC_GPIO_DEBUG_LED, /* Debug LED */ + EC_GPIO_POWER_BUTTON_OUT, /* Power button output to PCH */ EC_GPIO_LID_SWITCH_OUT, /* Lid switch output to PCH */ /* Number of GPIOs; not an actual GPIO */ EC_GPIO_COUNT