diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2016-01-21 10:09:53 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-01-27 14:52:18 -0800 |
commit | 7d0152a78b8b6947dd103c01d9fe380f5b55edf6 (patch) | |
tree | 0a9e0652a75514f9fc979c9eebaaa51850c6cce9 | |
parent | 0801ac67b9310ff6d75e57430235857ecd3ce0a0 (diff) | |
download | chrome-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.c | 58 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 6 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/usb_mux.h | 1 |
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, ®); + 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, ®); + 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[]; |