summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2021-11-04 12:09:09 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-11 21:41:22 +0000
commit99a6013a9a7b31b4698d2ecd5a68d5a1e61fc036 (patch)
tree46bab0ee940f210cb1bd9be82be29275c6e4ec40
parent65ec8708608955683f04e7bbfdf2cef39b5214f9 (diff)
downloadchrome-ec-99a6013a9a7b31b4698d2ecd5a68d5a1e61fc036.tar.gz
TCPCI: Add an interface for I2C wake
When we wake a TCPC from I2C idle, there is a procedure in the TCPCI specificaiton to follow. Implementing the full procedure will take some refactoring, but for now at least send the i2c wake to the chip when we plan to wake it. Otherwise, we don't actually wake the chip until the LPM exit debounce finishes, which isn't in the intended use of the LPM exit debounce. BRANCH=None BUG=b:195393479 TEST=make -j buildall Signed-off-by: Diana Z <dzigterman@chromium.org> Change-Id: I6d5a6d27cce653ab02b59ab0e09d06657f640c39 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262585 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--driver/tcpm/tcpci.c13
-rw-r--r--include/driver/tcpm/tcpci.h2
-rw-r--r--include/driver/tcpm/tcpm.h7
-rw-r--r--include/usb_pd_tcpm.h10
4 files changed, 32 insertions, 0 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index e22a284a1a..8a6aea2dbb 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -580,6 +580,19 @@ int tcpci_enter_low_power_mode(int port)
{
return tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
}
+
+void tcpci_wake_low_power_mode(int port)
+{
+ /*
+ * TCPCI 4.8.1 I2C Interface - wake the TCPC with a throw-away command
+ *
+ * TODO(b/205140007): Align LPM exit to TCPCI spec for TCPCs which can
+ * correctly support it
+ */
+ i2c_write8(tcpc_config[port].i2c_info.port,
+ tcpc_config[port].i2c_info.addr_flags,
+ TCPC_REG_COMMAND, TCPC_REG_COMMAND_WAKE_I2C);
+}
#endif
int tcpci_tcpm_set_polarity(int port, enum tcpc_cc_polarity polarity)
diff --git a/include/driver/tcpm/tcpci.h b/include/driver/tcpm/tcpci.h
index 8ed4647983..932139b82d 100644
--- a/include/driver/tcpm/tcpci.h
+++ b/include/driver/tcpm/tcpci.h
@@ -159,6 +159,7 @@
#define TCPC_REG_ALERT_EXT_SNK_FRS BIT(0)
#define TCPC_REG_COMMAND 0x23
+#define TCPC_REG_COMMAND_WAKE_I2C 0x11
#define TCPC_REG_COMMAND_ENABLE_VBUS_DETECT 0x33
#define TCPC_REG_COMMAND_SNK_CTRL_LOW 0x44
#define TCPC_REG_COMMAND_SNK_CTRL_HIGH 0x55
@@ -304,6 +305,7 @@ int tcpci_tcpc_drp_toggle(int port);
#endif
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
int tcpci_enter_low_power_mode(int port);
+void tcpci_wake_low_power_mode(int port);
#endif
enum ec_error_list tcpci_set_bist_test_mode(const int port,
const bool enable);
diff --git a/include/driver/tcpm/tcpm.h b/include/driver/tcpm/tcpm.h
index ef5981f1b4..1c01b6692b 100644
--- a/include/driver/tcpm/tcpm.h
+++ b/include/driver/tcpm/tcpm.h
@@ -356,8 +356,15 @@ static inline int tcpm_enter_low_power_mode(int port)
{
return tcpc_config[port].drv->enter_low_power_mode(port);
}
+
+static inline void tcpm_wake_low_power_mode(int port)
+{
+ if (tcpc_config[port].drv->wake_low_power_mode)
+ tcpc_config[port].drv->wake_low_power_mode(port);
+}
#else
int tcpm_enter_low_power_mode(int port);
+void tcpm_wake_low_power_mode(int port);
#endif
#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC
diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h
index 13d1fbbcb5..d17dab6aab 100644
--- a/include/usb_pd_tcpm.h
+++ b/include/usb_pd_tcpm.h
@@ -430,6 +430,16 @@ struct tcpm_drv {
* @return EC_SUCCESS or error
*/
int (*enter_low_power_mode)(int port);
+
+ /**
+ * Starts I2C wake sequence for TCPC
+ *
+ * NOTE: Do no use tcpc_(read|write) style helper methods in this
+ * function. You must use i2c_(read|write) directly.
+ *
+ * @param port Type-C port number
+ */
+ void (*wake_low_power_mode)(int port);
#endif
#ifdef CONFIG_USB_PD_FRS_TCPC