diff options
-rw-r--r-- | common/lightbar.c | 237 | ||||
-rw-r--r-- | include/ec_commands.h | 61 | ||||
-rw-r--r-- | include/lightbar_msg_list.h | 3 | ||||
-rw-r--r-- | util/ectool.c | 264 |
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], + ¶m.set_params_v0); + if (r) + return r; + return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0, + ¶m, &resp); + } + r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V0, ¶m, &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], + ¶m.set_params_v1); + if (r) + return r; + return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1, + ¶m, &resp); + } + r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V1, ¶m, &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, ¶m, &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], - ¶m.set_params); - if (r) - return r; - return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS, - ¶m, &resp); - } - r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS, ¶m, &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")) { |