diff options
author | Vic Yang <victoryang@chromium.org> | 2013-05-27 16:14:28 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-05-28 12:53:51 -0700 |
commit | 87d8f8e5b1ced8647640eef710088d453d0f0e33 (patch) | |
tree | 2af7b6bdf6ec8b3e88471de07198baa9f8c86e8f | |
parent | 99e3fc93e697d646925972790060805e72e39da5 (diff) | |
download | chrome-ec-87d8f8e5b1ced8647640eef710088d453d0f0e33.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
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>
-rw-r--r-- | common/lp5562_battery_led.c | 37 | ||||
-rw-r--r-- | include/ec_commands.h | 14 | ||||
-rw-r--r-- | util/ectool.c | 52 |
3 files changed, 101 insertions, 2 deletions
diff --git a/common/lp5562_battery_led.c b/common/lp5562_battery_led.c index f041499f7a..165bbc9eca 100644 --- a/common/lp5562_battery_led.c +++ b/common/lp5562_battery_led.c @@ -6,8 +6,10 @@ */ #include "common.h" +#include "ec_commands.h" #include "extpower.h" #include "hooks.h" +#include "host_command.h" #include "lp5562.h" #include "pmu_tpschrome.h" #include "smart_battery.h" @@ -44,6 +46,9 @@ static const 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; + static int stop_led_engine(void) { int pc; @@ -67,13 +72,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) { @@ -170,6 +174,35 @@ static void 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 (!extpower_is_present()) + lp5562_poweroff(); + last_state = LED_STATE_OFF; + led_auto_control = 1; + } else { + led_auto_control = 0; + if (!extpower_is_present()) + 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 battery_led_update(void) { int current; diff --git a/include/ec_commands.h b/include/ec_commands.h index 4f226f7abf..d4a88f510b 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -723,6 +723,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 97d9a4a3a0..85da6327a2 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -98,6 +98,8 @@ const char help_str[] = " Perform I2C transfer on EC's 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; @@ -2910,6 +2961,7 @@ const struct command commands[] = { {"i2cread", cmd_i2c_read}, {"i2cwrite", cmd_i2c_write}, {"i2cxfer", cmd_i2c_xfer}, + {"led", cmd_led}, {"lightbar", cmd_lightbar}, {"keyconfig", cmd_keyconfig}, {"keyscan", cmd_keyscan}, |