summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2014-06-03 17:22:22 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-06-07 06:01:00 +0000
commitf7ae0fb81b4b43c939ec1be674e940377b8c8d64 (patch)
treea10b56287afa8a06c8652c768d84ae682446f768
parentbcb9428312f2f053b2f9da642d658d01ecec085a (diff)
downloadchrome-ec-f7ae0fb81b4b43c939ec1be674e940377b8c8d64.tar.gz
Add display-battery-level function to lightbar
This adds a new lightbar sequence (TAP), which temporarily displays the battery level. It pulses if the system is charging. BUG=chrome-os-partner:29041 BRANCH=ToT TEST=manual From the EC console, run lightbar seq tap The lightbar should change temporarily. Then run lightbar demo on and press the Up, Down, Left, and Right keys to fake the battery charge level (up & down) and the AC present state (left & right). Run the lightbar seq tap command periodically to watch it change. Change-Id: I84ff928d93060f7ef7d46d608732d37cf5185aff Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/202964 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--common/lightbar.c237
-rw-r--r--include/ec_commands.h61
-rw-r--r--include/lightbar_msg_list.h3
-rw-r--r--util/ectool.c264
4 files changed, 489 insertions, 76 deletions
diff --git a/common/lightbar.c b/common/lightbar.c
index 8ddf76bd3e..d08f12cf0b 100644
--- a/common/lightbar.c
+++ b/common/lightbar.c
@@ -48,6 +48,7 @@ static struct p_state {
/* Quantized battery charge level: 0=low 1=med 2=high 3=full. */
int battery_level;
+ int battery_percent;
/* It's either charging or discharging. */
int battery_is_charging;
@@ -58,11 +59,11 @@ static struct p_state {
uint8_t _pad0; /* next item is __packed */
- /* Tweakable parameters */
- struct lightbar_params p;
+ /* Tweakable parameters. */
+ struct lightbar_params_v1 p;
} st;
-static const struct lightbar_params default_params = {
+static const struct lightbar_params_v1 default_params = {
.google_ramp_up = 2500,
.google_ramp_down = 10000,
.s3s0_ramp_up = 2000,
@@ -72,8 +73,15 @@ static const struct lightbar_params default_params = {
.s3_sleep_for = 5 * SECOND, /* between checks */
.s3_ramp_up = 2500,
.s3_ramp_down = 10000,
+ .tap_tick_delay = 5000, /* oscillation step time */
+ .tap_display_time = 5000000, /* total sequence time */
- .new_s0 = 1, /* 0=gentle, 1=pulse */
+ .tap_pct_red = 10, /* below this is red */
+ .tap_pct_green = 97, /* above this is green */
+ .tap_seg_min_on = 35, /* min intensity (%) for "on" */
+ .tap_seg_max_on = 100, /* max intensity (%) for "on" */
+ .tap_seg_osc = 25, /* amplitude for charging osc */
+ .tap_idx = {5, 6, 7}, /* color [red, yellow, green] */
.osc_min = { 0x60, 0x60 }, /* battery, AC */
.osc_max = { 0xd0, 0xd0 }, /* battery, AC */
@@ -119,11 +127,14 @@ static void lightbar_restore_state(void)
old_state = system_get_jump_tag(LB_SYSJUMP_TAG, 0, &size);
if (old_state && size == sizeof(st)) {
memcpy(&st, old_state, size);
- CPRINTS("LB state restored: %d %d - %d/%d",
+ CPRINTS("LB state restored: %d %d - %d %d/%d",
st.cur_seq, st.prev_seq,
- st.battery_is_charging, st.battery_level);
+ st.battery_is_charging,
+ st.battery_percent,
+ st.battery_level);
} else {
st.cur_seq = st.prev_seq = LIGHTBAR_S5;
+ st.battery_percent = 100;
st.battery_level = LB_BATTERY_LEVELS - 1;
st.w0 = 0;
st.ramp = 0;
@@ -145,25 +156,31 @@ static int last_backlight_level;
static int demo_mode = DEMO_MODE_DEFAULT;
+static int quantize_battery_level(int pct)
+{
+ int i, bl = 0;
+ for (i = 0; i < LB_BATTERY_LEVELS - 1; i++)
+ if (pct >= st.p.battery_threshold[i])
+ bl++;
+ return bl;
+}
+
/* Update the known state. */
static void get_battery_level(void)
{
int pct = 0;
- int i, bl;
+ int bl;
if (demo_mode)
return;
#ifdef HAS_TASK_CHARGER
- pct = charge_get_percent();
+ st.battery_percent = pct = charge_get_percent();
st.battery_is_charging = (PWR_STATE_DISCHARGE != charge_get_state());
#endif
/* Find the new battery level */
- bl = 0;
- for (i = 0; i < LB_BATTERY_LEVELS - 1; i++)
- if (pct >= st.p.battery_threshold[i])
- bl++;
+ bl = quantize_battery_level(pct);
/* Use some hysteresis to avoid flickering */
if (bl > st.battery_level
@@ -203,21 +220,27 @@ static void get_battery_level(void)
/* Forcing functions for demo mode, called by the keyboard task. */
/* Up/Down keys */
+#define DEMO_CHARGE_STEP 1
void demo_battery_level(int inc)
{
if (!demo_mode)
return;
- st.battery_level += inc;
- if (st.battery_level >= LB_BATTERY_LEVELS)
- st.battery_level = LB_BATTERY_LEVELS - 1;
- else if (st.battery_level < 0)
- st.battery_level = 0;
+ st.battery_percent += DEMO_CHARGE_STEP * inc;
+
+ if (st.battery_percent > 100)
+ st.battery_percent = 100;
+ else if (st.battery_percent < 0)
+ st.battery_percent = 0;
+
+ st.battery_level = quantize_battery_level(st.battery_percent);
- CPRINTS("LB demo: battery_level=%d", st.battery_level);
+ CPRINTS("LB demo: battery_percent = %d%%, battery_level=%d",
+ st.battery_percent, st.battery_level);
}
/* Left/Right keys */
+
void demo_is_charging(int ischarge)
{
if (!demo_mode)
@@ -282,10 +305,9 @@ static inline float cycle_010(uint8_t i)
/* This function provides a smooth oscillation between -0.5 and +0.5.
* Zero starts at 0x00. */
-static inline float cycle_0p0n0(uint16_t i)
+static inline float cycle_0p0n0(uint8_t i)
{
- uint8_t i8 = i & 0x00FF;
- return cycle_010(i8+64) - 0.5f;
+ return cycle_010(i + 64) - 0.5f;
}
/* This function provides a pulsing oscillation between -0.5 and +0.5. */
@@ -348,7 +370,7 @@ static uint32_t pulse_google_colors(void)
static uint32_t sequence_S3S0(void)
{
int w, r, g, b;
- float f, fmin, fmax, base_s0, goal;
+ float f, fmin;
int ci;
uint32_t res;
@@ -366,12 +388,9 @@ static uint32_t sequence_S3S0(void)
ci = 0;
fmin = st.p.osc_min[st.battery_is_charging] / 255.0f;
- fmax = st.p.osc_max[st.battery_is_charging] / 255.0f;
- base_s0 = (fmax + fmin) * 0.5f;
- goal = st.p.new_s0 ? fmin : base_s0;
for (w = 0; w <= 128; w++) {
- f = cycle_010(w) * goal;
+ f = cycle_010(w) * fmin;
r = st.p.color[ci].r * f;
g = st.p.color[ci].g * f;
b = st.p.color[ci].b * f;
@@ -428,13 +447,8 @@ static uint32_t sequence_S0(void)
f_ramp = st.ramp / 255.0f;
for (i = 0; i < NUM_LEDS; i++) {
- if (st.p.new_s0) {
- w = st.w0 - i * w_ofs * f_ramp;
- f = base_s0 + osc_s0 * cycle_npn(w);
- } else {
- w = st.w0 - i * w_ofs * f_ramp;
- f = base_s0 + osc_s0 * cycle_0p0n0(w) * f_ramp;
- }
+ w = st.w0 - i * w_ofs * f_ramp;
+ f = base_s0 + osc_s0 * cycle_npn(w);
r = st.p.color[ci].r * f;
g = st.p.color[ci].g * f;
b = st.p.color[ci].b * f;
@@ -451,8 +465,7 @@ static uint32_t sequence_S0(void)
if (st.ramp < 0xff)
st.ramp++;
- i = st.p.new_s0 ? st.p.s0a_tick_delay[st.battery_is_charging]
- : st.p.s0_tick_delay[st.battery_is_charging];
+ i = st.p.s0a_tick_delay[st.battery_is_charging];
WAIT_OR_RET(i);
}
return 0;
@@ -751,10 +764,6 @@ static uint32_t sequence_KONAMI(void)
int i;
int tmp;
- lb_off();
- lb_init();
- lb_on();
-
tmp = lb_get_brightness();
lb_set_brightness(255);
@@ -769,6 +778,113 @@ static uint32_t sequence_KONAMI(void)
return 0;
}
+/* Returns 0.0 to 1.0 for val in [min, min + ofs] */
+static float range(int val, int min, int ofs)
+{
+ if (val <= min)
+ return 0.0f;
+ if (val >= min+ofs)
+ return 1.0f;
+ return (float)(val - min) / ofs;
+}
+
+/* Handy constant */
+#define CUT (100 / NUM_LEDS)
+
+static uint32_t sequence_TAP_inner(void)
+{
+ enum { RED, YELLOW, GREEN } base_color;
+ timestamp_t start, now;
+ int i, ci, max_led;
+ float min, delta, osc, power, mult;
+ uint8_t w = 0;
+
+ min = st.p.tap_seg_min_on / 100.0f;
+ delta = (st.p.tap_seg_max_on - st.p.tap_seg_min_on) / 100.0f;
+ osc = st.p.tap_seg_osc / 100.0f;
+
+ start = get_time();
+ while (1) {
+ if (st.battery_percent < st.p.tap_pct_red)
+ base_color = RED;
+ else if (st.battery_percent > st.p.tap_pct_green)
+ base_color = GREEN;
+ else
+ base_color = YELLOW;
+
+ ci = st.p.tap_idx[base_color];
+ max_led = st.battery_percent / CUT;
+
+ for (i = 0; i < NUM_LEDS; i++) {
+
+ if (max_led > i) {
+ mult = 1.0f;
+ } else if (max_led < i) {
+ mult = 0.0f;
+ } else {
+ switch (base_color) {
+ case RED:
+ power = range(st.battery_percent,
+ 0, st.p.tap_pct_red - 1);
+ break;
+ case YELLOW:
+ power = range(st.battery_percent,
+ i * CUT, CUT - 1);
+ break;
+ case GREEN:
+ /* green is always full on */
+ power = 1.0f;
+ }
+ mult = min + power * delta;
+ }
+
+ /* Pulse when charging */
+ if (st.battery_is_charging)
+ mult *= 1.0f - (osc * cycle_010(w++));
+
+ lb_set_rgb(i, mult * st.p.color[ci].r,
+ mult * st.p.color[ci].g,
+ mult * st.p.color[ci].b);
+ }
+ /*
+ * TODO: Use a different delay function here. Otherwise,
+ * it's possible that a new sequence (such as KONAMI) can end
+ * up with TAP as it's previous sequence. It's okay to return
+ * early from TAP (or not), but we don't want to end up stuck
+ * in the TAP sequence.
+ */
+ WAIT_OR_RET(st.p.tap_tick_delay);
+ now = get_time();
+ if (now.le.lo - start.le.lo > st.p.tap_display_time)
+ break;
+ }
+ return 0;
+}
+
+static uint32_t sequence_TAP(void)
+{
+ int i;
+ uint32_t r;
+ uint8_t br, save[NUM_LEDS][3];
+
+ /* TODO(crosbug.com/p/29041): do we need more than lb_init() */
+ lb_init();
+ lb_on();
+
+ for (i = 0; i < NUM_LEDS; i++)
+ lb_get_rgb(i, &save[i][0], &save[i][1], &save[i][2]);
+ br = lb_get_brightness();
+ lb_set_brightness(255);
+
+ r = sequence_TAP_inner();
+
+ lb_set_brightness(br);
+ for (i = 0; i < NUM_LEDS; i++)
+ lb_set_rgb(i, save[i][0], save[i][1], save[i][2]);
+
+ return r;
+}
+
/****************************************************************************/
/* The main lightbar task. It just cycles between various pretty patterns. */
/****************************************************************************/
@@ -801,8 +917,10 @@ void lightbar_task(void)
if (TASK_EVENT_CUSTOM(msg) == PENDING_MSG) {
CPRINTS("LB msg %d = %s", pending_msg,
lightbar_cmds[pending_msg].string);
- st.prev_seq = st.cur_seq;
- st.cur_seq = pending_msg;
+ if (st.cur_seq != pending_msg) {
+ st.prev_seq = st.cur_seq;
+ st.cur_seq = pending_msg;
+ }
} else {
CPRINTS("LB msg 0x%x", msg);
switch (st.cur_seq) {
@@ -823,6 +941,7 @@ void lightbar_task(void)
case LIGHTBAR_RUN:
case LIGHTBAR_ERROR:
case LIGHTBAR_KONAMI:
+ case LIGHTBAR_TAP:
st.cur_seq = st.prev_seq;
default:
break;
@@ -935,14 +1054,22 @@ static int lpc_cmd_lightbar(struct host_cmd_handler_args *args)
out->get_demo.num = demo_mode;
args->response_size = sizeof(out->get_demo);
break;
- case LIGHTBAR_CMD_GET_PARAMS:
- CPRINTS("LB_get_params");
- memcpy(&out->get_params, &st.p, sizeof(st.p));
- args->response_size = sizeof(out->get_params);
+ case LIGHTBAR_CMD_GET_PARAMS_V0:
+ CPRINTS("LB_get_params_v0 not supported");
+ return EC_RES_INVALID_VERSION;
+ break;
+ case LIGHTBAR_CMD_SET_PARAMS_V0:
+ CPRINTS("LB_set_params_v0 not supported");
+ return EC_RES_INVALID_VERSION;
+ break;
+ case LIGHTBAR_CMD_GET_PARAMS_V1:
+ CPRINTS("LB_get_params_v1");
+ memcpy(&out->get_params_v1, &st.p, sizeof(st.p));
+ args->response_size = sizeof(out->get_params_v1);
break;
- case LIGHTBAR_CMD_SET_PARAMS:
- CPRINTS("LB_set_params");
- memcpy(&st.p, &in->set_params, sizeof(st.p));
+ case LIGHTBAR_CMD_SET_PARAMS_V1:
+ CPRINTS("LB_set_params_v1");
+ memcpy(&st.p, &in->set_params_v1, sizeof(st.p));
break;
case LIGHTBAR_CMD_VERSION:
CPRINTS("LB_version");
@@ -1008,7 +1135,7 @@ static void show_msg_names(void)
lightbar_cmds[st.cur_seq].string);
}
-static void show_params(const struct lightbar_params *p)
+static void show_params_v1(const struct lightbar_params_v1 *p)
{
int i;
@@ -1023,7 +1150,15 @@ static void show_params(const struct lightbar_params *p)
ccprintf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
ccprintf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
ccprintf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- ccprintf("%d\t\t# .new_s0\n", p->new_s0);
+ ccprintf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
+ ccprintf("%d\t\t# .tap_display_time\n", p->tap_display_time);
+ ccprintf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
+ ccprintf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
+ ccprintf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
+ ccprintf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
+ ccprintf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
+ ccprintf("%d %d %d\t\t# .tap_idx\n",
+ p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
ccprintf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
p->osc_min[0], p->osc_min[1]);
ccprintf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
@@ -1097,7 +1232,7 @@ static int command_lightbar(int argc, char **argv)
if (argc > 2)
lb_read_params_from_file(argv[2], &st.p);
#endif
- show_params(&st.p);
+ show_params_v1(&st.p);
return EC_SUCCESS;
}
diff --git a/include/ec_commands.h b/include/ec_commands.h
index d6ad5386f9..1526084986 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -951,7 +951,7 @@ struct rgb_s {
/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a
* host command, but the alignment is the same regardless. Keep it that way.
*/
-struct lightbar_params {
+struct lightbar_params_v0 {
/* Timing */
int32_t google_ramp_up;
int32_t google_ramp_down;
@@ -985,12 +985,55 @@ struct lightbar_params {
struct rgb_s color[8]; /* 0-3 are Google colors */
} __packed;
+struct lightbar_params_v1 {
+ /* Timing */
+ int32_t google_ramp_up;
+ int32_t google_ramp_down;
+ int32_t s3s0_ramp_up;
+ int32_t s0_tick_delay[2]; /* AC=0/1 */
+ int32_t s0a_tick_delay[2]; /* AC=0/1 */
+ int32_t s0s3_ramp_down;
+ int32_t s3_sleep_for;
+ int32_t s3_ramp_up;
+ int32_t s3_ramp_down;
+ int32_t tap_tick_delay;
+ int32_t tap_display_time;
+
+ /* Tap-for-battery params */
+ uint8_t tap_pct_red;
+ uint8_t tap_pct_green;
+ uint8_t tap_seg_min_on;
+ uint8_t tap_seg_max_on;
+ uint8_t tap_seg_osc;
+ uint8_t tap_idx[3];
+
+ /* Oscillation */
+ uint8_t osc_min[2]; /* AC=0/1 */
+ uint8_t osc_max[2]; /* AC=0/1 */
+ uint8_t w_ofs[2]; /* AC=0/1 */
+
+ /* Brightness limits based on the backlight and AC. */
+ uint8_t bright_bl_off_fixed[2]; /* AC=0/1 */
+ uint8_t bright_bl_on_min[2]; /* AC=0/1 */
+ uint8_t bright_bl_on_max[2]; /* AC=0/1 */
+
+ /* Battery level thresholds */
+ uint8_t battery_threshold[LB_BATTERY_LEVELS - 1];
+
+ /* Map [AC][battery_level] to color index */
+ uint8_t s0_idx[2][LB_BATTERY_LEVELS]; /* AP is running */
+ uint8_t s3_idx[2][LB_BATTERY_LEVELS]; /* AP is sleeping */
+
+ /* Color palette */
+ struct rgb_s color[8]; /* 0-3 are Google colors */
+} __packed;
+
struct ec_params_lightbar {
uint8_t cmd; /* Command (see enum lightbar_command) */
union {
struct {
/* no args */
- } dump, off, on, init, get_seq, get_params,
+ } dump, off, on, init, get_seq, get_params_v0, get_params_v1,
version, get_brightness, get_demo;
struct {
@@ -1009,7 +1052,8 @@ struct ec_params_lightbar {
uint8_t led;
} get_rgb;
- struct lightbar_params set_params;
+ struct lightbar_params_v0 set_params_v0;
+ struct lightbar_params_v1 set_params_v1;
};
} __packed;
@@ -1027,7 +1071,8 @@ struct ec_response_lightbar {
uint8_t num;
} get_seq, get_brightness, get_demo;
- struct lightbar_params get_params;
+ struct lightbar_params_v0 get_params_v0;
+ struct lightbar_params_v1 get_params_v1;
struct {
uint32_t num;
@@ -1041,7 +1086,7 @@ struct ec_response_lightbar {
struct {
/* no return params */
} off, on, init, set_brightness, seq, reg, set_rgb,
- demo, set_params;
+ demo, set_params_v0, set_params_v1;
};
} __packed;
@@ -1057,12 +1102,14 @@ enum lightbar_command {
LIGHTBAR_CMD_SET_RGB = 7,
LIGHTBAR_CMD_GET_SEQ = 8,
LIGHTBAR_CMD_DEMO = 9,
- LIGHTBAR_CMD_GET_PARAMS = 10,
- LIGHTBAR_CMD_SET_PARAMS = 11,
+ LIGHTBAR_CMD_GET_PARAMS_V0 = 10,
+ LIGHTBAR_CMD_SET_PARAMS_V0 = 11,
LIGHTBAR_CMD_VERSION = 12,
LIGHTBAR_CMD_GET_BRIGHTNESS = 13,
LIGHTBAR_CMD_GET_RGB = 14,
LIGHTBAR_CMD_GET_DEMO = 15,
+ LIGHTBAR_CMD_GET_PARAMS_V1 = 16,
+ LIGHTBAR_CMD_SET_PARAMS_V1 = 17,
LIGHTBAR_NUM_CMDS
};
diff --git a/include/lightbar_msg_list.h b/include/lightbar_msg_list.h
index d4563ab348..fe75ccc021 100644
--- a/include/lightbar_msg_list.h
+++ b/include/lightbar_msg_list.h
@@ -19,4 +19,5 @@
LBMSG(RUN), /* 9 */ \
LBMSG(PULSE), /* A */ \
LBMSG(TEST), /* B */ \
- LBMSG(KONAMI), /* C */
+ LBMSG(KONAMI), /* C */ \
+ LBMSG(TAP), /* D */
diff --git a/util/ectool.c b/util/ectool.c
index 977480eedf..13062afcbf 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -1354,12 +1354,14 @@ static const struct {
LB_SIZES(set_rgb),
LB_SIZES(get_seq),
LB_SIZES(demo),
- LB_SIZES(get_params),
- LB_SIZES(set_params),
+ LB_SIZES(get_params_v0),
+ LB_SIZES(set_params_v0),
LB_SIZES(version),
LB_SIZES(get_brightness),
LB_SIZES(get_rgb),
LB_SIZES(get_demo),
+ LB_SIZES(get_params_v1),
+ LB_SIZES(set_params_v1),
};
#undef LB_SIZES
@@ -1425,8 +1427,8 @@ static int lb_show_msg_names(void)
return 0;
}
-static int lb_read_params_from_file(const char *filename,
- struct lightbar_params *p)
+static int lb_read_params_v0_from_file(const char *filename,
+ struct lightbar_params_v0 *p)
{
FILE *fp;
char buf[80];
@@ -1529,6 +1531,8 @@ static int lb_read_params_from_file(const char *filename,
p->color[i].b = val[2];
}
+#undef READ
+
/* Yay */
r = 0;
done:
@@ -1539,7 +1543,7 @@ done:
return r;
}
-static void lb_show_params(const struct lightbar_params *p)
+static void lb_show_params_v0(const struct lightbar_params_v0 *p)
{
int i;
@@ -1590,6 +1594,232 @@ static void lb_show_params(const struct lightbar_params *p)
p->color[i].b, i);
}
+static int lb_read_params_v1_from_file(const char *filename,
+ struct lightbar_params_v1 *p)
+{
+ FILE *fp;
+ char buf[80];
+ int val[4];
+ int r = 1;
+ int line = 0;
+ int want, got;
+ int i;
+
+ fp = fopen(filename, "rb");
+ if (!fp) {
+ fprintf(stderr, "Can't open %s: %s\n",
+ filename, strerror(errno));
+ return 1;
+ }
+
+ /* We must read the correct number of params from each line */
+#define READ(N) do { \
+ line++; \
+ want = (N); \
+ got = -1; \
+ if (!fgets(buf, sizeof(buf), fp)) \
+ goto done; \
+ got = sscanf(buf, "%i %i %i %i", \
+ &val[0], &val[1], &val[2], &val[3]); \
+ if (want != got) \
+ goto done; \
+ } while (0)
+
+
+ /* Do it */
+ READ(1); p->google_ramp_up = val[0];
+ READ(1); p->google_ramp_down = val[0];
+ READ(1); p->s3s0_ramp_up = val[0];
+ READ(1); p->s0_tick_delay[0] = val[0];
+ READ(1); p->s0_tick_delay[1] = val[0];
+ READ(1); p->s0a_tick_delay[0] = val[0];
+ READ(1); p->s0a_tick_delay[1] = val[0];
+ READ(1); p->s0s3_ramp_down = val[0];
+ READ(1); p->s3_sleep_for = val[0];
+ READ(1); p->s3_ramp_up = val[0];
+ READ(1); p->s3_ramp_down = val[0];
+ READ(1); p->tap_tick_delay = val[0];
+ READ(1); p->tap_display_time = val[0];
+
+ READ(1); p->tap_pct_red = val[0];
+ READ(1); p->tap_pct_green = val[0];
+ READ(1); p->tap_seg_min_on = val[0];
+ READ(1); p->tap_seg_max_on = val[0];
+ READ(1); p->tap_seg_osc = val[0];
+ READ(3);
+ p->tap_idx[0] = val[0];
+ p->tap_idx[1] = val[1];
+ p->tap_idx[2] = val[2];
+
+ READ(2);
+ p->osc_min[0] = val[0];
+ p->osc_min[1] = val[1];
+ READ(2);
+ p->osc_max[0] = val[0];
+ p->osc_max[1] = val[1];
+ READ(2);
+ p->w_ofs[0] = val[0];
+ p->w_ofs[1] = val[1];
+
+ READ(2);
+ p->bright_bl_off_fixed[0] = val[0];
+ p->bright_bl_off_fixed[1] = val[1];
+
+ READ(2);
+ p->bright_bl_on_min[0] = val[0];
+ p->bright_bl_on_min[1] = val[1];
+
+ READ(2);
+ p->bright_bl_on_max[0] = val[0];
+ p->bright_bl_on_max[1] = val[1];
+
+ READ(3);
+ p->battery_threshold[0] = val[0];
+ p->battery_threshold[1] = val[1];
+ p->battery_threshold[2] = val[2];
+
+ READ(4);
+ p->s0_idx[0][0] = val[0];
+ p->s0_idx[0][1] = val[1];
+ p->s0_idx[0][2] = val[2];
+ p->s0_idx[0][3] = val[3];
+
+ READ(4);
+ p->s0_idx[1][0] = val[0];
+ p->s0_idx[1][1] = val[1];
+ p->s0_idx[1][2] = val[2];
+ p->s0_idx[1][3] = val[3];
+
+ READ(4);
+ p->s3_idx[0][0] = val[0];
+ p->s3_idx[0][1] = val[1];
+ p->s3_idx[0][2] = val[2];
+ p->s3_idx[0][3] = val[3];
+
+ READ(4);
+ p->s3_idx[1][0] = val[0];
+ p->s3_idx[1][1] = val[1];
+ p->s3_idx[1][2] = val[2];
+ p->s3_idx[1][3] = val[3];
+
+ for (i = 0; i < ARRAY_SIZE(p->color); i++) {
+ READ(3);
+ p->color[i].r = val[0];
+ p->color[i].g = val[1];
+ p->color[i].b = val[2];
+ }
+
+#undef READ
+
+ /* Yay */
+ r = 0;
+done:
+ if (r)
+ fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
+ line, want, got);
+ fclose(fp);
+ return r;
+}
+
+static void lb_show_params_v1(const struct lightbar_params_v1 *p)
+{
+ int i;
+
+ printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
+ printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
+ printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
+ printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
+ printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
+ printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
+ printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
+ printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
+ printf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
+ printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
+ printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
+ printf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
+ printf("%d\t\t# .tap_display_time\n", p->tap_display_time);
+ printf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
+ printf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
+ printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
+ printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
+ printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
+ printf("%d %d %d\t\t# .tap_idx\n",
+ p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
+ printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
+ p->osc_min[0], p->osc_min[1]);
+ printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
+ p->osc_max[0], p->osc_max[1]);
+ printf("%d %d\t\t# .w_ofs (battery, AC)\n",
+ p->w_ofs[0], p->w_ofs[1]);
+ printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
+ p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
+ printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
+ p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
+ printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
+ p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
+ printf("%d %d %d\t# .battery_threshold\n",
+ p->battery_threshold[0],
+ p->battery_threshold[1],
+ p->battery_threshold[2]);
+ printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
+ p->s0_idx[0][0], p->s0_idx[0][1],
+ p->s0_idx[0][2], p->s0_idx[0][3]);
+ printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
+ p->s0_idx[1][0], p->s0_idx[1][1],
+ p->s0_idx[1][2], p->s0_idx[1][3]);
+ printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
+ p->s3_idx[0][0], p->s3_idx[0][1],
+ p->s3_idx[0][2], p->s3_idx[0][3]);
+ printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
+ p->s3_idx[1][0], p->s3_idx[1][1],
+ p->s3_idx[1][2], p->s3_idx[1][3]);
+ for (i = 0; i < ARRAY_SIZE(p->color); i++)
+ printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
+ p->color[i].r,
+ p->color[i].g,
+ p->color[i].b, i);
+}
+
+static int cmd_lightbar_params_v0(int argc, char **argv)
+{
+ struct ec_params_lightbar param;
+ struct ec_response_lightbar resp;
+ int r;
+
+ if (argc > 2) {
+ r = lb_read_params_v0_from_file(argv[2],
+ &param.set_params_v0);
+ if (r)
+ return r;
+ return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0,
+ &param, &resp);
+ }
+ r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V0, &param, &resp);
+ if (!r)
+ lb_show_params_v0(&resp.get_params_v0);
+ return r;
+}
+
+static int cmd_lightbar_params_v1(int argc, char **argv)
+{
+ struct ec_params_lightbar param;
+ struct ec_response_lightbar resp;
+ int r;
+
+ if (argc > 2) {
+ r = lb_read_params_v1_from_file(argv[2],
+ &param.set_params_v1);
+ if (r)
+ return r;
+ return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1,
+ &param, &resp);
+ }
+ r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V1, &param, &resp);
+ if (!r)
+ lb_show_params_v1(&resp.get_params_v1);
+ return r;
+}
+
static int cmd_lightbar(int argc, char **argv)
{
int i, r;
@@ -1618,19 +1848,19 @@ static int cmd_lightbar(int argc, char **argv)
if (argc == 2 && !strcasecmp(argv[1], "on"))
return lb_do_cmd(LIGHTBAR_CMD_ON, &param, &resp);
+ if (!strcasecmp(argv[1], "params0"))
+ return cmd_lightbar_params_v0(argc, argv);
+
+ if (!strcasecmp(argv[1], "params1"))
+ return cmd_lightbar_params_v1(argc, argv);
+
if (!strcasecmp(argv[1], "params")) {
- if (argc > 2) {
- r = lb_read_params_from_file(argv[2],
- &param.set_params);
- if (r)
- return r;
- return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS,
- &param, &resp);
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS, &param, &resp);
- if (!r)
- lb_show_params(&resp.get_params);
- return r;
+ /* Just try them both */
+ fprintf(stderr, "trying params1 ...\n");
+ if (0 == cmd_lightbar_params_v1(argc, argv))
+ return 0;
+ fprintf(stderr, "trying params0 ...\n");
+ return cmd_lightbar_params_v0(argc, argv);
}
if (!strcasecmp(argv[1], "version")) {