summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-05-27 16:14:28 +0800
committerChromeBot <chrome-bot@google.com>2013-05-28 12:53:51 -0700
commit87d8f8e5b1ced8647640eef710088d453d0f0e33 (patch)
tree2af7b6bdf6ec8b3e88471de07198baa9f8c86e8f
parent99e3fc93e697d646925972790060805e72e39da5 (diff)
downloadchrome-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.c37
-rw-r--r--include/ec_commands.h14
-rw-r--r--util/ectool.c52
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},