summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2016-01-21 10:09:53 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-01-27 14:52:18 -0800
commit7d0152a78b8b6947dd103c01d9fe380f5b55edf6 (patch)
tree0a9e0652a75514f9fc979c9eebaaa51850c6cce9
parent0801ac67b9310ff6d75e57430235857ecd3ce0a0 (diff)
downloadchrome-ec-7d0152a78b8b6947dd103c01d9fe380f5b55edf6.tar.gz
tcpc: add support for TCPC with integrated high-speed muxes
The TCPCI specification defines ane optional register 18h 'CONFIG_STANDARD_OUTPUT' providing a standardized way of steering the high-speed muxes. Implement the feature as a usb_mux_driver, under the conditional flag CONFIG_USB_PD_TCPM_MUX. The USB PD port index should be set in the port_addr field of the 'usb_mux' structure. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=chrome-os-partner:49605 TEST=run pdeval-stm32f072 connected to a Parade PS8751 board and test USB/DP muxing. Change-Id: I7e5f0b8ec70b1910b2cff9d106514baca8c899e5 Reviewed-on: https://chromium-review.googlesource.com/322956 Commit-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--driver/tcpm/tcpci.c58
-rw-r--r--driver/tcpm/tcpci.h6
-rw-r--r--include/config.h6
-rw-r--r--include/usb_mux.h1
4 files changed, 71 insertions, 0 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 2d268a961a..375e56aa5c 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -10,6 +10,7 @@
#include "tcpm.h"
#include "timer.h"
#include "usb_charge.h"
+#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_tcpc.h"
#include "util.h"
@@ -286,3 +287,60 @@ int tcpm_init(int port)
msleep(10);
}
}
+
+#ifdef CONFIG_USB_PD_TCPM_MUX
+
+static int tcpm_mux_init(int i2c_addr)
+{
+ return EC_SUCCESS;
+}
+
+static int tcpm_mux_set(int i2c_addr, mux_state_t mux_state)
+{
+ int reg = 0;
+ int rv;
+ int port = i2c_addr; /* use port index in port_addr field */
+
+ rv = tcpc_read(port, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
+ if (rv != EC_SUCCESS)
+ return rv;
+
+ reg &= ~TCPC_REG_CONFIG_STD_OUTPUT_MUX_MASK;
+ if (mux_state & MUX_USB_ENABLED)
+ reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB;
+ if (mux_state & MUX_DP_ENABLED)
+ reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP;
+ /* MUX_POLARITY_INVERTED: polarity is handled by the TCPC */
+
+ return tcpc_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg);
+}
+
+/* Reads control register and updates mux_state accordingly */
+static int tcpm_mux_get(int i2c_addr, mux_state_t *mux_state)
+{
+ int reg = 0;
+ int rv;
+ int port = i2c_addr; /* use port index in port_addr field */
+
+ *mux_state = 0;
+ rv = tcpc_read(port, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
+ if (rv != EC_SUCCESS)
+ return rv;
+
+ if (reg & TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB)
+ *mux_state |= MUX_USB_ENABLED;
+ if (reg & TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP)
+ *mux_state |= MUX_DP_ENABLED;
+ /* MUX_POLARITY_INVERTED is always omitted */
+
+ return EC_SUCCESS;
+}
+
+
+const struct usb_mux_driver tcpm_usb_mux_driver = {
+ .init = tcpm_mux_init,
+ .set = tcpm_mux_set,
+ .get = tcpm_mux_get,
+};
+
+#endif /* CONFIG_USB_PD_TCPM_MUX */
diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h
index d105ea5361..eb87b7d0e2 100644
--- a/driver/tcpm/tcpci.h
+++ b/driver/tcpm/tcpci.h
@@ -37,6 +37,12 @@
#define TCPC_REG_POWER_STATUS_MASK 0x14
#define TCPC_REG_FAULT_STATUS_MASK 0x15
#define TCPC_REG_CONFIG_STD_OUTPUT 0x18
+
+#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_MASK (3 << 2)
+#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_NONE (0 << 2)
+#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB (1 << 2)
+#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP (2 << 2)
+
#define TCPC_REG_TCPC_CTRL 0x19
#define TCPC_REG_TCPC_CTRL_SET(polarity) (polarity)
#define TCPC_REG_TCPC_CTRL_POLARITY(reg) ((reg) & 0x1)
diff --git a/include/config.h b/include/config.h
index d307b75ad2..bd86449519 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1827,6 +1827,12 @@
#undef CONFIG_USB_PD_TCPM_FUSB302
/*
+ * Use this option if the TCPC port controller supports the optional register
+ * 18h CONFIG_STANDARD_OUTPUT to steer the high-speed muxes.
+ */
+#undef CONFIG_USB_PD_TCPM_MUX
+
+/*
* Use this option if the TCPC port controller is on a seperate chip from
* the TCPM layer and if VUBS detect GPIO is not available on the TCPM
* mcu.
diff --git a/include/usb_mux.h b/include/usb_mux.h
index 1524caa3fa..4f38b8e68e 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -80,6 +80,7 @@ struct usb_mux {
/* Supported USB mux drivers */
extern const struct usb_mux_driver pi3usb30532_usb_mux_driver;
extern const struct usb_mux_driver ps8740_usb_mux_driver;
+extern const struct usb_mux_driver tcpm_usb_mux_driver;
/* USB muxes present in system, ordered by PD port #, defined at board-level */
extern struct usb_mux usb_muxes[];