Add GPIO get/set commands

Signed-off-by: Randall Spangler <rspangler@chromium.org>

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
This commit is contained in:
Randall Spangler
2012-01-11 10:59:59 -08:00
parent 39f86d2fad
commit a767d9b22b
2 changed files with 96 additions and 8 deletions

View File

@@ -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 <signal_name> <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;
}

View File

@@ -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