summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/tcpm/ps8xxx.c74
-rw-r--r--driver/tcpm/ps8xxx.h22
-rw-r--r--driver/tcpm/tcpci.c10
-rw-r--r--driver/tcpm/tcpm.h26
4 files changed, 110 insertions, 22 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c
index 7c8f53f745..c2e647e693 100644
--- a/driver/tcpm/ps8xxx.c
+++ b/driver/tcpm/ps8xxx.c
@@ -168,8 +168,80 @@ static int ps8xxx_get_chip_info(int port, int live,
}
+/*
+ * DCI is enabled by default and burns about 40 mW when the port is in
+ * USB2 mode or when a C-to-A dongle is attached, so force it off.
+ */
+
+static int ps8xxx_addr_dci_disable(int port, int i2c_addr, int i2c_reg)
+{
+ int status;
+ int dci;
+
+ status = tcpc_addr_read(port, i2c_addr, i2c_reg, &dci);
+ if (status != EC_SUCCESS)
+ return status;
+ if ((dci & PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK) !=
+ PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF) {
+ dci &= ~PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK;
+ dci |= PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF;
+ if (tcpc_addr_write(port, i2c_addr, i2c_reg, dci) != EC_SUCCESS)
+ return status;
+ }
+ return EC_SUCCESS;
+}
+
+#ifdef CONFIG_USB_PD_TCPM_PS8805
+static int ps8xxx_dci_disable(int port)
+{
+ int status, e;
+ int p1_addr;
+
+ status = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE,
+ PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON);
+ if (status != EC_SUCCESS)
+ return status;
+
+ p1_addr = tcpc_config[port].i2c_info.addr_flags -
+ (PS8751_I2C_ADDR1_FLAGS - PS8751_I2C_ADDR1_P1_FLAGS);
+ status = ps8xxx_addr_dci_disable(port, p1_addr,
+ PS8805_P1_REG_MUX_USB_DCI_CFG);
+
+ e = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE,
+ PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF);
+ if (e != EC_SUCCESS) {
+ if (status == EC_SUCCESS)
+ status = e;
+ }
+
+ return status;
+}
+#endif /* CONFIG_USB_PD_TCPM_PS8805 */
+
+#ifdef CONFIG_USB_PD_TCPM_PS8751
+static int ps8xxx_dci_disable(int port)
+{
+ int p3_addr;
+
+ p3_addr = tcpc_config[port].i2c_info.addr_flags;
+ return ps8xxx_addr_dci_disable(port, p3_addr,
+ PS8751_REG_MUX_USB_DCI_CFG);
+}
+#endif /* CONFIG_USB_PD_TCPM_PS8751 */
+
+static int ps8xxx_tcpm_init(int port)
+{
+ int status;
+
+ status = tcpci_tcpm_init(port);
+ if (status != EC_SUCCESS)
+ return status;
+
+ return ps8xxx_dci_disable(port);
+}
+
const struct tcpm_drv ps8xxx_tcpm_drv = {
- .init = &tcpci_tcpm_init,
+ .init = &ps8xxx_tcpm_init,
.release = &ps8xxx_tcpm_release,
.get_cc = &tcpci_tcpm_get_cc,
#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h
index 4047fb5c14..fc474f6a2b 100644
--- a/driver/tcpm/ps8xxx.h
+++ b/driver/tcpm/ps8xxx.h
@@ -9,10 +9,11 @@
#define __CROS_EC_USB_PD_TCPM_PS8XXX_H
/* I2C interface */
-#define PS8751_I2C_ADDR1_FLAGS 0x0B
-#define PS8751_I2C_ADDR2_FLAGS 0x1B
-#define PS8751_I2C_ADDR3_FLAGS 0x2B
-#define PS8751_I2C_ADDR4_FLAGS 0x4B
+#define PS8751_I2C_ADDR1_P1_FLAGS 0x09
+#define PS8751_I2C_ADDR1_FLAGS 0x0B
+#define PS8751_I2C_ADDR2_FLAGS 0x1B
+#define PS8751_I2C_ADDR3_FLAGS 0x2B
+#define PS8751_I2C_ADDR4_FLAGS 0x4B
/* Minimum Delay for reset assertion */
#define PS8XXX_RESET_DELAY_MS 1
@@ -29,12 +30,17 @@
#define PS8XXX_VENDOR_ID 0x1DA0
#define PS8XXX_REG_I2C_DEBUGGING_ENABLE 0xA0
+#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON 0x30
+#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF 0x31 /* default */
#define PS8XXX_REG_BIST_CONT_MODE_BYTE0 0xBC
#define PS8XXX_REG_BIST_CONT_MODE_BYTE1 0xBD
#define PS8XXX_REG_BIST_CONT_MODE_BYTE2 0xBE
-#define PS8XXX_REG_BIST_CONT_MODE_CTR 0XBF
+#define PS8XXX_REG_BIST_CONT_MODE_CTR 0xBF
#define PS8XXX_REG_DET_CTRL0 0x08
+#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK 0xC0
+#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF 0x80
+
#if defined(CONFIG_USB_PD_TCPM_PS8751)
/* Vendor defined registers */
#define PS8XXX_PRODUCT_ID 0x8751
@@ -48,13 +54,15 @@
#define PS8XXX_REG_MUX_DP_EQ_CONFIGURATION 0xD3
#define PS8XXX_REG_MUX_USB_C2SS_EQ 0xE7
#define PS8XXX_REG_MUX_USB_C2SS_HS_THRESHOLD 0xE8
+#define PS8751_REG_MUX_USB_DCI_CFG 0xED
#elif defined(CONFIG_USB_PD_TCPM_PS8805)
/* Vendor defined registers */
#define PS8XXX_PRODUCT_ID 0x8805
-#define FW_VER_REG 0x82
-#define MUX_IN_HPD_ASSERTION_REG 0xD0
+#define PS8805_P1_REG_MUX_USB_DCI_CFG 0x4B
+#define FW_VER_REG 0x82
+#define MUX_IN_HPD_ASSERTION_REG 0xD0
#define IN_HPD (1 << 0)
#define HPD_IRQ (1 << 1)
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 215ffd8a9c..135e13d7d5 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -30,15 +30,14 @@ static int selected_rp[CONFIG_USB_PD_PORT_COUNT];
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
-int tcpc_write(int port, int reg, int val)
+int tcpc_addr_write(int port, int i2c_addr, int reg, int val)
{
int rv;
pd_wait_exit_low_power(port);
rv = i2c_write8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
pd_device_accessed(port);
return rv;
@@ -58,15 +57,14 @@ int tcpc_write16(int port, int reg, int val)
return rv;
}
-int tcpc_read(int port, int reg, int *val)
+int tcpc_addr_read(int port, int i2c_addr, int reg, int *val)
{
int rv;
pd_wait_exit_low_power(port);
rv = i2c_read8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
pd_device_accessed(port);
return rv;
diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h
index ca7d3cf7bd..2b645f3510 100644
--- a/driver/tcpm/tcpm.h
+++ b/driver/tcpm/tcpm.h
@@ -25,11 +25,10 @@
/* I2C wrapper functions - get I2C port / slave addr from config struct. */
#ifndef CONFIG_USB_PD_TCPC_LOW_POWER
-static inline int tcpc_write(int port, int reg, int val)
+static inline int tcpc_addr_write(int port, int i2c_addr, int reg, int val)
{
return i2c_write8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_write16(int port, int reg, int val)
@@ -39,11 +38,10 @@ static inline int tcpc_write16(int port, int reg, int val)
reg, val);
}
-static inline int tcpc_read(int port, int reg, int *val)
+static inline int tcpc_addr_read(int port, int i2c_addr, int reg, int *val)
{
return i2c_read8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_read16(int port, int reg, int *val)
@@ -85,9 +83,9 @@ static inline int tcpc_write_block(int port, int reg,
}
#else /* !CONFIG_USB_PD_TCPC_LOW_POWER */
-int tcpc_write(int port, int reg, int val);
+int tcpc_addr_write(int port, int i2c_addr, int reg, int val);
int tcpc_write16(int port, int reg, int val);
-int tcpc_read(int port, int reg, int *val);
+int tcpc_addr_read(int port, int i2c_addr, int reg, int *val);
int tcpc_read16(int port, 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);
@@ -98,6 +96,18 @@ int tcpc_xfer_unlocked(int port, const uint8_t *out, int out_size,
#endif /* CONFIG_USB_PD_TCPC_LOW_POWER */
+static inline int tcpc_write(int port, int reg, int val)
+{
+ return tcpc_addr_write(port,
+ tcpc_config[port].i2c_info.addr_flags, reg, val);
+}
+
+static inline int tcpc_read(int port, int reg, int *val)
+{
+ return tcpc_addr_read(port,
+ tcpc_config[port].i2c_info.addr_flags, reg, val);
+}
+
static inline void tcpc_lock(int port, int lock)
{
i2c_lock(tcpc_config[port].i2c_info.port, lock);