From 79251ee91734ba4f6882992801d75e66c8daf4e4 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Tue, 15 Nov 2016 13:55:18 -0800 Subject: [PATCH] Reef: Disable keyboard and trackpad in tablet mode Enabling/Dislabling keyboard and touchpad is required to prevent EC from waking up the system from S3 in tablet mode. This change disables the keyboard and the trackpad when the lid goes beyond 180 degree. Keyboard and touchpad are also enabled/disabled by the tablet switch. When the lid reaches 360 position, keyboard and touchpad are disabled. And they stay disabled as long as the lid stays at 360 position. This prevents keyboard and touchpad from turning on by the (faulty) lid angle calculation. BUG=chrome-os-partner:58792 BRANCH=none TEST=Keyboard and trackpad are disabled when the lid goes beyond 180 and re-enabled when it's smaller than 180. Keyboard and trackpad are disabled when the lid goes to 360 degree and the system doesn't wake up by a keypress. Change-Id: I48c04bd576f457a899dfdf9b4718d73b59419cbe Signed-off-by: Daisuke Nojiri Reviewed-on: https://chromium-review.googlesource.com/411395 --- board/reef/board.c | 42 +++++++++++++++++++++++++++--------------- board/reef/board.h | 3 +++ board/reef/gpio.inc | 5 ++--- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/board/reef/board.c b/board/reef/board.c index 2e38e4df7e..de0a1966f9 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -31,6 +31,7 @@ #include "host_command.h" #include "i2c.h" #include "keyboard_scan.h" +#include "lid_angle.h" #include "lid_switch.h" #include "math_util.h" #include "motion_sense.h" @@ -42,6 +43,7 @@ #include "spi.h" #include "switch.h" #include "system.h" +#include "tablet_mode.h" #include "task.h" #include "temp_sensor.h" #include "thermistor.h" @@ -104,9 +106,10 @@ void anx74xx_cable_det_interrupt(enum gpio_signal signal) static void enable_input_devices(void); DECLARE_DEFERRED(enable_input_devices); +#define LID_DEBOUNCE_US (30 * MSEC) /* Debounce time for lid switch */ void tablet_mode_interrupt(enum gpio_signal signal) { - hook_call_deferred(&enable_input_devices_data, 0); + hook_call_deferred(&enable_input_devices_data, LID_DEBOUNCE_US); } #include "gpio_list.h" @@ -492,8 +495,7 @@ DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, chipset_pre_init, HOOK_PRIO_DEFAULT); /* Initialize board. */ static void board_init(void) { - /* FIXME: Handle tablet mode */ - /* gpio_enable_interrupt(GPIO_TABLET_MODE_L); */ + gpio_enable_interrupt(GPIO_TABLET_MODE_L); /* Enable charger interrupts */ gpio_enable_interrupt(GPIO_CHARGER_INT_L); @@ -630,23 +632,33 @@ int board_is_vbus_too_low(enum chg_ramp_vbus_state ramp_state) return charger_get_vbus_level() < BD9995X_BC12_MIN_VOLTAGE; } -/* Enable or disable input devices, based upon chipset state and tablet mode */ static void enable_input_devices(void) { - int kb_enable = 1; - int tp_enable = 1; + /* We need to turn on tablet mode for motion sense */ + tablet_set_mode(!gpio_get_level(GPIO_TABLET_MODE_L)); - /* Disable KB & TP if chipset is off */ - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - kb_enable = 0; - tp_enable = 0; - } - - keyboard_scan_enable(kb_enable, KB_SCAN_DISABLE_LID_ANGLE); - - gpio_set_level(GPIO_EN_P3300_TRACKPAD_ODL, !tp_enable); + /* Then, we disable peripherals only when the lid reaches 360 position. + * (It's probably already disabled by motion_sense_task.) + * We deliberately do not enable peripherals when the lid is leaving + * 360 position. Instead, we let motion_sense_task enable it once it + * reaches laptop zone (180 or less). */ + if (tablet_get_mode()) + lid_angle_peripheral_enable(0); } +/* Enable or disable input devices, based on chipset state and tablet mode */ +#ifndef TEST_BUILD +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. */ + if (tablet_get_mode() || chipset_in_state(CHIPSET_STATE_ANY_OFF)) + enable = 0; + keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE); + gpio_set_level(GPIO_EN_P3300_TRACKPAD_ODL, !enable); +} +#endif + /* Called on AP S5 -> S3 transition */ static void board_chipset_startup(void) { diff --git a/board/reef/board.h b/board/reef/board.h index 947fb9fe72..392d69cab6 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -76,6 +76,8 @@ #define GPIO_USB_ILIM_SEL GPIO_USB_A_CHARGE_EN_L #define GPIO_USB_CTL1 GPIO_EN_PP5000 +#define CONFIG_TABLET_MODE + /* USB PD config */ #define CONFIG_CASE_CLOSED_DEBUG_EXTERNAL #define CONFIG_CMD_PD_CONTROL @@ -190,6 +192,7 @@ #define OPT3001_I2C_ADDR OPT3001_I2C_ADDR1 #define CONFIG_BARO_BMP280 #define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE #define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL #define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL diff --git a/board/reef/gpio.inc b/board/reef/gpio.inc index 21efc87c33..232393569a 100644 --- a/board/reef/gpio.inc +++ b/board/reef/gpio.inc @@ -36,14 +36,13 @@ GPIO_INT(EC_VOLDN_BTN_ODL_SWAPPED, PIN(8, 3), GPIO_INT_BOTH | GPIO_PULL_UP, butt GPIO_INT(EC_VOLUP_BTN_ODL_SWAPPED, PIN(8, 2), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) #define GPIO_EC_VOLDN_BTN_ODL GPIO_EC_VOLUP_BTN_ODL_SWAPPED #define GPIO_EC_VOLUP_BTN_ODL GPIO_EC_VOLDN_BTN_ODL_SWAPPED -/* Tablet switch is active-low. L: lid is attached (360 position) H: detached */GPIO_INT(TABLET_MODE, PIN(3, 6), GPIO_INT_BOTH, tablet_mode_interrupt) +/* Tablet switch is active-low. L: lid is attached (360 position) H: detached */ +GPIO_INT(TABLET_MODE_L, PIN(3, 6), GPIO_INT_BOTH, tablet_mode_interrupt) GPIO_INT(WP_L, PIN(4, 0), GPIO_INT_BOTH | GPIO_SEL_1P8V, switch_interrupt) /* EC_WP_ODL */ -/* FIXME(dhendrix): Implement interrupt handlers for lid, tablet mode, etc. */ //GPIO_INT(BASE_SIXAXIS_INT_L, PIN(9, 3), GPIO_INT_LOW | GPIO_SEL_1P8V, gyro_interrupt) GPIO(BASE_SIXAXIS_INT_L, PIN(9, 3), GPIO_INPUT | GPIO_SEL_1P8V) -//GPIO_INT(LID_ACCEL_INT_L, PIN(C, 7), GPIO_INT_LOW | GPIO_SEL_1P8V, lid_interrupt) GPIO(LID_ACCEL_INT_L, PIN(C, 7), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C GPIOs will be set to alt. function later. */