summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-05-29 10:26:18 +0800
committerChromeBot <chrome-bot@google.com>2013-06-04 07:35:59 -0700
commit97612af4101da4f83626185ad9cbe556c00ae3b5 (patch)
treea25acc6902db9e4c91f30c563108e43a4ba0e4aa
parent18509e27346cd150d56cb8bf0b5c7307c4dc5ad3 (diff)
downloadchrome-ec-97612af4101da4f83626185ad9cbe556c00ae3b5.tar.gz
Make ectool LED command more generic
This adds the option to specify which LED to control as well as the ability to query the supported LED color on the board. BUG=chrome-os-partner:19745 TEST=On Spring: - ectool led 0 query -> See the max value for R, G, Y is 0x80. - ectool led 1 query -> See error message. - ectool led 0 yellow -> See LED turns yellow. - ectool led 0 green=0x40 red=0x40 -> See green and red lit up. - ectool led 0 auto -> See LED turns off (without charger.) BRANCH=spring Original-Change-Id: Ibdde2f7450122f59383dad1030a0a2a985386f73 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/56877 (cherry picked from commit e52aba6ecac45d2c27acc78316e835620840408a) Change-Id: Ib6bbf6b52f36c82a616c02a60296c8ec9834e382 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/57414 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/spring/board.c67
-rw-r--r--include/ec_commands.h43
-rw-r--r--util/ectool.c100
3 files changed, 144 insertions, 66 deletions
diff --git a/board/spring/board.c b/board/spring/board.c
index db65e77986..117338d469 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -342,32 +342,6 @@ static int set_led_color(enum led_state_t 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)
@@ -458,3 +432,44 @@ static int power_command_info(struct host_cmd_handler_args *args)
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_POWER_INFO, power_command_info, EC_VER_MASK(0));
+
+static int led_command_control(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_led_control *p = args->params;
+ struct ec_response_led_control *r = args->response;
+ int i;
+ uint8_t clipped[EC_LED_COLOR_COUNT];
+
+ /* Only support battery LED control */
+ if (p->led_id != EC_LED_ID_BATTERY_LED)
+ return EC_RES_INVALID_PARAM;
+
+ if (p->flags & EC_LED_FLAGS_AUTO) {
+ if (!board_get_ac())
+ lp5562_poweroff();
+ last_state = LED_STATE_OFF;
+ led_auto_control = 1;
+ } else if (!(p->flags & EC_LED_FLAGS_QUERY)) {
+ for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
+ clipped[i] = MIN(p->brightness[i], 0x80);
+ led_auto_control = 0;
+ if (!board_get_ac())
+ lp5562_poweron();
+ if (lp5562_set_color((clipped[EC_LED_COLOR_RED] << 16) +
+ (clipped[EC_LED_COLOR_GREEN] << 8) +
+ clipped[EC_LED_COLOR_YELLOW]))
+ return EC_RES_ERROR;
+ }
+
+ r->brightness_range[EC_LED_COLOR_RED] = 0x80;
+ r->brightness_range[EC_LED_COLOR_GREEN] = 0x80;
+ r->brightness_range[EC_LED_COLOR_BLUE] = 0x0;
+ r->brightness_range[EC_LED_COLOR_YELLOW] = 0x80;
+ r->brightness_range[EC_LED_COLOR_WHITE] = 0x0;
+ args->response_size = sizeof(struct ec_response_led_control);
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_LED_CONTROL,
+ led_command_control,
+ EC_VER_MASK(1));
diff --git a/include/ec_commands.h b/include/ec_commands.h
index b16871462e..b35b15050a 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -729,15 +729,44 @@ enum lightbar_command {
/*****************************************************************************/
/* LED control commands */
-#define EC_CMD_LED_SET 0x29
+#define EC_CMD_LED_CONTROL 0x29
-#define EC_LED_FLAGS_AUTO (1 << 1)
+enum ec_led_id {
+ EC_LED_ID_BATTERY_LED = 0,
+ EC_LED_ID_POWER_BUTTON_LED,
+ EC_LED_ID_ADAPTER_LED,
+};
-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;
+/* LED control flags */
+#define EC_LED_FLAGS_QUERY (1 << 0) /* Query LED capability only */
+#define EC_LED_FLAGS_AUTO (1 << 1) /* Switch LED back to automatic control */
+
+enum ec_led_colors {
+ EC_LED_COLOR_RED = 0,
+ EC_LED_COLOR_GREEN,
+ EC_LED_COLOR_BLUE,
+ EC_LED_COLOR_YELLOW,
+ EC_LED_COLOR_WHITE,
+
+ EC_LED_COLOR_COUNT
+};
+
+struct ec_params_led_control {
+ uint8_t led_id; /* Which LED to control */
+ uint8_t flags; /* Control flags */
+
+ uint8_t brightness[EC_LED_COLOR_COUNT];
+} __packed;
+
+struct ec_response_led_control {
+ /*
+ * Available brightness value range.
+ *
+ * Range 0 means color channel not present.
+ * Range 1 means on/off control.
+ * Other values means the LED is control by PWM.
+ */
+ uint8_t brightness_range[EC_LED_COLOR_COUNT];
} __packed;
/*****************************************************************************/
diff --git a/util/ectool.c b/util/ectool.c
index c5ebf30c6f..597dd72eaf 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -161,6 +161,10 @@ const char help_str[] =
/* Note: depends on enum system_image_copy_t */
static const char * const image_names[] = {"unknown", "RO", "RW"};
+/* Note: depends on enum ec_led_colors */
+static const char * const led_color_names[EC_LED_COLOR_COUNT] = {
+ "red", "green", "blue", "yellow", "white"};
+
/* Write a buffer to the file. Return non-zero if error. */
static int write_file(const char *filename, const char *buf, int size)
{
@@ -1405,51 +1409,81 @@ static int cmd_lightbar(int argc, char **argv)
}
+static int find_led_color_by_name(const char *color)
+{
+ int i;
+
+ for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
+ if (!strcasecmp(color, led_color_names[i]))
+ return i;
+ return -1;
+}
+
int cmd_led(int argc, char *argv[])
{
- struct ec_params_led_set p;
- char *e;
- int rv;
+ struct ec_params_led_control p;
+ struct ec_response_led_control r;
+ char *e, *ptr;
+ int rv, i, j;
- if (argc == 1) {
+ memset(p.brightness, 0, sizeof(p.brightness));
+ p.flags = 0;
+
+ if (argc < 3) {
fprintf(stderr,
- "Usage: %s <auto | red | green | blue | "
- "<R> <G> <B>>\n", argv[0]);
+ "Usage: %s <ID> <query | auto | "
+ "<color>=<brightness>...>\n", argv[0]);
return -1;
}
- p.r = p.g = p.b = p.flags = 0;
+ p.led_id = strtol(argv[1], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad LED ID.\n");
+ return -1;
+ }
- if (!strcasecmp(argv[1], "auto")) {
+ if (!strcasecmp(argv[2], "query")) {
+ p.flags = EC_LED_FLAGS_QUERY;
+ rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p),
+ &r, sizeof(r));
+ printf("Brightness range for LED %d:\n", p.led_id);
+ if (rv < 0) {
+ fprintf(stderr, "Error. Not existing LED?\n");
+ return rv;
+ }
+ for (i = 0; i < 5; ++i)
+ printf("\t%s\t: 0x%x\n",
+ led_color_names[i],
+ r.brightness_range[i]);
+ return 0;
+ }
+
+ if (!strcasecmp(argv[2], "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 if ((i = find_led_color_by_name(argv[2])) != -1) {
+ p.brightness[i] = 0xff;
} 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;
+ for (i = 2; i < argc; ++i) {
+ ptr = strtok(argv[i], "=");
+ j = find_led_color_by_name(ptr);
+ if (j == -1) {
+ fprintf(stderr, "Bad color name: %s\n", ptr);
+ return -1;
+ }
+ ptr = strtok(NULL, "=");
+ if (ptr == NULL) {
+ fprintf(stderr, "Missing brightness value\n");
+ return -1;
+ }
+ p.brightness[j] = strtol(ptr, &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad brightness: %s\n", ptr);
+ return -1;
+ }
}
- p.flags = 0;
}
- rv = ec_command(EC_CMD_LED_SET, 0, &p, sizeof(p), NULL, 0);
+
+ rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p), &r, sizeof(r));
return (rv < 0 ? rv : 0);
}