From daed130e62e7332037e46c70277816e0630ad04a Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Thu, 30 Aug 2018 16:13:26 -0600 Subject: ss-mux: update semantics for TCPC/MUX only used as MUX This converts the compile time option of CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY into a runtime option to better support draggon egg designs and reduce CONFIG complexity in general. Introduce new mux_read/write to read from tcpc_config_t or mux driver depending on new flag setting. Audited all mux drivers for any use of tcpc_read/write and updated to mux_read/write. BRANCH=none BUG=b:110937880 TEST=On Bip with CL stack: Verified by connecting DP monitor at boot; Verified plug / unplug of DP cable works; Change-Id: I968893b886ff0ccc4074beae5ec42973814ae77c Signed-off-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/1200062 Commit-Ready: Gaggery Tsai Reviewed-by: Scott Collyer --- baseboard/octopus/baseboard.h | 1 - baseboard/octopus/variant_usbc_ec_tcpcs.c | 1 + board/chell/board.c | 4 +- board/coral/board.c | 4 +- board/fizz/board.c | 5 +-- board/reef/board.c | 4 +- board/reef_mchp/board.c | 5 +-- driver/tcpm/anx7447.c | 15 +++++-- driver/tcpm/anx74xx.c | 46 +++++++++---------- driver/tcpm/anx7688.c | 9 ++-- driver/tcpm/ps8xxx.c | 8 ++-- driver/tcpm/tcpci.c | 73 +++++++++---------------------- driver/usb_mux.c | 16 +++---- driver/usb_mux_it5205.c | 28 ++++++------ driver/usb_mux_pi3usb30532.c | 26 +++++------ driver/usb_mux_ps874x.c | 34 +++++++------- include/config.h | 8 ---- include/usb_mux.h | 70 +++++++++++++++++++++++------ 18 files changed, 181 insertions(+), 176 deletions(-) diff --git a/baseboard/octopus/baseboard.h b/baseboard/octopus/baseboard.h index 016d3156c4..96b5a519e2 100644 --- a/baseboard/octopus/baseboard.h +++ b/baseboard/octopus/baseboard.h @@ -161,7 +161,6 @@ #define CONFIG_USB_PD_TCPM_ITE83XX /* C0 & C1 TCPC: ITE EC */ #define CONFIG_USB_MUX_IT5205 /* C0 MUX: IT5205 */ #define CONFIG_USB_PD_TCPM_PS8751 /* C1 Mux: PS8751 */ - #define CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY #define CONFIG_USBC_PPC_SN5S330 /* C0 & C1 PPC: each SN5S330 */ #define CONFIG_USBC_PPC_VCONN #else diff --git a/baseboard/octopus/variant_usbc_ec_tcpcs.c b/baseboard/octopus/variant_usbc_ec_tcpcs.c index a4676f6f40..e7fc7fb7bd 100644 --- a/baseboard/octopus/variant_usbc_ec_tcpcs.c +++ b/baseboard/octopus/variant_usbc_ec_tcpcs.c @@ -71,6 +71,7 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = { /* Use PS8751 as mux only */ .port_addr = MUX_PORT_AND_ADDR( I2C_PORT_USBC1, PS8751_I2C_ADDR1), + .flags = USB_MUX_FLAG_NOT_TCPC, .driver = &tcpci_tcpm_usb_mux_driver, .hpd_update = &board_it83xx_hpd_status, } diff --git a/board/chell/board.c b/board/chell/board.c index 5fc0a47965..a3f7875166 100644 --- a/board/chell/board.c +++ b/board/chell/board.c @@ -171,10 +171,10 @@ struct pi3usb9281_config pi3usb9281_chips[] = { BUILD_ASSERT(ARRAY_SIZE(pi3usb9281_chips) == CONFIG_BC12_DETECT_PI3USB9281_CHIP_COUNT); -static int ps874x_tune_mux(const struct usb_mux *mux) +static int ps874x_tune_mux(int port) { /* Apply same USB EQ settings to both Type-C mux */ - ps874x_tune_usb_eq(mux->port_addr, + ps874x_tune_usb_eq(port, PS874X_USB_EQ_TX_6_5_DB, PS874X_USB_EQ_RX_14_3_DB); diff --git a/board/coral/board.c b/board/coral/board.c index bc37b92d13..2cf54638e5 100644 --- a/board/coral/board.c +++ b/board/coral/board.c @@ -278,10 +278,10 @@ const enum gpio_signal hibernate_wake_pins[] = { const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); -static int ps8751_tune_mux(const struct usb_mux *mux) +static int ps8751_tune_mux(int port) { /* 0x98 sets lower EQ of DP port (4.5db) */ - tcpc_write(mux->port_addr, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); + mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); return EC_SUCCESS; } diff --git a/board/fizz/board.c b/board/fizz/board.c index fdc4a5620e..2c2877c0c1 100644 --- a/board/fizz/board.c +++ b/board/fizz/board.c @@ -201,11 +201,10 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { TCPC_ALERT_ACTIVE_LOW}, }; -static int ps8751_tune_mux(const struct usb_mux *mux) +static int ps8751_tune_mux(int port) { /* 0x98 sets lower EQ of DP port (4.5db) */ - i2c_write8(I2C_PORT_TCPC0, I2C_ADDR_TCPC0, - PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); + mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); return EC_SUCCESS; } diff --git a/board/reef/board.c b/board/reef/board.c index 6df8b781ef..d5cbe46099 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -283,10 +283,10 @@ const enum gpio_signal hibernate_wake_pins[] = { const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); -static int ps8751_tune_mux(const struct usb_mux *mux) +static int ps8751_tune_mux(int port) { /* 0x98 sets lower EQ of DP port (4.5db) */ - tcpc_write(mux->port_addr, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); + mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); return EC_SUCCESS; } diff --git a/board/reef_mchp/board.c b/board/reef_mchp/board.c index 4efe7dcdb3..81d6134915 100644 --- a/board/reef_mchp/board.c +++ b/board/reef_mchp/board.c @@ -413,13 +413,12 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); * results taking up to 10ms before I2C communication with PS8751 * is stable. Don't know how to fix this. */ -static int ps8751_tune_mux(const struct usb_mux *mux) +static int ps8751_tune_mux(int port) { int rv; /* 0x98 sets lower EQ of DP port (4.5db) */ - rv = i2c_write8(MCHP_I2C_PORT2, 0x16, - PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); + rv = mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98); /* TCPCI spec. delay msleep(6); */ diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c index 0d263e6061..a6cfb75937 100644 --- a/driver/tcpm/anx7447.c +++ b/driver/tcpm/anx7447.c @@ -435,6 +435,15 @@ void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) { int reg = 0; + /* + * All calls within this method need to update to a mux_read/write calls + * that use the secondary address. This is a non-trival change and no + * one is using the anx7447 as a mux only (and probably never will since + * it doesn't have a re-driver). If that changes, we need to update this + * code. + */ + ASSERT(!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)); + anx7447_set_hpd_level(port, hpd_lvl); if (hpd_irq) { @@ -524,9 +533,9 @@ static int anx7447_mux_set(int port, mux_state_t mux_state) sw_sel = 0x10; } } - rv = tcpc_write(port, ANX7447_REG_TCPC_SWITCH_0, sw_sel); - rv |= tcpc_write(port, ANX7447_REG_TCPC_SWITCH_1, sw_sel); - rv |= tcpc_write(port, ANX7447_REG_TCPC_AUX_SWITCH, aux_sw); + rv = mux_write(port, ANX7447_REG_TCPC_SWITCH_0, sw_sel); + rv |= mux_write(port, ANX7447_REG_TCPC_SWITCH_1, sw_sel); + rv |= mux_write(port, ANX7447_REG_TCPC_AUX_SWITCH, aux_sw); anx[port].mux_state = mux_state; diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c index 1a08998bf0..669966ddee 100644 --- a/driver/tcpm/anx74xx.c +++ b/driver/tcpm/anx74xx.c @@ -200,12 +200,12 @@ void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) { int reg; - tcpc_read(port, ANX74XX_REG_HPD_CTRL_0, ®); + mux_read(port, ANX74XX_REG_HPD_CTRL_0, ®); if (hpd_lvl) reg |= ANX74XX_REG_HPD_OUT_DATA; else reg &= ~ANX74XX_REG_HPD_OUT_DATA; - tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, reg); + mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); if (hpd_irq) { uint64_t now = get_time().val; @@ -213,12 +213,12 @@ void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) if (now < hpd_deadline[port]) usleep(hpd_deadline[port] - now); - tcpc_read(port, ANX74XX_REG_HPD_CTRL_0, ®); + mux_read(port, ANX74XX_REG_HPD_CTRL_0, ®); reg &= ~ANX74XX_REG_HPD_OUT_DATA; - tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, reg); + mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); usleep(HPD_DSTREAM_DEBOUNCE_IRQ); reg |= ANX74XX_REG_HPD_OUT_DATA; - tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, reg); + mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); } /* enforce 2-ms delay between HPD pulses */ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; @@ -234,10 +234,8 @@ void anx74xx_tcpc_clear_hpd_status(int port) } #ifdef CONFIG_USB_PD_TCPM_MUX -static int anx74xx_tcpm_mux_init(int i2c_addr) +static int anx74xx_tcpm_mux_init(int port) { - int port = i2c_addr; - /* Nothing to do here, ANX initializes its muxes * as (MUX_USB_ENABLED | MUX_DP_ENABLED) */ @@ -250,9 +248,9 @@ static int anx74xx_tcpm_mux_enter_safe_mode(int port) { int reg; - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) + if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) return EC_ERROR_UNKNOWN; - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg | + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg | ANX74XX_REG_MODE_TRANS)) return EC_ERROR_UNKNOWN; @@ -264,9 +262,9 @@ static int anx74xx_tcpm_mux_exit_safe_mode(int port) { int reg; - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) + if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) return EC_ERROR_UNKNOWN; - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & ~ANX74XX_REG_MODE_TRANS)) return EC_ERROR_UNKNOWN; @@ -290,18 +288,18 @@ static int anx74xx_tcpm_mux_exit(int port) return EC_ERROR_UNKNOWN; /* Disconnect aux from sbu */ - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) + if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) return EC_ERROR_UNKNOWN; - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & 0xf)) + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & 0xf)) return EC_ERROR_UNKNOWN; /* Clear Bit[7:0] R_SWITCH */ - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_1, 0x0)) + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, 0x0)) return EC_ERROR_UNKNOWN; /* Clear Bit[7:4] R_SWITCH_H */ - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®)) + if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®)) return EC_ERROR_UNKNOWN; - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg & 0x0f)) + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg & 0x0f)) return EC_ERROR_UNKNOWN; /* Exit safe mode */ @@ -324,7 +322,7 @@ static int anx74xx_mux_aux_to_sbu(int port, int polarity, int enabled) * about setting the correct value for the upper 4 bits of analog_ctrl_2 * here. */ - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) + if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) return EC_ERROR_UNKNOWN; /* Assume aux_p/n lines are not connected */ @@ -338,7 +336,7 @@ static int anx74xx_mux_aux_to_sbu(int port, int polarity, int enabled) reg |= ANX74XX_REG_AUX_SWAP_SET_CC1; } /* Write new aux <-> sbu settings */ - if (tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg)) + if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg)) return EC_ERROR_UNKNOWN; return EC_SUCCESS; @@ -356,7 +354,7 @@ static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state) return anx74xx_tcpm_mux_exit(port); } - rv = tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®); + rv = mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®); if (rv) return EC_ERROR_UNKNOWN; reg &= 0x0f; @@ -394,9 +392,9 @@ static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state) return EC_ERROR_UNKNOWN; /* Write updated pin assignment */ - rv = tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_1, pin_cfg); + rv = mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, pin_cfg); /* Write Rswitch config bits */ - rv |= tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg); + rv |= mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg); if (rv) return EC_ERROR_UNKNOWN; @@ -415,10 +413,8 @@ static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state) } /* current mux state */ -static int anx74xx_tcpm_mux_get(int i2c_addr, mux_state_t *mux_state) +static int anx74xx_tcpm_mux_get(int port, mux_state_t *mux_state) { - int port = i2c_addr; - *mux_state = anx[port].mux_state; return EC_SUCCESS; diff --git a/driver/tcpm/anx7688.c b/driver/tcpm/anx7688.c index 6b73108739..6cbfba9dcf 100644 --- a/driver/tcpm/anx7688.c +++ b/driver/tcpm/anx7688.c @@ -138,13 +138,12 @@ static void anx7688_tcpc_alert(int port) anx7688_update_hpd_enable(port); } -static int anx7688_mux_set(int i2c_addr, mux_state_t mux_state) +static int anx7688_mux_set(int port, mux_state_t mux_state) { int reg = 0; int rv, polarity; - int port = i2c_addr; /* use port index in port_addr field */ - rv = tcpc_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); + rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); if (rv != EC_SUCCESS) return rv; @@ -155,14 +154,14 @@ static int anx7688_mux_set(int i2c_addr, mux_state_t mux_state) reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP; /* ANX7688 needs to set bit0 */ - rv = tcpc_read(port, TCPC_REG_TCPC_CTRL, &polarity); + rv = mux_read(port, TCPC_REG_TCPC_CTRL, &polarity); if (rv != EC_SUCCESS) return rv; /* copy the polarity from TCPC_CTRL[0], take care clear then set */ reg &= ~TCPC_REG_TCPC_CTRL_POLARITY(1); reg |= TCPC_REG_TCPC_CTRL_POLARITY(polarity); - return tcpc_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg); + return mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg); } #ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index 4d4960580c..2caceacde8 100644 --- a/driver/tcpm/ps8xxx.c +++ b/driver/tcpm/ps8xxx.c @@ -43,14 +43,14 @@ static int dp_set_hpd(int port, int enable) int reg; int rv; - rv = tcpc_read(port, MUX_IN_HPD_ASSERTION_REG, ®); + rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, ®); if (rv) return rv; if (enable) reg |= IN_HPD; else reg &= ~IN_HPD; - return tcpc_write(port, MUX_IN_HPD_ASSERTION_REG, reg); + return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg); } static int dp_set_irq(int port, int enable) @@ -59,14 +59,14 @@ static int dp_set_irq(int port, int enable) int reg; int rv; - rv = tcpc_read(port, MUX_IN_HPD_ASSERTION_REG, ®); + rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, ®); if (rv) return rv; if (enable) reg |= HPD_IRQ; else reg &= ~HPD_IRQ; - return tcpc_write(port, MUX_IN_HPD_ASSERTION_REG, reg); + return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg); } void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index aec5c8a329..c81d62d8ac 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -618,24 +618,24 @@ int tcpci_tcpm_init(int port) #ifdef CONFIG_USB_PD_TCPM_MUX -#ifdef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* - * Since the TCPC/MUX device is only used for the MUX, we need to initialize it + * When the TCPC/MUX device is only used for the MUX, we need to initialize it * via mux init because tcpc_init won't run for the device. This is borrowed * from tcpc_init. */ -int tcpci_tcpm_mux_init(int i2c_port_addr) +int tcpci_tcpm_mux_init(int port) { int error; int power_status; int tries = TCPM_INIT_TRIES; + /* If this MUX is also the TCPC, then skip init */ + if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) + return EC_SUCCESS; + /* Wait for the device to exit low power state */ while (1) { - error = i2c_read8(MUX_PORT(i2c_port_addr), - MUX_ADDR(i2c_port_addr), - TCPC_REG_POWER_STATUS, &power_status); + error = mux_read(port, TCPC_REG_POWER_STATUS, &power_status); /* * If read succeeds and the uninitialized bit is clear, then * initialization is complete. @@ -648,43 +648,28 @@ int tcpci_tcpm_mux_init(int i2c_port_addr) } /* Turn off all alerts and acknowledge any pending IRQ */ - error = i2c_write16(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_ALERT_MASK, 0); - error |= i2c_write16(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_ALERT, 0xffff); + error = mux_write16(port, TCPC_REG_ALERT_MASK, 0); + error |= mux_write16(port, TCPC_REG_ALERT, 0xffff); return error ? EC_ERROR_UNKNOWN : EC_SUCCESS; } -static int tcpci_tcpm_mux_enter_low_power(int i2c_port_addr) +static int tcpci_tcpm_mux_enter_low_power(int port) { - return i2c_write8(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE); -} - -#else /* !CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY */ + /* If this MUX is also the TCPC, then skip low power */ + if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) + return EC_SUCCESS; -/* Nothing to init for mux since TCPC init will take care of it. */ -int tcpci_tcpm_mux_init(int i2c_addr) -{ - return EC_SUCCESS; + return mux_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE); } -#endif /* CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY */ - -int tcpci_tcpm_mux_set(int i2c_port_addr, mux_state_t mux_state) +int tcpci_tcpm_mux_set(int port, mux_state_t mux_state) { int reg = 0; int rv; -#ifdef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* Parameter is port and i2c address */ - rv = i2c_read8(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_CONFIG_STD_OUTPUT, ®); -#else /* Parameter is port only */ - rv = tcpc_read(i2c_port_addr, TCPC_REG_CONFIG_STD_OUTPUT, ®); -#endif + rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); if (rv != EC_SUCCESS) return rv; @@ -697,31 +682,20 @@ int tcpci_tcpm_mux_set(int i2c_port_addr, mux_state_t mux_state) if (mux_state & MUX_POLARITY_INVERTED) reg |= TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED; -#ifdef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* Parameter is port and i2c address */ - return i2c_write8(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_CONFIG_STD_OUTPUT, reg); -#else /* Parameter is port only */ - return tcpc_write(i2c_port_addr, TCPC_REG_CONFIG_STD_OUTPUT, reg); -#endif + return mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg); } /* Reads control register and updates mux_state accordingly */ -int tcpci_tcpm_mux_get(int i2c_port_addr, mux_state_t *mux_state) +int tcpci_tcpm_mux_get(int port, mux_state_t *mux_state) { int reg = 0; int rv; *mux_state = 0; -#ifdef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* Parameter is port and i2c address */ - rv = i2c_read8(MUX_PORT(i2c_port_addr), MUX_ADDR(i2c_port_addr), - TCPC_REG_CONFIG_STD_OUTPUT, ®); -#else + /* Parameter is port only */ - rv = tcpc_read(i2c_port_addr, TCPC_REG_CONFIG_STD_OUTPUT, ®); -#endif + rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); if (rv != EC_SUCCESS) return rv; @@ -740,14 +714,7 @@ const struct usb_mux_driver tcpci_tcpm_usb_mux_driver = { .init = &tcpci_tcpm_mux_init, .set = &tcpci_tcpm_mux_set, .get = &tcpci_tcpm_mux_get, -#ifdef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* - * This method is only needed when the TCPC/MUX device is acting solely - * as a MUX (and not the TCPC). In that case, we need to put the device - * into LPM via the mux path since the TCPC path won't do it for us. - */ .enter_low_power_mode = &tcpci_tcpm_mux_enter_low_power, -#endif }; #endif /* CONFIG_USB_PD_TCPM_MUX */ diff --git a/driver/usb_mux.c b/driver/usb_mux.c index 9d2df37a51..97c76d1828 100644 --- a/driver/usb_mux.c +++ b/driver/usb_mux.c @@ -39,7 +39,7 @@ static void enter_low_power_mode(int port) /* Apply any low power customization if present */ if (mux->driver->enter_low_power_mode) { - res = mux->driver->enter_low_power_mode(mux->port_addr); + res = mux->driver->enter_low_power_mode(port); if (res) CPRINTS("Err: enter_low_power_mode mux port(%d): %d", @@ -61,7 +61,7 @@ void usb_mux_init(int port) ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_COUNT); - res = mux->driver->init(mux->port_addr); + res = mux->driver->init(port); if (res) { CPRINTS("Err: init mux port(%d): %d", port, res); return; @@ -72,7 +72,7 @@ void usb_mux_init(int port) /* Apply board specific initialization */ if (mux->board_init) { - res = mux->board_init(mux); + res = mux->board_init(port); if (res) CPRINTS("Err: board_init mux port(%d): %d", port, res); @@ -109,7 +109,7 @@ void usb_mux_set(int port, enum typec_mux mux_mode, /* Configure superspeed lanes */ mux_state = polarity ? mux_mode | MUX_POLARITY_INVERTED : mux_mode; - res = mux->driver->set(mux->port_addr, mux_state); + res = mux->driver->set(port, mux_state); if (res) { CPRINTS("Err: set mux port(%d): %d", port, res); return; @@ -137,7 +137,7 @@ int usb_mux_get(int port, const char **dp_str, const char **usb_str) exit_low_power_mode(port); - res = mux->driver->get(mux->port_addr, &mux_state); + res = mux->driver->get(port, &mux_state); if (res) { CPRINTS("Err: get mux port(%d): %d", port, res); return 0; @@ -160,7 +160,7 @@ void usb_mux_flip(int port) exit_low_power_mode(port); - res = mux->driver->get(mux->port_addr, &mux_state); + res = mux->driver->get(port, &mux_state); if (res) { CPRINTS("Err: get mux port(%d): %d", port, res); return; @@ -171,7 +171,7 @@ void usb_mux_flip(int port) else mux_state |= MUX_POLARITY_INVERTED; - res = mux->driver->set(mux->port_addr, mux_state); + res = mux->driver->set(port, mux_state); if (res) CPRINTS("Err: set mux port(%d): %d", port, res); } @@ -237,7 +237,7 @@ static int hc_usb_pd_mux_info(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; mux = &usb_muxes[port]; - if (mux->driver->get(mux->port_addr, &r->flags) != EC_SUCCESS) + if (mux->driver->get(port, &r->flags) != EC_SUCCESS) return EC_RES_ERROR; #ifdef CONFIG_USB_MUX_VIRTUAL diff --git a/driver/usb_mux_it5205.c b/driver/usb_mux_it5205.c index dcd3eaa414..4c2f274c88 100644 --- a/driver/usb_mux_it5205.c +++ b/driver/usb_mux_it5205.c @@ -14,14 +14,14 @@ #define MUX_STATE_DP_USB_MASK (MUX_USB_ENABLED | MUX_DP_ENABLED) -static int it5205_read(int i2c_addr, uint8_t reg, int *val) +static int it5205_read(int port, uint8_t reg, int *val) { - return i2c_read8(I2C_PORT_USB_MUX, i2c_addr, reg, val); + return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); } -static int it5205_write(int i2c_addr, uint8_t reg, uint8_t val) +static int it5205_write(int port, uint8_t reg, uint8_t val) { - return i2c_write8(I2C_PORT_USB_MUX, i2c_addr, reg, val); + return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); } struct mux_chip_id_t { @@ -36,17 +36,17 @@ static const struct mux_chip_id_t mux_chip_id_verify[] = { { '5', IT5205_REG_CHIP_ID0}, }; -static int it5205_init(int i2c_addr) +static int it5205_init(int port) { int i, val, ret; /* bit[0]: mux power on, bit[7-1]: reserved. */ - ret = it5205_write(i2c_addr, IT5205_REG_MUXPDR, 0); + ret = it5205_write(port, IT5205_REG_MUXPDR, 0); if (ret) return ret; /* Verify chip ID registers. */ for (i = 0; i < ARRAY_SIZE(mux_chip_id_verify); i++) { - ret = it5205_read(i2c_addr, mux_chip_id_verify[i].reg, &val); + ret = it5205_read(port, mux_chip_id_verify[i].reg, &val); if (ret) return ret; @@ -58,7 +58,7 @@ static int it5205_init(int i2c_addr) } /* Writes control register to set switch mode */ -static int it5205_set_mux(int i2c_addr, mux_state_t mux_state) +static int it5205_set_mux(int port, mux_state_t mux_state) { uint8_t reg; @@ -80,15 +80,15 @@ static int it5205_set_mux(int i2c_addr, mux_state_t mux_state) if (mux_state & MUX_POLARITY_INVERTED) reg |= IT5205_POLARITY_INVERTED; - return it5205_write(i2c_addr, IT5205_REG_MUXCR, reg); + return it5205_write(port, IT5205_REG_MUXCR, reg); } /* Reads control register and updates mux_state accordingly */ -static int it5205_get_mux(int i2c_addr, mux_state_t *mux_state) +static int it5205_get_mux(int port, mux_state_t *mux_state) { int reg, ret; - ret = it5205_read(i2c_addr, IT5205_REG_MUXCR, ®); + ret = it5205_read(port, IT5205_REG_MUXCR, ®); if (ret) return ret; @@ -113,18 +113,18 @@ static int it5205_get_mux(int i2c_addr, mux_state_t *mux_state) return EC_SUCCESS; } -static int it5205_enter_low_power_mode(int i2c_addr) +static int it5205_enter_low_power_mode(int port) { int rv; /* Turn off all switches */ - rv = it5205_write(i2c_addr, IT5205_REG_MUXCR, 0); + rv = it5205_write(port, IT5205_REG_MUXCR, 0); if (rv) return rv; /* Power down mux */ - return it5205_write(i2c_addr, IT5205_REG_MUXPDR, IT5205_MUX_POWER_DOWN); + return it5205_write(port, IT5205_REG_MUXPDR, IT5205_MUX_POWER_DOWN); } const struct usb_mux_driver it5205_usb_mux_driver = { diff --git a/driver/usb_mux_pi3usb30532.c b/driver/usb_mux_pi3usb30532.c index 57f81ff3e9..54d6f49fe7 100644 --- a/driver/usb_mux_pi3usb30532.c +++ b/driver/usb_mux_pi3usb30532.c @@ -11,7 +11,7 @@ #include "usb_mux.h" #include "util.h" -static int pi3usb30532_read(int i2c_addr, uint8_t reg, uint8_t *val) +static int pi3usb30532_read(int port, uint8_t reg, uint8_t *val) { int read, res; @@ -20,7 +20,7 @@ static int pi3usb30532_read(int i2c_addr, uint8_t reg, uint8_t *val) * Second byte read will be vendor ID. * Third byte read will be selection control. */ - res = i2c_read16(I2C_PORT_USB_MUX, i2c_addr, 0, &read); + res = i2c_read16(I2C_PORT_USB_MUX, MUX_ADDR(port), 0, &read); if (res) return res; @@ -32,32 +32,32 @@ static int pi3usb30532_read(int i2c_addr, uint8_t reg, uint8_t *val) return EC_SUCCESS; } -static int pi3usb30532_write(int i2c_addr, uint8_t reg, uint8_t val) +static int pi3usb30532_write(int port, uint8_t reg, uint8_t val) { if (reg != PI3USB30532_REG_CONTROL) return EC_ERROR_UNKNOWN; - return i2c_write8(I2C_PORT_USB_MUX, i2c_addr, 0, val); + return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), 0, val); } -static int pi3usb30532_reset(int i2c_addr) +static int pi3usb30532_reset(int port) { return pi3usb30532_write( - i2c_addr, + port, PI3USB30532_REG_CONTROL, (PI3USB30532_MODE_POWERDOWN & PI3USB30532_CTRL_MASK) | PI3USB30532_CTRL_RSVD); } -static int pi3usb30532_init(int i2c_addr) +static int pi3usb30532_init(int port) { uint8_t val; int res; - res = pi3usb30532_reset(i2c_addr); + res = pi3usb30532_reset(port); if (res) return res; - res = pi3usb30532_read(i2c_addr, PI3USB30532_REG_VENDOR, &val); + res = pi3usb30532_read(port, PI3USB30532_REG_VENDOR, &val); if (res) return res; if (val != PI3USB30532_VENDOR_ID) @@ -67,7 +67,7 @@ static int pi3usb30532_init(int i2c_addr) } /* Writes control register to set switch mode */ -static int pi3usb30532_set_mux(int i2c_addr, mux_state_t mux_state) +static int pi3usb30532_set_mux(int port, mux_state_t mux_state) { uint8_t reg = 0; @@ -78,18 +78,18 @@ static int pi3usb30532_set_mux(int i2c_addr, mux_state_t mux_state) if (mux_state & MUX_POLARITY_INVERTED) reg |= PI3USB30532_BIT_SWAP; - return pi3usb30532_write(i2c_addr, PI3USB30532_REG_CONTROL, + return pi3usb30532_write(port, PI3USB30532_REG_CONTROL, reg | PI3USB30532_CTRL_RSVD); } /* Reads control register and updates mux_state accordingly */ -static int pi3usb30532_get_mux(int i2c_addr, mux_state_t *mux_state) +static int pi3usb30532_get_mux(int port, mux_state_t *mux_state) { uint8_t reg = 0; uint8_t res; *mux_state = 0; - res = pi3usb30532_read(i2c_addr, PI3USB30532_REG_CONTROL, ®); + res = pi3usb30532_read(port, PI3USB30532_REG_CONTROL, ®); if (res) return res; diff --git a/driver/usb_mux_ps874x.c b/driver/usb_mux_ps874x.c index 900ae0763a..b560329c2a 100644 --- a/driver/usb_mux_ps874x.c +++ b/driver/usb_mux_ps874x.c @@ -11,30 +11,30 @@ #include "usb_mux.h" #include "util.h" -static inline int ps874x_read(int i2c_addr, uint8_t reg, int *val) +static inline int ps874x_read(int port, uint8_t reg, int *val) { - return i2c_read8(I2C_PORT_USB_MUX, i2c_addr, reg, val); + return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); } -static inline int ps874x_write(int i2c_addr, uint8_t reg, uint8_t val) +static inline int ps874x_write(int port, uint8_t reg, uint8_t val) { - return i2c_write8(I2C_PORT_USB_MUX, i2c_addr, reg, val); + return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); } -static int ps874x_init(int i2c_addr) +static int ps874x_init(int port) { int val; int res; /* Reset chip back to power-on state */ - res = ps874x_write(i2c_addr, PS874X_REG_MODE, PS874X_MODE_POWER_DOWN); + res = ps874x_write(port, PS874X_REG_MODE, PS874X_MODE_POWER_DOWN); if (res) return res; /* * Verify revision / chip ID registers. */ - res = ps874x_read(i2c_addr, PS874X_REG_REVISION_ID1, &val); + res = ps874x_read(port, PS874X_REG_REVISION_ID1, &val); if (res) return res; @@ -50,19 +50,19 @@ static int ps874x_init(int i2c_addr) return EC_ERROR_UNKNOWN; #endif - res = ps874x_read(i2c_addr, PS874X_REG_REVISION_ID2, &val); + res = ps874x_read(port, PS874X_REG_REVISION_ID2, &val); if (res) return res; if (val != PS874X_REVISION_ID2) return EC_ERROR_UNKNOWN; - res = ps874x_read(i2c_addr, PS874X_REG_CHIP_ID1, &val); + res = ps874x_read(port, PS874X_REG_CHIP_ID1, &val); if (res) return res; if (val != PS874X_CHIP_ID1) return EC_ERROR_UNKNOWN; - res = ps874x_read(i2c_addr, PS874X_REG_CHIP_ID2, &val); + res = ps874x_read(port, PS874X_REG_CHIP_ID2, &val); if (res) return res; if (val != PS874X_CHIP_ID2) @@ -72,7 +72,7 @@ static int ps874x_init(int i2c_addr) } /* Writes control register to set switch mode */ -static int ps874x_set_mux(int i2c_addr, mux_state_t mux_state) +static int ps874x_set_mux(int port, mux_state_t mux_state) { uint8_t reg = 0; @@ -83,16 +83,16 @@ static int ps874x_set_mux(int i2c_addr, mux_state_t mux_state) if (mux_state & MUX_POLARITY_INVERTED) reg |= PS874X_MODE_POLARITY_INVERTED; - return ps874x_write(i2c_addr, PS874X_REG_MODE, reg); + return ps874x_write(port, PS874X_REG_MODE, reg); } /* Reads control register and updates mux_state accordingly */ -static int ps874x_get_mux(int i2c_addr, mux_state_t *mux_state) +static int ps874x_get_mux(int port, mux_state_t *mux_state) { int reg; int res; - res = ps874x_read(i2c_addr, PS874X_REG_STATUS, ®); + res = ps874x_read(port, PS874X_REG_STATUS, ®); if (res) return res; @@ -108,12 +108,12 @@ static int ps874x_get_mux(int i2c_addr, mux_state_t *mux_state) } /* Tune USB Tx/Rx Equalization */ -int ps874x_tune_usb_eq(int i2c_addr, uint8_t tx, uint8_t rx) +int ps874x_tune_usb_eq(int port, uint8_t tx, uint8_t rx) { int ret; - ret = ps874x_write(i2c_addr, PS874X_REG_USB_EQ_TX, tx); - ret |= ps874x_write(i2c_addr, PS874X_REG_USB_EQ_RX, rx); + ret = ps874x_write(port, PS874X_REG_USB_EQ_TX, tx); + ret |= ps874x_write(port, PS874X_REG_USB_EQ_RX, rx); return ret; } diff --git a/include/config.h b/include/config.h index 6d8cf67d6e..935206e426 100644 --- a/include/config.h +++ b/include/config.h @@ -3195,14 +3195,6 @@ */ #undef CONFIG_USB_PD_TCPM_MUX -/* - * Use this option if any TCPC/MUX chip is only being used as a mux and the - * board's tcpc_config_t does not specify the chip. When this option is defined, - * all TPCPI mux drivers must use the MUX_PORT_AND_ADDR define to pack the port - * and address together. - */ -#undef CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY - /* * The TCPM must know whether VBUS is present in order to make proper state * transitions. In addition, charge_manager must know about VBUS presence in diff --git a/include/usb_mux.h b/include/usb_mux.h index 8944c4b774..7c3f5ae55f 100644 --- a/include/usb_mux.h +++ b/include/usb_mux.h @@ -9,6 +9,7 @@ #define __CROS_EC_USB_MUX_H #include "ec_commands.h" +#include "tcpm.h" #include "usb_charge.h" #include "usb_pd.h" @@ -20,10 +21,13 @@ */ typedef uint8_t mux_state_t; -/* Packing and Unpacking defines used with CONFIG_USB_PD_TCPM_TCPCI_MUX_ONLY */ +/* + * Packing and Unpacking defines used with USB_MUX_FLAG_NOT_TCPC + * MUX_PORT takes in a USB-C port number and returns the I2C port number + */ #define MUX_PORT_AND_ADDR(port, addr) ((port << 8) | (addr & 0xFF)) -#define MUX_PORT(port_addr) (port_addr >> 8) -#define MUX_ADDR(port_addr) (port_addr & 0xFF) +#define MUX_PORT(port) (usb_muxes[port].port_addr >> 8) +#define MUX_ADDR(port) (usb_muxes[port].port_addr & 0xFF) /* Mux state attributes */ /* TODO: Directly use USB_PD_MUX_* everywhere and remove these 3 defines */ @@ -46,28 +50,28 @@ struct usb_mux_driver { * Initialize USB mux. This is called every time the MUX is access after * being put in a fully disconnected state (low power mode). * - * @param port_addr Port/address driver-defined parameter. + * @param port usb port of mux (not port_addr) * @return EC_SUCCESS on success, non-zero error code on failure. */ - int (*init)(int port_addr); + int (*init)(int port); /** * Set USB mux state. * - * @param port_addr Port/address driver-defined parameter. + * @param port usb port of mux (not port_addr) * @param mux_state State to set mux to. * @return EC_SUCCESS on success, non-zero error code on failure. */ - int (*set)(int port_addr, mux_state_t mux_state); + int (*set)(int port, mux_state_t mux_state); /** * Get current state of USB mux. * - * @param port_addr Port / address driver-defined parameter. + * @param port usb port of mux (not port_addr) * @param mux_state Gets set to current state of mux. * @return EC_SUCCESS on success, non-zero error code on failure. */ - int (*get)(int port_addr, mux_state_t *mux_state); + int (*get)(int port, mux_state_t *mux_state); /** * Optional method that is called after the mux fully disconnects. @@ -76,12 +80,15 @@ struct usb_mux_driver { * where the TCPC is actively used since the PD state machine * will put the chip into lower power mode. * - * @param mux USB mux to put into low power. + * @param port usb port of mux (not port_addr) * @return EC_SUCCESS on success, non-zero error code on failure. */ - int (*enter_low_power_mode)(int port_addr); + int (*enter_low_power_mode)(int port); }; +/* Flags used for usb_mux.flags */ +#define USB_MUX_FLAG_NOT_TCPC (1 << 0) /* TCPC/MUX device used only as MUX */ + /* Describes a USB mux present in the system */ struct usb_mux { /* @@ -90,16 +97,19 @@ struct usb_mux { */ const int port_addr; + /* Run-time flags with prefix USB_MUX_FLAG_ */ + const uint32_t flags; + /* Mux driver */ const struct usb_mux_driver *driver; /** * Optional method for tuning for USB mux during mux->driver->init(). * - * @param mux USB mux to tune + * @param port usb port of mux (not port_addr) * @return EC_SUCCESS on success, non-zero error code on failure. */ - int (*board_init)(const struct usb_mux *mux); + int (*board_init)(int port); /* * USB Type-C DP alt mode support. Notify Type-C controller @@ -122,6 +132,40 @@ void virtual_hpd_update(int port, int hpd_lvl, int hpd_irq); /* USB muxes present in system, ordered by PD port #, defined at board-level */ extern struct usb_mux usb_muxes[]; +/* + * Helper methods that either use tcpc communication or direct i2c + * communication depending on how the TCPC/MUX device is configured. + */ +#ifdef CONFIG_USB_PD_TCPM_MUX +static inline int mux_write(int port, int reg, int val) +{ + return usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC + ? i2c_write8(MUX_PORT(port), MUX_ADDR(port), reg, val) + : tcpc_write(port, reg, val); +} + +static inline int mux_read(int port, int reg, int *val) +{ + return usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC + ? i2c_read8(MUX_PORT(port), MUX_ADDR(port), reg, val) + : tcpc_read(port, reg, val); +} + +static inline int mux_write16(int port, int reg, int val) +{ + return usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC + ? i2c_write16(MUX_PORT(port), MUX_ADDR(port), reg, val) + : tcpc_write16(port, reg, val); +} + +static inline int mux_read16(int port, int reg, int *val) +{ + return usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC + ? i2c_read16(MUX_PORT(port), MUX_ADDR(port), reg, val) + : tcpc_read16(port, reg, val); +} +#endif /* CONFIG_USB_PD_TCPM_MUX */ + /** * Initialize USB mux to its default state. * -- cgit v1.2.1