diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-08-20 08:59:58 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-03 02:20:47 -0700 |
commit | c355ba59732e25a4c8bff89e63e89f0faafa8afc (patch) | |
tree | 0d2db50ae8c6f00d473d5d2161b2ebf03a7bf248 | |
parent | be9683a42d06097161ae09919dcfedd218a3c576 (diff) | |
download | chrome-ec-c355ba59732e25a4c8bff89e63e89f0faafa8afc.tar.gz |
whiskers: Disable keyboard scanning and touchpad in tablet mode
When in tablet mode, disable keyboard scanning and touchpad.
Refactor touchpad_*.c power management to take both into account
(there is some duplicated code here, that we may want to merge
in the future).
This will also prevent magic keyboard from working, but we are
ok with this, at least for now.
BRANCH=none
BUG=b:73133611
TEST=In tablet mode, keyboard scanning and touchpad are both disabled.
Change-Id: I51b7c50b90cca9b9f574c5c611daa89fe8a480bb
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1180639
Tested-by: Wei-Han Chen <stimim@chromium.org>
Reviewed-by: Wei-Han Chen <stimim@chromium.org>
-rw-r--r-- | board/hammer/board.c | 17 | ||||
-rw-r--r-- | driver/touchpad_elan.c | 57 | ||||
-rw-r--r-- | driver/touchpad_st.c | 61 |
3 files changed, 105 insertions, 30 deletions
diff --git a/board/hammer/board.c b/board/hammer/board.c index b91d775437..06f231e25a 100644 --- a/board/hammer/board.c +++ b/board/hammer/board.c @@ -256,6 +256,23 @@ void board_touchpad_reset(void) #endif } +#if defined(BOARD_WHISKERS) && defined(SECTION_IS_RW) +static void board_tablet_mode_change(void) +{ + /* + * Turn off key scanning in tablet mode. + */ + if (tablet_get_mode()) + keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE); + else + keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE); +} +DECLARE_HOOK(HOOK_TABLET_MODE_CHANGE, board_tablet_mode_change, + HOOK_PRIO_DEFAULT); +/* Run after tablet_mode_init. */ +DECLARE_HOOK(HOOK_INIT, board_tablet_mode_change, HOOK_PRIO_DEFAULT+1); +#endif + /* * Get entropy based on Clock Recovery System, which is enabled on hammer to * synchronize USB SOF with internal oscillator. diff --git a/driver/touchpad_elan.c b/driver/touchpad_elan.c index dfedbe6c2d..712125a021 100644 --- a/driver/touchpad_elan.c +++ b/driver/touchpad_elan.c @@ -25,8 +25,7 @@ #define CPRINTF(format, args...) cprintf(CC_TOUCHPAD, format, ## args) #define CPRINTS(format, args...) cprints(CC_TOUCHPAD, format, ## args) -#define TASK_EVENT_POWERON TASK_EVENT_CUSTOM(1) -#define TASK_EVENT_POWEROFF TASK_EVENT_CUSTOM(2) +#define TASK_EVENT_POWER TASK_EVENT_CUSTOM(1) /******************************************************************************/ /* How to talk to the controller */ @@ -697,11 +696,35 @@ void touchpad_interrupt(enum gpio_signal signal) task_wake(TASK_ID_TOUCHPAD); } +/* Make a decision on touchpad power, based on USB and tablet mode status. */ +static void touchpad_power_control(void) +{ + static int enabled = 1; + int enable = 1; + +#ifdef CONFIG_USB_SUSPEND + enable = enable && + (!usb_is_suspended() || usb_is_remote_wakeup_enabled()); +#endif + +#ifdef CONFIG_TABLET_MODE + enable = enable && !tablet_get_mode(); +#endif + + if (enabled == enable) + return; + + elan_tp_set_power(enable); + + enabled = enable; +} + void touchpad_task(void *u) { uint32_t event; elan_tp_init(); + touchpad_power_control(); while (1) { event = task_wait_event(-1); @@ -709,24 +732,24 @@ void touchpad_task(void *u) if (event & TASK_EVENT_WAKE) elan_tp_read_report_retry(); - if (event & TASK_EVENT_POWERON) - elan_tp_set_power(1); - else if (event & TASK_EVENT_POWEROFF) - elan_tp_set_power(0); + if (event & TASK_EVENT_POWER) + touchpad_power_control(); } } -#ifdef CONFIG_USB_SUSPEND -static void touchpad_usb_pm_change(void) +/* + * When USB PM status changes, or tablet mode changes, call in the main task to + * decide whether to turn touchpad on or off. + */ +#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_TABLET_MODE) +static void touchpad_power_change(void) { - /* - * If USB interface is suspended, and host is not asking us to do remote - * wakeup, we can turn off the touchpad. - */ - if (usb_is_suspended() && !usb_is_remote_wakeup_enabled()) - task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWEROFF, 0); - else - task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWERON, 0); + task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWER, 0); } -DECLARE_HOOK(HOOK_USB_PM_CHANGE, touchpad_usb_pm_change, HOOK_PRIO_DEFAULT); +#endif +#ifdef CONFIG_USB_SUSPEND +DECLARE_HOOK(HOOK_USB_PM_CHANGE, touchpad_power_change, HOOK_PRIO_DEFAULT); +#endif +#ifdef CONFIG_TABLET_MODE +DECLARE_HOOK(HOOK_TABLET_MODE_CHANGE, touchpad_power_change, HOOK_PRIO_DEFAULT); #endif diff --git a/driver/touchpad_st.c b/driver/touchpad_st.c index f6c29a9a01..bcf186b7ae 100644 --- a/driver/touchpad_st.c +++ b/driver/touchpad_st.c @@ -14,6 +14,7 @@ #include "registers.h" #include "spi.h" #include "task.h" +#include "tablet_mode.h" #include "timer.h" #include "touchpad.h" #include "touchpad_st.h" @@ -29,8 +30,7 @@ #define CPRINTF(format, args...) cprintf(CC_TOUCHPAD, format, ## args) #define CPRINTS(format, args...) cprints(CC_TOUCHPAD, format, ## args) -#define TASK_EVENT_POWERON TASK_EVENT_CUSTOM(1) -#define TASK_EVENT_POWEROFF TASK_EVENT_CUSTOM(2) +#define TASK_EVENT_POWER TASK_EVENT_CUSTOM(1) #define SPI (&(spi_devices[SPI_ST_TP_DEVICE_ID])) @@ -388,11 +388,13 @@ static int st_tp_start_scan(void) int mask = new_state; int ret; + CPRINTS("ST: Start scanning"); ret = st_tp_update_system_state(new_state, mask); if (ret) return ret; st_tp_send_ack(); st_tp_enable_interrupt(1); + return ret; } @@ -411,8 +413,10 @@ static int st_tp_stop_scan(void) int mask = SYSTEM_STATE_ACTIVE_MODE; int ret; + CPRINTS("ST: Stop scanning"); ret = st_tp_update_system_state(new_state, mask); st_tp_enable_interrupt(0); + return ret; } @@ -918,11 +922,38 @@ void touchpad_interrupt(enum gpio_signal signal) task_wake(TASK_ID_TOUCHPAD); } +/* Make a decision on touchpad power, based on USB and tablet mode status. */ +static void touchpad_power_control(void) +{ + static int enabled = 1; + int enable = 1; + +#ifdef CONFIG_USB_SUSPEND + enable = enable && + (!usb_is_suspended() || usb_is_remote_wakeup_enabled()); +#endif + +#ifdef CONFIG_TABLET_MODE + enable = enable && !tablet_get_mode(); +#endif + + if (enabled == enable) + return; + + if (enable) + st_tp_start_scan(); + else + st_tp_stop_scan(); + + enabled = enable; +} + void touchpad_task(void *u) { uint32_t event; st_tp_init(); + touchpad_power_control(); while (1) { event = task_wait_event(-1); @@ -931,22 +962,26 @@ void touchpad_task(void *u) while (!gpio_get_level(GPIO_TOUCHPAD_INT)) st_tp_read_report(); - if (event & TASK_EVENT_POWERON) - st_tp_start_scan(); - else if (event & TASK_EVENT_POWEROFF) - st_tp_stop_scan(); + if (event & TASK_EVENT_POWER) + touchpad_power_control(); } } -#ifdef CONFIG_USB_SUSPEND -static void touchpad_usb_pm_change(void) +/* + * When USB PM status changes, or tablet mode changes, call in the main task to + * decide whether to turn touchpad on or off. + */ +#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_TABLET_MODE) +static void touchpad_power_change(void) { - if (usb_is_suspended() && !usb_is_remote_wakeup_enabled()) - task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWEROFF, 0); - else - task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWERON, 0); + task_set_event(TASK_ID_TOUCHPAD, TASK_EVENT_POWER, 0); } -DECLARE_HOOK(HOOK_USB_PM_CHANGE, touchpad_usb_pm_change, HOOK_PRIO_DEFAULT); +#endif +#ifdef CONFIG_USB_SUSPEND +DECLARE_HOOK(HOOK_USB_PM_CHANGE, touchpad_power_change, HOOK_PRIO_DEFAULT); +#endif +#ifdef CONFIG_TABLET_MODE +DECLARE_HOOK(HOOK_TABLET_MODE_CHANGE, touchpad_power_change, HOOK_PRIO_DEFAULT); #endif #ifdef CONFIG_USB_ISOCHRONOUS |