summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerrit <chrome-bot@google.com>2012-04-26 01:46:29 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2012-04-26 01:46:29 -0700
commitb4f69c406d0698c9e03d6a76b380bd49ba286455 (patch)
treeae81b64f0867fa405a4496e0f8b1059a83c4e0b8
parenteca27481950fe6b43d9167568d1c524091317eb3 (diff)
parente763812a3a420e313d8784ad1c0ab510f2c174b3 (diff)
downloadchrome-ec-b4f69c406d0698c9e03d6a76b380bd49ba286455.tar.gz
Merge "Give ectool the same lightbar commands as the console."
-rw-r--r--common/lightbar.c188
-rw-r--r--include/lightbar.h21
-rw-r--r--include/lightbar_msg_list.h26
-rw-r--r--include/lpc_commands.h48
-rw-r--r--util/ectool.c167
5 files changed, 342 insertions, 108 deletions
diff --git a/common/lightbar.c b/common/lightbar.c
index 3aff41130c..dc07ba3952 100644
--- a/common/lightbar.c
+++ b/common/lightbar.c
@@ -93,12 +93,6 @@ static void set_from_array(const struct initdata_s *data, int count)
}
}
-static void lightbar_init_vals(void)
-{
- CPRINTF("[%s()]\n", __func__);
- set_from_array(init_vals, ARRAY_SIZE(init_vals));
-}
-
/* Controller register lookup tables. */
static const uint8_t led_to_ctrl[] = { 0, 0, 1, 1 };
static const uint8_t led_to_isc[] = { 0x15, 0x18, 0x15, 0x18 };
@@ -122,6 +116,13 @@ static inline uint8_t scale(int val, int max)
return scale_abs((val * brightness)/255, max);
}
+static void lightbar_init_vals(void)
+{
+ CPRINTF("[%s()]\n", __func__);
+ set_from_array(init_vals, ARRAY_SIZE(init_vals));
+ memset(current, 0, sizeof(current));
+}
+
/* Helper function. */
static void setrgb(int led, int red, int green, int blue)
@@ -582,7 +583,7 @@ struct lightbar_cmd_t {
uint32_t (*sequence)(void);
};
-#define LBMSG(state) { #state, sequence_##state },
+#define LBMSG(state) { #state, sequence_##state }
#include "lightbar_msg_list.h"
static struct lightbar_cmd_t lightbar_cmds[] = {
LIGHTBAR_MSG_LIST
@@ -652,24 +653,93 @@ void lightbar_sequence(enum lightbar_sequence num)
/****************************************************************************/
-/* Host commands via LPC bus */
+/* Generic command-handling (should work the same for both console & LPC) */
/****************************************************************************/
-/* FIXME(wfrichar): provide the same functions as the EC console */
+static const uint8_t dump_reglist[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a
+};
-static enum lpc_status lpc_cmd_reset(uint8_t *data)
+static void do_cmd_dump(uint8_t *outptr)
{
- lightbar_init_vals();
- return EC_LPC_RESULT_SUCCESS;
+ int i, n;
+ uint8_t reg;
+
+ BUILD_ASSERT(3 * ARRAY_SIZE(dump_reglist) ==
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.dump));
+
+ n = ARRAY_SIZE(dump_reglist);
+ for (i = 0; i < n; i++) {
+ reg = dump_reglist[i];
+ *outptr++ = reg;
+ *outptr++ = controller_read(0, reg);
+ *outptr++ = controller_read(1, reg);
+ }
+}
+
+static void do_cmd_rgb(uint8_t led,
+ uint8_t red, uint8_t green, uint8_t blue)
+{
+ int i;
+
+ if (led >= NUM_LEDS)
+ for (i = 0; i < NUM_LEDS; i++)
+ lightbar_setrgb(i, red, green, blue);
+ else
+ lightbar_setrgb(led, red, green, blue);
}
-DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_RESET, lpc_cmd_reset);
-static enum lpc_status lpc_cmd_test(uint8_t *data)
+
+/****************************************************************************/
+/* Host commands via LPC bus */
+/****************************************************************************/
+
+static enum lpc_status lpc_cmd_lightbar(uint8_t *data)
{
- lightbar_sequence(LIGHTBAR_TEST);
+ struct lpc_params_lightbar_cmd *ptr =
+ (struct lpc_params_lightbar_cmd *)data;
+
+ switch (ptr->in.cmd) {
+ case LIGHTBAR_CMD_DUMP:
+ do_cmd_dump(ptr->out.dump);
+ break;
+ case LIGHTBAR_CMD_OFF:
+ lightbar_off();
+ break;
+ case LIGHTBAR_CMD_ON:
+ lightbar_on();
+ break;
+ case LIGHTBAR_CMD_INIT:
+ lightbar_init_vals();
+ break;
+ case LIGHTBAR_CMD_BRIGHTNESS:
+ lightbar_brightness(ptr->in.brightness.num);
+ break;
+ case LIGHTBAR_CMD_SEQ:
+ lightbar_sequence(ptr->in.seq.num);
+ break;
+ case LIGHTBAR_CMD_REG:
+ controller_write(ptr->in.reg.ctrl,
+ ptr->in.reg.reg,
+ ptr->in.reg.value);
+ break;
+ case LIGHTBAR_CMD_RGB:
+ do_cmd_rgb(ptr->in.rgb.led,
+ ptr->in.rgb.red,
+ ptr->in.rgb.green,
+ ptr->in.rgb.blue);
+ break;
+ default:
+ return EC_LPC_RESULT_INVALID_PARAM;
+ }
+
return EC_LPC_RESULT_SUCCESS;
}
-DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_TEST, lpc_cmd_test);
+
+DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_CMD, lpc_cmd_lightbar);
/****************************************************************************/
@@ -678,46 +748,34 @@ DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_TEST, lpc_cmd_test);
static int help(const char *cmd)
{
- ccprintf("Usage: %s\n", cmd);
- ccprintf(" %s off\n", cmd);
- ccprintf(" %s init\n", cmd);
- ccprintf(" %s on\n", cmd);
- ccprintf(" %s msg NUM\n", cmd);
- ccprintf(" %s brightness NUM\n", cmd);
- ccprintf(" %s CTRL REG VAL\n", cmd);
- ccprintf(" %s LED RED GREEN BLUE\n", cmd);
- return EC_ERROR_UNKNOWN;
-}
-
-static void dump_regs(void)
-{
- int reg, d1, d2, i;
- int reglist[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a };
- for (i = 0; i < ARRAY_SIZE(reglist); i++) {
- reg = reglist[i];
- d1 = controller_read(0, reg);
- d2 = controller_read(1, reg);
- ccprintf(" %02x %02x %02x\n", reg, d1, d2);
- }
+ ccprintf("Usage:\n");
+ ccprintf(" %s - dump all regs\n", cmd);
+ ccprintf(" %s off - enter standby\n", cmd);
+ ccprintf(" %s on - leave standby\n", cmd);
+ ccprintf(" %s init - load default vals\n", cmd);
+ ccprintf(" %s brightness NUM - set intensity (0-ff)\n", cmd);
+ ccprintf(" %s seq [NUM|SEQUENCE] - run given pattern"
+ " (no arg for list)\n", cmd);
+ ccprintf(" %s CTRL REG VAL - set LED controller regs\n", cmd);
+ ccprintf(" %s LED RED GREEN BLUE - set color manually"
+ " (LED=4 for all)\n", cmd);
+ return EC_SUCCESS;
}
-static int find_msg_by_name(const char *str)
+static uint8_t find_msg_by_name(const char *str)
{
- int i;
+ uint8_t i;
for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
if (!strcasecmp(str, lightbar_cmds[i].string))
return i;
- return LIGHTBAR_ERROR;
+ return LIGHTBAR_NUM_SEQUENCES;
}
static void show_msg_names(void)
{
int i;
- ccprintf("message names: ");
+ ccprintf("sequence names:");
for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
ccprintf(" %s", lightbar_cmds[i].string);
ccprintf("\n");
@@ -725,10 +783,14 @@ static void show_msg_names(void)
static int command_lightbar(int argc, char **argv)
{
- int i;
+ int i, j;
+ uint8_t num, buf[128];
if (1 == argc) { /* no args = dump 'em all */
- dump_regs();
+ do_cmd_dump(buf);
+ for (i = j = 0; i < ARRAY_SIZE(dump_reglist); i++, j += 3)
+ ccprintf(" %02x %02x %02x\n",
+ buf[j], buf[j+1], buf[j+2]);
return EC_SUCCESS;
}
@@ -749,45 +811,45 @@ static int command_lightbar(int argc, char **argv)
if (argc == 3 && !strcasecmp(argv[1], "brightness")) {
char *e;
- int num = strtoi(argv[2], &e, 16);
+ num = 0xff & strtoi(argv[2], &e, 16);
lightbar_brightness(num);
return EC_SUCCESS;
}
- if (argc >= 2 && !strcasecmp(argv[1], "msg")) {
+ if (argc >= 2 && !strcasecmp(argv[1], "seq")) {
char *e;
- int num;
+ uint8_t num;
if (argc == 2) {
show_msg_names();
- return EC_SUCCESS;
+ return 0;
}
- num = strtoi(argv[2], &e, 16);
+ num = 0xff & strtoi(argv[2], &e, 16);
if (e && *e)
num = find_msg_by_name(argv[2]);
+ if (num >= LIGHTBAR_NUM_SEQUENCES)
+ return EC_ERROR_INVAL;
lightbar_sequence(num);
return EC_SUCCESS;
}
if (argc == 4) {
char *e;
- int ctrl = strtoi(argv[1], &e, 16);
- int reg = strtoi(argv[2], &e, 16);
- int val = strtoi(argv[3], &e, 16);
+ uint8_t ctrl, reg, val;
+ ctrl = 0xff & strtoi(argv[1], &e, 16);
+ reg = 0xff & strtoi(argv[2], &e, 16);
+ val = 0xff & strtoi(argv[3], &e, 16);
controller_write(ctrl, reg, val);
return EC_SUCCESS;
}
if (argc == 5) {
char *e;
- int led = strtoi(argv[1], &e, 16);
- int red = strtoi(argv[2], &e, 16);
- int green = strtoi(argv[3], &e, 16);
- int blue = strtoi(argv[4], &e, 16);
- if (led >= NUM_LEDS)
- for (i = 0; i < NUM_LEDS; i++)
- lightbar_setrgb(i, red, green, blue);
- else
- lightbar_setrgb(led, red, green, blue);
+ uint8_t led, r, g, b;
+ led = strtoi(argv[1], &e, 16);
+ r = strtoi(argv[2], &e, 16);
+ g = strtoi(argv[3], &e, 16);
+ b = strtoi(argv[4], &e, 16);
+ do_cmd_rgb(led, r, g, b);
return EC_SUCCESS;
}
diff --git a/include/lightbar.h b/include/lightbar.h
index a18f236f3f..0cc19e2b9b 100644
--- a/include/lightbar.h
+++ b/include/lightbar.h
@@ -7,8 +7,11 @@
#ifndef __CROS_EC_LIGHTBAR_H
#define __CROS_EC_LIGHTBAR_H
+/****************************************************************************/
+/* Internal stuff */
+
/* Define the types of sequences */
-#define LBMSG(state) LIGHTBAR_##state,
+#define LBMSG(state) LIGHTBAR_##state
#include "lightbar_msg_list.h"
enum lightbar_sequence {
LIGHTBAR_MSG_LIST
@@ -19,4 +22,20 @@ enum lightbar_sequence {
/* Request a preset sequence from the lightbar task. */
void lightbar_sequence(enum lightbar_sequence s);
+/****************************************************************************/
+/* External stuff */
+
+/* These are the commands available to the EC console or via LPC. */
+enum lightbar_command {
+ LIGHTBAR_CMD_DUMP,
+ LIGHTBAR_CMD_OFF,
+ LIGHTBAR_CMD_ON,
+ LIGHTBAR_CMD_INIT,
+ LIGHTBAR_CMD_BRIGHTNESS,
+ LIGHTBAR_CMD_SEQ,
+ LIGHTBAR_CMD_REG,
+ LIGHTBAR_CMD_RGB,
+ LIGHTBAR_NUM_CMDS
+};
+
#endif /* __CROS_EC_LIGHTBAR_H */
diff --git a/include/lightbar_msg_list.h b/include/lightbar_msg_list.h
index d6a33ed20f..f1c73a7f83 100644
--- a/include/lightbar_msg_list.h
+++ b/include/lightbar_msg_list.h
@@ -7,16 +7,16 @@
* types.
*/
#define LIGHTBAR_MSG_LIST \
- LBMSG(ERROR) \
- LBMSG(S5) \
- LBMSG(S3) \
- LBMSG(S0) \
- LBMSG(S5S3) \
- LBMSG(S3S0) \
- LBMSG(S0S3) \
- LBMSG(S3S5) \
- LBMSG(STOP) \
- LBMSG(RUN) \
- LBMSG(PULSE) \
- LBMSG(TEST) \
- LBMSG(KONAMI)
+ LBMSG(ERROR), \
+ LBMSG(S5), \
+ LBMSG(S3), \
+ LBMSG(S0), \
+ LBMSG(S5S3), \
+ LBMSG(S3S0), \
+ LBMSG(S0S3), \
+ LBMSG(S3S5), \
+ LBMSG(STOP), \
+ LBMSG(RUN), \
+ LBMSG(PULSE), \
+ LBMSG(TEST), \
+ LBMSG(KONAMI),
diff --git a/include/lpc_commands.h b/include/lpc_commands.h
index d9890b7b25..a3386c7280 100644
--- a/include/lpc_commands.h
+++ b/include/lpc_commands.h
@@ -345,18 +345,46 @@ struct lpc_params_pwm_set_keyboard_backlight {
} __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;
+/* Lightbar commands. This looks worse than it is. Since we only use one LPC
+ * command to say "talk to the lightbar", we put the "and tell it to do X"
+ * part into a subcommand. We'll make separate structs for subcommands with
+ * different input args, so that we know how much to expect. */
+
+#define EC_LPC_COMMAND_LIGHTBAR_CMD 0x28
+struct lpc_params_lightbar_cmd {
+ union {
+ union {
+ uint8_t cmd;
+ struct {
+ uint8_t cmd;
+ } dump, off, on, init;
+ struct num {
+ uint8_t cmd;
+ uint8_t num;
+ } brightness, seq;
+
+ struct reg {
+ uint8_t cmd;
+ uint8_t ctrl, reg, value;
+ } reg;
+ struct rgb {
+ uint8_t cmd;
+ uint8_t led, red, green, blue;
+ } rgb;
+ } in;
+ union {
+ uint8_t dump[69];
+ uint8_t off[0];
+ uint8_t on[0];
+ uint8_t init[0];
+ uint8_t brightness[0];
+ uint8_t seq[0];
+ uint8_t reg[0];
+ uint8_t rgb[0];
+ } out;
+ };
} __attribute__ ((packed));
-
-
/*****************************************************************************/
/* USB charging control commands */
diff --git a/util/ectool.c b/util/ectool.c
index 944265fe8e..8b3b000fa5 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -3,12 +3,14 @@
* found in the LICENSE file.
*/
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/io.h>
#include <unistd.h>
+#include "lightbar.h"
#include "lpc_commands.h"
#include "battery.h"
@@ -816,32 +818,155 @@ int cmd_pwm_set_keyboard_backlight(int argc, char *argv[])
return 0;
}
-int cmd_lightbar(int argc, char *argv[])
+
+#define LBMSG(state) #state
+#include "lightbar_msg_list.h"
+static const char const *lightbar_cmds[] = {
+ LIGHTBAR_MSG_LIST
+};
+#undef LBMSG
+
+/* This needs to match the values used in common/lightbar.c. I'd like to
+ * define this in one and only one place, but I can't think of a good way to do
+ * that without adding bunch of complexity. This will do for now.
+ */
+static const struct {
+ uint8_t insize;
+ uint8_t outsize;
+} lb_command_paramcount[LIGHTBAR_NUM_CMDS] = {
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.dump),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.dump) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.off),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.off) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.on),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.on) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.init),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.init) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.brightness),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.brightness) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.seq),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.seq) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.reg),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.reg) },
+ { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.rgb),
+ sizeof(((struct lpc_params_lightbar_cmd *)0)->out.rgb) },
+};
+
+static int lb_help(const char *cmd)
{
- struct lpc_params_lightbar_test p;
- char *e;
+ printf("Usage:\n");
+ printf(" %s - dump all regs\n", cmd);
+ printf(" %s off - enter standby\n", cmd);
+ printf(" %s on - leave standby\n", cmd);
+ printf(" %s init - load default vals\n", cmd);
+ printf(" %s brightness NUM - set intensity (0-ff)\n", cmd);
+ printf(" %s seq [NUM|SEQUENCE] - run given pattern"
+ " (no arg for list)\n", cmd);
+ printf(" %s CTRL REG VAL - set LED controller regs\n", cmd);
+ printf(" %s LED RED GREEN BLUE - set color manually"
+ " (LED=4 for all)\n", cmd);
+ return 0;
+}
- p.tbd = 0;
-
- if (argc > 1) {
- if (!strcmp("reset", argv[1])) {
- return ec_command(EC_LPC_COMMAND_LIGHTBAR_RESET,
- NULL, 0, NULL, 0);
- } else if (!strcmp("test", argv[1])) {
- if (argc > 2) {
- p.tbd = strtol(argv[2], &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);
+static uint8_t lb_find_msg_by_name(const char *str)
+{
+ uint8_t i;
+ for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
+ if (!strcasecmp(str, lightbar_cmds[i]))
+ return i;
+
+ return LIGHTBAR_NUM_SEQUENCES;
+}
+
+static void lb_show_msg_names(void)
+{
+ int i;
+ printf("sequence names:");
+ for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
+ printf(" %s", lightbar_cmds[i]);
+ printf("\n");
+}
+
+static int lb_do_cmd(enum lightbar_command cmd,
+ struct lpc_params_lightbar_cmd *ptr)
+{
+ int r;
+ ptr->in.cmd = cmd;
+ r = ec_command(EC_LPC_COMMAND_LIGHTBAR_CMD,
+ ptr, lb_command_paramcount[cmd].insize,
+ ptr, lb_command_paramcount[cmd].outsize);
+ return r;
+}
+
+static int cmd_lightbar(int argc, char **argv)
+{
+ int i, r;
+ struct lpc_params_lightbar_cmd param;
+
+ if (1 == argc) { /* no args = dump 'em all */
+ r = lb_do_cmd(LIGHTBAR_CMD_DUMP, &param);
+ if (r)
+ return r;
+ for (i = 0; i < sizeof(param.out.dump); i += 3) {
+ printf(" %02x %02x %02x\n",
+ param.out.dump[i],
+ param.out.dump[i+1],
+ param.out.dump[i+2]);
+ }
+ return 0;
+ }
+
+ if (argc == 2 && !strcasecmp(argv[1], "init"))
+ return lb_do_cmd(LIGHTBAR_CMD_INIT, &param);
+
+ if (argc == 2 && !strcasecmp(argv[1], "off"))
+ return lb_do_cmd(LIGHTBAR_CMD_OFF, &param);
+
+ if (argc == 2 && !strcasecmp(argv[1], "on"))
+ return lb_do_cmd(LIGHTBAR_CMD_ON, &param);
+
+ if (argc == 3 && !strcasecmp(argv[1], "brightness")) {
+ char *e;
+ param.in.brightness.num = 0xff & strtoul(argv[2], &e, 16);
+ return lb_do_cmd(LIGHTBAR_CMD_BRIGHTNESS, &param);
+ }
+
+ if (argc >= 2 && !strcasecmp(argv[1], "seq")) {
+ char *e;
+ uint8_t num;
+ if (argc == 2) {
+ lb_show_msg_names();
+ return 0;
+ }
+ num = 0xff & strtoul(argv[2], &e, 16);
+ if (e && *e)
+ num = lb_find_msg_by_name(argv[2]);
+ if (num >= LIGHTBAR_NUM_SEQUENCES) {
+ fprintf(stderr, "Invalid arg\n");
+ return -1;
}
+ param.in.seq.num = num;
+ return lb_do_cmd(LIGHTBAR_CMD_SEQ, &param);
+ }
+
+ if (argc == 4) {
+ char *e;
+ param.in.reg.ctrl = 0xff & strtoul(argv[1], &e, 16);
+ param.in.reg.reg = 0xff & strtoul(argv[2], &e, 16);
+ param.in.reg.value = 0xff & strtoul(argv[3], &e, 16);
+ return lb_do_cmd(LIGHTBAR_CMD_REG, &param);
+ }
+
+ if (argc == 5) {
+ char *e;
+ param.in.rgb.led = strtoul(argv[1], &e, 16);
+ param.in.rgb.red = strtoul(argv[2], &e, 16);
+ param.in.rgb.green = strtoul(argv[3], &e, 16);
+ param.in.rgb.blue = strtoul(argv[4], &e, 16);
+ return lb_do_cmd(LIGHTBAR_CMD_RGB, &param);
}
- printf("Usage: %s reset | test [NUM]\n", argv[0]);
- return -1;
+ return lb_help(argv[0]);
}
int cmd_usb_charge_set_mode(int argc, char *argv[])