diff options
-rw-r--r-- | board/cranky/board.c | 3 | ||||
-rw-r--r-- | board/cranky/board.h | 2 | ||||
-rw-r--r-- | board/cranky/led.c | 101 |
3 files changed, 89 insertions, 17 deletions
diff --git a/board/cranky/board.c b/board/cranky/board.c index 8df1305c14..4a781f0e31 100644 --- a/board/cranky/board.c +++ b/board/cranky/board.c @@ -131,7 +131,7 @@ const struct gpio_alt_func gpio_alt_funcs[] = { {GPIO_D, 0x0f, 2, MODULE_SPI}, /* SPI1 */ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */ {GPIO_M, 0x21, 15, MODULE_LPC}, /* LPC */ - {GPIO_N, 0x50, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM 3&4 */ + {GPIO_N, 0x54, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM 2&3&4 */ }; const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs); @@ -177,6 +177,7 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); const struct pwm_t pwm_channels[] = { {4, PWM_CONFIG_ACTIVE_LOW}, {3, PWM_CONFIG_ACTIVE_LOW}, + {2, PWM_CONFIG_ACTIVE_LOW}, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/cranky/board.h b/board/cranky/board.h index 6b88370e04..11ba3c8436 100644 --- a/board/cranky/board.h +++ b/board/cranky/board.h @@ -173,7 +173,7 @@ enum adc_channel { enum pwm_channel { PWM_CH_LED_GREEN, PWM_CH_LED_RED, - + PWM_CH_LED_BLUE_POWER_LED, /* Number of PWM channels */ PWM_CH_COUNT }; diff --git a/board/cranky/led.c b/board/cranky/led.c index d83778a1d3..122a7f6dda 100644 --- a/board/cranky/led.c +++ b/board/cranky/led.c @@ -13,11 +13,13 @@ #include "pwm.h" #include "util.h" -const enum ec_led_id supported_led_ids[] = {EC_LED_ID_BATTERY_LED}; +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, EC_LED_ID_POWER_LED}; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); enum led_color { LED_OFF = 0, + LED_BLUE, LED_RED, LED_ORANGE, LED_YELLOW, @@ -31,6 +33,7 @@ enum led_color { static const uint8_t color_brightness[LED_COLOR_COUNT][2] = { {0, 0}, {100, 0}, + {100, 0}, {30, 45}, {20, 60}, {0, 100}, @@ -41,22 +44,49 @@ static const uint8_t color_brightness[LED_COLOR_COUNT][2] = { * * @param color Enumerated color value */ -static void set_color(enum led_color color) +static void set_color_battery_led(enum led_color color) { pwm_set_duty(PWM_CH_LED_RED, color_brightness[color][0]); pwm_set_duty(PWM_CH_LED_GREEN, color_brightness[color][1]); } +static void set_color_power_led(enum led_color color) +{ + pwm_set_duty(PWM_CH_LED_BLUE_POWER_LED, color_brightness[color][0]); +} + void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { - brightness_range[EC_LED_COLOR_RED] = 100; - brightness_range[EC_LED_COLOR_GREEN] = 100; + switch (led_id) { + case EC_LED_ID_BATTERY_LED: + brightness_range[EC_LED_COLOR_RED] = 100; + brightness_range[EC_LED_COLOR_GREEN] = 100; + break; + case EC_LED_ID_POWER_LED: + brightness_range[EC_LED_COLOR_BLUE] = 100; + break; + default: + /* Nothing to do */ + break; + } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { - pwm_set_duty(PWM_CH_LED_RED, brightness[EC_LED_COLOR_RED]); - pwm_set_duty(PWM_CH_LED_GREEN, brightness[EC_LED_COLOR_GREEN]); + switch (led_id) { + case EC_LED_ID_BATTERY_LED: + pwm_set_duty(PWM_CH_LED_RED, + brightness[EC_LED_COLOR_RED]); + pwm_set_duty(PWM_CH_LED_GREEN, + brightness[EC_LED_COLOR_GREEN]); + break; + case EC_LED_ID_POWER_LED: + pwm_set_duty(PWM_CH_LED_BLUE_POWER_LED, + brightness[EC_LED_COLOR_BLUE]); + break; + default: + break; + } return EC_SUCCESS; } @@ -71,19 +101,52 @@ static void led_init(void) */ pwm_enable(PWM_CH_LED_RED, 1); pwm_enable(PWM_CH_LED_GREEN, 1); - set_color(LED_OFF); + pwm_enable(PWM_CH_LED_BLUE_POWER_LED, 1); + set_color_battery_led(LED_OFF); + set_color_power_led(LED_OFF); } DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT); /** * Called by hook task every 250 ms */ -static void led_tick(void) +static void power_led_tick(void) { - static unsigned ticks; + static unsigned power_ticks; + static int previous_state_suspend; + + power_ticks++; + + /* If we don't control the LED, nothing to do */ + if (!led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) + return; + + if (chipset_in_state(CHIPSET_STATE_ON)) { + set_color_power_led(LED_BLUE); + } else if (chipset_in_state(CHIPSET_STATE_SUSPEND)) { + if (!previous_state_suspend) { + previous_state_suspend = 1; + power_ticks = 0; + } + /* Flashing 1 sec on, 1 sec off */ + set_color_power_led((power_ticks % 8) < 4 ? LED_BLUE : LED_OFF); + return; + } else { + set_color_power_led(LED_OFF); + } + + previous_state_suspend = 0; +} + +/** + * Called by hook task every 250 ms + */ +static void battery_led_tick(void) +{ + static unsigned battery_ticks; int chstate = charge_get_state(); - ticks++; + battery_ticks++; /* If we don't control the LED, nothing to do */ if (!led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) @@ -91,31 +154,39 @@ static void led_tick(void) /* If charging error, blink orange, 25% duty cycle, 4 sec period */ if (chstate == PWR_STATE_ERROR) { - set_color((ticks % 16) < 4 ? LED_ORANGE : LED_OFF); + set_color_battery_led((battery_ticks % 16) < 4 ? + LED_ORANGE : LED_OFF); return; } /* If charge-force-idle, blink green, 50% duty cycle, 2 sec period */ if (chstate == PWR_STATE_IDLE && (charge_get_flags() & CHARGE_FLAG_FORCE_IDLE)) { - set_color((ticks & 0x4) ? LED_GREEN : LED_OFF); + set_color_battery_led((battery_ticks & 0x4) ? + LED_GREEN : LED_OFF); return; } /* If the system is charging, solid orange */ if (chstate == PWR_STATE_CHARGE) { - set_color(LED_ORANGE); + set_color_battery_led(LED_ORANGE); return; } /* If AC connected and fully charged (or close to it), solid green */ if (chstate == PWR_STATE_CHARGE_NEAR_FULL || chstate == PWR_STATE_IDLE) { - set_color(LED_GREEN); + set_color_battery_led(LED_GREEN); return; } /* Otherwise, system is off and AC not connected, LED off */ - set_color(LED_OFF); + set_color_battery_led(LED_OFF); +} + +static void led_tick(void) +{ + battery_led_tick(); + power_led_tick(); } DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); |