diff options
author | Elsie Shih <elsie_shih@wistron.corp-partner.google.com> | 2022-07-15 15:05:13 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-11-28 07:55:03 +0000 |
commit | dd451d0aab9c78f0fc7cff91c39a7f5c50f2790d (patch) | |
tree | 4c6bb0947d468576bd79fd411c4aa11b225a63e1 | |
parent | f80955b5fcca49f2188b32d5ca66cc04b6031ab3 (diff) | |
download | chrome-ec-dd451d0aab9c78f0fc7cff91c39a7f5c50f2790d.tar.gz |
moli: add power on/wakeup by HDMI monitor
After EC received interrupt from monitor on GPIOB4/ GPIOB5/ GPIO10. EC
will power on the system.
If EC received interrupt during s0ix, EC will trigger powr button to
wake AP.
BUG=b:239634608
BRANCH=none
TEST=make BOARD=moli
Signed-off-by: Elsie Shih <elsie_shih@wistron.corp-partner.google.com>
Change-Id: Ia407468afc103595d33b6ce526d8e05bc66c76a2
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3771361
Tested-by: Scott Chao <scott_chao@wistron.corp-partner.google.com>
Reviewed-by: Zhuohao Lee <zhuohao@chromium.org>
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r-- | board/moli/board.c | 113 | ||||
-rw-r--r-- | board/moli/board.h | 10 | ||||
-rw-r--r-- | board/moli/gpio.inc | 12 |
3 files changed, 129 insertions, 6 deletions
diff --git a/board/moli/board.c b/board/moli/board.c index c995fe6ef7..a63c93ae50 100644 --- a/board/moli/board.c +++ b/board/moli/board.c @@ -8,6 +8,7 @@ #include "button.h" #include "charge_manager.h" #include "charge_state_v2.h" +#include "chipset.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" @@ -32,6 +33,32 @@ static void power_monitor(void); DECLARE_DEFERRED(power_monitor); /******************************************************************************/ +/* Power on by HDMI/ DP monitor */ +struct monitor_config { + enum gpio_signal gpio; + uint8_t state; +}; + +static struct monitor_config monitors[MONITOR_COUNT] = { + [HDMI1_MONITOR] = { + .gpio = GPIO_HDMI1_MONITOR_ON, + .state = MONITOR_OFF, + }, + + [HDMI2_MONITOR] = { + .gpio = GPIO_HDMI2_MONITOR_ON, + .state = MONITOR_OFF, + }, + + [OPTION_MONITOR] = { + .gpio = GPIO_OPTION_MONITOR_ON, + .state = MONITOR_OFF, + }, +}; + +/******************************************************************************/ + +/******************************************************************************/ /* USB-A charging control */ const int usb_port_enable[USB_PORT_COUNT] = { @@ -162,12 +189,29 @@ DECLARE_HOOK(HOOK_INIT, adp_state_init, HOOK_PRIO_INIT_CHARGE_MANAGER + 1); static void board_init(void) { + int i; + gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_ODL); gpio_enable_interrupt(GPIO_HDMI_CONN_OC_ODL); gpio_enable_interrupt(GPIO_USB_A1_OC_ODL); gpio_enable_interrupt(GPIO_USB_A2_OC_ODL); gpio_enable_interrupt(GPIO_USB_A3_OC_ODL); gpio_enable_interrupt(GPIO_USB_A4_OC_ODL); + + if (ec_cfg_power_on_monitor() == POWER_ON_MONITOR_ENABLE) { + /* + * Only enable interrupt when fw_config set it as enable. + */ + gpio_enable_interrupt(GPIO_HDMI1_MONITOR_ON); + gpio_enable_interrupt(GPIO_HDMI2_MONITOR_ON); + gpio_enable_interrupt(GPIO_OPTION_MONITOR_ON); + + /* + * Initialize the monitor state to corresponding gpio state. + */ + for (i = 0; i < MONITOR_COUNT; i++) + monitors[i].state = gpio_get_level(monitors[i].gpio); + } } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); @@ -402,3 +446,72 @@ static void power_monitor(void) * Start power monitoring after ADCs have been initialised. */ DECLARE_HOOK(HOOK_INIT, power_monitor, HOOK_PRIO_INIT_ADC + 1); + +/******************************************************************************/ +/* + * System power on and wake up by monitor power button. + * + * After pressing power button of monitor for power on, monitor will send power + * on signal with 3.3V / 200ms to DT. If DT detect that pulse, there are three + * DT behavior: + * + * - Do nothing in state S0. + * - Wake up from state S0ix. + * - Power on from state S5 and G3. + */ + +/* Debounce time for HDMI power button press */ +#define MONITOR_DEBOUNCE_MS 100 + +static void monitor_irq_deferred(void); +DECLARE_DEFERRED(monitor_irq_deferred); + +static void monitor_irq_deferred(void) +{ + int i; + + for (i = 0; i < MONITOR_COUNT; i++) { + if (monitors[i].state && gpio_get_level(monitors[i].gpio)) { + /* + * System power on from state S5 and G3. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + chipset_power_on(); + /* + * System wake up from state S0ix. + */ + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + power_button_simulate_press(200); + } + monitors[i].state = MONITOR_OFF; + } +} + +/* Power on by HDMI/ DP monitor. */ +void monitor_interrupt(enum gpio_signal signal) +{ + /* + * Power on by HDMI/ DP monitor only works + * when system is not in S0. + */ + if (chipset_in_state(CHIPSET_STATE_ON)) + return; + + if (ec_cfg_power_on_monitor() == POWER_ON_MONITOR_ENABLE) { + switch (signal) { + case GPIO_HDMI1_MONITOR_ON: + monitors[HDMI1_MONITOR].state = MONITOR_ON; + break; + case GPIO_HDMI2_MONITOR_ON: + monitors[HDMI2_MONITOR].state = MONITOR_ON; + break; + case GPIO_OPTION_MONITOR_ON: + monitors[OPTION_MONITOR].state = MONITOR_ON; + break; + default: + break; + } + hook_call_deferred(&monitor_irq_deferred_data, + MONITOR_DEBOUNCE_MS * MSEC); + } +} diff --git a/board/moli/board.h b/board/moli/board.h index aa2a2bc354..8d0ba97fb2 100644 --- a/board/moli/board.h +++ b/board/moli/board.h @@ -181,7 +181,17 @@ enum fan_channel { FAN_CH_0 = 0, FAN_CH_COUNT }; enum mft_channel { MFT_CH_0 = 0, MFT_CH_COUNT }; +enum monitor_port { + HDMI1_MONITOR, + HDMI2_MONITOR, + OPTION_MONITOR, + MONITOR_COUNT +}; + +enum monitor_state { MONITOR_OFF, MONITOR_ON }; + extern void adp_connect_interrupt(enum gpio_signal signal); +extern void monitor_interrupt(enum gpio_signal signal); #endif /* !__ASSEMBLER__ */ diff --git a/board/moli/gpio.inc b/board/moli/gpio.inc index fb3b508573..e8473f8c95 100644 --- a/board/moli/gpio.inc +++ b/board/moli/gpio.inc @@ -25,6 +25,9 @@ GPIO_INT(EC_RECOVERY_BTN_ODL, PIN(2, 3), GPIO_INT_BOTH, button_interrupt) GPIO_INT(USB_C1_RT_INT_ODL, PIN(4, 1), GPIO_INT_FALLING, retimer_interrupt) GPIO_INT(USB_C1_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt) GPIO_INT(USB_C1_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(HDMI1_MONITOR_ON, PIN(B, 4), GPIO_INT_RISING, monitor_interrupt) +GPIO_INT(HDMI2_MONITOR_ON, PIN(B, 5), GPIO_INT_RISING, monitor_interrupt) +GPIO_INT(OPTION_MONITOR_ON, PIN(1, 0), GPIO_INT_RISING, monitor_interrupt) /* CCD */ GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) @@ -120,12 +123,9 @@ GPIO(LED_ORANGE_CONTROL, PIN(3, 1), GPIO_ODR_LOW) GPIO(LED_BLUE_CONTROL, PIN(2, 5), GPIO_ODR_LOW) /* Option Board */ -GPIO(HDMI1_MONITOR_ON, PIN(B, 4), GPIO_INPUT) -GPIO(HDMI1_MONON_SIO, PIN(1, 6), GPIO_ODR_LOW) -GPIO(OPTION_MONITOR_ON, PIN(1, 0), GPIO_INPUT) -GPIO(OPTION_MONON_SIO, PIN(2, 1), GPIO_ODR_LOW) -GPIO(HDMI2_MONITOR_ON, PIN(B, 5), GPIO_INPUT) -GPIO(HDMI2_MONON_SIO, PIN(1, 5), GPIO_ODR_LOW) +GPIO(HDMI1_MONON_SIO, PIN(1, 6), GPIO_INPUT) +GPIO(HDMI2_MONON_SIO, PIN(1, 5), GPIO_INPUT) +GPIO(OPTION_MONON_SIO, PIN(2, 1), GPIO_INPUT) IOEX(USB_C0_OC_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 4), GPIO_ODR_HIGH) IOEX(USB_C0_FRS_EN, EXPIN(IOEX_C0_NCT38XX, 0, 6), GPIO_LOW) |