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>
This commit is contained in:
Duncan Laurie
2017-03-07 10:18:09 -08:00
committed by chrome-bot
parent 1851495eb2
commit c4fe1efc2c
2 changed files with 48 additions and 3 deletions

View File

@@ -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;

View File

@@ -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 */
/*