summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/lightbar.c274
-rw-r--r--include/ec_commands.h43
-rw-r--r--util/ectool.c156
-rw-r--r--util/lbplay.c4
4 files changed, 378 insertions, 99 deletions
diff --git a/common/lightbar.c b/common/lightbar.c
index c99a444c84..e70e69bd3a 100644
--- a/common/lightbar.c
+++ b/common/lightbar.c
@@ -25,8 +25,6 @@
#define CPUTS(outstr) cputs(CC_LIGHTBAR, outstr)
#define CPRINTF(format, args...) cprintf(CC_LIGHTBAR, format, ## args)
-#define CONSOLE_COMMAND_LIGHTBAR_HELP
-
/******************************************************************************/
/* How to talk to the controller */
/******************************************************************************/
@@ -157,7 +155,7 @@ static void setrgb(int led, int red, int green, int blue)
/* Here's some state that we might want to maintain across sysjumps, just to
* prevent the lightbar from flashing during normal boot as the EC jumps from
* RO to RW. */
-static struct {
+static struct p_state {
/* What patterns are we showing? */
enum lightbar_sequence cur_seq;
enum lightbar_sequence prev_seq;
@@ -172,8 +170,47 @@ static struct {
uint8_t w0; /* primary phase */
uint8_t amp; /* amplitude */
uint8_t ramp; /* ramp-in for S3->S0 */
+
+ uint8_t _pad0; /* next item is __packed */
+
+ /* Tweakable parameters */
+ struct lightbar_params p;
} st;
+static const struct lightbar_params default_params = {
+ .google_ramp_up = 2500,
+ .google_ramp_down = 10000,
+ .s3s0_ramp_up = 2000,
+ .s0_tick_delay = { 45000, 30000 }, /* battery, AC */
+ .s0s3_ramp_down = 2000,
+ .s3_sleep_for = 15000000, /* between checks */
+ .s3_tick_delay = 15000,
+
+ .w_ofs = 24, /* phase offset, 256 == 2*PI */
+
+ .bright_bl_off_fixed = {0x80, 0x80}, /* backlight off: battery, AC */
+ .bright_bl_on_min = {0x40, 0x40}, /* backlight on: battery, AC */
+ .bright_bl_on_max = {0xff, 0xff}, /* backlight on: battery, AC */
+ .s0_idx = {
+ { 5, 4, 4, 4 }, /* battery: 0 = red, other = blue */
+ { 5, 4, 4, 4 } /* AC: 0 = red, other = blue */
+ },
+ .s3_idx = {
+ { 5, 0xff, 0xff, 0xff }, /* battery: 0 = red, else off */
+ { 0xff, 0xff, 0xff, 0xff } /* AC: do nothing */
+ },
+ .color = {
+ {0x33, 0x69, 0xe8}, /* 0: Google blue */
+ {0xd5, 0x0f, 0x25}, /* 1: Google red */
+ {0xee, 0xb2, 0x11}, /* 2: Google yellow */
+ {0x00, 0x99, 0x25}, /* 3: Google green */
+ {0x00, 0x00, 0xff}, /* 4: full blue */
+ {0xff, 0x00, 0x00}, /* 5: full red */
+ {0xff, 0xff, 0x00}, /* 6: full yellow */
+ {0x00, 0xff, 0x00}, /* 7: full green */
+ },
+};
+
#define LB_SYSJUMP_TAG 0x4c42 /* "LB" */
static int lb_preserve_state(void)
{
@@ -190,16 +227,18 @@ static void lb_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);
+ CPRINTF("[%T LB state restored: %d %d - %d/%d]\n",
+ st.cur_seq, st.prev_seq,
+ st.battery_is_charging, st.battery_level);
} else {
st.cur_seq = st.prev_seq = LIGHTBAR_S5;
st.battery_level = 3;
st.w0 = 0;
st.amp = 0;
st.ramp = 0;
+ memcpy(&st.p, &default_params, sizeof(st.p));
+ CPRINTF("[%T LB state initialized]\n");
}
- CPRINTF("[%T LB state: %d %d - %d/%d]\n",
- st.cur_seq, st.prev_seq,
- st.battery_is_charging, st.battery_level);
}
/******************************************************************************/
@@ -223,6 +262,20 @@ static void get_battery_level(void)
if (demo_mode)
return;
+#ifdef CONFIG_TASK_POWERSTATE
+ pct = charge_get_percent();
+ st.battery_is_charging = (PWR_STATE_DISCHARGE != charge_get_state());
+#endif
+
+ /* For some reason we only have four states */
+ st.battery_level = 0;
+ if (pct >= LIGHTBAR_POWER_THRESHOLD_MEDIUM)
+ st.battery_level = 1;
+ if (pct >= LIGHTBAR_POWER_THRESHOLD_HIGH)
+ st.battery_level = 2;
+ if (pct >= LIGHTBAR_POWER_THRESHOLD_FULL)
+ st.battery_level = 3;
+
#ifdef CONFIG_TASK_PWM
/* With nothing else to go on, use the keyboard backlight level to
* set the brightness. If the keyboard backlight is OFF (which it is
@@ -231,25 +284,19 @@ static void get_battery_level(void)
*/
if (pwm_get_keyboard_backlight_enabled()) {
pct = pwm_get_keyboard_backlight();
- if (pct != last_backlight_level) {
- last_backlight_level = pct;
- pct = (255 * pct) / 100;
- lightbar_brightness(pct);
- }
+ pct = (255 * pct) / 100; /* 00 - FF */
+ if (pct > st.p.bright_bl_on_max[st.battery_is_charging])
+ pct = st.p.bright_bl_on_max[st.battery_is_charging];
+ else if (pct < st.p.bright_bl_on_min[st.battery_is_charging])
+ pct = st.p.bright_bl_on_min[st.battery_is_charging];
} else
- lightbar_brightness(255);
-#endif
+ pct = st.p.bright_bl_off_fixed[st.battery_is_charging];
-#ifdef CONFIG_TASK_POWERSTATE
- pct = charge_get_percent();
- st.battery_is_charging = (PWR_STATE_DISCHARGE != charge_get_state());
+ if (pct != last_backlight_level) {
+ last_backlight_level = pct;
+ lightbar_brightness(pct);
+ }
#endif
-
- /* We're only using two of the four levels at the moment. */
- if (pct > LIGHTBAR_POWER_THRESHOLD_MEDIUM)
- st.battery_level = 3;
- else
- st.battery_level = 0;
}
@@ -342,35 +389,6 @@ static void lightbar_brightness(int newval)
/* Helper functions and data. */
/******************************************************************************/
-struct rgb_s {
- uint8_t r, g, b;
-};
-
-/* These are the official Google colors, in order. */
-enum { BLUE = 0, RED, YELLOW, GREEN, INVALID };
-static const struct rgb_s google[] = {
- {0x33, 0x69, 0xe8}, /* blue */
- {0xd5, 0x0f, 0x25}, /* red */
- {0xee, 0xb2, 0x11}, /* yellow */
- {0x00, 0x99, 0x25}, /* green */
-
- {0xff, 0x00, 0xFF}, /* invalid */
-};
-
-/* These are used for test patterns. */
-static const struct rgb_s colors[] = {
- {0xff, 0x00, 0x00},
- {0xff, 0xff, 0x00},
- {0x00, 0xff, 0x00},
- {0x00, 0x00, 0xff},
- {0x00, 0xff, 0xff},
- {0xff, 0x00, 0xff},
- {0xff, 0xff, 0xff},
-};
-
-/* Map battery_level to one of the google colors */
-static const int battery_color[] = { RED, YELLOW, GREEN, BLUE };
-
const float _ramp_table[] = {
0.000000f, 0.000151f, 0.000602f, 0.001355f, 0.002408f, 0.003760f,
0.005412f, 0.007361f, 0.009607f, 0.012149f, 0.014984f, 0.018112f,
@@ -442,22 +460,22 @@ static uint32_t pulse_google_colors(void)
for (w = 0; w < 128; w += 2) {
f = cycle_010(w);
for (i = 0; i < NUM_LEDS; i++) {
- r = google[i].r * f;
- g = google[i].g * f;
- b = google[i].b * f;
+ r = st.p.color[i].r * f;
+ g = st.p.color[i].g * f;
+ b = st.p.color[i].b * f;
lightbar_setrgb(i, r, g, b);
}
- WAIT_OR_RET(2500);
+ WAIT_OR_RET(st.p.google_ramp_up);
}
for (w = 128; w <= 256; w++) {
f = cycle_010(w);
for (i = 0; i < NUM_LEDS; i++) {
- r = google[i].r * f;
- g = google[i].g * f;
- b = google[i].b * f;
+ r = st.p.color[i].r * f;
+ g = st.p.color[i].g * f;
+ b = st.p.color[i].b * f;
lightbar_setrgb(i, r, g, b);
}
- WAIT_OR_RET(10000);
+ WAIT_OR_RET(st.p.google_ramp_down);
}
return 0;
@@ -484,16 +502,18 @@ static uint32_t sequence_S3S0(void)
if (res)
return res;
- /* Ramp up to base brightness. */
+ /* Ramp up to base brightness, using S0 colors */
get_battery_level();
- ci = battery_color[st.battery_level];
+ ci = st.p.s0_idx[st.battery_is_charging][st.battery_level];
+ if (ci >= ARRAY_SIZE(st.p.color))
+ ci = 0;
for (w = 0; w <= 128; w++) {
f = cycle_010(w) * BASE_S0;
- r = google[ci].r * f;
- g = google[ci].g * f;
- b = google[ci].b * f;
+ r = st.p.color[ci].r * f;
+ g = st.p.color[ci].g * f;
+ b = st.p.color[ci].b * f;
lightbar_setrgb(NUM_LEDS, r, g, b);
- WAIT_OR_RET(2000);
+ WAIT_OR_RET(st.p.s3s0_ramp_up);
}
/* Initial conditions */
@@ -534,14 +554,16 @@ static uint32_t sequence_S0(void)
}
/* Calculate the colors */
- ci = battery_color[st.battery_level];
+ ci = st.p.s0_idx[st.battery_is_charging][st.battery_level];
+ if (ci >= ARRAY_SIZE(st.p.color))
+ ci = 0;
ff = st.amp / 255.0f;
for (i = 0; i < NUM_LEDS; i++) {
- w = st.w0 - i * 24 * st.ramp / 255;
+ w = st.w0 - i * st.p.w_ofs * st.ramp / 255;
f = BASE_S0 + OSC_S0 * cycle_0P0N0(w) * ff;
- r = google[ci].r * f;
- g = google[ci].g * f;
- b = google[ci].b * f;
+ r = st.p.color[ci].r * f;
+ g = st.p.color[ci].g * f;
+ b = st.p.color[ci].b * f;
lightbar_setrgb(i, r, g, b);
}
@@ -553,17 +575,16 @@ static uint32_t sequence_S0(void)
st.amp++;
/* Increment the phase */
- if (st.battery_is_charging) {
+ if (st.battery_is_charging)
st.w0--;
- WAIT_OR_RET(MSECS(2 * 15));
- } else {
+ else
st.w0++;
- WAIT_OR_RET(MSECS(3 * 15));
- }
/* Continue ramping in if needed */
if (st.ramp < 0xff)
st.ramp++;
+
+ WAIT_OR_RET(st.p.s0_tick_delay[st.battery_is_charging]);
}
return 0;
}
@@ -587,7 +608,7 @@ static uint32_t sequence_S0S3(void)
b = drop[i][2] * f;
lightbar_setrgb(i, r, g, b);
}
- WAIT_OR_RET(2000);
+ WAIT_OR_RET(st.p.s0s3_ramp_down);
}
/* pulse once and done */
@@ -606,23 +627,23 @@ static uint32_t sequence_S3(void)
lightbar_init_vals();
lightbar_setrgb(NUM_LEDS, 0, 0, 0);
while (1) {
- WAIT_OR_RET(SEC(15));
+ WAIT_OR_RET(st.p.s3_sleep_for);
get_battery_level();
- /* only pulse if we're off AC and the battery level is low */
- if (st.battery_is_charging || st.battery_level > 0)
+ /* only pulse if we've been given a valid color index */
+ ci = st.p.s3_idx[st.battery_is_charging][st.battery_level];
+ if (ci >= ARRAY_SIZE(st.p.color))
continue;
/* pulse once */
- ci = battery_color[st.battery_level];
lightbar_on();
for (w = 0; w < 255; w += 5) {
f = cycle_010(w);
- r = google[ci].r * f;
- g = google[ci].g * f;
- b = google[ci].b * f;
+ r = st.p.color[ci].r * f;
+ g = st.p.color[ci].g * f;
+ b = st.p.color[ci].b * f;
lightbar_setrgb(NUM_LEDS, r, g, b);
- WAIT_OR_RET(15000);
+ WAIT_OR_RET(st.p.s3_tick_delay);
}
lightbar_setrgb(NUM_LEDS, 0, 0, 0);
lightbar_off();
@@ -668,20 +689,30 @@ static uint32_t sequence_TEST_inner(void)
int kmax = 254;
int kstep = 8;
+ static const struct rgb_s testcolors[] = {
+ {0xff, 0x00, 0x00},
+ {0xff, 0xff, 0x00},
+ {0x00, 0xff, 0x00},
+ {0x00, 0x00, 0xff},
+ {0x00, 0xff, 0xff},
+ {0xff, 0x00, 0xff},
+ {0xff, 0xff, 0xff},
+ };
+
lightbar_init_vals();
lightbar_on();
- for (i = 0; i < ARRAY_SIZE(colors); i++) {
+ for (i = 0; i < ARRAY_SIZE(testcolors); i++) {
for (k = 0; k <= kmax; k += kstep) {
- r = colors[i].r ? k : 0;
- g = colors[i].g ? k : 0;
- b = colors[i].b ? k : 0;
+ r = testcolors[i].r ? k : 0;
+ g = testcolors[i].g ? k : 0;
+ b = testcolors[i].b ? k : 0;
lightbar_setrgb(NUM_LEDS, r, g, b);
WAIT_OR_RET(10000);
}
for (k = kmax; k >= 0; k -= kstep) {
- r = colors[i].r ? k : 0;
- g = colors[i].g ? k : 0;
- b = colors[i].b ? k : 0;
+ r = testcolors[i].r ? k : 0;
+ g = testcolors[i].g ? k : 0;
+ b = testcolors[i].b ? k : 0;
lightbar_setrgb(NUM_LEDS, r, g, b);
WAIT_OR_RET(10000);
}
@@ -776,7 +807,7 @@ static uint32_t sequence_ERROR(void)
lightbar_setrgb(2, 0, 255, 255);
lightbar_setrgb(3, 255, 255, 255);
- WAIT_OR_RET(10000000);
+ WAIT_OR_RET(SEC(10));
return 0;
}
@@ -994,7 +1025,7 @@ DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, lightbar_shutdown, HOOK_PRIO_DEFAULT);
static const uint8_t dump_reglist[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0f,
+ 0x08, 0x09, 0x0a, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a
};
@@ -1076,6 +1107,15 @@ static int lpc_cmd_lightbar(struct host_cmd_handler_args *args)
demo_mode = in->demo.num ? 1 : 0;
CPRINTF("[%T LB_demo %d]\n", demo_mode);
break;
+ case LIGHTBAR_CMD_GET_PARAMS:
+ CPRINTF("[%T LB_get_params]\n");
+ memcpy(&out->get_params, &st.p, sizeof(st.p));
+ args->response_size = sizeof(out->get_params);
+ break;
+ case LIGHTBAR_CMD_SET_PARAMS:
+ CPRINTF("[%T LB_set_params]\n");
+ memcpy(&st.p, &in->set_params, sizeof(st.p));
+ break;
default:
CPRINTF("[%T LB bad cmd 0x%x]\n", in->cmd);
return EC_RES_INVALID_PARAM;
@@ -1093,7 +1133,7 @@ DECLARE_HOST_COMMAND(EC_CMD_LIGHTBAR_CMD,
/* EC console commands */
/****************************************************************************/
-#ifdef CONSOLE_COMMAND_LIGHTBAR_HELP
+#ifdef CONFIG_CONSOLE_CMDHELP
static int help(const char *cmd)
{
ccprintf("Usage:\n");
@@ -1108,6 +1148,7 @@ static int help(const char *cmd)
ccprintf(" %s LED RED GREEN BLUE - set color manually"
" (LED=4 for all)\n", cmd);
ccprintf(" %s demo [0|1] - turn demo mode on & off\n", cmd);
+ ccprintf(" %s params - show current params\n", cmd);
return EC_SUCCESS;
}
#endif
@@ -1132,6 +1173,44 @@ static void show_msg_names(void)
lightbar_cmds[st.cur_seq].string);
}
+static void show_params(const struct lightbar_params *p)
+{
+ int i;
+
+ ccprintf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
+ ccprintf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
+ ccprintf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
+ ccprintf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
+ ccprintf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
+ ccprintf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
+ ccprintf("%d\t# .s3_sleep_for\n", p->s3_sleep_for);
+ ccprintf("%d\t\t# .s3_tick_delay\n", p->s3_tick_delay);
+ ccprintf("%d\t\t# .w_ofs\n", p->w_ofs);
+ ccprintf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
+ p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
+ ccprintf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
+ p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
+ ccprintf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
+ p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
+ ccprintf("%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]);
+ ccprintf("%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]);
+ ccprintf("%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]);
+ ccprintf("%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++)
+ ccprintf("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 command_lightbar(int argc, char **argv)
{
int i;
@@ -1164,6 +1243,11 @@ static int command_lightbar(int argc, char **argv)
return EC_SUCCESS;
}
+ if (!strcasecmp(argv[1], "params")) {
+ show_params(&st.p);
+ return EC_SUCCESS;
+ }
+
if (!strcasecmp(argv[1], "brightness")) {
char *e;
if (argc > 2) {
@@ -1226,7 +1310,7 @@ static int command_lightbar(int argc, char **argv)
return EC_SUCCESS;
}
-#ifdef CONSOLE_COMMAND_LIGHTBAR_HELP
+#ifdef CONFIG_CONSOLE_CMDHELP
help(argv[0]);
#endif
diff --git a/include/ec_commands.h b/include/ec_commands.h
index ee893c8065..22b8b96177 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -621,12 +621,45 @@ struct ec_params_pwm_set_fan_duty {
*/
#define EC_CMD_LIGHTBAR_CMD 0x28
+struct rgb_s {
+ uint8_t r, g, b;
+};
+
+/* 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 {
+ /* Timing */
+ int google_ramp_up;
+ int google_ramp_down;
+ int s3s0_ramp_up;
+ int s0_tick_delay[2]; /* AC=0/1 */
+ int s0s3_ramp_down;
+ int s3_sleep_for;
+ int s3_tick_delay;
+
+ /* Phase shift */
+ uint8_t w_ofs;
+
+ /* 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 */
+
+ /* Map [AC][battery_level] to color index */
+ uint8_t s0_idx[2][4]; /* AP is running */
+ uint8_t s3_idx[2][4]; /* 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;
+ } dump, off, on, init, get_seq, get_params;
struct num {
uint8_t num;
@@ -639,6 +672,8 @@ struct ec_params_lightbar {
struct rgb {
uint8_t led, red, green, blue;
} rgb;
+
+ struct lightbar_params set_params;
};
} __packed;
@@ -656,9 +691,11 @@ struct ec_response_lightbar {
uint8_t num;
} get_seq;
+ struct lightbar_params get_params;
+
struct {
/* no return params */
- } off, on, init, brightness, seq, reg, rgb, demo;
+ } off, on, init, brightness, seq, reg, rgb, demo, set_params;
};
} __packed;
@@ -674,6 +711,8 @@ enum lightbar_command {
LIGHTBAR_CMD_RGB = 7,
LIGHTBAR_CMD_GET_SEQ = 8,
LIGHTBAR_CMD_DEMO = 9,
+ LIGHTBAR_CMD_GET_PARAMS = 10,
+ LIGHTBAR_CMD_SET_PARAMS = 11,
LIGHTBAR_NUM_CMDS
};
diff --git a/util/ectool.c b/util/ectool.c
index 9fb8a19635..5b1cec8be7 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -4,6 +4,7 @@
*/
#include <ctype.h>
+#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -1061,7 +1062,9 @@ static const struct {
LB_SIZES(reg),
LB_SIZES(rgb),
LB_SIZES(get_seq),
- LB_SIZES(demo)
+ LB_SIZES(demo),
+ LB_SIZES(get_params),
+ LB_SIZES(set_params),
};
#undef LB_SIZES
@@ -1079,6 +1082,8 @@ static int lb_help(const char *cmd)
printf(" %s LED RED GREEN BLUE - set color manually"
" (LED=4 for all)\n", cmd);
printf(" %s demo 0|1 - turn demo mode on & off\n", cmd);
+ printf(" %s params [setfile] - get params"
+ " (or set from file)\n", cmd);
return 0;
}
@@ -1124,6 +1129,140 @@ static int lb_show_msg_names(void)
return 0;
}
+static int lb_read_params_from_file(const char *filename,
+ struct lightbar_params *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->s0s3_ramp_down = val[0];
+ READ(1); p->s3_sleep_for = val[0];
+ READ(1); p->s3_tick_delay = val[0];
+ READ(1); p->w_ofs = val[0];
+
+ 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(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];
+ }
+
+ /* 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(const struct lightbar_params *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# .s0s3_ramp_down\n", p->s0s3_ramp_down);
+ printf("%d\t# .s3_sleep_for\n", p->s3_sleep_for);
+ printf("%d\t\t# .s3_tick_delay\n", p->s3_tick_delay);
+ printf("%d\t\t# .w_ofs\n", p->w_ofs);
+ 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 %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(int argc, char **argv)
{
int i, r;
@@ -1152,6 +1291,21 @@ 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], "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;
+ }
+
if (argc == 3 && !strcasecmp(argv[1], "brightness")) {
char *e;
param.brightness.num = 0xff & strtoul(argv[2], &e, 16);
diff --git a/util/lbplay.c b/util/lbplay.c
index 8658368160..907374e9cc 100644
--- a/util/lbplay.c
+++ b/util/lbplay.c
@@ -35,7 +35,9 @@ static const struct {
LB_SIZES(reg),
LB_SIZES(rgb),
LB_SIZES(get_seq),
- LB_SIZES(demo)
+ LB_SIZES(demo),
+ LB_SIZES(get_params),
+ LB_SIZES(set_params)
};
#undef LB_SIZES