From 9eb2427c58b38cb7daaf0410a914f63da884372a Mon Sep 17 00:00:00 2001 From: Josh Tsai Date: Tue, 31 Aug 2021 09:46:24 +0800 Subject: Felwinter: modified power and battery LED behavior Power LED (DC/AC): S0: Solid White S3: Blinking White, 1s on / 3s off S5: LED off Battery LED: Charging (0%-94%): Amber Full charged: White Discharging: LED off Battery Error (S0): Blinking Amber, 1s on / 1s off Battery Error (S0ix/S5): LED off Battery Low (S0): Blinking Amnber, 1s on / 3s off Battery Low (S0ix/S5): LED off BUG=b:197593645 BRANCH=brya TEST=make BOARD=felwinter, test on brya MB Signed-off-by: Josh Tsai Change-Id: I478e5fb5de0f1cf8d71a08a919dcbb248a55f8b8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3131956 Reviewed-by: Elmo Lan Reviewed-by: Boris Mittelberg Commit-Queue: Boris Mittelberg --- board/felwinter/board.h | 21 ++----- board/felwinter/gpio.inc | 8 ++- board/felwinter/led.c | 161 +++++++++++++++++++++++++++-------------------- board/felwinter/pwm.c | 33 ---------- 4 files changed, 105 insertions(+), 118 deletions(-) diff --git a/board/felwinter/board.h b/board/felwinter/board.h index 1febcf6685..c2a182eddb 100644 --- a/board/felwinter/board.h +++ b/board/felwinter/board.h @@ -27,16 +27,11 @@ #define CONFIG_MP2964 /* LED */ -#define CONFIG_LED_PWM -#define CONFIG_LED_PWM_COUNT 2 -#undef CONFIG_LED_PWM_NEAR_FULL_COLOR -#undef CONFIG_LED_PWM_SOC_ON_COLOR -#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR -#undef CONFIG_LED_PWM_LOW_BATT_COLOR -#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER +#define CONFIG_LED_ONOFF_STATES +#define CONFIG_LED_ONOFF_STATES_BAT_LOW 10 +#define GPIO_PWR_LED_WHITE_L GPIO_LED_1_L +#define GPIO_BAT_LED_AMBER_L GPIO_LED_3_L +#define GPIO_BAT_LED_WHITE_L GPIO_LED_4_L /* Sensors */ #define CONFIG_ACCELGYRO_LSM6DSO /* Base accel */ @@ -247,12 +242,8 @@ enum battery_type { }; enum pwm_channel { - PWM_CH_LED2 = 0, /* PWM0 (white charger) */ - PWM_CH_LED3, /* PWM1 (orange on DB) */ - PWM_CH_LED1, /* PWM2 (orange charger) */ - PWM_CH_KBLIGHT, /* PWM3 */ + PWM_CH_KBLIGHT = 0, /* PWM3 */ PWM_CH_FAN, /* PWM5 */ - PWM_CH_LED4, /* PWM7 (white on DB) */ PWM_CH_COUNT }; diff --git a/board/felwinter/gpio.inc b/board/felwinter/gpio.inc index 1cd6e9919a..f65dc8f677 100644 --- a/board/felwinter/gpio.inc +++ b/board/felwinter/gpio.inc @@ -82,6 +82,11 @@ GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT) GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_LOW) GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) +/* LED */ +GPIO(LED_4_L, PIN(6, 0), GPIO_OUT_HIGH) /* battery led white */ +GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_HIGH) /* battery led amber */ +GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_HIGH) /* power led white */ + /* UART alternate functions */ ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* GPIO64/CR_SIN1, GPO65/CR_SOUT1/FLPRG1_L */ @@ -97,10 +102,8 @@ ALTERNATE(PIN_MASK(F, 0x0c), 0, MODULE_I2C, 0) /* GPIOF3/I2C4_SCL1 /* PWM alternate functions */ ALTERNATE(PIN_MASK(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ -ALTERNATE(PIN_MASK(6, 0x01), 0, MODULE_PWM, 0) /* GPIO60/PWM7 */ ALTERNATE(PIN_MASK(8, 0x01), 0, MODULE_PWM, 0) /* GPIO80/PWM3 */ ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */ -ALTERNATE(PIN_MASK(C, 0x1c), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0, GPIOC2/PWM1/I2C6_SCL0 */ /* ADC alternate functions */ ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ @@ -125,6 +128,7 @@ UNUSED(PIN(D, 6)) /* GPOD6/CR_SOUT3/SHDF_ESPI_L */ UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */ UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */ UNUSED(PIN(6, 6)) /* GPIO66 */ +UNUSED(PIN(C, 3)) /* GPIOC3 */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/felwinter/led.c b/board/felwinter/led.c index 38caa38d37..3b7e649470 100644 --- a/board/felwinter/led.c +++ b/board/felwinter/led.c @@ -1,93 +1,118 @@ /* Copyright 2021 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. + * + * Power and battery LED control for felwinter */ -/* Brya specific PWM LED settings: there are 2 LEDs on each side of the board, - * each one can be controlled separately. The LED colors are white or amber, - * and the default behavior is tied to the charging process: both sides are - * amber while charging the battery and white when the battery is charged. - */ +#include "chipset.h" +#include "gpio.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "system.h" -#include +#define LED_OFF_LVL 1 +#define LED_ON_LVL 0 -#include "common.h" -#include "compile_time_macros.h" -#include "ec_commands.h" -#include "led_pwm.h" -#include "pwm.h" -#include "util.h" +__override const int led_charge_lvl_1; +__override const int led_charge_lvl_2 = 94; -const enum ec_led_id supported_led_ids[] = { - EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED, +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, }; -const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); - -/* - * We only have a white and an amber LED, so setting any other color results in - * both LEDs being off. - */ -struct pwm_led led_color_map[EC_LED_COLOR_COUNT] = { - /* Amber, White */ - [EC_LED_COLOR_RED] = { 0, 0 }, - [EC_LED_COLOR_GREEN] = { 0, 0 }, - [EC_LED_COLOR_BLUE] = { 0, 0 }, - [EC_LED_COLOR_YELLOW] = { 0, 0 }, - [EC_LED_COLOR_WHITE] = { 0, 100 }, - [EC_LED_COLOR_AMBER] = { 100, 0 }, +__override const struct led_descriptor + led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { + [PWR_LED_STATE_ON] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [PWR_LED_STATE_SUSPEND_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_SUSPEND_NO_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} }, }; -/* Two logical LEDs with amber and white channels. */ -struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { - { - .ch0 = PWM_CH_LED1, - .ch1 = PWM_CH_LED2, - .ch2 = PWM_LED_NO_CHANNEL, - .enable = &pwm_enable, - .set_duty = &pwm_set_duty, - }, - { - .ch0 = PWM_CH_LED3, - .ch1 = PWM_CH_LED4, - .ch2 = PWM_LED_NO_CHANNEL, - .enable = &pwm_enable, - .set_duty = &pwm_set_duty, - }, +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, + EC_LED_ID_POWER_LED, }; -void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_power(enum ec_led_colors color) { - memset(brightness_range, '\0', - sizeof(*brightness_range) * EC_LED_COLOR_COUNT); - brightness_range[EC_LED_COLOR_AMBER] = 100; - brightness_range[EC_LED_COLOR_WHITE] = 100; + if (color == EC_LED_COLOR_WHITE) + gpio_set_level(GPIO_PWR_LED_WHITE_L, LED_ON_LVL); + else + /* LED_OFF and unsupported colors */ + gpio_set_level(GPIO_PWR_LED_WHITE_L, LED_OFF_LVL); } -int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +__override void led_set_color_battery(enum ec_led_colors color) { - enum pwm_led_id pwm_id; - - /* Convert ec_led_id to pwm_led_id. */ - switch (led_id) { - case EC_LED_ID_LEFT_LED: - pwm_id = PWM_LED0; + switch (color) { + case EC_LED_COLOR_WHITE: + gpio_set_level(GPIO_BAT_LED_WHITE_L, LED_ON_LVL); + gpio_set_level(GPIO_BAT_LED_AMBER_L, LED_OFF_LVL); + break; + case EC_LED_COLOR_AMBER: + gpio_set_level(GPIO_BAT_LED_WHITE_L, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_AMBER_L, LED_ON_LVL); break; - case EC_LED_ID_RIGHT_LED: - pwm_id = PWM_LED1; + default: /* LED_OFF and other unsupported colors */ + gpio_set_level(GPIO_BAT_LED_WHITE_L, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_AMBER_L, LED_OFF_LVL); break; - default: - return EC_ERROR_UNKNOWN; } +} - if (brightness[EC_LED_COLOR_WHITE]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); - else if (brightness[EC_LED_COLOR_AMBER]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); - else - /* Otherwise, the "color" is "off". */ - set_pwm_led_color(pwm_id, -1); +__override enum led_states board_led_get_state(enum led_states desired_state) +{ + if (desired_state == STATE_BATTERY_ERROR) { + if (chipset_in_state(CHIPSET_STATE_ON)) + return desired_state; + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + return STATE_DISCHARGE_S3; + else + return STATE_DISCHARGE_S5; + } + return desired_state; +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + } else if (led_id == EC_LED_ID_POWER_LED) { + brightness_range[EC_LED_COLOR_WHITE] = 1; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else + led_set_color_battery(LED_OFF); + } else if (led_id == EC_LED_ID_POWER_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(EC_LED_COLOR_WHITE); + else + led_set_color_power(LED_OFF); + } return EC_SUCCESS; } diff --git a/board/felwinter/pwm.c b/board/felwinter/pwm.c index 263e494650..985305449b 100644 --- a/board/felwinter/pwm.c +++ b/board/felwinter/pwm.c @@ -11,21 +11,6 @@ #include "pwm_chip.h" const struct pwm_t pwm_channels[] = { - [PWM_CH_LED2] = { - .channel = 0, - .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, - .freq = 4800, - }, - [PWM_CH_LED3] = { - .channel = 1, - .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, - .freq = 4800, - }, - [PWM_CH_LED1] = { - .channel = 2, - .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, - .freq = 4800, - }, [PWM_CH_KBLIGHT] = { .channel = 3, .flags = 0, @@ -42,29 +27,11 @@ const struct pwm_t pwm_channels[] = { .flags = PWM_CONFIG_OPEN_DRAIN, .freq = 25000 }, - [PWM_CH_LED4] = { - .channel = 7, - .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, - .freq = 4800, - }, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); static void board_pwm_init(void) { - /* - * Turn on all the LED at 50%. - * Turn on the fan at 100%. - */ - pwm_enable(PWM_CH_LED1, 1); - pwm_set_duty(PWM_CH_LED1, 50); - pwm_enable(PWM_CH_LED2, 1); - pwm_set_duty(PWM_CH_LED2, 50); - pwm_enable(PWM_CH_LED3, 1); - pwm_set_duty(PWM_CH_LED3, 50); - pwm_enable(PWM_CH_LED4, 1); - pwm_set_duty(PWM_CH_LED4, 50); - pwm_enable(PWM_CH_KBLIGHT, 1); pwm_set_duty(PWM_CH_KBLIGHT, 50); } -- cgit v1.2.1