diff options
author | Vic Yang <victoryang@chromium.org> | 2013-05-27 16:14:28 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-06-03 01:40:01 -0700 |
commit | 59efd52ed437bd73fdf5e2fd3d571225969bc211 (patch) | |
tree | dd62e4d99ce548dc3558e30dea94044d145dd69c | |
parent | 7efb1289d6c99db37b120cc2bc7ae19efd4be879 (diff) | |
download | chrome-ec-59efd52ed437bd73fdf5e2fd3d571225969bc211.tar.gz |
Add ectool command to control LED color
This provides a way to control LED color with ectool. We can either set
the color or switch back to automatic control.
BUG=chrome-os-partner:19745
TEST=ectool led red -> LED turns red.
ectool led green -> LED turns green.
Unplug charger -> LED turns off.
ectool led green -> LED turns of and shows green.
ectool led auto -> LED back to normal.
BRANCH=spring
Original-Change-Id: I0b455f34cea448660fe44a5fecaac1cb084f8144
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/56721
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
(cherry picked from commit 87d8f8e5b1ced8647640eef710088d453d0f0e33)
Change-Id: I912db968f030a24527ea2ddbf9c63ad56297b57a
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/56906
-rw-r--r-- | board/spring/board.c | 35 | ||||
-rw-r--r-- | include/ec_commands.h | 14 | ||||
-rw-r--r-- | util/ectool.c | 52 |
3 files changed, 99 insertions, 2 deletions
diff --git a/board/spring/board.c b/board/spring/board.c index 95792f9780..f6d6092b41 100644 --- a/board/spring/board.c +++ b/board/spring/board.c @@ -61,6 +61,9 @@ uint8_t breathing_prog[] = {0x41, 0xff, /* 0x80 -> 0x0 */ 0x00, 0x00}; /* Go to start */ #define BREATHING_PROG_ENTRY 7 +static enum led_state_t last_state = LED_STATE_OFF; +static int led_auto_control = 1; + /* GPIO interrupt handlers prototypes */ #ifndef CONFIG_TASK_GAIAPOWER #define gaia_power_event NULL @@ -350,13 +353,12 @@ static int stop_led_engine(void) static int set_led_color(enum led_state_t state) { - static enum led_state_t last_state = LED_STATE_OFF; int rv; ASSERT(state != LED_STATE_TRANSITION_ON && state != LED_STATE_TRANSITION_OFF); - if (state == last_state) + if (!led_auto_control || state == last_state) return EC_SUCCESS; switch (state) { @@ -453,6 +455,35 @@ static void board_stablize_led(enum led_state_t desired_state) current_state = next_state; } +/*****************************************************************************/ +/* Host commands */ + +static int led_command_set(struct host_cmd_handler_args *args) +{ + const struct ec_params_led_set *p = args->params; + + if (p->flags & EC_LED_FLAGS_AUTO) { + if (!board_get_ac()) + lp5562_poweroff(); + last_state = LED_STATE_OFF; + led_auto_control = 1; + } else { + led_auto_control = 0; + if (!board_get_ac()) + lp5562_poweron(); + if (lp5562_set_color((p->r << 16) + (p->g << 8) + p->b)) + return EC_RES_ERROR; + } + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_LED_SET, + led_command_set, + EC_VER_MASK(0)); + +/*****************************************************************************/ +/* Hooks */ + static void board_battery_led_update(void) { int current; diff --git a/include/ec_commands.h b/include/ec_commands.h index 84b5d5582a..b16871462e 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -727,6 +727,20 @@ enum lightbar_command { }; /*****************************************************************************/ +/* LED control commands */ + +#define EC_CMD_LED_SET 0x29 + +#define EC_LED_FLAGS_AUTO (1 << 1) + +struct ec_params_led_set { + uint8_t r; + uint8_t g; + uint8_t b; /* Used as yellow if there is no blue LED */ + uint8_t flags; +} __packed; + +/*****************************************************************************/ /* Verified boot commands */ /* diff --git a/util/ectool.c b/util/ectool.c index ff40734529..c5ebf30c6f 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -98,6 +98,8 @@ const char help_str[] = " Write I2C bus\n" " keyscan <beat_us> <filename>\n" " Test low-level key scanning\n" + " led <auto | red | green | blue | <R> <G> <B>>\n" + " Set the color of LED\n" " lightbar [CMDS]\n" " Various lightbar control commands\n" " port80flood\n" @@ -1403,6 +1405,55 @@ static int cmd_lightbar(int argc, char **argv) } +int cmd_led(int argc, char *argv[]) +{ + struct ec_params_led_set p; + char *e; + int rv; + + if (argc == 1) { + fprintf(stderr, + "Usage: %s <auto | red | green | blue | " + "<R> <G> <B>>\n", argv[0]); + return -1; + } + + p.r = p.g = p.b = p.flags = 0; + + if (!strcasecmp(argv[1], "auto")) { + p.flags = EC_LED_FLAGS_AUTO; + } else if (!strcasecmp(argv[1], "red")) { + p.r = 0xff; + } else if (!strcasecmp(argv[1], "green")) { + p.g = 0xff; + } else if (!strcasecmp(argv[1], "blue")) { + p.b = 0xff; + } else if (argc != 4) { + fprintf(stderr, "Incorrect number of arguments\n"); + return -1; + } else { + p.r = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad R value.\n"); + return -1; + } + p.g = strtol(argv[2], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad G value.\n"); + return -1; + } + p.b = strtol(argv[3], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad B value.\n"); + return -1; + } + p.flags = 0; + } + rv = ec_command(EC_CMD_LED_SET, 0, &p, sizeof(p), NULL, 0); + return (rv < 0 ? rv : 0); +} + + int cmd_usb_charge_set_mode(int argc, char *argv[]) { struct ec_params_usb_charge_set_mode p; @@ -2791,6 +2842,7 @@ const struct command commands[] = { {"kbpress", cmd_kbpress}, {"i2cread", cmd_i2c_read}, {"i2cwrite", cmd_i2c_write}, + {"led", cmd_led}, {"lightbar", cmd_lightbar}, {"keyconfig", cmd_keyconfig}, {"keyscan", cmd_keyscan}, |