diff options
author | Bill Richardson <wfrichar@chromium.org> | 2014-04-16 13:18:26 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-05-15 05:18:11 +0000 |
commit | 485554aea38b3e23d576bb10c8ff159f6d31c8e9 (patch) | |
tree | 9f173b1f3f4d45b74640562d951759be31acdafd | |
parent | 0869221e4fe556a031e0a82574c9979ea5401090 (diff) | |
download | chrome-ec-485554aea38b3e23d576bb10c8ff159f6d31c8e9.tar.gz |
Rearrange lightbar.c to separate IC control from pattern logic
Just refactoring the code to make it neater. No functional changes.
BUG=chrome-os-partner:28596
BRANCH=ToT
TEST=make buildall -j
Change-Id: Ib436369c2242de3b0fdacf65404eaba4a309e73b
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/199880
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | common/lightbar.c | 371 |
1 files changed, 186 insertions, 185 deletions
diff --git a/common/lightbar.c b/common/lightbar.c index 6a24eab05d..d6e71759b6 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -141,10 +141,9 @@ static inline uint8_t scale_abs(int val, int max) return (val * max)/255; } -/* It will often be simpler to provide an overall brightness control. */ +/* This is the overall brightness control. */ static int brightness = 0xc0; - /* So that we can make brightness changes happen instantly, we need to track * the current values. The values in the controllers aren't very helpful. */ static uint8_t current[NUM_LEDS][3]; @@ -155,18 +154,7 @@ static inline uint8_t scale(int val, int max) return scale_abs((val * brightness)/255, max); } -static void lightbar_init_vals(void) -{ - CPRINTF("[%T LB_init_vals]\n"); - set_from_array(init_vals, ARRAY_SIZE(init_vals)); - memset(current, 0, sizeof(current)); -} - -/* Change it with this function (defined below). */ -static void lightbar_brightness(int newval); - - -/* Helper function. */ +/* Helper function to set one LED color and remember it for later */ static void setrgb(int led, int red, int green, int blue) { int ctrl, bank; @@ -180,6 +168,109 @@ static void setrgb(int led, int red, int green, int blue) controller_write(ctrl, bank+2, scale(green, MAX_GREEN)); } +/* LEDs are numbered 0-3, RGB values should be in 0-255. + * If you specify too large an LED, it sets them all. */ +static void lb_setrgb(int led, int red, int green, int blue) +{ + int i; + if (led >= NUM_LEDS) + for (i = 0; i < NUM_LEDS; i++) + setrgb(i, red, green, blue); + else + setrgb(led, red, green, blue); +} + +/* Change current display brightness (0-255) */ +static void lb_brightness(int newval) +{ + int i; + CPRINTF("[%T LB_bright 0x%02x]\n", newval); + brightness = newval; + for (i = 0; i < NUM_LEDS; i++) + setrgb(i, current[i][0], current[i][1], current[i][2]); +} + +/* Initialize the controller ICs after reset */ +static void lb_init(void) +{ + CPRINTF("[%T LB_init_vals]\n"); + set_from_array(init_vals, ARRAY_SIZE(init_vals)); + memset(current, 0, sizeof(current)); +} + +/* Just go into standby mode. No register values should change. */ +static void lb_off(void) +{ + CPRINTF("[%T LB_off]\n"); + controller_write(0, 0x01, 0x00); + controller_write(1, 0x01, 0x00); +} + +/* Come out of standby mode. */ +static void lb_on(void) +{ + CPRINTF("[%T LB_on]\n"); + controller_write(0, 0x01, 0x20); + controller_write(1, 0x01, 0x20); +} + +/* + * This sets up the auto-cycling features of the controllers to make a + * semi-random pattern of slowly fading colors. This is interesting only + * because it doesn't require any effort from the EC. +*/ +static void lb_start_builtin_cycle(void) +{ + int r = scale(255, MAX_RED); + int g = scale(255, MAX_BLUE); + int b = scale(255, MAX_GREEN); + struct initdata_s pulse_vals[] = { + {0x11, 0xce}, + {0x12, 0x67}, + {0x13, 0xef}, + {0x15, b}, + {0x16, r}, + {0x17, g}, + {0x18, b}, + {0x19, r}, + {0x1a, g}, + }; + + set_from_array(pulse_vals, ARRAY_SIZE(pulse_vals)); + controller_write(1, 0x13, 0xcd); /* this one's different */ +} + +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 +}; + +/* Helper for host command to dump controller registers */ +static void lb_hc_cmd_dump(struct ec_response_lightbar *out) +{ + int i; + uint8_t reg; + + BUILD_ASSERT(ARRAY_SIZE(dump_reglist) == + ARRAY_SIZE(out->dump.vals)); + + for (i = 0; i < ARRAY_SIZE(dump_reglist); i++) { + reg = dump_reglist[i]; + out->dump.vals[i].reg = reg; + out->dump.vals[i].ic0 = controller_read(0, reg); + out->dump.vals[i].ic1 = controller_read(1, reg); + } +} + +/* Helper for host command to write controller registers directly */ +static void lb_hc_cmd_reg(const struct ec_params_lightbar *in) +{ + controller_write(in->reg.ctrl, in->reg.reg, in->reg.value); +} + + /******************************************************************************/ /* Here's some state that we might want to maintain across sysjumps, just to @@ -249,13 +340,13 @@ static const struct lightbar_params default_params = { }; #define LB_SYSJUMP_TAG 0x4c42 /* "LB" */ -static void lb_preserve_state(void) +static void lightbar_preserve_state(void) { system_add_jump_tag(LB_SYSJUMP_TAG, 0, sizeof(st), &st); } -DECLARE_HOOK(HOOK_SYSJUMP, lb_preserve_state, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_SYSJUMP, lightbar_preserve_state, HOOK_PRIO_DEFAULT); -static void lb_restore_state(void) +static void lightbar_restore_state(void) { const uint8_t *old_state = 0; int size; @@ -320,10 +411,14 @@ static void get_battery_level(void) #ifdef CONFIG_PWM_KBLIGHT - /* With nothing else to go on, use the keyboard backlight level to - * set the brightness. If the keyboard backlight is OFF (which it is - * when ambient is bright), use max brightness for lightbar. If - * keyboard backlight is ON, use keyboard backlight brightness. + /* + * With nothing else to go on, use the keyboard backlight level to * + * set the brightness. In general, if the keyboard backlight + * is OFF (which it is when ambient is bright), use max brightness for + * lightbar. If keyboard backlight is ON, use keyboard backlight + * brightness. That fails if the keyboard backlight is off because + * someone's watching a movie in the dark, of course. Ideally we should + * just let the AP control it directly. */ if (pwm_get_enabled(PWM_CH_KBLIGHT)) { pct = pwm_get_duty(PWM_CH_KBLIGHT); @@ -337,14 +432,15 @@ static void get_battery_level(void) if (pct != last_backlight_level) { last_backlight_level = pct; - lightbar_brightness(pct); + lb_brightness(pct); } #endif } -/* Forcing functions for demo mode */ +/* Forcing functions for demo mode, called by the keyboard task. */ +/* Up/Down keys */ void demo_battery_level(int inc) { if (!demo_mode) @@ -359,6 +455,7 @@ void demo_battery_level(int inc) CPRINTF("[%T LB demo: battery_level=%d]\n", st.battery_level); } +/* Left/Right keys */ void demo_is_charging(int ischarge) { if (!demo_mode) @@ -369,6 +466,7 @@ void demo_is_charging(int ischarge) st.battery_is_charging); } +/* Bright/Dim keys */ void demo_brightness(int inc) { int b; @@ -381,7 +479,7 @@ void demo_brightness(int inc) b = 0xff; else if (b < 0) b = 0; - lightbar_brightness(b); + lb_brightness(b); } @@ -389,50 +487,13 @@ void demo_brightness(int inc) /* Basic LED control functions. Use these to implement the pretty patterns. */ /******************************************************************************/ -/* Just go into standby mode. No register values should change. */ -static void lightbar_off(void) -{ - CPRINTF("[%T LB_off]\n"); - controller_write(0, 0x01, 0x00); - controller_write(1, 0x01, 0x00); -} - -/* Come out of standby mode. */ -static void lightbar_on(void) -{ - CPRINTF("[%T LB_on]\n"); - controller_write(0, 0x01, 0x20); - controller_write(1, 0x01, 0x20); -} - -/* LEDs are numbered 0-3, RGB values should be in 0-255. - * If you specify too large an LED, it sets them all. */ -static void lightbar_setrgb(int led, int red, int green, int blue) -{ - int i; - if (led >= NUM_LEDS) - for (i = 0; i < NUM_LEDS; i++) - setrgb(i, red, green, blue); - else - setrgb(led, red, green, blue); -} -/* Change current display brightness (0-255) */ -static void lightbar_brightness(int newval) -{ - int i; - CPRINTF("[%T LB_bright 0x%02x]\n", newval); - brightness = newval; - for (i = 0; i < NUM_LEDS; i++) - lightbar_setrgb(i, current[i][0], - current[i][1], current[i][2]); -} /******************************************************************************/ /* Helper functions and data. */ /******************************************************************************/ -const float _ramp_table[] = { +static 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, 0.021530f, 0.025236f, 0.029228f, 0.033504f, 0.038060f, 0.042895f, @@ -510,7 +571,7 @@ static uint32_t pulse_google_colors(void) 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); + lb_setrgb(i, r, g, b); } WAIT_OR_RET(st.p.google_ramp_up); } @@ -520,7 +581,7 @@ static uint32_t pulse_google_colors(void) 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); + lb_setrgb(i, r, g, b); } WAIT_OR_RET(st.p.google_ramp_down); } @@ -536,8 +597,8 @@ static uint32_t sequence_S3S0(void) int ci; uint32_t res; - lightbar_init_vals(); - lightbar_on(); + lb_init(); + lb_on(); get_battery_level(); res = pulse_google_colors(); @@ -559,7 +620,7 @@ static uint32_t sequence_S3S0(void) 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); + lb_setrgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3s0_ramp_up); } @@ -585,8 +646,8 @@ static uint32_t sequence_S0(void) start = get_time(); tick = last_tick = 0; - lightbar_setrgb(NUM_LEDS, 0, 0, 0); - lightbar_on(); + lb_setrgb(NUM_LEDS, 0, 0, 0); + lb_on(); while (1) { now = get_time(); @@ -622,7 +683,7 @@ static uint32_t sequence_S0(void) 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); + lb_setrgb(i, r, g, b); } /* Increment the phase */ @@ -659,7 +720,7 @@ static uint32_t sequence_S0S3(void) r = drop[i][0] * f; g = drop[i][1] * f; b = drop[i][2] * f; - lightbar_setrgb(i, r, g, b); + lb_setrgb(i, r, g, b); } WAIT_OR_RET(st.p.s0s3_ramp_down); } @@ -676,9 +737,9 @@ static uint32_t sequence_S3(void) float f; int ci; - lightbar_off(); - lightbar_init_vals(); - lightbar_setrgb(NUM_LEDS, 0, 0, 0); + lb_off(); + lb_init(); + lb_setrgb(NUM_LEDS, 0, 0, 0); while (1) { WAIT_OR_RET(st.p.s3_sleep_for); get_battery_level(); @@ -689,14 +750,14 @@ static uint32_t sequence_S3(void) continue; /* pulse once */ - lightbar_on(); + lb_on(); for (w = 0; w < 128; w += 2) { f = cycle_010(w); 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); + lb_setrgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3_ramp_up); } for (w = 128; w <= 256; w++) { @@ -704,12 +765,12 @@ static uint32_t sequence_S3(void) 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); + lb_setrgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3_ramp_down); } - lightbar_setrgb(NUM_LEDS, 0, 0, 0); - lightbar_off(); + lb_setrgb(NUM_LEDS, 0, 0, 0); + lb_off(); } return 0; } @@ -723,16 +784,16 @@ static uint32_t sequence_S5S3(void) * respond. Don't return early, because we still want to initialize the * lightbar even if another message comes along while we're waiting. */ usleep(100); - lightbar_init_vals(); - lightbar_setrgb(NUM_LEDS, 0, 0, 0); - lightbar_on(); + lb_init(); + lb_setrgb(NUM_LEDS, 0, 0, 0); + lb_on(); return 0; } /* Sleep to off. The S3->S5 transition takes about 10msec, so just wait. */ static uint32_t sequence_S3S5(void) { - lightbar_off(); + lb_off(); WAIT_OR_RET(-1); return 0; } @@ -762,26 +823,26 @@ static uint32_t sequence_TEST_inner(void) {0xff, 0xff, 0xff}, }; - lightbar_init_vals(); - lightbar_on(); + lb_init(); + lb_on(); for (i = 0; i < ARRAY_SIZE(testcolors); i++) { for (k = 0; k <= kmax; k += kstep) { 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); + lb_setrgb(NUM_LEDS, r, g, b); WAIT_OR_RET(10000); } for (k = kmax; k >= 0; k -= kstep) { 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); + lb_setrgb(NUM_LEDS, r, g, b); WAIT_OR_RET(10000); } } - lightbar_setrgb(NUM_LEDS, 0, 0, 0); + lb_setrgb(NUM_LEDS, 0, 0, 0); return 0; } @@ -798,37 +859,19 @@ static uint32_t sequence_TEST(void) return r; } -/* This uses the auto-cycling features of the controllers to make a semi-random - * pattern of slowly fading colors. This is interesting only because it doesn't - * require any effort from the EC. */ static uint32_t sequence_PULSE(void) { uint32_t msg; - int r = scale(255, MAX_RED); - int g = scale(255, MAX_BLUE); - int b = scale(255, MAX_GREEN); - struct initdata_s pulse_vals[] = { - {0x11, 0xce}, - {0x12, 0x67}, - {0x13, 0xef}, - {0x15, b}, - {0x16, r}, - {0x17, g}, - {0x18, b}, - {0x19, r}, - {0x1a, g}, - }; - lightbar_init_vals(); - lightbar_on(); + lb_init(); + lb_on(); - set_from_array(pulse_vals, ARRAY_SIZE(pulse_vals)); - controller_write(1, 0x13, 0xcd); /* this one's different */ + lb_start_builtin_cycle(); /* Not using WAIT_OR_RET() here, because we want to clean up when we're * done. The only way out is to get a message. */ msg = task_wait_event(-1); - lightbar_init_vals(); + lb_init(); return TASK_EVENT_CUSTOM(msg); } @@ -862,13 +905,13 @@ static uint32_t sequence_RUN(void) /* We shouldn't come here, but if we do it shouldn't hurt anything */ static uint32_t sequence_ERROR(void) { - lightbar_init_vals(); - lightbar_on(); + lb_init(); + lb_on(); - lightbar_setrgb(0, 255, 255, 255); - lightbar_setrgb(1, 255, 0, 255); - lightbar_setrgb(2, 0, 255, 255); - lightbar_setrgb(3, 255, 255, 255); + lb_setrgb(0, 255, 255, 255); + lb_setrgb(1, 255, 0, 255); + lb_setrgb(2, 0, 255, 255); + lb_setrgb(3, 255, 255, 255); WAIT_OR_RET(10 * SECOND); return 0; @@ -956,15 +999,15 @@ static uint32_t sequence_KONAMI(void) int i; int tmp; - lightbar_off(); - lightbar_init_vals(); - lightbar_on(); + lb_off(); + lb_init(); + lb_on(); tmp = brightness; brightness = 255; for (i = 0; i < ARRAY_SIZE(konami); i++) { - lightbar_setrgb(konami[i].led, + lb_setrgb(konami[i].led, konami[i].r, konami[i].g, konami[i].b); if (konami[i].delay) usleep(konami[i].delay); @@ -997,7 +1040,7 @@ void lightbar_task(void) CPRINTF("[%T LB task starting]\n"); - lb_restore_state(); + lightbar_restore_state(); while (1) { CPRINTF("[%T LB task %d = %s]\n", @@ -1078,46 +1121,6 @@ static void lightbar_shutdown(void) DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, lightbar_shutdown, HOOK_PRIO_DEFAULT); /****************************************************************************/ -/* Generic command-handling (should work the same for both console & LPC) */ -/****************************************************************************/ - -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 void do_cmd_dump(struct ec_response_lightbar *out) -{ - int i; - uint8_t reg; - - BUILD_ASSERT(ARRAY_SIZE(dump_reglist) == - ARRAY_SIZE(out->dump.vals)); - - for (i = 0; i < ARRAY_SIZE(dump_reglist); i++) { - reg = dump_reglist[i]; - out->dump.vals[i].reg = reg; - out->dump.vals[i].ic0 = controller_read(0, reg); - out->dump.vals[i].ic1 = 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); -} - - -/****************************************************************************/ /* Host commands via LPC bus */ /****************************************************************************/ @@ -1128,34 +1131,32 @@ static int lpc_cmd_lightbar(struct host_cmd_handler_args *args) switch (in->cmd) { case LIGHTBAR_CMD_DUMP: - do_cmd_dump(out); + lb_hc_cmd_dump(out); args->response_size = sizeof(out->dump); break; case LIGHTBAR_CMD_OFF: - lightbar_off(); + lb_off(); break; case LIGHTBAR_CMD_ON: - lightbar_on(); + lb_on(); break; case LIGHTBAR_CMD_INIT: - lightbar_init_vals(); + lb_init(); break; case LIGHTBAR_CMD_BRIGHTNESS: - lightbar_brightness(in->brightness.num); + lb_brightness(in->brightness.num); break; case LIGHTBAR_CMD_SEQ: lightbar_sequence(in->seq.num); break; case LIGHTBAR_CMD_REG: - controller_write(in->reg.ctrl, - in->reg.reg, - in->reg.value); + lb_hc_cmd_reg(in); break; case LIGHTBAR_CMD_RGB: - do_cmd_rgb(in->rgb.led, - in->rgb.red, - in->rgb.green, - in->rgb.blue); + lb_setrgb(in->rgb.led, + in->rgb.red, + in->rgb.green, + in->rgb.blue); break; case LIGHTBAR_CMD_GET_SEQ: out->get_seq.num = st.cur_seq; @@ -1296,8 +1297,8 @@ static int command_lightbar(int argc, char **argv) struct ec_response_lightbar out; if (argc == 1) { /* no args = dump 'em all */ - do_cmd_dump(&out); - for (i = 0; i < ARRAY_SIZE(dump_reglist); i++) + lb_hc_cmd_dump(&out); + for (i = 0; i < ARRAY_SIZE(out.dump.vals); i++) ccprintf(" %02x %02x %02x\n", out.dump.vals[i].reg, out.dump.vals[i].ic0, @@ -1307,17 +1308,17 @@ static int command_lightbar(int argc, char **argv) } if (!strcasecmp(argv[1], "init")) { - lightbar_init_vals(); + lb_init(); return EC_SUCCESS; } if (!strcasecmp(argv[1], "off")) { - lightbar_off(); + lb_off(); return EC_SUCCESS; } if (!strcasecmp(argv[1], "on")) { - lightbar_on(); + lb_on(); return EC_SUCCESS; } @@ -1336,7 +1337,7 @@ static int command_lightbar(int argc, char **argv) char *e; if (argc > 2) { num = 0xff & strtoi(argv[2], &e, 16); - lightbar_brightness(num); + lb_brightness(num); } ccprintf("brightness is %02x\n", brightness); return EC_SUCCESS; @@ -1375,11 +1376,11 @@ static int command_lightbar(int argc, char **argv) if (argc == 4) { char *e; - 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); + struct ec_params_lightbar in; + in.reg.ctrl = strtoi(argv[1], &e, 16); + in.reg.reg = strtoi(argv[2], &e, 16); + in.reg.value = strtoi(argv[3], &e, 16); + lb_hc_cmd_reg(&in); return EC_SUCCESS; } @@ -1390,7 +1391,7 @@ static int command_lightbar(int argc, char **argv) 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); + lb_setrgb(led, r, g, b); return EC_SUCCESS; } |