summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElsie Shih <elsie_shih@wistron.corp-partner.google.com>2022-07-15 15:05:13 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-28 07:55:03 +0000
commitdd451d0aab9c78f0fc7cff91c39a7f5c50f2790d (patch)
tree4c6bb0947d468576bd79fd411c4aa11b225a63e1
parentf80955b5fcca49f2188b32d5ca66cc04b6031ab3 (diff)
downloadchrome-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.c113
-rw-r--r--board/moli/board.h10
-rw-r--r--board/moli/gpio.inc12
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)