summaryrefslogtreecommitdiff
path: root/driver/tcpm/ps8xxx.c
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2019-07-30 17:45:59 -0700
committerCommit Bot <commit-bot@chromium.org>2020-09-01 12:42:22 +0000
commit689e8cdc09254072c0dface2954bc6e87f5ceaf7 (patch)
tree90eaf2adfbc5ff996f63a6cbe51ea657e6e67032 /driver/tcpm/ps8xxx.c
parent9c880833331e25bf436aa6628e837b9c98a47bc2 (diff)
downloadchrome-ec-689e8cdc09254072c0dface2954bc6e87f5ceaf7.tar.gz
ps8xxx: disable DCI mode
DCI mode is auto-enabled by default. we don't actually support DCI (intel specific SoC debug path), so we can explicitly disable DCI mode. doing so, saves about 40mW on the 3.3v rail when USB2 devices or USB-C to USB-A dongles are left plugged in. this is particulary relevant in sleep mode as this accounts for a significant portion of the system power consumption. BUG=b:119875949 BRANCH=none TEST=verified power consumption drops using sweetberry, USB devices still functional across suspend/resume. Change-Id: Id13630425c78965d2ac4f2e97715374ae0640d23 Signed-off-by: Caveh Jalali <caveh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1732231 Reviewed-by: Edward Hill <ecgh@chromium.org> Commit-Queue: Caveh Jalali <caveh@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2315962 Tested-by: Devin Lu <Devin.Lu@quantatw.com> Reviewed-by: Marco Chen <marcochen@chromium.org> Commit-Queue: Marco Chen <marcochen@chromium.org>
Diffstat (limited to 'driver/tcpm/ps8xxx.c')
-rw-r--r--driver/tcpm/ps8xxx.c74
1 files changed, 73 insertions, 1 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