From b81c17122e7e4c206d91446bcd7ec039397c3e08 Mon Sep 17 00:00:00 2001 From: Scott Chao Date: Wed, 23 Mar 2022 14:44:58 +0800 Subject: primus: send suspend mode to trackpoint BUG=b:226215983 BRANCH=none TEST=make -j BOARD=primus TEST=verify by EE Signed-off-by: Scott Chao Change-Id: I139c8a628f9c01ce299b7ec650839f67ca99a12e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3544753 Reviewed-by: caveh jalali Commit-Queue: caveh jalali --- board/primus/board.h | 2 ++ board/primus/ps2.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++-- board/primus/ps2.h | 31 ++++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 board/primus/ps2.h diff --git a/board/primus/board.h b/board/primus/board.h index 8687e96825..8d4482277e 100644 --- a/board/primus/board.h +++ b/board/primus/board.h @@ -160,6 +160,8 @@ #define CONFIG_8042_AUX #define CONFIG_PS2 #define CONFIG_CMD_PS2 +#define PRIMUS_PS2_CH NPCX_PS2_CH1 + /* Button */ #undef CONFIG_VOLUME_BUTTONS diff --git a/board/primus/ps2.c b/board/primus/ps2.c index d91527c508..e5ac1f0aa7 100644 --- a/board/primus/ps2.c +++ b/board/primus/ps2.c @@ -3,20 +3,27 @@ * found in the LICENSE file. */ +#include + +#include "cbi_ssfc.h" #include "gpio.h" #include "hooks.h" #include "keyboard_8042.h" +#include "ps2.h" #include "ps2_chip.h" #include "time.h" +#include "registers.h" + +#define PS2_TRANSMIT_DELAY_MS 10 void send_aux_data_to_device(uint8_t data) { - ps2_transmit_byte(NPCX_PS2_CH1, data); + ps2_transmit_byte(PRIMUS_PS2_CH, data); } static void board_init(void) { - ps2_enable_channel(NPCX_PS2_CH1, 1, send_aux_data_to_host_interrupt); + ps2_enable_channel(PRIMUS_PS2_CH, 1, send_aux_data_to_host_interrupt); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); @@ -43,3 +50,73 @@ static void disable_ps2(void) hook_call_deferred(&enable_ps2_data, 2 * SECOND); } DECLARE_HOOK(HOOK_CHIPSET_RESET, disable_ps2, HOOK_PRIO_DEFAULT); + +static void ps2_transmit(uint8_t cmd) +{ + ps2_transmit_byte(PRIMUS_PS2_CH, cmd); + msleep(PS2_TRANSMIT_DELAY_MS); +} + +static void send_command_to_trackpoint(uint8_t command1, uint8_t command2) +{ + /* + * Send command to trackpoint and wait, + * this will make sure EC get ACK from PS2 device + * and send the next command. + */ + + ps2_transmit(TP_COMMAND); + ps2_transmit(TP_TOGGLE); + ps2_transmit(command1); + ps2_transmit(command2); +} + +int get_trackpoint_id(void) +{ + if (get_cbi_ssfc_trackpoint() == SSFC_SENSOR_TRACKPOINT_ELAN) + return TP_VARIANT_ELAN; + else + return TP_VARIANT_SYNAPTICS; +} + +/* Called on AP S0 -> S3 transition */ +static void ps2_suspend(void) +{ + int trackpoint_id; + /* + * When EC send PS2 command to PS2 device, + * PS2 device will return ACK(0xFA). + * EC will send it to host and cause host wake from suspend. + * So disable EC send data to host to avoid it. + */ + ps2_enable_channel(PRIMUS_PS2_CH, 1, NULL); + trackpoint_id = get_trackpoint_id(); + /* + * Send suspend mode to trackpoint + * Those commands was provide by Elan and Synaptics + */ + if (trackpoint_id == TP_VARIANT_ELAN) + send_command_to_trackpoint(TP_TOGGLE_BURST, + TP_TOGGLE_ELAN_SLEEP); + else if (trackpoint_id == TP_VARIANT_SYNAPTICS) + send_command_to_trackpoint(TP_TOGGLE_SOURCE_TAG, + TP_TOGGLE_SNAPTICS_SLEEP); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, ps2_suspend, HOOK_PRIO_DEFAULT); + +/* Called on AP S3 -> S0 transition */ +static void ps2_resume(void) +{ + int trackpoint_id; + + trackpoint_id = get_trackpoint_id(); + ps2_enable_channel(PRIMUS_PS2_CH, 1, send_aux_data_to_host_interrupt); + /* + * For Synaptics trackpoint, EC need to send command to it again. + * For Elan trackpoint, we just need to touch trackpoint and it wake. + */ + if (trackpoint_id == TP_VARIANT_SYNAPTICS) + send_command_to_trackpoint(TP_TOGGLE_SOURCE_TAG, + TP_TOGGLE_SNAPTICS_SLEEP); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, ps2_resume, HOOK_PRIO_DEFAULT); diff --git a/board/primus/ps2.h b/board/primus/ps2.h new file mode 100644 index 0000000000..0943d5ba4b --- /dev/null +++ b/board/primus/ps2.h @@ -0,0 +1,31 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_PRIMUS_PS2_H +#define __CROS_EC_PRIMUS_PS2_H + +/* Primus board-specific PS2 configuration */ +/* + * Valid first byte responses to the "Read Secondary ID" (0xE1) command. + * 0x01 was the original IBM trackpoint, others implement very limited + * subset of trackpoint features. + */ +#define TP_READ_ID 0xE1 /* Sent for device identification */ + +#define TP_COMMAND 0xE2 /* Commands start with this */ + +/* + * Toggling Flag bits + */ +#define TP_TOGGLE 0x47 /* Toggle command */ + +#define TP_VARIANT_ELAN 0x03 +#define TP_VARIANT_SYNAPTICS 0x06 +#define TP_TOGGLE_SOURCE_TAG 0x20 +#define TP_TOGGLE_BURST 0x28 +#define TP_TOGGLE_SNAPTICS_SLEEP 0x10 +#define TP_TOGGLE_ELAN_SLEEP 0x8 + +#endif /* __CROS_EC_PRIMUS_PS2_H */ -- cgit v1.2.1