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 <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/411395
This commit is contained in:
Daisuke Nojiri
2016-11-15 13:55:18 -08:00
committed by chrome-bot
parent 526adbe531
commit 79251ee917
3 changed files with 32 additions and 18 deletions

View File

@@ -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)
{

View File

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

View File

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