From 4e47e1382ffa3f3f82291e62f0ba0315e6decbcf Mon Sep 17 00:00:00 2001 From: Tommy Chung Date: Tue, 25 Apr 2023 15:31:47 +0800 Subject: yavilla: Update led behavior Yavilla has convertible sku with power led, and the behavior of power led is described as following: Power state in S0: White on. Power state in suspend: Blink white (1 sec. on, 1 sec. off). Power state in G3/S5: Off. Also, C0/C1 port is on right/left port on Yavilla respectively. Set ports to correct ports. BUG=b:273791621 TEST=make sure power led works correctly. Change-Id: I433def8dcfddafbd5e5b3601105621d3aa041e07 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4474088 Tested-by: Tommy Chung Reviewed-by: Devin Lu Commit-Queue: Tommy Chung Reviewed-by: Peter Marheine --- zephyr/program/nissa/yavilla/gpio.dtsi | 3 + zephyr/program/nissa/yavilla/project.conf | 1 + zephyr/program/nissa/yavilla/src/led.c | 94 ++++++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/zephyr/program/nissa/yavilla/gpio.dtsi b/zephyr/program/nissa/yavilla/gpio.dtsi index d063b897d9..a18e674b11 100644 --- a/zephyr/program/nissa/yavilla/gpio.dtsi +++ b/zephyr/program/nissa/yavilla/gpio.dtsi @@ -209,6 +209,9 @@ gpio_c0_charger_led_amber_l: c0_charger_led_amber_l { gpios = <&gpioj 7 GPIO_OUTPUT_HIGH>; }; + gpio_power_led_white_l: power_led_white_l { + gpios = <&gpioa 3 GPIO_OUTPUT_HIGH>; + }; gpio_ec_kso_02_inv: ec_kso_02_inv { gpios = <&gpioksol 2 GPIO_OUTPUT_HIGH>; enum-name = "GPIO_KBD_KSO2"; diff --git a/zephyr/program/nissa/yavilla/project.conf b/zephyr/program/nissa/yavilla/project.conf index bbabd05b37..4c89a45147 100644 --- a/zephyr/program/nissa/yavilla/project.conf +++ b/zephyr/program/nissa/yavilla/project.conf @@ -31,6 +31,7 @@ CONFIG_PLATFORM_EC_CUSTOM_FAN_CONTROL=y # LED CONFIG_PLATFORM_EC_LED_PWM=n +CONFIG_PLATFORM_EC_LED_ONOFF_STATES=n CONFIG_NISSA_SUB_BOARD=n diff --git a/zephyr/program/nissa/yavilla/src/led.c b/zephyr/program/nissa/yavilla/src/led.c index a1ae6b24cf..5bbc9d15b1 100644 --- a/zephyr/program/nissa/yavilla/src/led.c +++ b/zephyr/program/nissa/yavilla/src/led.c @@ -7,6 +7,7 @@ #include "charge_manager.h" #include "charge_state.h" #include "chipset.h" +#include "cros_cbi.h" #include "ec_commands.h" #include "gpio.h" #include "hooks.h" @@ -15,9 +16,16 @@ #include +#include + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + #define BAT_LED_ON 0 #define BAT_LED_OFF 1 +#define PWR_LED_ON 0 +#define PWR_LED_OFF 1 + #define BATT_LOW_BCT 10 #define LED_TICKS_PER_CYCLE 4 @@ -25,8 +33,11 @@ #define LED_ON_TICKS 2 #define POWER_LED_ON_S3_TICKS 2 -const enum ec_led_id supported_led_ids[] = { EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED }; +static bool power_led_support; + +const enum ec_led_id supported_led_ids[] = { EC_LED_ID_RIGHT_LED, + EC_LED_ID_LEFT_LED, + EC_LED_ID_POWER_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); @@ -37,16 +48,16 @@ enum led_color { LED_COLOR_COUNT /* Number of colors, not a color itself */ }; -enum led_port { LEFT_PORT = 0, RIGHT_PORT }; +enum led_port { RIGHT_PORT = 0, LEFT_PORT }; static void led_set_color_battery(int port, enum led_color color) { const struct gpio_dt_spec *amber_led, *white_led; - if (port == LEFT_PORT) { + if (port == RIGHT_PORT) { amber_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_amber_l); white_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_white_l); - } else if (port == RIGHT_PORT) { + } else if (port == LEFT_PORT) { amber_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_amber_l); white_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_white_l); } @@ -69,6 +80,22 @@ static void led_set_color_battery(int port, enum led_color color) } } +static void led_set_color_power(enum led_color color) +{ + switch (color) { + case LED_OFF: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_white_l), + PWR_LED_OFF); + break; + case LED_WHITE: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_white_l), + PWR_LED_ON); + break; + default: + break; + } +} + void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { switch (led_id) { @@ -80,6 +107,9 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) brightness_range[EC_LED_COLOR_WHITE] = 1; brightness_range[EC_LED_COLOR_AMBER] = 1; break; + case EC_LED_ID_POWER_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + break; default: break; } @@ -104,6 +134,12 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) else led_set_color_battery(RIGHT_PORT, LED_OFF); break; + case EC_LED_ID_POWER_LED: + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(LED_WHITE); + else + led_set_color_power(LED_OFF); + break; default: return EC_ERROR_PARAM1; } @@ -135,11 +171,11 @@ static void led_set_battery(void) battery_ticks++; /* - * Override battery LEDs for Yavilla, Yavilla is non-power LED - * design, blinking both two side battery white LEDs to indicate + * Override battery LEDs for Yavilla without power led support, + * blinking both two side battery white LEDs to indicate * system suspend with non-charging state. */ - if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + if (!power_led_support && chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && charge_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; @@ -223,9 +259,51 @@ static void led_set_battery(void) } } +static void led_set_power(void) +{ + static int power_ticks; + + power_ticks++; + + if (chipset_in_state(CHIPSET_STATE_ON)) + led_set_color_power(LED_WHITE); + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + led_set_color_power((power_ticks % LED_TICKS_PER_CYCLE_S3 < + POWER_LED_ON_S3_TICKS) ? + LED_WHITE : + LED_OFF); + else + led_set_color_power(LED_OFF); +} + +static void power_led_check(void) +{ + int ret; + uint32_t val; + + /* + * Retrieve the tablet config. + */ + ret = cros_cbi_get_fw_config(FW_TABLET, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_TABLET); + return; + } + + if (val == FW_TABLET_PRESENT) + power_led_support = true; + else /* Clameshell */ + power_led_support = false; +} +DECLARE_HOOK(HOOK_INIT, power_led_check, HOOK_PRIO_DEFAULT); + /* Called by hook task every TICK(IT83xx 500ms) */ static void led_tick(void) { led_set_battery(); + + if (power_led_support && + led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) + led_set_power(); } DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); -- cgit v1.2.1