diff options
-rw-r--r-- | driver/tcpm/ps8xxx.c | 74 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.h | 22 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 8 | ||||
-rw-r--r-- | driver/tcpm/tcpm.h | 24 |
4 files changed, 110 insertions, 18 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index bbdf8f1a82..9cb6e46017 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 - + (PS8751_I2C_ADDR1 - PS8751_I2C_ADDR1_P1); + 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; + 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 2d878216e3..99ba60d43c 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 0x16 -#define PS8751_I2C_ADDR2 0x36 -#define PS8751_I2C_ADDR3 0x56 -#define PS8751_I2C_ADDR4 0x96 +#define PS8751_I2C_ADDR1_P1 0x12 +#define PS8751_I2C_ADDR1 0x16 +#define PS8751_I2C_ADDR2 0x36 +#define PS8751_I2C_ADDR3 0x56 +#define PS8751_I2C_ADDR4 0x96 /* 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 @@ -49,13 +55,15 @@ #define PS8XXX_REG_MUX_DP_OUTPUT_CONFIGURATION 0xD4 #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 223527fc29..17cb8b08d0 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -30,14 +30,14 @@ static int selected_rp[CONFIG_USB_PD_PORT_MAX_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, reg, val); + i2c_addr, reg, val); pd_device_accessed(port); return rv; @@ -56,14 +56,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, 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 186c88a276..3cef4b4b41 100644 --- a/driver/tcpm/tcpm.h +++ b/driver/tcpm/tcpm.h @@ -25,10 +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, reg, val); + i2c_addr, reg, val); } static inline int tcpc_write16(int port, int reg, int val) @@ -37,10 +37,10 @@ static inline int tcpc_write16(int port, int reg, int val) tcpc_config[port].i2c_info.addr, 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, reg, val); + i2c_addr, reg, val); } static inline int tcpc_read16(int port, int reg, int *val) @@ -79,9 +79,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); @@ -92,6 +92,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, reg, val); +} + +static inline int tcpc_read(int port, int reg, int *val) +{ + return tcpc_addr_read(port, + tcpc_config[port].i2c_info.addr, reg, val); +} + static inline void tcpc_lock(int port, int lock) { i2c_lock(tcpc_config[port].i2c_info.port, lock); |