From 17fe1ce017143da110b50a3adf19d9fa399a7282 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 3 Apr 2012 17:38:16 -0700 Subject: [PATCH] First "ectool lightbar" command. BUG=chrome-os-partner:8728 TEST=manual I don't have a system that has both an EC and a lightsaber, so I can't be certain this works, but I *think* it will. I do have a Link proto 0.5. With that, you can say ectool lightbar test and the EC console says it's poking at the lightbar, but of course there's nothing there. If there was, it *should* flash in pretty colors. I have a lightsaber attached to a BDS, and from the EC console running "lightsaber test" does make it blink. Change-Id: Ib6021ad8e53959de52b12efda376254071e5fb4b Signed-off-by: Bill Richardson --- common/lightbar.c | 112 +++++++++++++++++++++++++---------------- include/lpc_commands.h | 13 +++++ util/ectool.c | 32 ++++++++++++ 3 files changed, 114 insertions(+), 43 deletions(-) diff --git a/common/lightbar.c b/common/lightbar.c index 743962e43f..46129179cc 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -8,6 +8,7 @@ #include "board.h" #include "console.h" #include "gpio.h" +#include "host_command.h" #include "i2c.h" #include "timer.h" #include "uart.h" @@ -61,7 +62,7 @@ static const struct { /* We don't actually shut down the driver chips, because the reset pullup * uses more power than leaving them enabled but inactive. */ -void lightbar_off(void) +static void lightbar_off(void) { gpio_set_level(GPIO_LIGHTBAR_RESETn, 1); i2c_write8(I2C_PORT_LIGHTBAR, DRIVER_FUN, 0x01, 0x00); @@ -69,7 +70,7 @@ void lightbar_off(void) } /* Initialize & activate driver chips, but no LEDs on yet. */ -void lightbar_on(void) +static void lightbar_on(void) { int i; gpio_set_level(GPIO_LIGHTBAR_RESETn, 1); @@ -83,7 +84,7 @@ void lightbar_on(void) /* Set the color for an LED (0-3). RGB values should be in 0-255. They'll be * scaled so that maxium brightness is at 255. */ -void lightbar_setcolor(int led, int red, int green, int blue) +static void lightbar_setcolor(int led, int red, int green, int blue) { int driver, bank; driver = DRIVER_SMART + (led/2) * 2; @@ -93,9 +94,73 @@ void lightbar_setcolor(int led, int red, int green, int blue) i2c_write8(I2C_PORT_LIGHTBAR, driver, bank+2, SCALE(green, MAX_GREEN)); } +static const struct { + uint8_t r, g, b; +} testy[] = { + {0xff, 0x00, 0x00}, + {0x00, 0xff, 0x00}, + {0x00, 0x00, 0xff}, + {0xff, 0xff, 0x00}, + {0x00, 0xff, 0xff}, + {0xff, 0x00, 0xff}, + {0xff, 0xff, 0xff}, +}; + +static void lightbar_test(void) +{ + int i, j, k, r, g, b; + int kmax = 254; + int kstep = 4; + lightbar_on(); + for (i = 0; i < ARRAY_SIZE(testy); i++) { + for (k = 0; k <= kmax; k += kstep) { + for (j = 0; j < 4; j++) { + r = testy[i].r ? k : 0; + g = testy[i].g ? k : 0; + b = testy[i].b ? k : 0; + lightbar_setcolor(j, r, g, b); + } + } + for (k = kmax; k >= 0; k -= kstep) { + for (j = 0; j < 4; j++) { + r = testy[i].r ? k : 0; + g = testy[i].g ? k : 0; + b = testy[i].b ? k : 0; + lightbar_setcolor(j, r, g, b); + } + } + } + lightbar_on(); +} + + + /* FIXME: Do I want some auto-cycling functions? Pulsing, etc.? Investigate to * see what's possible and looks nice. */ +/****************************************************************************/ +/* host commands */ + +static enum lpc_status lpc_cmd_reset(uint8_t *data) +{ + uart_printf("%s()\n", __func__); + lightbar_off(); + return EC_LPC_RESULT_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_RESET, lpc_cmd_reset); + +static enum lpc_status lpc_cmd_test(uint8_t *data) +{ + struct lpc_params_lightbar_test *p = + (struct lpc_params_lightbar_test *)data; + + uart_printf("%s(0x%02x)\n", __func__, p->tbd); + lightbar_test(); + return EC_LPC_RESULT_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_TEST, lpc_cmd_test); + + /****************************************************************************/ /* Console commands */ @@ -136,19 +201,6 @@ static int set(int driver, char *regstr, char *valstr) return EC_SUCCESS; } -static const struct { - uint8_t r, g, b; -} testy[] = { - {0xff, 0x00, 0x00}, - {0x00, 0xff, 0x00}, - {0x00, 0x00, 0xff}, - {0xff, 0xff, 0x00}, - {0x00, 0xff, 0xff}, - {0xff, 0x00, 0xff}, - {0xff, 0xff, 0xff}, -}; - - static int command_lightbar(int argc, char **argv) { int led, red, green, blue; @@ -185,33 +237,7 @@ static int command_lightbar(int argc, char **argv) } if (!strcasecmp(argv[1], "test")) { - int i, j, k, r, g, b; - int kmax = 254; - if (3 == argc) - kmax = strtoi(argv[2], &e, 16); - kmax &= 0xfe; - lightbar_on(); - for (i = 0; i < ARRAY_SIZE(testy); i++) { - for (k = 0; k <= kmax; k += 2) { - for (j = 0; j < 4; j++) { - r = testy[i].r ? k : 0; - g = testy[i].g ? k : 0; - b = testy[i].b ? k : 0; - lightbar_setcolor(j, r, g, b); - } - usleep(1000); - } - for (k = kmax; k; k -= 2) { - for (j = 0; j < 4; j++) { - r = testy[i].r ? k : 0; - g = testy[i].g ? k : 0; - b = testy[i].b ? k : 0; - lightbar_setcolor(j, r, g, b); - } - usleep(1000); - } - } - lightbar_on(); + lightbar_test(); return EC_SUCCESS; } diff --git a/include/lpc_commands.h b/include/lpc_commands.h index 5fa58310cc..1f77b9b58c 100644 --- a/include/lpc_commands.h +++ b/include/lpc_commands.h @@ -317,6 +317,19 @@ struct lpc_params_pwm_set_keyboard_backlight { uint8_t percent; } __attribute__ ((packed)); +/*****************************************************************************/ +/* Lightbar commands */ + +#define EC_LPC_COMMAND_LIGHTBAR_RESET 0x28 +/* No params needed */ + +#define EC_LPC_COMMAND_LIGHTBAR_TEST 0x29 +struct lpc_params_lightbar_test { + uint8_t tbd; +} __attribute__ ((packed)); + + + /*****************************************************************************/ /* USB charging control commands */ diff --git a/util/ectool.c b/util/ectool.c index 5e13902951..dcfe3a375d 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -46,6 +46,10 @@ const char help_str[] = " Erases EC flash\n" " hello\n" " Checks for basic communication with EC\n" + " lightbar reset\n" + " Puts the lightbar into idle mode\n" + " lightbar test [NUM]\n" + " Cycles lights once. Optional argument does nothing.\n" " pstoreinfo\n" " Prints information on the EC host persistent storage\n" " pstoreread \n" @@ -793,6 +797,33 @@ int cmd_pwm_set_keyboard_backlight(int argc, char *argv[]) return 0; } +int cmd_lightbar(int argc, char *argv[]) +{ + struct lpc_params_lightbar_test p; + char *e; + + p.tbd = 0; + + if (argc) { + if (!strcmp("reset", argv[0])) { + return ec_command(EC_LPC_COMMAND_LIGHTBAR_RESET, + NULL, 0, NULL, 0); + } else if (!strcmp("test", argv[0])) { + if (argc > 1) { + p.tbd = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad arg\n"); + return -1; + } + } + return ec_command(EC_LPC_COMMAND_LIGHTBAR_TEST, + &p, sizeof(p), NULL, 0); + } + } + + printf("Usage: lightbar reset | test [NUM]\n"); + return -1; +} int cmd_usb_charge_set_mode(int argc, char *argv[]) { @@ -1211,6 +1242,7 @@ const struct command commands[] = { {"flashwrite", cmd_flash_write}, {"flashinfo", cmd_flash_info}, {"hello", cmd_hello}, + {"lightbar", cmd_lightbar}, {"pstoreinfo", cmd_pstore_info}, {"pstoreread", cmd_pstore_read}, {"pstorewrite", cmd_pstore_write},