diff options
author | Duncan Laurie <dlaurie@google.com> | 2017-03-07 10:18:09 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-03-16 18:06:59 -0700 |
commit | c4fe1efc2cfca39cc679b5b9f3f5d6d6c4f503e7 (patch) | |
tree | 2702b2b5429e9aa2ef1f8aa9ca68e15d9c128b90 | |
parent | 1851495eb2bea80c49f8e5a4951a003088e960f6 (diff) | |
download | chrome-ec-c4fe1efc2cfca39cc679b5b9f3f5d6d6c4f503e7.tar.gz |
eve: Enable trackpad wake from Deep S3
In order to support waking from Deep S3 the trackpad interrupt
is routed to the EC.
The EC needs to enable this interrupt when going into S3, and
disable it otherwise.
It also needs to filter events and only wake the system when it
is not in tablet mode.
This is accomplished with the following rules:
1) Enable trackpad wake in S0->S3 transition, if !tablet_mode
2) Disable trackpad wake in S3->S5 transition
3) Disable trackpad wake in S3->S0 transition
4) Disable trackpad wake when entering tablet mode in S3
5) Enable trackpad wake when lid angle is <180 degrees and in S3
And finally a check in the trackpad interrupt itself to ensure that
it only sends the wake event if not in tablet mode.
The function to enable or disable trackpad wake uses a static variable
to keep track of the enable state because when enabling the GPIO for
wake it first clears pending events and if multiple transitions are
happening (suspending, plus lid angle rotation) this can get called
multiple times in quick succession.
Currently a placeholder KEY_PRESSED event is used to wake the AP
since we do not have device specific events. Fixing this behavior
is tracked in b/36024430.
BUG=b:35587072
BRANCH=none
TEST=manual testing on eve P1b:
1) ensure that trackpad wake in clamshell mode works
2) ensure that trackpad wake in tablet mode does not waork
3) ensure that if in S3 during transition to or from tablet
mode the wake event is enabled appropriately
Change-Id: Ib2020b5010bdde396a3b05243894431b67edb503
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/450954
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
-rw-r--r-- | board/eve/board.c | 47 | ||||
-rw-r--r-- | board/eve/gpio.inc | 4 |
2 files changed, 48 insertions, 3 deletions
diff --git a/board/eve/board.c b/board/eve/board.c index cc0a9096d1..7b83c05659 100644 --- a/board/eve/board.c +++ b/board/eve/board.c @@ -85,6 +85,13 @@ void tablet_mode_interrupt(enum gpio_signal signal) hook_call_deferred(&enable_input_devices_data, LID_DEBOUNCE_US); } +/* Send event to wake AP based on trackpad input */ +void trackpad_interrupt(enum gpio_signal signal) +{ + /* TODO(b/36024430): Use device specific wake event */ + host_set_single_event(EC_HOST_EVENT_KEY_PRESSED); +} + #ifdef CONFIG_USB_PD_TCPC_LOW_POWER static void anx74xx_c0_cable_det_handler(void) { @@ -534,6 +541,23 @@ int board_is_vbus_too_low(int port, enum chg_ramp_vbus_state ramp_state) return charger_get_vbus_voltage(port) < BD9995X_BC12_MIN_VOLTAGE; } +/* Clear pending interrupts and enable trackpad for wake */ +static void trackpad_wake_enable(int enable) +{ + static int prev_enable = -1; + + if (prev_enable == enable) + return; + prev_enable = enable; + + if (enable) { + gpio_clear_pending_interrupt(GPIO_TRACKPAD_INT_L); + gpio_enable_interrupt(GPIO_TRACKPAD_INT_L); + } else { + gpio_disable_interrupt(GPIO_TRACKPAD_INT_L); + } +} + /* Enable or disable input devices, based upon chipset state and tablet mode */ static void enable_input_devices(void) { @@ -557,11 +581,16 @@ void lid_angle_peripheral_enable(int enable) { /* * If the lid is in 360 position, ignore the lid angle, - * which might be faulty. Disable keyboard and touchpad. + * which might be faulty. Disable keyboard and trackpad wake. */ if (tablet_get_mode() || chipset_in_state(CHIPSET_STATE_ANY_OFF)) enable = 0; keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE); + + /* Also disable trackpad wake if not in suspend */ + if (!chipset_in_state(CHIPSET_STATE_SUSPEND)) + enable = 0; + trackpad_wake_enable(enable); } #endif @@ -578,11 +607,27 @@ DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); static void board_chipset_shutdown(void) { /* Disable Trackpad */ + trackpad_wake_enable(0); gpio_set_level(GPIO_TRACKPAD_SHDN_L, 0); hook_call_deferred(&enable_input_devices_data, 0); } DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); +/* Called on AP S0 -> S3 transition */ +static void board_chipset_suspend(void) +{ + if (!tablet_get_mode()) + trackpad_wake_enable(1); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); + +/* Called on AP S3 -> S0 transition */ +static void board_chipset_resume(void) +{ + trackpad_wake_enable(0); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); + void board_hibernate_late(void) { int i; diff --git a/board/eve/gpio.inc b/board/eve/gpio.inc index 2c9d556a99..7ae031940c 100644 --- a/board/eve/gpio.inc +++ b/board/eve/gpio.inc @@ -23,6 +23,7 @@ GPIO_INT(VOLUME_UP_L, PIN(8, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt GPIO_INT(WP_L, PIN(4, 0), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(AC_PRESENT, PIN(C, 1), GPIO_INT_BOTH, extpower_interrupt) GPIO_INT(ACCELGYRO3_INT_L, PIN(9, 3), GPIO_INT_FALLING, bmi160_interrupt) +GPIO_INT(TRACKPAD_INT_L, PIN(7, 1), GPIO_INT_FALLING, trackpad_interrupt) #ifdef CONFIG_USB_PD_TCPC_LOW_POWER GPIO_INT(USB_C0_CABLE_DET, PIN(D, 2), GPIO_INT_RISING, anx74xx_cable_det_interrupt) GPIO_INT(USB_C1_CABLE_DET, PIN(D, 3), GPIO_INT_RISING, anx74xx_cable_det_interrupt) @@ -32,7 +33,7 @@ GPIO(USB_C1_CABLE_DET, PIN(D, 3), GPIO_INPUT) #endif /* Lid KCJX9 accelerometer sensor interrupt */ -GPIO(ACCEL1_INT_L, PIN(C, 7), GPIO_INPUT | GPIO_PULL_UP) +GPIO(ACCEL1_INT_L, PIN(C, 7), GPIO_INPUT | GPIO_PULL_UP) GPIO(PCH_RTCRST, PIN(E, 7), GPIO_OUT_LOW) /* RTCRST# to SOC */ GPIO(ENABLE_BACKLIGHT, PIN(5, 6), GPIO_OUT_LOW) /* Enable Backlight */ @@ -67,7 +68,6 @@ GPIO(I2C3_SCL, PIN(D, 1), GPIO_INPUT) /* EC_I2C3_POWER_SCL */ GPIO(I2C3_SDA, PIN(D, 0), GPIO_INPUT) /* EC_I2C3_POWER_SDA */ /* AP wake sources when in Deep-S3 state */ -GPIO(TRACKPAD_INT_L, PIN(7, 1), GPIO_INPUT) /* INT# from Trackpad */ GPIO(DSP_WAKE_L, PIN(C, 6), GPIO_INPUT | GPIO_SEL_1P8V) /* INT# from DSP Mic */ /* |