summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2021-06-23 21:27:24 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-25 20:58:18 +0000
commit917f3aa53a336bd89cc3bf7ed7b1508a0473967a (patch)
tree4a1222347a8aa89d732c1beaf7ac22bd3046c2f9
parent65fd96d4c1900e31d6296e768743f421953fd026 (diff)
downloadchrome-ec-917f3aa53a336bd89cc3bf7ed7b1508a0473967a.tar.gz
TCPM: Add new LPM bypass TCPC accessors
This adds a set of light-weight TCPC register access functions for special cases where the caller arranges for the TCPC to be accessible and the complexity of fully taking a TCPC out of LPM mode is not desirable. A typical use case is for alert service routines to be able to peek at a TCPCs alert register to determine if further processing is requested. BRANCH=none BUG=b:191531291 TEST=buildall passes Change-Id: Ib5c9add95f04be311315808168b070793b51cb24 Signed-off-by: Caveh Jalali <caveh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2986601 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Commit-Queue: Diana Z <dzigterman@chromium.org>
-rw-r--r--driver/tcpm/tcpci.c9
-rw-r--r--include/driver/tcpm/tcpm.h24
2 files changed, 31 insertions, 2 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 021afc070f..3bd5d1b5d0 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -175,10 +175,15 @@ int tcpc_addr_read(int port, int i2c_addr, int reg, int *val)
int tcpc_addr_read16(int port, int i2c_addr, int reg, int *val)
{
- int rv;
-
pd_wait_exit_low_power(port);
+ return tcpc_addr_read16_no_lpm_exit(port, i2c_addr, reg, val);
+}
+
+int tcpc_addr_read16_no_lpm_exit(int port, int i2c_addr, int reg, int *val)
+{
+ int rv;
+
rv = i2c_read16(tcpc_config[port].i2c_info.port,
i2c_addr, reg, val);
diff --git a/include/driver/tcpm/tcpm.h b/include/driver/tcpm/tcpm.h
index df717dcb6a..d76b187464 100644
--- a/include/driver/tcpm/tcpm.h
+++ b/include/driver/tcpm/tcpm.h
@@ -49,6 +49,29 @@ static inline int tcpc_addr_read16(int port, int i2c_addr, int reg, int *val)
i2c_addr, reg, val);
}
+/*
+ * The *_no_lpm_exit() routines are intende to be used where the TCPC
+ * needs to be accessed without being being taken out of LPM. The main
+ * use case is to check the alert register to determine if a TCPC is the
+ * source of an interrupt in a shared interrupt implementation. If the
+ * TCPC is taken out of LPM, it may generate a new alert which can lead
+ * to successive unintended interrupts. The TCPC is placed back into the
+ * idle state after the LPM timer expires similar to other tcpc_*()
+ * routines.
+ *
+ * The caller must guarantee that the chip responds to I2C as expected:
+ * - some TCPCs wake up when they alert and do not need special handing
+ * - some TCPCs wake up on I2C and respond as expected
+ * - some TCPCs wake up on I2C and throw away the transaction - these
+ * need an explicit by the caller.
+ */
+
+static inline int tcpc_addr_read16_no_lpm_exit(int port, int i2c_addr,
+ int reg, int *val)
+{
+ return tcpc_addr_read16(port, i2c_addr, reg, val);
+}
+
static inline int tcpc_xfer(int port, const uint8_t *out, int out_size,
uint8_t *in, int in_size)
{
@@ -103,6 +126,7 @@ int tcpc_addr_write(int port, int i2c_addr, int reg, int val);
int tcpc_addr_write16(int port, int i2c_addr, int reg, int val);
int tcpc_addr_read(int port, int i2c_addr, int reg, int *val);
int tcpc_addr_read16(int port, int i2c_addr, int reg, int *val);
+int tcpc_addr_read16_no_lpm_exit(int port, int i2c_addr, int reg, int *val);
int tcpc_read_block(int port, int reg, uint8_t *in, int size);
int tcpc_write_block(int port, int reg, const uint8_t *out, int size);
int tcpc_xfer(int port, const uint8_t *out, int out_size,