mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user