summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2020-02-21 14:21:05 -0700
committerCommit Bot <commit-bot@chromium.org>2020-02-28 22:47:11 +0000
commit9c194fd057558a1dfadee419e92aca31953a86fc (patch)
tree001ae7c162a4152312a180574ae58e19a3763eb8
parentab35b456ad8c52f336ea793b17155cfc796c4e44 (diff)
downloadchrome-ec-9c194fd057558a1dfadee419e92aca31953a86fc.tar.gz
usb_mux: retimer: mux as chained mux and retimer
This makes retimers appear as generic muxes. By allowing a chain of muxes they can be stacked up to the new configurations that zork requires and will continue to work as they did before on configurations that only have a single mux. The code used to have two different arrays, 1) muxes and 2) retimers. On one of the zork configurations the processor MUX stopped being the primary mux and the retimer took its place. In a different configuration of that same platform it left the primary and secondary alone but the mux_set FLIP operation had to be ignored. Since the same interfaces needed to be available for both it stopped making sense to have two different structures and two different methods of handling them. This consolodates the two into one. The platforms that do not have retimers, this change will not make any difference. For platforms like zork, it will remove the retimers and make them chained muxes. So testing on trembyle makes sense to verify, BUG=b:147593660 BRANCH=none TEST=verify USB still works on trembyle Change-Id: I286cf1e302f9bd3dd7e81098ec08514a2a009fe3 Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2066794 Commit-Queue: Jett Rink <jettrink@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--baseboard/dragonegg/baseboard.c6
-rw-r--r--baseboard/grunt/baseboard.c18
-rw-r--r--baseboard/grunt/usb_pd_policy.c4
-rw-r--r--baseboard/intelrvp/retimer.c15
-rw-r--r--baseboard/intelrvp/usb_mux.c44
-rw-r--r--baseboard/kalista/baseboard.c17
-rw-r--r--baseboard/kukui/usb_pd_policy.c12
-rw-r--r--baseboard/octopus/baseboard.c9
-rw-r--r--baseboard/octopus/variant_usbc_ec_tcpcs.c15
-rw-r--r--baseboard/octopus/variant_usbc_standalone_tcpcs.c8
-rw-r--r--baseboard/volteer/baseboard.c24
-rw-r--r--baseboard/volteer/baseboard.h3
-rw-r--r--baseboard/zork/baseboard.c175
-rw-r--r--baseboard/zork/baseboard.h2
-rw-r--r--baseboard/zork/usb_pd_policy.c10
-rw-r--r--board/akemi/board.c4
-rw-r--r--board/ampton/board.c20
-rw-r--r--board/ampton/board.h2
-rw-r--r--board/atlas/board.c13
-rw-r--r--board/chell/board.c8
-rw-r--r--board/cheza/board.c45
-rw-r--r--board/cheza/usb_pd_policy.c3
-rw-r--r--board/coral/board.c17
-rw-r--r--board/damu/board.c10
-rw-r--r--board/dratini/board.c4
-rw-r--r--board/elm/board.c3
-rw-r--r--board/eve/board.c13
-rw-r--r--board/fizz/board.c15
-rw-r--r--board/flapjack/board.c3
-rw-r--r--board/flapjack/usb_pd_policy.c11
-rw-r--r--board/glados/board.c9
-rw-r--r--board/glkrvp/chg_usb_pd.c10
-rw-r--r--board/glkrvp_ite/chg_usb_pd.c10
-rw-r--r--board/hatch/board.c4
-rw-r--r--board/helios/board.c4
-rw-r--r--board/jacuzzi/board.c10
-rw-r--r--board/jinlon/board.c4
-rw-r--r--board/kakadu/board.c9
-rw-r--r--board/kappa/board.c10
-rw-r--r--board/kindred/board.c4
-rw-r--r--board/kodama/board.c9
-rw-r--r--board/kohaku/board.c4
-rw-r--r--board/kukui/board.c7
-rw-r--r--board/kukui/board.h1
-rw-r--r--board/mchpevb1/board.c9
-rw-r--r--board/mushu/board.c4
-rw-r--r--board/nami/board.c14
-rw-r--r--board/nami/board.h1
-rw-r--r--board/nautilus/board.c13
-rw-r--r--board/nocturne/board.c4
-rw-r--r--board/oak/board.c20
-rw-r--r--board/pdeval-stm32f072/usb_pd_policy.c20
-rw-r--r--board/poppy/board.c13
-rw-r--r--board/puff/board.c3
-rw-r--r--board/rainier/board.c3
-rw-r--r--board/rammus/board.c12
-rw-r--r--board/reef/board.c17
-rw-r--r--board/reef_it8320/board.c23
-rw-r--r--board/reef_mchp/board.c17
-rw-r--r--board/samus_pd/usb_mux.c14
-rw-r--r--board/scarlet/board.c3
-rw-r--r--board/strago/board.c7
-rw-r--r--board/stryke/board.c4
-rw-r--r--board/trogdor/board.c13
-rw-r--r--board/trogdor/usb_pd_policy.c7
-rw-r--r--board/waddledoo/board.c28
-rw-r--r--common/mock/usb_mux_mock.c8
-rw-r--r--driver/retimer/bb_retimer.c56
-rw-r--r--driver/retimer/bb_retimer.h2
-rw-r--r--driver/retimer/nb7v904m.c53
-rw-r--r--driver/retimer/nb7v904m.h2
-rw-r--r--driver/retimer/pi3dpx1207.c31
-rw-r--r--driver/retimer/pi3dpx1207.h2
-rw-r--r--driver/retimer/ps8802.c129
-rw-r--r--driver/retimer/ps8802.h17
-rw-r--r--driver/retimer/ps8818.c71
-rw-r--r--driver/retimer/ps8818.h14
-rw-r--r--driver/tcpm/anx7447.c66
-rw-r--r--driver/tcpm/anx7447.h5
-rw-r--r--driver/tcpm/anx74xx.c70
-rw-r--r--driver/tcpm/anx74xx.h5
-rw-r--r--driver/tcpm/anx7688.c8
-rw-r--r--driver/tcpm/ps8xxx.c39
-rw-r--r--driver/tcpm/ps8xxx.h4
-rw-r--r--driver/tcpm/tcpci.c31
-rw-r--r--driver/tcpm/tcpci.h8
-rw-r--r--driver/usb_mux/amd_fp5.c36
-rw-r--r--driver/usb_mux/amd_fp5.h3
-rw-r--r--driver/usb_mux/anx7440.c24
-rw-r--r--driver/usb_mux/it5205.c28
-rw-r--r--driver/usb_mux/pi3usb3x532.c30
-rw-r--r--driver/usb_mux/ps874x.c35
-rw-r--r--driver/usb_mux/usb_mux.c156
-rw-r--r--driver/usb_mux/virtual.c14
-rw-r--r--include/config.h25
-rw-r--r--include/usb_mux.h197
-rw-r--r--test/usb_pd_int.c2
-rw-r--r--test/usb_typec_drp_acc_trysrc.c2
-rw-r--r--util/ectool.c2
99 files changed, 1051 insertions, 1001 deletions
diff --git a/baseboard/dragonegg/baseboard.c b/baseboard/dragonegg/baseboard.c
index 85c39296f6..aa2ee875b7 100644
--- a/baseboard/dragonegg/baseboard.c
+++ b/baseboard/dragonegg/baseboard.c
@@ -200,19 +200,21 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ITE_0] = {
+ .usb_port = USB_PD_PORT_ITE_0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USB_PD_PORT_ITE_1] = {
+ .usb_port = USB_PD_PORT_ITE_1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USB_PD_PORT_TUSB422_2] = {
- .port_addr = 0,
+ .usb_port = USB_PD_PORT_TUSB422_2,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
diff --git a/baseboard/grunt/baseboard.c b/baseboard/grunt/baseboard.c
index 5ab7dc8d53..82bf063bf9 100644
--- a/baseboard/grunt/baseboard.c
+++ b/baseboard/grunt/baseboard.c
@@ -135,8 +135,6 @@ void tcpc_alert_event(enum gpio_signal signal)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -157,11 +155,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
@@ -280,28 +275,31 @@ void board_reset_pd_mcu(void)
static uint32_t sku_id;
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* Tune USB mux registers for treeya's port 1 Rx measurement */
if ((sku_id >= 0xa0) && (sku_id <= 0xaf))
- mux_write(port, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
+ mux_write(me, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
#ifdef VARIANT_GRUNT_TCPC_0_ANX3429
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
#elif defined(VARIANT_GRUNT_TCPC_0_ANX3447)
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
#endif
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
diff --git a/baseboard/grunt/usb_pd_policy.c b/baseboard/grunt/usb_pd_policy.c
index 4edee5f232..0d2e41b64a 100644
--- a/baseboard/grunt/usb_pd_policy.c
+++ b/baseboard/grunt/usb_pd_policy.c
@@ -129,8 +129,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
/* Connect the SBU and USB lines to the connector. */
ppc_set_sbu(port, 1);
usb_mux_set(port, svdm_dp_mux_mode(port), USB_SWITCH_CONNECT,
@@ -144,7 +142,7 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- mux->hpd_update(port, 1, 0);
+ usb_mux_hpd_update(port, 1, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/baseboard/intelrvp/retimer.c b/baseboard/intelrvp/retimer.c
index a444806062..0397057641 100644
--- a/baseboard/intelrvp/retimer.c
+++ b/baseboard/intelrvp/retimer.c
@@ -29,19 +29,4 @@ const struct bb_usb_control bb_controls[] = {
};
BUILD_ASSERT(ARRAY_SIZE(bb_controls) == CONFIG_USB_PD_PORT_MAX_COUNT);
-struct usb_retimer usb_retimers[] = {
- [TYPE_C_PORT_0] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT0_BB_RETIMER,
- .i2c_addr_flags = I2C_PORT0_BB_RETIMER_ADDR,
- },
-#ifdef HAS_TASK_PD_C1
- [TYPE_C_PORT_1] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT1_BB_RETIMER,
- .i2c_addr_flags = I2C_PORT1_BB_RETIMER_ADDR,
- },
-#endif /* HAS_TASK_PD_C1 */
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == CONFIG_USB_PD_PORT_MAX_COUNT);
#endif /* CONFIG_USBC_RETIMER_INTEL_BB */
diff --git a/baseboard/intelrvp/usb_mux.c b/baseboard/intelrvp/usb_mux.c
index 2dee2bf759..644ae1735c 100644
--- a/baseboard/intelrvp/usb_mux.c
+++ b/baseboard/intelrvp/usb_mux.c
@@ -7,20 +7,46 @@
#include "common.h"
#include "anx7440.h"
+#include "bb_retimer.h"
#include "timer.h"
#include "usb_mux.h"
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+struct usb_mux usbc0_retimer = {
+ .usb_port = TYPE_C_PORT_0,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT0_BB_RETIMER,
+ .i2c_addr_flags = I2C_PORT0_BB_RETIMER_ADDR,
+};
+#ifdef HAS_TASK_PD_C1
+struct usb_mux usbc1_retimer = {
+ .usb_port = TYPE_C_PORT_1,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT1_BB_RETIMER,
+ .i2c_addr_flags = I2C_PORT1_BB_RETIMER_ADDR,
+};
+#endif /* HAS_TASK_PD_C1 */
+#endif
+
/* USB muxes Configuration */
#ifdef CONFIG_USB_MUX_VIRTUAL
-struct usb_mux usb_muxes[] = {
+const struct usb_mux usb_muxes[] = {
[TYPE_C_PORT_0] = {
+ .usb_port = TYPE_C_PORT_0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc0_retimer,
+#endif
},
#ifdef HAS_TASK_PD_C1
[TYPE_C_PORT_1] = {
+ .usb_port = TYPE_C_PORT_1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc1_retimer,
+#endif
},
#endif /* HAS_TASK_PD_C1 */
};
@@ -28,15 +54,25 @@ BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == CONFIG_USB_PD_PORT_MAX_COUNT);
#endif /* CONFIG_USB_MUX_VIRTUAL */
#ifdef CONFIG_USB_MUX_ANX7440
-struct usb_mux usb_muxes[] = {
+const struct usb_mux usb_muxes[] = {
[TYPE_C_PORT_0] = {
- .port_addr = I2C_ADDR_USB_MUX0_FLAGS,
+ .usb_port = TYPE_C_PORT_0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = I2C_ADDR_USB_MUX0_FLAGS,
.driver = &anx7440_usb_mux_driver,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc0_retimer,
+#endif
},
#ifdef HAS_TASK_PD_C1
[TYPE_C_PORT_1] = {
- .port_addr = I2C_ADDR_USB_MUX1_FLAGS,
+ .usb_port = TYPE_C_PORT_1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = I2C_ADDR_USB_MUX1_FLAGS,
.driver = &anx7440_usb_mux_driver,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc1_retimer,
+#endif
},
#endif /* HAS_TASK_PD_C1 */
};
diff --git a/baseboard/kalista/baseboard.c b/baseboard/kalista/baseboard.c
index 859962b07c..6592033c83 100644
--- a/baseboard/kalista/baseboard.c
+++ b/baseboard/kalista/baseboard.c
@@ -150,19 +150,20 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (4.5db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
- }
+ },
};
const int usb_port_enable[USB_PORT_COUNT] = {
@@ -181,7 +182,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* This needs to be executed only once per boot. It could be run by RO
* if we boot in recovery mode. It could be run by RW if we boot in
@@ -202,10 +203,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/baseboard/kukui/usb_pd_policy.c b/baseboard/kukui/usb_pd_policy.c
index 0925c1b329..b2d56e23b2 100644
--- a/baseboard/kukui/usb_pd_policy.c
+++ b/baseboard/kukui/usb_pd_policy.c
@@ -179,8 +179,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
dp_flags[port] |= DP_FLAGS_DP_ON;
if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
return;
@@ -192,7 +190,8 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- mux->hpd_update(port, 1, 0);
+
+ usb_mux_hpd_update(port, 1, 0);
}
__override int svdm_dp_attention(int port, uint32_t *payload)
@@ -200,7 +199,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
int cur_lvl = gpio_get_level(GPIO_USB_C0_HPD_OD);
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
- const struct usb_mux * const mux = &usb_muxes[port];
dp_status[port] = payload[1];
@@ -211,7 +209,7 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
return 1;
}
- mux->hpd_update(port, lvl, irq);
+ usb_mux_hpd_update(port, lvl, irq);
if (irq & cur_lvl) {
uint64_t now = get_time().val;
@@ -250,13 +248,11 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
svdm_safe_dp_mode(port);
gpio_set_level(GPIO_USB_C0_HPD_OD, 0);
#ifdef VARIANT_KUKUI_DP_MUX_GPIO
board_set_dp_mux_control(0, 0);
#endif
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/baseboard/octopus/baseboard.c b/baseboard/octopus/baseboard.c
index cd9296cd19..ceb32868a0 100644
--- a/baseboard/octopus/baseboard.c
+++ b/baseboard/octopus/baseboard.c
@@ -216,8 +216,6 @@ enum adc_channel board_get_vbus_adc(int port)
void baseboard_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -226,11 +224,8 @@ void baseboard_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
/* Called after the cbi_init (via +2) */
DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_I2C + 2);
diff --git a/baseboard/octopus/variant_usbc_ec_tcpcs.c b/baseboard/octopus/variant_usbc_ec_tcpcs.c
index a247ef6452..cbc5fd79e0 100644
--- a/baseboard/octopus/variant_usbc_ec_tcpcs.c
+++ b/baseboard/octopus/variant_usbc_ec_tcpcs.c
@@ -48,9 +48,10 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
/* USB-C MUX Configuration */
/* TODO(crbug.com/826441): Consolidate this logic with other impls */
-static void board_it83xx_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_it83xx_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
- enum gpio_signal gpio = port ?
+ enum gpio_signal gpio = me->usb_port ?
GPIO_USB_C1_HPD_1V8_ODL : GPIO_USB_C0_HPD_1V8_ODL;
/* Invert HPD level since GPIOs are active low. */
@@ -67,15 +68,17 @@ static void board_it83xx_hpd_status(int port, int hpd_lvl, int hpd_irq)
/* This configuration might be override by each boards */
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ITE_0] = {
- /* Driver uses I2C_PORT_USB_MUX as I2C port */
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = USB_PD_PORT_ITE_0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_it83xx_hpd_status,
},
[USB_PD_PORT_ITE_1] = {
+ .usb_port = USB_PD_PORT_ITE_1,
/* Use PS8751 as mux only */
- .port_addr = MUX_PORT_AND_ADDR(
- I2C_PORT_USBC1, PS8751_I2C_ADDR1_FLAGS),
+ .i2c_port = I2C_PORT_USBC1,
+ .i2c_addr_flags = PS8751_I2C_ADDR1_FLAGS,
.flags = USB_MUX_FLAG_NOT_TCPC,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
diff --git a/baseboard/octopus/variant_usbc_standalone_tcpcs.c b/baseboard/octopus/variant_usbc_standalone_tcpcs.c
index 41025de7fa..18a8a3035a 100644
--- a/baseboard/octopus/variant_usbc_standalone_tcpcs.c
+++ b/baseboard/octopus/variant_usbc_standalone_tcpcs.c
@@ -61,16 +61,17 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
/* USB-C MUX Configuration */
#if defined(VARIANT_OCTOPUS_TCPC_0_PS8751)
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* Tune USB mux registers for casta's port 0 Rx measurement */
- mux_write(port, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
+ mux_write(me, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
return EC_SUCCESS;
}
#endif
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
#if defined(VARIANT_OCTOPUS_TCPC_0_PS8751)
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
@@ -81,6 +82,7 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
#endif
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/baseboard/volteer/baseboard.c b/baseboard/volteer/baseboard.c
index 53b3a0d146..24e08b514b 100644
--- a/baseboard/volteer/baseboard.c
+++ b/baseboard/volteer/baseboard.c
@@ -396,14 +396,23 @@ unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
/******************************************************************************/
/* USBC mux configuration - Tiger Lake includes internal mux */
+struct usb_mux usbc1_usb_retimer = {
+ .usb_port = USBC_PORT_C1,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT_USB_1_MIX,
+ .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR,
+};
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
+ .usb_port = USBC_PORT_C0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USBC_PORT_C1] = {
+ .usb_port = USBC_PORT_C1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+ .next_mux = &usbc1_usb_retimer,
},
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
@@ -421,18 +430,6 @@ struct bb_usb_control bb_controls[] = {
};
BUILD_ASSERT(ARRAY_SIZE(bb_controls) == USBC_PORT_COUNT);
-struct usb_retimer usb_retimers[] = {
- [USBC_PORT_C0] = {
- /* USB-C port 0 doesn't have a retimer */
- },
- [USBC_PORT_C1] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT_USB_1_MIX,
- .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR,
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == USBC_PORT_COUNT);
-
static void baseboard_tcpc_init(void)
{
/* Only reset TCPC if not sysjump */
@@ -660,8 +657,7 @@ static void config_db_usb3(void)
{
tcpc_config[USBC_PORT_C1] = tcpc_config_p1_usb3;
/* USB-C port 1 has an integrated retimer */
- memset(&usb_retimers[USBC_PORT_C1], 0,
- sizeof(usb_retimers[USBC_PORT_C1]));
+ usb_muxes[USBC_PORT_C1].next_mux = NULL;
}
/*
diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h
index 0f53a0eb65..a9d1816fea 100644
--- a/baseboard/volteer/baseboard.h
+++ b/baseboard/volteer/baseboard.h
@@ -184,6 +184,8 @@
#define CONFIG_USB_PD_VBUS_DETECT_PPC
#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
+
#define CONFIG_USBC_PPC
#define CONFIG_CMD_PPC_DUMP
/* Note - SN5S330 support automatically adds
@@ -224,7 +226,6 @@
#define PD_VCONN_SWAP_DELAY 5000 /* us */
/* Retimer */
-#define CONFIG_USBC_MUX_RETIMER
#define CONFIG_USBC_RETIMER_INTEL_BB
#define CONFIG_USBC_RETIMER_INTEL_BB_RUNTIME_CONFIG
#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x40
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c
index f64a911f94..69a61681ff 100644
--- a/baseboard/zork/baseboard.c
+++ b/baseboard/zork/baseboard.c
@@ -23,7 +23,6 @@
#include "driver/retimer/pi3dpx1207.h"
#include "driver/retimer/ps8802.h"
#include "driver/retimer/ps8818.h"
-#include "driver/tcpm/ps8xxx.h"
#include "driver/tcpm/nct38xx.h"
#include "driver/temp_sensor/sb_tsi.h"
#include "driver/usb_mux/amd_fp5.h"
@@ -440,19 +439,19 @@ void bc12_interrupt(enum gpio_signal signal)
* PS8802 set mux tuning.
* Adds in board specific gain and DP lane count configuration
*/
-static int ps8802_tune_mux(int port, mux_state_t mux_state)
+static int ps8802_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
int rv = EC_SUCCESS;
/* Make sure the PS8802 is awake */
- rv = ps8802_i2c_wake(port);
+ rv = ps8802_i2c_wake(me);
if (rv)
return rv;
/* USB specific config */
if (mux_state & USB_PD_MUX_USB_ENABLED) {
/* Boost the USB gain */
- rv = ps8802_i2c_field_update16(port,
+ rv = ps8802_i2c_field_update16(me,
PS8802_REG_PAGE2,
PS8802_REG2_USB_SSEQ_LEVEL,
PS8802_USBEQ_LEVEL_UP_MASK,
@@ -464,7 +463,7 @@ static int ps8802_tune_mux(int port, mux_state_t mux_state)
/* DP specific config */
if (mux_state & USB_PD_MUX_DP_ENABLED) {
/* Boost the DP gain */
- rv = ps8802_i2c_field_update8(port,
+ rv = ps8802_i2c_field_update8(me,
PS8802_REG_PAGE2,
PS8802_REG2_DPEQ_LEVEL,
PS8802_DPEQ_LEVEL_UP_MASK,
@@ -486,14 +485,14 @@ static int ps8802_tune_mux(int port, mux_state_t mux_state)
* PS8818 set mux tuning.
* Adds in board specific gain and DP lane count configuration
*/
-static int ps8818_tune_mux(int port, mux_state_t mux_state)
+static int ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
int rv = EC_SUCCESS;
/* USB specific config */
if (mux_state & USB_PD_MUX_USB_ENABLED) {
/* Boost the USB gain */
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX1EQ_10G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -501,7 +500,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX2EQ_10G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -509,7 +508,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX1EQ_5G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -517,7 +516,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX2EQ_5G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -529,7 +528,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
/* DP specific config */
if (mux_state & USB_PD_MUX_DP_ENABLED) {
/* Boost the DP gain */
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_DPEQ_LEVEL,
PS8818_DPEQ_LEVEL_UP_MASK,
@@ -548,47 +547,15 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
}
/*
- * FP5 is a true MUX but being used as a secondary MUX. Don't want to
- * send FLIP or this will cause a double flip
- */
-static int zork_c1_retimer_set_mux(int port, mux_state_t mux_state)
-{
- return amd_fp5_usb_retimer.set(port,
- mux_state & ~USB_PD_MUX_POLARITY_INVERTED);
-}
-
-const struct usb_retimer_driver zork_c1_usb_retimer = {
- /* Secondary MUX/Retimer only needs the set mux interface */
- .set = zork_c1_retimer_set_mux,
-};
-
-struct usb_retimer usb_retimers[] = {
- [USBC_PORT_C0] = {
- .driver = &pi3dpx1207_usb_retimer,
- .i2c_port = I2C_PORT_TCPC0,
- .i2c_addr_flags = PI3DPX1207_I2C_ADDR_FLAGS,
- },
- [USBC_PORT_C1] = {
- /*
- * The driver is left off until we detect the
- * hardware present. Once the hardware has been
- * detected, the driver will be set to the
- * detected hardware driver table.
- */
- .i2c_port = I2C_PORT_TCPC1,
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == USBC_PORT_COUNT);
-
-/*
* To support both OPT1 DB with PS8818 retimer, and OPT3 DB with PS8802
* retimer, Try both, and remember the first one that succeeds.
- *
- * TODO(b:147593660) Cleanup of retimers as muxes in a more
- * generalized mechanism
*/
+const struct usb_mux usbc1_ps8802;
+const struct usb_mux usbc1_ps8818;
+struct usb_mux usbc1_amd_fp5_usb_mux;
+
enum zork_c1_retimer zork_c1_retimer = C1_RETIMER_UNKNOWN;
-static int zork_c1_detect(int port, int err_if_power_off)
+static int zork_c1_detect(const struct usb_mux *me, int err_if_power_off)
{
int rv;
@@ -604,29 +571,30 @@ static int zork_c1_detect(int port, int err_if_power_off)
* Identifying a PS8818 is faster than the PS8802,
* so do it first.
*/
- usb_retimers[port].i2c_addr_flags = PS8818_I2C_ADDR_FLAGS;
- rv = ps8818_detect(port);
+ rv = ps8818_detect(&usbc1_ps8818);
if (rv == EC_SUCCESS) {
zork_c1_retimer = C1_RETIMER_PS8818;
ccprints("C1 PS8818 detected");
/* Main MUX is FP5, secondary MUX is PS8818 */
- usb_muxes[USBC_PORT_C1].driver = &amd_fp5_usb_mux_driver;
- usb_retimers[USBC_PORT_C1].driver = &ps8818_usb_retimer;
- usb_retimers[USBC_PORT_C1].tune = &ps8818_tune_mux;
+ memcpy(&usb_muxes[USBC_PORT_C1],
+ &usbc1_amd_fp5_usb_mux,
+ sizeof(struct usb_mux));
+ usb_muxes[USBC_PORT_C1].next_mux = &usbc1_ps8818;
return rv;
}
- usb_retimers[port].i2c_addr_flags = PS8802_I2C_ADDR_FLAGS;
- rv = ps8802_detect(port);
+ rv = ps8802_detect(&usbc1_ps8802);
if (rv == EC_SUCCESS) {
zork_c1_retimer = C1_RETIMER_PS8802;
ccprints("C1 PS8802 detected");
/* Main MUX is PS8802, secondary MUX is modified FP5 */
- usb_muxes[USBC_PORT_C1].driver = &ps8802_usb_mux_driver;
- usb_retimers[USBC_PORT_C1].driver = &zork_c1_usb_retimer;
- usb_retimers[USBC_PORT_C1].tune = &ps8802_tune_mux;
+ memcpy(&usb_muxes[USBC_PORT_C1],
+ &usbc1_ps8802,
+ sizeof(struct usb_mux));
+ usb_muxes[USBC_PORT_C1].next_mux = &usbc1_amd_fp5_usb_mux;
+ usbc1_amd_fp5_usb_mux.flags = USB_MUX_FLAG_SET_WITHOUT_FLIP;
}
return rv;
@@ -637,14 +605,36 @@ static int zork_c1_detect(int port, int err_if_power_off)
* the interface to be this special primary MUX driver in order to
* determine the actual hardware and then we patch the jump tables
* to go to the actual drivers instead.
+ *
+ * "me" will always point to usb_muxes[0]. If detection is made
+ * on the real device, then detect will change the tables so the
+ * content of me is the real driver configuration and will setup
+ * next_mux appropriately. So all we have to do on detection is
+ * perform the actual call for this entry and then let the generic
+ * chain traverse mechanism in usb_mux.c do any following calls.
*/
-static int zork_c1_init_mux(int port)
+static int zork_c1_init_mux(const struct usb_mux *me)
{
+ int rv;
+
/* Try to detect, but don't give an error if no power */
- return zork_c1_detect(port, 0);
+ rv = zork_c1_detect(me, 0);
+ if (rv)
+ return rv;
+
+ /*
+ * If we detected the hardware, then call the real routine.
+ * We only do this one time, after that time we will go direct
+ * and avoid this special driver.
+ */
+ if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
+ if (me->driver && me->driver->init)
+ rv = me->driver->init(me);
+
+ return rv;
}
-static int zork_c1_set_mux(int port, mux_state_t mux_state)
+static int zork_c1_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int rv;
@@ -652,7 +642,7 @@ static int zork_c1_set_mux(int port, mux_state_t mux_state)
* Try to detect, give an error if we are setting to a
* MUX value that is not NONE when we have no power.
*/
- rv = zork_c1_detect(port, mux_state != USB_PD_MUX_NONE);
+ rv = zork_c1_detect(me, mux_state != USB_PD_MUX_NONE);
if (rv)
return rv;
@@ -661,18 +651,35 @@ static int zork_c1_set_mux(int port, mux_state_t mux_state)
* We only do this one time, after that time we will go direct
* and avoid this special driver.
*/
- if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
- rv = usb_muxes[port].driver->set(port, mux_state);
+ if (zork_c1_retimer != C1_RETIMER_UNKNOWN) {
+ const struct usb_mux_driver *drv = me->driver;
+
+ if (drv && drv->set) {
+ mux_state_t state = mux_state;
+
+ if (me->flags & USB_MUX_FLAG_SET_WITHOUT_FLIP)
+ state &= ~USB_PD_MUX_POLARITY_INVERTED;
+
+ /* Apply Driver generic settings */
+ rv = drv->set(me, state);
+ if (rv)
+ return rv;
+
+ /* Apply Board specific settings */
+ if (me->board_set)
+ rv = me->board_set(me, state);
+ }
+ }
return rv;
}
-static int zork_c1_get_mux(int port, mux_state_t *mux_state)
+static int zork_c1_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int rv;
/* Try to detect the hardware */
- rv = zork_c1_detect(port, 1);
+ rv = zork_c1_detect(me, 1);
if (rv) {
/*
* Not powered is MUX_NONE, so change the values
@@ -691,7 +698,8 @@ static int zork_c1_get_mux(int port, mux_state_t *mux_state)
* and avoid this special driver.
*/
if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
- rv = usb_muxes[port].driver->get(port, mux_state);
+ if (me->driver && me->driver->get)
+ rv = me->driver->get(me, mux_state);
return rv;
}
@@ -714,9 +722,37 @@ const struct usb_mux_driver zork_c1_usb_mux_driver = {
.get = zork_c1_get_mux,
};
+const struct usb_mux usbc0_pi3dpx1207_usb_retimer = {
+ .usb_port = USBC_PORT_C0,
+ .i2c_port = I2C_PORT_TCPC0,
+ .i2c_addr_flags = PI3DPX1207_I2C_ADDR_FLAGS,
+ .driver = &pi3dpx1207_usb_retimer,
+};
+
+const struct usb_mux usbc1_ps8802 = {
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
+ .i2c_addr_flags = PS8802_I2C_ADDR_FLAGS,
+ .driver = &ps8802_usb_mux_driver,
+ .board_set = &ps8802_mux_set,
+};
+const struct usb_mux usbc1_ps8818 = {
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
+ .i2c_addr_flags = PS8818_I2C_ADDR_FLAGS,
+ .driver = &ps8818_usb_retimer_driver,
+ .board_set = &ps8818_mux_set,
+};
+struct usb_mux usbc1_amd_fp5_usb_mux = {
+ .usb_port = USBC_PORT_C1,
+ .driver = &amd_fp5_usb_mux_driver,
+};
+
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
+ .usb_port = USBC_PORT_C0,
.driver = &amd_fp5_usb_mux_driver,
+ .next_mux = &usbc0_pi3dpx1207_usb_retimer,
},
[USBC_PORT_C1] = {
/*
@@ -724,11 +760,14 @@ struct usb_mux usb_muxes[] = {
* has been detected, the driver will change to the
* detected hardware driver table.
*/
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
.driver = &zork_c1_usb_mux_driver,
- },
+ }
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
+
struct ioexpander_config_t ioex_config[] = {
[USBC_PORT_C0] = {
.i2c_host_port = I2C_PORT_TCPC0,
diff --git a/baseboard/zork/baseboard.h b/baseboard/zork/baseboard.h
index 61719b012c..b51f42b683 100644
--- a/baseboard/zork/baseboard.h
+++ b/baseboard/zork/baseboard.h
@@ -133,6 +133,7 @@
#define CONFIG_CMD_PD_CONTROL
#define CONFIG_USB_CHARGER
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
#define CONFIG_USB_PD_ALT_MODE_DFP
@@ -147,7 +148,6 @@
#define CONFIG_USB_PD_TCPC_LOW_POWER
#define CONFIG_USB_PD_TCPM_MUX
#define CONFIG_USB_PD_TCPM_NCT38XX
-#define CONFIG_USB_PD_TCPM_PS8751
#define CONFIG_USB_PD_TCPM_TCPCI
#define CONFIG_USB_PD_TRY_SRC
#define CONFIG_USB_PD_VBUS_DETECT_TCPC
diff --git a/baseboard/zork/usb_pd_policy.c b/baseboard/zork/usb_pd_policy.c
index 66433f9ac0..26cc885479 100644
--- a/baseboard/zork/usb_pd_policy.c
+++ b/baseboard/zork/usb_pd_policy.c
@@ -136,8 +136,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
/* Connect the SBU and USB lines to the connector. */
ppc_set_sbu(port, 1);
usb_mux_set(port, svdm_dp_mux_mode(port), USB_SWITCH_CONNECT,
@@ -152,14 +150,11 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- if (mux->hpd_update)
- mux->hpd_update(port, 1, 0);
+ usb_mux_hpd_update(port, 1, 0);
}
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
dp_flags[port] = 0;
dp_status[port] = 0;
@@ -167,7 +162,6 @@ __override void svdm_exit_dp_mode(int port)
pd_get_polarity(port));
gpio_set_level(PORT_TO_HPD(port), 0);
- if (mux->hpd_update)
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/board/akemi/board.c b/board/akemi/board.c
index c2f6b14d76..ad5fce6d71 100644
--- a/board/akemi/board.c
+++ b/board/akemi/board.c
@@ -141,12 +141,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/ampton/board.c b/board/ampton/board.c
index df151c8918..4f1f0880df 100644
--- a/board/ampton/board.c
+++ b/board/ampton/board.c
@@ -66,13 +66,14 @@ int ppc_get_alert_status(int port)
#define USB_PD_PORT_ITE_0 0
#define USB_PD_PORT_ITE_1 1
-static int tune_mux(int port);
+static int tune_mux(const struct usb_mux *me);
-struct usb_mux ampton_usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux ampton_usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ITE_0] = {
/* Use PS8751 as mux only */
- .port_addr = MUX_PORT_AND_ADDR(
- I2C_PORT_USBC0, PS8751_I2C_ADDR1_FLAGS),
+ .usb_port = USB_PD_PORT_ITE_0,
+ .i2c_port = I2C_PORT_USBC0,
+ .i2c_addr_flags = PS8751_I2C_ADDR1_FLAGS,
.flags = USB_MUX_FLAG_NOT_TCPC,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
@@ -80,8 +81,9 @@ struct usb_mux ampton_usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
[USB_PD_PORT_ITE_1] = {
/* Use PS8751 as mux only */
- .port_addr = MUX_PORT_AND_ADDR(
- I2C_PORT_USBC1, PS8751_I2C_ADDR1_FLAGS),
+ .usb_port = USB_PD_PORT_ITE_1,
+ .i2c_port = I2C_PORT_USBC1,
+ .i2c_addr_flags = PS8751_I2C_ADDR1_FLAGS,
.flags = USB_MUX_FLAG_NOT_TCPC,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
@@ -92,12 +94,12 @@ struct usb_mux ampton_usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
/* Some external monitors can't display content normally (eg. ViewSonic VX2880).
* We need to turn the mux for monitors to function normally.
*/
-static int tune_mux(int port)
+static int tune_mux(const struct usb_mux *me)
{
/* Auto EQ disabled, compensate for channel lost up to 3.6dB */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
/* DP output swing adjustment +15% */
- mux_write(port, PS8XXX_REG_MUX_DP_OUTPUT_CONFIGURATION, 0xc0);
+ mux_write(me, PS8XXX_REG_MUX_DP_OUTPUT_CONFIGURATION, 0xc0);
return EC_SUCCESS;
}
diff --git a/board/ampton/board.h b/board/ampton/board.h
index 96b135d774..0420bc5ccf 100644
--- a/board/ampton/board.h
+++ b/board/ampton/board.h
@@ -58,6 +58,8 @@
#undef CONFIG_UART_TX_BUF_SIZE
#define CONFIG_UART_TX_BUF_SIZE 4096
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
+
#ifndef __ASSEMBLER__
#include "gpio_signal.h"
diff --git a/board/atlas/board.c b/board/atlas/board.c
index 5a0659ba97..82dc847623 100644
--- a/board/atlas/board.c
+++ b/board/atlas/board.c
@@ -189,12 +189,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
@@ -209,8 +211,6 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -222,11 +222,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/chell/board.c b/board/chell/board.c
index 7b56ca621a..1472d7e5e9 100644
--- a/board/chell/board.c
+++ b/board/chell/board.c
@@ -183,12 +183,16 @@ static int ps874x_tune_mux(int port)
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = 0x1A,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x1A,
.driver = &ps874x_usb_mux_driver,
.board_init = &ps874x_tune_mux,
},
{
- .port_addr = 0x10,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
.board_init = &ps874x_tune_mux,
}
diff --git a/board/cheza/board.c b/board/cheza/board.c
index 232f6cfc3d..855451049d 100644
--- a/board/cheza/board.c
+++ b/board/cheza/board.c
@@ -294,23 +294,23 @@ const unsigned int chg_cnt = ARRAY_SIZE(chg_chips);
* Redirect to anx74xx_tcpm_usb_mux_driver but override the get() function
* to check the HPD_IRQ mask from virtual_usb_mux_driver.
*/
-static int port0_usb_mux_init(int port)
+static int port0_usb_mux_init(const struct usb_mux *me)
{
- return anx74xx_tcpm_usb_mux_driver.init(port);
+ return anx74xx_tcpm_usb_mux_driver.init(me);
}
-static int port0_usb_mux_set(int i2c_addr, mux_state_t mux_state)
+static int port0_usb_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
- return anx74xx_tcpm_usb_mux_driver.set(i2c_addr, mux_state);
+ return anx74xx_tcpm_usb_mux_driver.set(me, mux_state);
}
-static int port0_usb_mux_get(int port, mux_state_t *mux_state)
+static int port0_usb_mux_get(const struct usb_mux *me, mux_state_t *mux_state)
{
int rv;
mux_state_t virtual_mux_state;
- rv = anx74xx_tcpm_usb_mux_driver.get(port, mux_state);
- rv |= virtual_usb_mux_driver.get(port, &virtual_mux_state);
+ rv = anx74xx_tcpm_usb_mux_driver.get(me, mux_state);
+ rv |= virtual_usb_mux_driver.get(me, &virtual_mux_state);
if (virtual_mux_state & USB_PD_MUX_HPD_IRQ)
*mux_state |= USB_PD_MUX_HPD_IRQ;
@@ -330,32 +330,32 @@ const struct usb_mux_driver port0_usb_mux_driver = {
* Redirect to tcpci_tcpm_usb_mux_driver but override the get() function
* to check the HPD_IRQ mask from virtual_usb_mux_driver.
*/
-static int port1_usb_mux_init(int port)
+static int port1_usb_mux_init(const struct usb_mux *me)
{
- return tcpci_tcpm_usb_mux_driver.init(port);
+ return tcpci_tcpm_usb_mux_driver.init(me);
}
-static int port1_usb_mux_set(int i2c_addr, mux_state_t mux_state)
+static int port1_usb_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
- return tcpci_tcpm_usb_mux_driver.set(i2c_addr, mux_state);
+ return tcpci_tcpm_usb_mux_driver.set(me, mux_state);
}
-static int port1_usb_mux_get(int port, mux_state_t *mux_state)
+static int port1_usb_mux_get(const struct usb_mux *me, mux_state_t *mux_state)
{
int rv;
mux_state_t virtual_mux_state;
- rv = tcpci_tcpm_usb_mux_driver.get(port, mux_state);
- rv |= virtual_usb_mux_driver.get(port, &virtual_mux_state);
+ rv = tcpci_tcpm_usb_mux_driver.get(me, mux_state);
+ rv |= virtual_usb_mux_driver.get(me, &virtual_mux_state);
if (virtual_mux_state & USB_PD_MUX_HPD_IRQ)
*mux_state |= USB_PD_MUX_HPD_IRQ;
return rv;
}
-static int port1_usb_mux_enter_low_power(int port)
+static int port1_usb_mux_enter_low_power(const struct usb_mux *me)
{
- return tcpci_tcpm_usb_mux_driver.enter_low_power_mode(port);
+ return tcpci_tcpm_usb_mux_driver.enter_low_power_mode(me);
}
const struct usb_mux_driver port1_usb_mux_driver = {
@@ -365,12 +365,14 @@ const struct usb_mux_driver port1_usb_mux_driver = {
.enter_low_power_mode = &port1_usb_mux_enter_low_power,
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &port0_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
{
+ .usb_port = 1,
.driver = &port1_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
}
@@ -406,8 +408,6 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image()) {
/* TODO(crosbug.com/p/61098): How long do we need to wait? */
@@ -428,11 +428,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/cheza/usb_pd_policy.c b/board/cheza/usb_pd_policy.c
index 17f75136f9..694899ab79 100644
--- a/board/cheza/usb_pd_policy.c
+++ b/board/cheza/usb_pd_policy.c
@@ -177,11 +177,10 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
int mf_pref = PD_VDO_DPSTS_MF_PREF(payload[1]);
- const struct usb_mux *mux = &usb_muxes[port];
dp_status[port] = payload[1];
- mux->hpd_update(port, lvl, irq);
+ usb_mux_hpd_update(port, lvl, irq);
if (lvl && is_dp_muxable(port)) {
/*
diff --git a/board/coral/board.c b/board/coral/board.c
index 9da7fb375a..3af03d6e0d 100644
--- a/board/coral/board.c
+++ b/board/coral/board.c
@@ -274,19 +274,21 @@ const enum gpio_signal hibernate_wake_pins[] = {
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (4.5db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
@@ -357,7 +359,7 @@ void board_reset_pd_mcu(void)
static void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
int count = 0;
/* Wait for disconnected battery to wake up */
@@ -398,11 +400,8 @@ static void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_DEFAULT);
diff --git a/board/damu/board.c b/board/damu/board.c
index 87e78c5043..92b8a43b14 100644
--- a/board/damu/board.c
+++ b/board/damu/board.c
@@ -134,7 +134,8 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -143,10 +144,11 @@ static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
host_set_single_event(EC_HOST_EVENT_USB_MUX);
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- /* Driver uses I2C_PORT_USB_MUX as I2C port */
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_status,
},
diff --git a/board/dratini/board.c b/board/dratini/board.c
index 97b6a07eab..c4670cd65c 100644
--- a/board/dratini/board.c
+++ b/board/dratini/board.c
@@ -146,12 +146,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/elm/board.c b/board/elm/board.c
index 29c1b2e510..578e7ac312 100644
--- a/board/elm/board.c
+++ b/board/elm/board.c
@@ -163,8 +163,9 @@ const struct temp_sensor_t temp_sensors[] = {
};
BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &anx7688_usb_mux_driver,
},
};
diff --git a/board/eve/board.c b/board/eve/board.c
index 452732e393..8d1b21ccd6 100644
--- a/board/eve/board.c
+++ b/board/eve/board.c
@@ -221,12 +221,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
@@ -299,8 +301,6 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -319,11 +319,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/fizz/board.c b/board/fizz/board.c
index 8461cc3ae3..b3627afa7b 100644
--- a/board/fizz/board.c
+++ b/board/fizz/board.c
@@ -185,15 +185,16 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (4.5db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
@@ -217,7 +218,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* This needs to be executed only once per boot. It could be run by RO
* if we boot in recovery mode. It could be run by RW if we boot in
@@ -238,10 +239,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/flapjack/board.c b/board/flapjack/board.c
index 0035bc01dd..3d0e08afe5 100644
--- a/board/flapjack/board.c
+++ b/board/flapjack/board.c
@@ -304,8 +304,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
.drv = &mt6370_tcpm_drv},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
diff --git a/board/flapjack/usb_pd_policy.c b/board/flapjack/usb_pd_policy.c
index 7174389dde..20de95dc3b 100644
--- a/board/flapjack/usb_pd_policy.c
+++ b/board/flapjack/usb_pd_policy.c
@@ -77,8 +77,6 @@ void pd_power_supply_reset(int port)
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
dp_flags[port] |= DP_FLAGS_DP_ON;
if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
return;
@@ -89,7 +87,7 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- mux->hpd_update(port, 1, 0);
+ usb_mux_hpd_update(port, 1, 0);
}
__override int svdm_dp_attention(int port, uint32_t *payload)
@@ -97,7 +95,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
int cur_lvl = gpio_get_level(GPIO_USB_C0_HPD_OD);
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
- const struct usb_mux * const mux = &usb_muxes[port];
dp_status[port] = payload[1];
@@ -111,7 +108,7 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
usb_mux_set(port, lvl ? USB_PD_MUX_DP_ENABLED : USB_PD_MUX_NONE,
USB_SWITCH_CONNECT, pd_get_polarity(port));
- mux->hpd_update(port, lvl, irq);
+ usb_mux_hpd_update(port, lvl, irq);
if (irq & cur_lvl) {
uint64_t now = get_time().val;
@@ -148,11 +145,9 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
svdm_safe_dp_mode(port);
gpio_set_level(GPIO_USB_C0_HPD_OD, 0);
gpio_set_level(GPIO_USB_C0_DP_OE_L, 1);
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/board/glados/board.c b/board/glados/board.c
index 2b70233631..f973e4f74b 100644
--- a/board/glados/board.c
+++ b/board/glados/board.c
@@ -166,12 +166,15 @@ BUILD_ASSERT(ARRAY_SIZE(pi3usb9281_chips) ==
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
},
{
- .port_addr = 0x10,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
}
};
diff --git a/board/glkrvp/chg_usb_pd.c b/board/glkrvp/chg_usb_pd.c
index f143dcece5..634da73a1c 100644
--- a/board/glkrvp/chg_usb_pd.c
+++ b/board/glkrvp/chg_usb_pd.c
@@ -50,13 +50,17 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == CONFIG_USB_PD_PORT_MAX_COUNT);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = 0x10,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
},
{
- .port_addr = 0x11,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x11,
.driver = &ps874x_usb_mux_driver,
},
};
diff --git a/board/glkrvp_ite/chg_usb_pd.c b/board/glkrvp_ite/chg_usb_pd.c
index 0dbf286b7e..87ff5bf6d9 100644
--- a/board/glkrvp_ite/chg_usb_pd.c
+++ b/board/glkrvp_ite/chg_usb_pd.c
@@ -50,13 +50,17 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == CONFIG_USB_PD_PORT_MAX_COUNT);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = 0x10,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
},
{
- .port_addr = 0x11,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x11,
.driver = &ps874x_usb_mux_driver,
},
};
diff --git a/board/hatch/board.c b/board/hatch/board.c
index 4e68b7d215..8060de471e 100644
--- a/board/hatch/board.c
+++ b/board/hatch/board.c
@@ -145,12 +145,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/helios/board.c b/board/helios/board.c
index dd0b2c87a3..7ab13d5734 100644
--- a/board/helios/board.c
+++ b/board/helios/board.c
@@ -167,12 +167,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/jacuzzi/board.c b/board/jacuzzi/board.c
index 7fb0f45fcc..defcebd884 100644
--- a/board/jacuzzi/board.c
+++ b/board/jacuzzi/board.c
@@ -142,7 +142,8 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -151,10 +152,11 @@ static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
host_set_single_event(EC_HOST_EVENT_USB_MUX);
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- /* Driver uses I2C_PORT_USB_MUX as I2C port */
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_status,
},
diff --git a/board/jinlon/board.c b/board/jinlon/board.c
index a9646a7794..56082fde2c 100644
--- a/board/jinlon/board.c
+++ b/board/jinlon/board.c
@@ -147,12 +147,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/kakadu/board.c b/board/kakadu/board.c
index 0a408d0c36..e6e63a9bc7 100644
--- a/board/kakadu/board.c
+++ b/board/kakadu/board.c
@@ -106,7 +106,8 @@ struct mt6370_thermal_bound thermal_bound = {
.err = 4,
};
-static void board_hpd_update(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_update(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -129,9 +130,11 @@ __override const struct rt946x_init_setting *board_rt946x_init_setting(void)
return &battery_init_setting;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_update,
},
diff --git a/board/kappa/board.c b/board/kappa/board.c
index 6f4628ab8a..b4f37975ae 100644
--- a/board/kappa/board.c
+++ b/board/kappa/board.c
@@ -138,7 +138,8 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -147,10 +148,11 @@ static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
host_set_single_event(EC_HOST_EVENT_USB_MUX);
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- /* Driver uses I2C_PORT_USB_MUX as I2C port */
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_status,
},
diff --git a/board/kindred/board.c b/board/kindred/board.c
index 308ccf2eca..fa5b064016 100644
--- a/board/kindred/board.c
+++ b/board/kindred/board.c
@@ -168,12 +168,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/kodama/board.c b/board/kodama/board.c
index abc44c43d4..03ecf1afe7 100644
--- a/board/kodama/board.c
+++ b/board/kodama/board.c
@@ -104,7 +104,8 @@ struct mt6370_thermal_bound thermal_bound = {
.err = 4,
};
-static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -128,9 +129,11 @@ __override const struct rt946x_init_setting *board_rt946x_init_setting(void)
return &battery_init_setting;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_status,
},
diff --git a/board/kohaku/board.c b/board/kohaku/board.c
index dc56f432e1..ef59e36afb 100644
--- a/board/kohaku/board.c
+++ b/board/kohaku/board.c
@@ -131,12 +131,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/kukui/board.c b/board/kukui/board.c
index 91b989aec8..5476030130 100644
--- a/board/kukui/board.c
+++ b/board/kukui/board.c
@@ -119,7 +119,8 @@ void board_set_dp_mux_control(int output_enable, int polarity)
gpio_set_level(GPIO_USB_C0_DP_POLARITY, polarity);
}
-static void board_hpd_update(int port, int hpd_lvl, int hpd_irq)
+static void board_hpd_update(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
/*
* svdm_dp_attention() did most of the work, we only need to notify
@@ -144,7 +145,9 @@ __override const struct rt946x_init_setting *board_rt946x_init_setting(void)
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_hpd_update,
},
diff --git a/board/kukui/board.h b/board/kukui/board.h
index 9b299bc02a..2057ab191a 100644
--- a/board/kukui/board.h
+++ b/board/kukui/board.h
@@ -28,6 +28,7 @@
#define CONFIG_USB_MUX_IT5205
#define CONFIG_USB_MUX_VIRTUAL
#define CONFIG_VOLUME_BUTTONS
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
/* Battery */
#ifdef BOARD_KRANE
diff --git a/board/mchpevb1/board.c b/board/mchpevb1/board.c
index 7fd2c16575..d6e8da3a02 100644
--- a/board/mchpevb1/board.c
+++ b/board/mchpevb1/board.c
@@ -389,12 +389,15 @@ BUILD_ASSERT(ARRAY_SIZE(pi3usb9281_chips) ==
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
},
{
- .port_addr = 0x10,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
}
};
diff --git a/board/mushu/board.c b/board/mushu/board.c
index 1656e4adf0..bd5d2750b3 100644
--- a/board/mushu/board.c
+++ b/board/mushu/board.c
@@ -147,12 +147,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/nami/board.c b/board/nami/board.c
index b6cbbd359d..9bbffdc755 100644
--- a/board/nami/board.c
+++ b/board/nami/board.c
@@ -252,19 +252,21 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (3.6db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
[USB_PD_PORT_ANX7447] = {
+ .usb_port = USB_PD_PORT_ANX7447,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
}
@@ -314,8 +316,6 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -331,10 +331,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 2);
diff --git a/board/nami/board.h b/board/nami/board.h
index e039f0dcb5..8159f13c7a 100644
--- a/board/nami/board.h
+++ b/board/nami/board.h
@@ -186,6 +186,7 @@
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
#define CONFIG_USBC_VCONN_SWAP
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
/* BC 1.2 charger */
diff --git a/board/nautilus/board.c b/board/nautilus/board.c
index c9897212f8..3f01a70f6c 100644
--- a/board/nautilus/board.c
+++ b/board/nautilus/board.c
@@ -166,12 +166,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
@@ -216,8 +218,6 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image()) {
board_reset_pd_mcu();
@@ -231,11 +231,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/nocturne/board.c b/board/nocturne/board.c
index 9a397d1298..3184b6293b 100644
--- a/board/nocturne/board.c
+++ b/board/nocturne/board.c
@@ -318,13 +318,15 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
diff --git a/board/oak/board.c b/board/oak/board.c
index ec871824bc..e79dc31460 100644
--- a/board/oak/board.c
+++ b/board/oak/board.c
@@ -195,24 +195,24 @@ struct als_t als[] = {
BUILD_ASSERT(ARRAY_SIZE(als) == ALS_COUNT);
#endif
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
},
-#if (BOARD_REV <= OAK_REV4)
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR1),
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+#if (BOARD_REV <= OAK_REV4)
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR1,
.driver = &pi3usb3x532_usb_mux_driver,
- },
#else
- {
- .port_addr = 0x10,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
- },
#endif
+ },
};
/**
diff --git a/board/pdeval-stm32f072/usb_pd_policy.c b/board/pdeval-stm32f072/usb_pd_policy.c
index 2f0022d211..775f8b8876 100644
--- a/board/pdeval-stm32f072/usb_pd_policy.c
+++ b/board/pdeval-stm32f072/usb_pd_policy.c
@@ -36,8 +36,9 @@ const uint32_t pd_snk_pdo[] = {
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
#if defined(CONFIG_USB_PD_TCPM_MUX) && defined(CONFIG_USB_PD_TCPM_ANX7447)
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &anx7447_usb_mux_driver,
},
};
@@ -200,6 +201,9 @@ __override int svdm_dp_config(int port, uint32_t *payload)
{
int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]);
+#if defined(CONFIG_USB_PD_TCPM_MUX) && defined(CONFIG_USB_PD_TCPM_ANX7447)
+ const struct usb_mux *mux = &usb_muxes[port];
+#endif
#ifdef CONFIG_USB_PD_TCPM_ANX7447
mux_state_t mux_state = USB_PD_MUX_NONE;
@@ -217,13 +221,13 @@ __override int svdm_dp_config(int port, uint32_t *payload)
case MODE_DP_PIN_C:
case MODE_DP_PIN_E:
mux_state |= USB_PD_MUX_DP_ENABLED;
- usb_muxes[port].driver->set(port, mux_state);
+ mux->driver->set(mux, mux_state);
break;
case MODE_DP_PIN_B:
case MODE_DP_PIN_D:
case MODE_DP_PIN_F:
mux_state |= USB_PD_MUX_DOCK;
- usb_muxes[port].driver->set(port, mux_state);
+ mux->driver->set(mux, mux_state);
break;
}
#endif
@@ -242,13 +246,14 @@ __override int svdm_dp_config(int port, uint32_t *payload)
__override void svdm_dp_post_config(int port)
{
+ const struct usb_mux *mux = &usb_muxes[port];
+
dp_flags[port] |= DP_FLAGS_DP_ON;
if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
return;
-#ifdef CONFIG_USB_PD_TCPM_ANX7447
- anx7447_tcpc_update_hpd_status(port, 1, 0);
-#endif
+ if (IS_ENABLED(CONFIG_USB_PD_TCPM_ANX7447))
+ anx7447_tcpc_update_hpd_status(mux, 1, 0);
}
__override int svdm_dp_attention(int port, uint32_t *payload)
@@ -256,9 +261,10 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
#ifdef CONFIG_USB_PD_TCPM_ANX7447
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+ const struct usb_mux *mux = &usb_muxes[port];
CPRINTS("Attention: 0x%x", payload[1]);
- anx7447_tcpc_update_hpd_status(port, lvl, irq);
+ anx7447_tcpc_update_hpd_status(mux, lvl, irq);
#endif
dp_status[port] = payload[1];
diff --git a/board/poppy/board.c b/board/poppy/board.c
index 9ccd9774b4..80bcf98433 100644
--- a/board/poppy/board.c
+++ b/board/poppy/board.c
@@ -208,12 +208,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
@@ -284,7 +286,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image()) {
@@ -318,11 +320,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/puff/board.c b/board/puff/board.c
index 4917432d6b..1f8162b147 100644
--- a/board/puff/board.c
+++ b/board/puff/board.c
@@ -244,8 +244,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
.flags = TCPC_FLAGS_RESET_ACTIVE_HIGH,
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
diff --git a/board/rainier/board.c b/board/rainier/board.c
index 99751de860..a2592bd54d 100644
--- a/board/rainier/board.c
+++ b/board/rainier/board.c
@@ -137,8 +137,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
diff --git a/board/rammus/board.c b/board/rammus/board.c
index 9ce61ef501..6f6d175959 100644
--- a/board/rammus/board.c
+++ b/board/rammus/board.c
@@ -178,12 +178,14 @@ struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
[USB_PD_PORT_ANX7447] = {
+ .usb_port = USB_PD_PORT_ANX7447,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
}
@@ -242,8 +244,6 @@ static void ps8751_i2c_remap(void)
void board_tcpc_init(void)
{
- int port;
-
ps8751_i2c_remap();
/* Only reset TCPC if not sysjump */
@@ -259,10 +259,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/reef/board.c b/board/reef/board.c
index 0a9d453ce5..30b3058161 100644
--- a/board/reef/board.c
+++ b/board/reef/board.c
@@ -279,19 +279,21 @@ const enum gpio_signal hibernate_wake_pins[] = {
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (4.5db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
@@ -361,7 +363,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
@@ -392,11 +394,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/reef_it8320/board.c b/board/reef_it8320/board.c
index c06ceaa87e..5c5796bb9e 100644
--- a/board/reef_it8320/board.c
+++ b/board/reef_it8320/board.c
@@ -146,10 +146,12 @@ const enum gpio_signal hibernate_wake_pins[] = {
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
-static void it83xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void it83xx_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
enum gpio_signal gpio =
- port ? GPIO_USB_C1_HPD_1P8_ODL : GPIO_USB_C0_HPD_1P8_ODL;
+ me->usb_port ? GPIO_USB_C1_HPD_1P8_ODL
+ : GPIO_USB_C0_HPD_1P8_ODL;
hpd_lvl = !hpd_lvl;
@@ -161,15 +163,18 @@ static void it83xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
}
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
.hpd_update = &it83xx_tcpc_update_hpd_status,
},
{
- .port_addr = 0x10,
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = 0x10,
.driver = &ps874x_usb_mux_driver,
.hpd_update = &it83xx_tcpc_update_hpd_status,
},
@@ -245,8 +250,6 @@ static void board_set_tablet_mode(void)
/* Initialize board. */
static void board_init(void)
{
- int port;
-
board_set_tablet_mode();
/* Enable charger interrupts */
gpio_enable_interrupt(GPIO_CHARGER_INT_L);
@@ -255,8 +258,8 @@ static void board_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++)
- usb_muxes[port].hpd_update(port, 0, 0);
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_INIT_I2C + 1);
diff --git a/board/reef_mchp/board.c b/board/reef_mchp/board.c
index 89fc2ec139..b9927976ab 100644
--- a/board/reef_mchp/board.c
+++ b/board/reef_mchp/board.c
@@ -406,12 +406,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(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
int rv;
/* 0x98 sets lower EQ of DP port (4.5db) */
- rv = mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ rv = mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
/* TCPCI spec. delay msleep(6); */
@@ -423,12 +423,14 @@ static int ps8751_tune_mux(int port)
* tcpc_config array. The tcpc_config array contains the actual EC I2C
* port, device slave address, and a function pointer into the driver code.
*/
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
@@ -501,7 +503,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
@@ -538,11 +540,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/samus_pd/usb_mux.c b/board/samus_pd/usb_mux.c
index 732de79968..2213fc41e0 100644
--- a/board/samus_pd/usb_mux.c
+++ b/board/samus_pd/usb_mux.c
@@ -40,14 +40,14 @@ static const struct usb_port_mux mux_gpios[] = {
BUILD_ASSERT(ARRAY_SIZE(mux_gpios) == CONFIG_USB_PD_PORT_MAX_COUNT);
-static int board_init_usb_mux(int port)
+static int board_init_usb_mux(const struct usb_mux *me)
{
return EC_SUCCESS;
}
-static int board_set_usb_mux(int port, mux_state_t mux_state)
+static int board_set_usb_mux(const struct usb_mux *me, mux_state_t mux_state)
{
- const struct usb_port_mux *usb_mux = mux_gpios + port;
+ const struct usb_port_mux *usb_mux = mux_gpios + me->usb_port;
int polarity = mux_state & USB_PD_MUX_POLARITY_INVERTED;
/* reset everything */
@@ -80,9 +80,9 @@ static int board_set_usb_mux(int port, mux_state_t mux_state)
return EC_SUCCESS;
}
-static int board_get_usb_mux(int port, mux_state_t *mux_state)
+static int board_get_usb_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
- const struct usb_port_mux *usb_mux = mux_gpios + port;
+ const struct usb_port_mux *usb_mux = mux_gpios + me->usb_port;
*mux_state = 0;
@@ -105,11 +105,13 @@ const struct usb_mux_driver board_custom_usb_mux_driver = {
.get = board_get_usb_mux,
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &board_custom_usb_mux_driver,
},
{
+ .usb_port = 1,
.driver = &board_custom_usb_mux_driver,
},
};
diff --git a/board/scarlet/board.c b/board/scarlet/board.c
index 5f20812a23..8de3de4bf5 100644
--- a/board/scarlet/board.c
+++ b/board/scarlet/board.c
@@ -144,8 +144,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
diff --git a/board/strago/board.c b/board/strago/board.c
index 73f105cd24..308c4ee8ce 100644
--- a/board/strago/board.c
+++ b/board/strago/board.c
@@ -141,10 +141,11 @@ struct pi3usb9281_config pi3usb9281_chips[] = {
BUILD_ASSERT(ARRAY_SIZE(pi3usb9281_chips) ==
CONFIG_BC12_DETECT_PI3USB9281_CHIP_COUNT);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_MUX,
- PI3USB3X532_I2C_ADDR1),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR1,
.driver = &pi3usb3x532_usb_mux_driver,
},
};
diff --git a/board/stryke/board.c b/board/stryke/board.c
index dc5de9d253..5f74ea26f6 100644
--- a/board/stryke/board.c
+++ b/board/stryke/board.c
@@ -144,12 +144,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/board/trogdor/board.c b/board/trogdor/board.c
index 717392a1a2..c8d770fc37 100644
--- a/board/trogdor/board.c
+++ b/board/trogdor/board.c
@@ -266,12 +266,14 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
* to AP. But the TCPC chip is also needed to know the HPD status; otherwise,
* the mux misbehaves.
*/
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
},
{
+ .usb_port = 1,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
@@ -328,8 +330,6 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image()) {
/* TODO(crosbug.com/p/61098): How long do we need to wait? */
@@ -347,11 +347,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/board/trogdor/usb_pd_policy.c b/board/trogdor/usb_pd_policy.c
index c88768f63a..6840ae919e 100644
--- a/board/trogdor/usb_pd_policy.c
+++ b/board/trogdor/usb_pd_policy.c
@@ -152,7 +152,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET;
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
- const struct usb_mux *mux = &usb_muxes[port];
int cur_lvl = gpio_get_level(hpd);
dp_status[port] = payload[1];
@@ -217,7 +216,7 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
pd_notify_dp_alt_mode_entry();
/* Configure TCPC for the HPD event, for proper muxing */
- mux->hpd_update(port, lvl, irq);
+ usb_mux_hpd_update(port, lvl, irq);
/* Signal AP for the HPD event, through GPIO to AP */
if (irq & cur_lvl) {
@@ -249,8 +248,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux *mux = &usb_muxes[port];
-
/* Disconnect the DP port selection mux. */
gpio_set_level(GPIO_DP_MUX_OE_L, 1);
@@ -258,7 +255,7 @@ __override void svdm_exit_dp_mode(int port)
svdm_safe_dp_mode(port);
/* Signal AP for the HPD low event */
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
gpio_set_level(GPIO_DP_HOT_PLUG_DET, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/board/waddledoo/board.c b/board/waddledoo/board.c
index cf697d6564..6979a326fe 100644
--- a/board/waddledoo/board.c
+++ b/board/waddledoo/board.c
@@ -344,28 +344,28 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usbc1_retimer = {
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_SUB_USB_C1,
+ .i2c_addr_flags = NB7V904M_I2C_ADDR0,
+ .driver = &nb7v904m_usb_redriver_drv,
+};
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_C0,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_C0,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
},
{
- .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_SUB_USB_C1,
- PI3USB3X532_I2C_ADDR0),
+ .usb_port = 1,
+ .i2c_port = I2C_PORT_SUB_USB_C1,
+ .i2c_addr_flags = PI3USB3X532_I2C_ADDR0,
.driver = &pi3usb3x532_usb_mux_driver,
+ .next_mux = &usbc1_retimer,
}
};
-struct usb_retimer usb_retimers[CONFIG_USB_PD_PORT_MAX_COUNT] = {
- { 0 }, /* There's no retimer on Port 0 */
- {
- .i2c_port = I2C_PORT_SUB_USB_C1,
- .i2c_addr_flags = NB7V904M_I2C_ADDR0,
- .driver = &nb7v904m_usb_redriver_drv,
- },
-};
-
uint16_t tcpc_get_alert_status(void)
{
uint16_t status = 0;
diff --git a/common/mock/usb_mux_mock.c b/common/mock/usb_mux_mock.c
index c64c5cad0b..f367bfeb95 100644
--- a/common/mock/usb_mux_mock.c
+++ b/common/mock/usb_mux_mock.c
@@ -18,12 +18,12 @@ void mock_usb_mux_reset(void)
memset(&mock_usb_mux, 0, sizeof(mock_usb_mux));
}
-static int mock_init(int port)
+static int mock_init(const struct usb_mux *me)
{
return EC_SUCCESS;
}
-static int mock_set(int port, mux_state_t mux_state)
+static int mock_set(const struct usb_mux *me, mux_state_t mux_state)
{
mock_usb_mux.state = mux_state;
++mock_usb_mux.num_set_calls;
@@ -32,13 +32,13 @@ static int mock_set(int port, mux_state_t mux_state)
return EC_SUCCESS;
}
-int mock_get(int port, mux_state_t *mux_state)
+int mock_get(const struct usb_mux *me, mux_state_t *mux_state)
{
*mux_state = mock_usb_mux.state;
return EC_SUCCESS;
}
-static int mock_enter_low_power_mode(int port)
+static int mock_enter_low_power_mode(const struct usb_mux *me)
{
return EC_SUCCESS;
}
diff --git a/driver/retimer/bb_retimer.c b/driver/retimer/bb_retimer.c
index 61a84c4116..08afbc7308 100644
--- a/driver/retimer/bb_retimer.c
+++ b/driver/retimer/bb_retimer.c
@@ -27,7 +27,8 @@
/**
* Utility functions
*/
-static int bb_retimer_read(int port, const uint8_t offset, uint32_t *data)
+static int bb_retimer_read(const struct usb_mux *me,
+ const uint8_t offset, uint32_t *data)
{
int rv;
uint8_t buf[BB_RETIMER_READ_SIZE];
@@ -39,8 +40,7 @@ static int bb_retimer_read(int port, const uint8_t offset, uint32_t *data)
* byte[1:4] : Data [LSB -> MSB]
* Stop
*/
- rv = i2c_xfer(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags,
+ rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags,
&offset, 1, buf, BB_RETIMER_READ_SIZE);
if (rv)
return rv;
@@ -52,7 +52,8 @@ static int bb_retimer_read(int port, const uint8_t offset, uint32_t *data)
return EC_SUCCESS;
}
-static int bb_retimer_write(int port, const uint8_t offset, uint32_t data)
+static int bb_retimer_write(const struct usb_mux *me,
+ const uint8_t offset, uint32_t data)
{
uint8_t buf[BB_RETIMER_WRITE_SIZE];
@@ -71,14 +72,14 @@ static int bb_retimer_write(int port, const uint8_t offset, uint32_t data)
buf[4] = (data >> 16) & 0xFF;
buf[5] = (data >> 24) & 0xFF;
- return i2c_xfer(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags,
+ return i2c_xfer(me->i2c_port,
+ me->i2c_addr_flags,
buf, BB_RETIMER_WRITE_SIZE, NULL, 0);
}
-static void bb_retimer_power_handle(int port, int on_off)
+static void bb_retimer_power_handle(const struct usb_mux *me, int on_off)
{
- const struct bb_usb_control *control = &bb_controls[port];
+ const struct bb_usb_control *control = &bb_controls[me->usb_port];
/* handle retimer's power domain */
@@ -110,10 +111,11 @@ static void bb_retimer_power_handle(int port, int on_off)
/**
* Driver interface functions
*/
-static int retimer_set_state(int port, mux_state_t mux_state)
+static int retimer_set_state(const struct usb_mux *me, mux_state_t mux_state)
{
uint32_t set_retimer_con = 0;
uint8_t dp_pin_mode;
+ int port = me->usb_port;
union tbt_mode_resp_cable cable_resp;
union tbt_mode_resp_device dev_resp;
@@ -280,30 +282,30 @@ static int retimer_set_state(int port, mux_state_t mux_state)
cable_resp.tbt_cable_speed);
}
/* Writing the register4 */
- return bb_retimer_write(port, BB_RETIMER_REG_CONNECTION_STATE,
+ return bb_retimer_write(me, BB_RETIMER_REG_CONNECTION_STATE,
set_retimer_con);
}
-static int retimer_low_power_mode(int port)
+static int retimer_low_power_mode(const struct usb_mux *me)
{
- bb_retimer_power_handle(port, 0);
+ bb_retimer_power_handle(me, 0);
return EC_SUCCESS;
}
-static int retimer_init(int port)
+static int retimer_init(const struct usb_mux *me)
{
int rv;
uint32_t data;
- bb_retimer_power_handle(port, 1);
+ bb_retimer_power_handle(me, 1);
- rv = bb_retimer_read(port, BB_RETIMER_REG_VENDOR_ID, &data);
+ rv = bb_retimer_read(me, BB_RETIMER_REG_VENDOR_ID, &data);
if (rv)
return rv;
if (data != BB_RETIMER_VENDOR_ID)
return EC_ERROR_UNKNOWN;
- rv = bb_retimer_read(port, BB_RETIMER_REG_DEVICE_ID, &data);
+ rv = bb_retimer_read(me, BB_RETIMER_REG_DEVICE_ID, &data);
if (rv)
return rv;
@@ -313,7 +315,7 @@ static int retimer_init(int port)
return EC_SUCCESS;
}
-const struct usb_retimer_driver bb_usb_retimer = {
+const struct usb_mux_driver bb_usb_retimer = {
.init = retimer_init,
.set = retimer_set_state,
.enter_low_power_mode = retimer_low_power_mode,
@@ -324,14 +326,24 @@ static int console_command_bb_retimer(int argc, char **argv)
{
char rw, *e;
int rv, port, reg, data, val;
+ const struct usb_mux *mux;
if (argc < 4)
return EC_ERROR_PARAM_COUNT;
/* Get port number */
port = strtoi(argv[1], &e, 0);
- if (*e || port < 0 || port > board_get_usb_pd_port_count() ||
- !usb_retimers[port].driver)
+ if (*e || port < 0 || port > board_get_usb_pd_port_count())
+ return EC_ERROR_PARAM1;
+
+ mux = &usb_muxes[port];
+ while (mux) {
+ if (mux->driver == &bb_usb_retimer)
+ break;
+ mux = mux->next_mux;
+ }
+
+ if (!mux)
return EC_ERROR_PARAM1;
/* Validate r/w selection */
@@ -345,16 +357,16 @@ static int console_command_bb_retimer(int argc, char **argv)
return EC_ERROR_PARAM3;
if (rw == 'r')
- rv = bb_retimer_read(port, reg, &data);
+ rv = bb_retimer_read(mux, reg, &data);
else {
/* Get value to be written */
val = strtoi(argv[4], &e, 0);
if (*e || val < 0)
return EC_ERROR_PARAM4;
- rv = bb_retimer_write(port, reg, val);
+ rv = bb_retimer_write(mux, reg, val);
if (rv == EC_SUCCESS) {
- rv = bb_retimer_read(port, reg, &data);
+ rv = bb_retimer_read(mux, reg, &data);
if (rv == EC_SUCCESS && data != val)
rv = EC_ERROR_UNKNOWN;
}
diff --git a/driver/retimer/bb_retimer.h b/driver/retimer/bb_retimer.h
index 3b34b72e3d..868cb5ee7c 100644
--- a/driver/retimer/bb_retimer.h
+++ b/driver/retimer/bb_retimer.h
@@ -40,7 +40,7 @@
#define BB_RETIMER_TBT_CABLE_GENERATION(x) (((x) & 0x3) << 28)
/* Supported USB retimer drivers */
-extern const struct usb_retimer_driver bb_usb_retimer;
+extern const struct usb_mux_driver bb_usb_retimer;
/* Retimer driver hardware specific controls */
struct bb_usb_control {
diff --git a/driver/retimer/nb7v904m.c b/driver/retimer/nb7v904m.c
index 81fd5abc93..e1cedede95 100644
--- a/driver/retimer/nb7v904m.c
+++ b/driver/retimer/nb7v904m.c
@@ -15,28 +15,28 @@
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-static int nb7v904m_write(int port, int offset, int data)
+static int nb7v904m_write(const struct usb_mux *me, int offset, int data)
{
- return i2c_write8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags,
+ return i2c_write8(me->i2c_port,
+ me->i2c_addr_flags,
offset, data);
}
-static int nb7v904m_read(int port, int offset, int *regval)
+static int nb7v904m_read(const struct usb_mux *me, int offset, int *regval)
{
- return i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags,
+ return i2c_read8(me->i2c_port,
+ me->i2c_addr_flags,
offset, regval);
}
-static int set_low_power_mode(int port, bool enable)
+static int set_low_power_mode(const struct usb_mux *me, bool enable)
{
int regval;
int rv;
- rv = nb7v904m_read(port, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
+ rv = nb7v904m_read(me, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
if (rv)
return rv;
@@ -45,28 +45,29 @@ static int set_low_power_mode(int port, bool enable)
else
regval &= ~NB7V904M_CHIP_EN;
- return nb7v904m_write(port, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
+ return nb7v904m_write(me, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
}
-static int nb7v904m_enter_low_power_mode(int port)
+static int nb7v904m_enter_low_power_mode(const struct usb_mux *me)
{
- int rv = set_low_power_mode(port, 1);
+ int rv = set_low_power_mode(me, 1);
if (rv)
- CPRINTS("C%d: NB7V904M: Failed to enter low power mode!", port);
+ CPRINTS("C%d: NB7V904M: Failed to enter low power mode!",
+ me->usb_port);
return rv;
}
-static int nb7v904m_init(int port)
+static int nb7v904m_init(const struct usb_mux *me)
{
- int rv = set_low_power_mode(port, 0);
+ int rv = set_low_power_mode(me, 0);
if (rv)
- CPRINTS("C%d: NB7V904M: init failed!", port);
+ CPRINTS("C%d: NB7V904M: init failed!", me->usb_port);
return rv;
}
-static int nb7v904m_set_mux(int port, mux_state_t mux_state)
+static int nb7v904m_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int rv = EC_SUCCESS;
int regval;
@@ -74,17 +75,17 @@ static int nb7v904m_set_mux(int port, mux_state_t mux_state)
/* Turn off redriver if it's not needed at all. */
if (mux_state == USB_PD_MUX_NONE)
- return nb7v904m_enter_low_power_mode(port);
+ return nb7v904m_enter_low_power_mode(me);
- rv = nb7v904m_init(port);
+ rv = nb7v904m_init(me);
if (rv)
return rv;
/* Clear operation mode field */
- rv = nb7v904m_read(port, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
+ rv = nb7v904m_read(me, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
if (rv) {
- CPRINTS("C%d %s: Failed to obtain dev settings!", port,
- __func__);
+ CPRINTS("C%d %s: Failed to obtain dev settings!",
+ me->usb_port, __func__);
return rv;
}
regval &= ~NB7V904M_OP_MODE_MASK;
@@ -108,14 +109,14 @@ static int nb7v904m_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_DP_ENABLED) {
/* Connect AUX */
- rv = nb7v904m_write(port, NB7V904M_REG_AUX_CH_CTRL, flipped ?
+ rv = nb7v904m_write(me, NB7V904M_REG_AUX_CH_CTRL, flipped ?
NB7V904M_AUX_CH_FLIPPED :
NB7V904M_AUX_CH_NORMAL);
/* Enable all channels for DP */
regval |= NB7V904M_CH_EN_MASK;
} else {
/* Disconnect AUX since it's not being used. */
- rv = nb7v904m_write(port, NB7V904M_REG_AUX_CH_CTRL,
+ rv = nb7v904m_write(me, NB7V904M_REG_AUX_CH_CTRL,
NB7V904M_AUX_CH_HI_Z);
/* Disable the unused channels to save power */
@@ -129,14 +130,14 @@ static int nb7v904m_set_mux(int port, mux_state_t mux_state)
}
}
- rv |= nb7v904m_write(port, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
+ rv |= nb7v904m_write(me, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
if (rv)
- CPRINTS("C%d: %s failed!", port, __func__);
+ CPRINTS("C%d: %s failed!", me->usb_port, __func__);
return rv;
}
-const struct usb_retimer_driver nb7v904m_usb_redriver_drv = {
+const struct usb_mux_driver nb7v904m_usb_redriver_drv = {
.enter_low_power_mode = &nb7v904m_enter_low_power_mode,
.init = &nb7v904m_init,
.set = &nb7v904m_set_mux,
diff --git a/driver/retimer/nb7v904m.h b/driver/retimer/nb7v904m.h
index 4306615825..8bb43f79eb 100644
--- a/driver/retimer/nb7v904m.h
+++ b/driver/retimer/nb7v904m.h
@@ -37,5 +37,5 @@
#define NB7V904M_AUX_CH_FLIPPED BIT(0)
#define NB7V904M_AUX_CH_HI_Z BIT(1)
-extern const struct usb_retimer_driver nb7v904m_usb_redriver_drv;
+extern const struct usb_mux_driver nb7v904m_usb_redriver_drv;
#endif /* __CROS_EC_USB_REDRIVER_NB7V904M_H */
diff --git a/driver/retimer/pi3dpx1207.c b/driver/retimer/pi3dpx1207.c
index 74eb80aac1..9254c3d4bb 100644
--- a/driver/retimer/pi3dpx1207.c
+++ b/driver/retimer/pi3dpx1207.c
@@ -21,8 +21,7 @@ static uint8_t buf[PI3DPX1207_NUM_REGISTERS];
/**
* Local utility functions
*/
-static int pi3dpx1207_i2c_write(int i2c_port,
- uint16_t addr_flags,
+static int pi3dpx1207_i2c_write(const struct usb_mux *me,
uint8_t offset,
uint8_t val)
{
@@ -45,7 +44,7 @@ static int pi3dpx1207_i2c_write(int i2c_port,
attempt = 0;
do {
attempt++;
- rv = i2c_xfer(i2c_port, addr_flags,
+ rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags,
NULL, 0, buf, offset);
} while ((rv != EC_SUCCESS) && (attempt < I2C_MAX_RETRIES));
}
@@ -56,15 +55,16 @@ static int pi3dpx1207_i2c_write(int i2c_port,
attempt = 0;
do {
attempt++;
- rv = i2c_xfer(i2c_port, addr_flags,
+ rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags,
buf, offset + 1, NULL, 0);
} while ((rv != EC_SUCCESS) && (attempt < I2C_MAX_RETRIES));
}
return rv;
}
-static void pi3dpx1207_shutoff_power(int port)
+static void pi3dpx1207_shutoff_power(const struct usb_mux *me)
{
+ const int port = me->usb_port;
const int gpio_enable = pi3dpx1207_controls[port].enable_gpio;
const int gpio_dp_enable = pi3dpx1207_controls[port].dp_enable_gpio;
@@ -75,27 +75,26 @@ static void pi3dpx1207_shutoff_power(int port)
/**
* Driver interface code
*/
-static int pi3dpx1207_init(int port)
+static int pi3dpx1207_init(const struct usb_mux *me)
{
+ const int port = me->usb_port;
const int gpio_enable = pi3dpx1207_controls[port].enable_gpio;
gpio_or_ioex_set_level(gpio_enable, 1);
return EC_SUCCESS;
}
-static int pi3dpx1207_enter_low_power_mode(int port)
+static int pi3dpx1207_enter_low_power_mode(const struct usb_mux *me)
{
- pi3dpx1207_shutoff_power(port);
+ pi3dpx1207_shutoff_power(me);
return EC_SUCCESS;
}
-static int pi3dpx1207_set_mux(int port, mux_state_t mux_state)
+static int pi3dpx1207_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int rv = EC_SUCCESS;
uint8_t mode_val = PI3DPX1207_MODE_WATCHDOG_EN;
-
- const int i2c_port = usb_retimers[port].i2c_port;
- const uint16_t i2c_addr_flags = usb_retimers[port].i2c_addr_flags;
+ const int port = me->usb_port;
const int gpio_enable = pi3dpx1207_controls[port].enable_gpio;
const int gpio_dp_enable = pi3dpx1207_controls[port].dp_enable_gpio;
@@ -127,18 +126,16 @@ static int pi3dpx1207_set_mux(int port, mux_state_t mux_state)
}
/* Nothing enabled, power down the retimer */
else {
- pi3dpx1207_shutoff_power(port);
+ pi3dpx1207_shutoff_power(me);
return EC_SUCCESS;
}
/* Write the retimer config byte */
- rv = pi3dpx1207_i2c_write(i2c_port, i2c_addr_flags,
- PI3DPX1207_MODE_OFFSET,
- mode_val);
+ rv = pi3dpx1207_i2c_write(me, PI3DPX1207_MODE_OFFSET, mode_val);
return rv;
}
-const struct usb_retimer_driver pi3dpx1207_usb_retimer = {
+const struct usb_mux_driver pi3dpx1207_usb_retimer = {
.init = pi3dpx1207_init,
.set = pi3dpx1207_set_mux,
.enter_low_power_mode = pi3dpx1207_enter_low_power_mode,
diff --git a/driver/retimer/pi3dpx1207.h b/driver/retimer/pi3dpx1207.h
index 53b849b081..2e3405d1aa 100644
--- a/driver/retimer/pi3dpx1207.h
+++ b/driver/retimer/pi3dpx1207.h
@@ -40,7 +40,7 @@
#define PI3DPX1207_MODE_CONF_USB_SUPER 0xC0
/* Supported USB retimer drivers */
-extern const struct usb_retimer_driver pi3dpx1207_usb_retimer;
+extern const struct usb_mux_driver pi3dpx1207_usb_retimer;
/* Retimer driver hardware specific controls */
struct pi3dpx1207_usb_control {
diff --git a/driver/retimer/ps8802.c b/driver/retimer/ps8802.c
index 94ea2e5797..c4a9a5478b 100644
--- a/driver/retimer/ps8802.c
+++ b/driver/retimer/ps8802.c
@@ -16,47 +16,47 @@
#define PS8802_DEBUG 0
#define PS8802_I2C_WAKE_DELAY 500
-int ps8802_i2c_read(int port, int page, int offset, int *data)
+int ps8802_i2c_read(const struct usb_mux *me, int page, int offset, int *data)
{
int rv;
- rv = i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data);
if (PS8802_DEBUG)
ccprintf("%s(%d:0x%02X, 0x%02X) =>0x%02X\n", __func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->i2c_port,
+ me->i2c_addr_flags + page,
offset, *data);
return rv;
}
-int ps8802_i2c_write(int port, int page, int offset, int data)
+int ps8802_i2c_write(const struct usb_mux *me, int page, int offset, int data)
{
int rv;
int pre_val, post_val;
if (PS8802_DEBUG)
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_write8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_write8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data);
if (PS8802_DEBUG) {
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X) "
"0x%02X=>0x%02X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data,
pre_val, post_val);
}
@@ -64,30 +64,31 @@ int ps8802_i2c_write(int port, int page, int offset, int data)
return rv;
}
-int ps8802_i2c_write16(int port, int page, int offset, int data)
+int ps8802_i2c_write16(const struct usb_mux *me, int page, int offset,
+ int data)
{
int rv;
int pre_val, post_val;
if (PS8802_DEBUG)
- i2c_read16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_write16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_write16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data);
if (PS8802_DEBUG) {
- i2c_read16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%04X) "
"0x%04X=>0x%04X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data,
pre_val, post_val);
}
@@ -95,33 +96,33 @@ int ps8802_i2c_write16(int port, int page, int offset, int data)
return rv;
}
-int ps8802_i2c_field_update8(int port, int page, int offset,
+int ps8802_i2c_field_update8(const struct usb_mux *me, int page, int offset,
uint8_t field_mask, uint8_t set_value)
{
int rv;
int pre_val, post_val;
if (PS8802_DEBUG)
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_field_update8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_field_update8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset,
field_mask,
set_value);
if (PS8802_DEBUG) {
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X, 0x%02X) "
"0x%02X=>0x%02X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->i2c_port,
+ me->i2c_addr_flags + page,
offset, field_mask, set_value,
pre_val, post_val);
}
@@ -129,33 +130,33 @@ int ps8802_i2c_field_update8(int port, int page, int offset,
return rv;
}
-int ps8802_i2c_field_update16(int port, int page, int offset,
+int ps8802_i2c_field_update16(const struct usb_mux *me, int page, int offset,
uint16_t field_mask, uint16_t set_value)
{
int rv;
int pre_val, post_val;
if (PS8802_DEBUG)
- i2c_read16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_field_update16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_field_update16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset,
field_mask,
set_value);
if (PS8802_DEBUG) {
- i2c_read16(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read16(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X, 0x%04X) "
"0x%04X=>0x%04X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->i2c_port,
+ me->i2c_addr_flags + page,
offset, field_mask, set_value,
pre_val, post_val);
}
@@ -168,14 +169,14 @@ int ps8802_i2c_field_update16(int port, int page, int offset,
* From Application Note: 1) Activate by reading any Page 2 register. 2) Wait
* 500 microseconds. 3) After 5 seconds idle, PS8802 will return to standby.
*/
-int ps8802_i2c_wake(int port)
+int ps8802_i2c_wake(const struct usb_mux *me)
{
int data;
int rv = EC_ERROR_UNKNOWN;
/* If in standby, first read will fail, second should succeed. */
for (int i = 0; i < 2; i++) {
- rv = ps8802_i2c_read(port,
+ rv = ps8802_i2c_read(me,
PS8802_REG_PAGE2,
PS8802_REG2_MODE,
&data);
@@ -188,39 +189,39 @@ int ps8802_i2c_wake(int port)
return rv;
}
-int ps8802_detect(int port)
+int ps8802_detect(const struct usb_mux *me)
{
int rv = EC_ERROR_NOT_POWERED;
/* Detected if we are powered and can read the device */
if (!chipset_in_state(CHIPSET_STATE_HARD_OFF))
- rv = ps8802_i2c_wake(port);
+ rv = ps8802_i2c_wake(me);
return rv;
}
-static int ps8802_init(int port)
+static int ps8802_init(const struct usb_mux *me)
{
return EC_SUCCESS;
}
-static int ps8802_set_mux(int port, mux_state_t mux_state)
+static int ps8802_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int val;
int rv;
if (chipset_in_state(CHIPSET_STATE_HARD_OFF))
return (mux_state == USB_PD_MUX_NONE) ? EC_SUCCESS
- : EC_ERROR_NOT_POWERED;
+ : EC_ERROR_NOT_POWERED;
/* Make sure the PS8802 is awake */
- rv = ps8802_i2c_wake(port);
+ rv = ps8802_i2c_wake(me);
if (rv)
return rv;
if (PS8802_DEBUG)
ccprintf("%s(%d, 0x%02X) %s %s %s\n",
- __func__, port, mux_state,
+ __func__, me->usb_port, mux_state,
(mux_state & USB_PD_MUX_USB_ENABLED) ? "USB" : "",
(mux_state & USB_PD_MUX_DP_ENABLED) ? "DP" : "",
(mux_state & USB_PD_MUX_POLARITY_INVERTED)
@@ -239,24 +240,15 @@ static int ps8802_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
val |= PS8802_MODE_FLIP_ENABLE;
- rv = ps8802_i2c_write(port,
+ rv = ps8802_i2c_write(me,
PS8802_REG_PAGE2,
PS8802_REG2_MODE,
val);
- if (rv)
- return rv;
-
- /* Board specific retimer mux tuning */
- if (usb_retimers[port].tune) {
- rv = usb_retimers[port].tune(port, mux_state);
- if (rv)
- return rv;
- }
return rv;
}
-static int ps8802_get_mux(int port, mux_state_t *mux_state)
+static int ps8802_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int rv;
int val;
@@ -266,11 +258,11 @@ static int ps8802_get_mux(int port, mux_state_t *mux_state)
if (chipset_in_state(CHIPSET_STATE_HARD_OFF))
return EC_ERROR_NOT_POWERED;
- rv = ps8802_i2c_wake(port);
+ rv = ps8802_i2c_wake(me);
if (rv)
return rv;
- rv = ps8802_i2c_read(port,
+ rv = ps8802_i2c_read(me,
PS8802_REG_PAGE2,
PS8802_REG2_MODE,
&val);
@@ -287,17 +279,6 @@ static int ps8802_get_mux(int port, mux_state_t *mux_state)
return rv;
}
-/*
- * PS8802 can look like a retimer or a MUX. So create both tables
- * and use them as needed, until retimers become a type of MUX and
- * then we will only need one of these tables.
- *
- * TODO(b:147593660) Cleanup of retimers as muxes in a more
- * generalized mechanism
- */
-const struct usb_retimer_driver ps8802_usb_retimer = {
- .set = ps8802_set_mux,
-};
const struct usb_mux_driver ps8802_usb_mux_driver = {
.init = ps8802_init,
.set = ps8802_set_mux,
diff --git a/driver/retimer/ps8802.h b/driver/retimer/ps8802.h
index 7c1b5c0cc8..2e4a301275 100644
--- a/driver/retimer/ps8802.h
+++ b/driver/retimer/ps8802.h
@@ -4,6 +4,7 @@
*
* PS8802 retimer.
*/
+#include "usb_mux.h"
#ifndef __CROS_EC_USB_RETIMER_PS8802_H
#define __CROS_EC_USB_RETIMER_PS8802_H
@@ -65,17 +66,17 @@
extern const struct usb_mux_driver ps8802_usb_mux_driver;
-extern const struct usb_retimer_driver ps8802_usb_retimer;
-int ps8802_i2c_wake(int port);
-int ps8802_detect(int port);
+int ps8802_i2c_wake(const struct usb_mux *me);
+int ps8802_detect(const struct usb_mux *me);
-int ps8802_i2c_read(int port, int page, int offset, int *data);
-int ps8802_i2c_write(int port, int page, int offset, int data);
-int ps8802_i2c_write16(int port, int page, int offset, int data);
-int ps8802_i2c_field_update8(int port, int page, int offset,
+int ps8802_i2c_read(const struct usb_mux *me, int page, int offset, int *data);
+int ps8802_i2c_write(const struct usb_mux *me, int page, int offset, int data);
+int ps8802_i2c_write16(const struct usb_mux *me, int page, int offset,
+ int data);
+int ps8802_i2c_field_update8(const struct usb_mux *me, int page, int offset,
uint8_t field_mask, uint8_t set_value);
-int ps8802_i2c_field_update16(int port, int page, int offset,
+int ps8802_i2c_field_update16(const struct usb_mux *me, int page, int offset,
uint16_t field_mask, uint16_t set_value);
#endif /* __CROS_EC_USB_RETIMER_PS8802_H */
diff --git a/driver/retimer/ps8818.c b/driver/retimer/ps8818.c
index 10dc70dca0..e70b8bf986 100644
--- a/driver/retimer/ps8818.c
+++ b/driver/retimer/ps8818.c
@@ -16,47 +16,47 @@
#define PS8818_DEBUG 0
-int ps8818_i2c_read(int port, int page, int offset, int *data)
+int ps8818_i2c_read(const struct usb_mux *me, int page, int offset, int *data)
{
int rv;
- rv = i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data);
if (PS8818_DEBUG)
ccprintf("%s(%d:0x%02X, 0x%02X) =>0x%02X\n", __func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->usb_port,
+ me->i2c_addr_flags + page,
offset, *data);
return rv;
}
-int ps8818_i2c_write(int port, int page, int offset, int data)
+int ps8818_i2c_write(const struct usb_mux *me, int page, int offset, int data)
{
int rv;
int pre_val, post_val;
if (PS8818_DEBUG)
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_write8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_write8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, data);
if (PS8818_DEBUG) {
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X) "
"0x%02X=>0x%02X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->usb_port,
+ me->i2c_addr_flags + page,
offset, data,
pre_val, post_val);
}
@@ -64,33 +64,33 @@ int ps8818_i2c_write(int port, int page, int offset, int data)
return rv;
}
-int ps8818_i2c_field_update8(int port, int page, int offset,
+int ps8818_i2c_field_update8(const struct usb_mux *me, int page, int offset,
uint8_t field_mask, uint8_t set_value)
{
int rv;
int pre_val, post_val;
if (PS8818_DEBUG)
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &pre_val);
- rv = i2c_field_update8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ rv = i2c_field_update8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset,
field_mask,
set_value);
if (PS8818_DEBUG) {
- i2c_read8(usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ i2c_read8(me->i2c_port,
+ me->i2c_addr_flags + page,
offset, &post_val);
ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X, 0x%02X) "
"0x%02X=>0x%02X\n",
__func__,
- usb_retimers[port].i2c_port,
- usb_retimers[port].i2c_addr_flags + page,
+ me->usb_port,
+ me->i2c_addr_flags + page,
offset, field_mask, set_value,
pre_val, post_val);
}
@@ -98,14 +98,14 @@ int ps8818_i2c_field_update8(int port, int page, int offset,
return rv;
}
-int ps8818_detect(int port)
+int ps8818_detect(const struct usb_mux *me)
{
int rv = EC_ERROR_NOT_POWERED;
int val;
/* Detected if we are powered and can read the device */
if (!chipset_in_state(CHIPSET_STATE_HARD_OFF))
- rv = ps8818_i2c_read(port,
+ rv = ps8818_i2c_read(me,
PS8818_REG_PAGE0,
PS8818_REG0_FLIP,
&val);
@@ -113,7 +113,7 @@ int ps8818_detect(int port)
return rv;
}
-static int ps8818_set_mux(int port, mux_state_t mux_state)
+static int ps8818_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int rv;
int val = 0;
@@ -124,7 +124,7 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (PS8818_DEBUG)
ccprintf("%s(%d, 0x%02X) %s %s %s\n",
- __func__, port, mux_state,
+ __func__, me->usb_port, mux_state,
(mux_state & USB_PD_MUX_USB_ENABLED) ? "USB" : "",
(mux_state & USB_PD_MUX_DP_ENABLED) ? "DP" : "",
(mux_state & USB_PD_MUX_POLARITY_INVERTED)
@@ -136,7 +136,7 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_DP_ENABLED)
val |= PS8818_MODE_DP_ENABLE;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE0,
PS8818_REG0_MODE,
PS8818_MODE_NON_RESERVED_MASK,
@@ -149,7 +149,7 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
val |= PS8818_FLIP_CONFIG;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE0,
PS8818_REG0_FLIP,
PS8818_FLIP_NON_RESERVED_MASK,
@@ -162,24 +162,15 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_DP_ENABLED)
val |= PS8818_DPHPD_PLUGGED;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE0,
PS8818_REG0_DPHPD_CONFIG,
PS8818_DPHPD_NON_RESERVED_MASK,
val);
- if (rv)
- return rv;
-
- /* Board specific retimer mux tuning */
- if (usb_retimers[port].tune) {
- rv = usb_retimers[port].tune(port, mux_state);
- if (rv)
- return rv;
- }
return rv;
}
-const struct usb_retimer_driver ps8818_usb_retimer = {
+const struct usb_mux_driver ps8818_usb_retimer_driver = {
.set = ps8818_set_mux,
};
diff --git a/driver/retimer/ps8818.h b/driver/retimer/ps8818.h
index a28d04a38b..c761284cf8 100644
--- a/driver/retimer/ps8818.h
+++ b/driver/retimer/ps8818.h
@@ -4,6 +4,7 @@
*
* PS8818 retimer.
*/
+#include "usb_mux.h"
#ifndef __CROS_EC_USB_RETIMER_PS8818_H
#define __CROS_EC_USB_RETIMER_PS8818_H
@@ -77,13 +78,16 @@
#define PS8818_STATUS_NORMAL_OPERATION BIT(7)
#define PS8818_STATUS_10_GBPS BIT(5)
-extern const struct usb_retimer_driver ps8818_usb_retimer;
+extern const struct usb_mux_driver ps8818_usb_retimer_driver;
-int ps8818_detect(int port);
+int ps8818_detect(const struct usb_mux *me);
-int ps8818_i2c_read(int port, int page, int offset, int *data);
-int ps8818_i2c_write(int port, int page, int offset, int data);
-int ps8818_i2c_field_update8(int port, int page, int offset,
+int ps8818_i2c_read(const struct usb_mux *me,
+ int page, int offset, int *data);
+int ps8818_i2c_write(const struct usb_mux *me,
+ int page, int offset, int data);
+int ps8818_i2c_field_update8(const struct usb_mux *me,
+ int page, int offset,
uint8_t field_mask, uint8_t set_value);
#endif /* __CROS_EC_USB_RETIMER_PS8818_H */
diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c
index ed4e601f6c..a093aa9094 100644
--- a/driver/tcpm/anx7447.c
+++ b/driver/tcpm/anx7447.c
@@ -48,7 +48,7 @@ struct anx_usb_mux {
int state;
};
-static int anx7447_mux_set(int port, mux_state_t mux_state);
+static int anx7447_mux_set(const struct usb_mux *me, mux_state_t mux_state);
static struct anx_state anx[CONFIG_USB_PD_PORT_MAX_COUNT];
static struct anx_usb_mux mux[CONFIG_USB_PD_PORT_MAX_COUNT];
@@ -285,6 +285,7 @@ DECLARE_CONSOLE_COMMAND(anx_ocm, command_anx_ocm,
static int anx7447_init(int port)
{
int rv, reg, i;
+ const struct usb_mux *me = &usb_muxes[port];
ASSERT(port < CONFIG_USB_PD_PORT_MAX_COUNT);
@@ -363,14 +364,20 @@ static int anx7447_init(int port)
reg &= ~ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_MASK;
reg |= ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_2430US;
rv = tcpc_write(port, ANX7447_REG_ANALOG_CTRL_10, reg);
+ if (rv)
+ return rv;
#ifdef CONFIG_USB_PD_TCPM_MUX
/*
* Run mux_set() here for considering CCD(Case-Closed Debugging) case
* If this TCPC is not also the MUX then don't initialize to NONE
*/
- if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC))
- rv |= anx7447_mux_set(port, USB_PD_MUX_NONE);
+ while ((me != NULL) && (me->driver != &anx7447_usb_mux_driver))
+ me = me->next_mux;
+
+ if (me != NULL &&
+ !(me->flags & USB_MUX_FLAG_NOT_TCPC))
+ rv = anx7447_mux_set(me, USB_PD_MUX_NONE);
#endif /* CONFIG_USB_PD_TCPM_MUX */
return rv;
@@ -453,9 +460,11 @@ static void anx7447_tcpc_alert(int port)
*/
static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT];
-void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
+void anx7447_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
int reg = 0;
+ int port = me->usb_port;
/*
* All calls within this method need to update to a mux_read/write calls
@@ -464,7 +473,7 @@ void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
* 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));
+ ASSERT(!(me->flags & USB_MUX_FLAG_NOT_TCPC));
anx7447_set_hpd_level(port, hpd_lvl);
@@ -492,8 +501,10 @@ void anx7447_tcpc_clear_hpd_status(int port)
}
#ifdef CONFIG_USB_PD_TCPM_MUX
-static int anx7447_mux_init(int port)
+static int anx7447_mux_init(const struct usb_mux *me)
{
+ int port = me->usb_port;
+
ASSERT(port < CONFIG_USB_PD_PORT_MAX_COUNT);
memset(&mux[port], 0, sizeof(struct anx_usb_mux));
@@ -508,41 +519,42 @@ static int anx7447_mux_init(int port)
* USB_PD_MUX_DP_ENABLED) when reinitialized, we need to force
* initialize it to USB_PD_MUX_NONE
*/
- return anx7447_mux_set(port, USB_PD_MUX_NONE);
+ return anx7447_mux_set(me, USB_PD_MUX_NONE);
}
#ifdef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD
-static void anx7447_mux_safemode(int port, int on_off)
+static void anx7447_mux_safemode(const struct usb_mux *me, int on_off)
{
int reg;
- mux_read(port, ANX7447_REG_ANALOG_CTRL_9, &reg);
+ mux_read(me, ANX7447_REG_ANALOG_CTRL_9, &reg);
if (on_off)
reg |= ANX7447_REG_SAFE_MODE;
else
reg &= ~(ANX7447_REG_SAFE_MODE);
- mux_write(port, ANX7447_REG_ANALOG_CTRL_9, reg);
+ mux_write(me, ANX7447_REG_ANALOG_CTRL_9, reg);
CPRINTS("C%d set mux to safemode %s, reg = 0x%x",
- port, (on_off) ? "on" : "off", reg);
+ me->usb_port, (on_off) ? "on" : "off", reg);
}
-static inline void anx7447_configure_aux_src(int port, int on_off)
+static inline void anx7447_configure_aux_src(const struct usb_mux *me,
+ int on_off)
{
int reg;
- mux_read(port, ANX7447_REG_ANALOG_CTRL_9, &reg);
+ mux_read(me, ANX7447_REG_ANALOG_CTRL_9, &reg);
if (on_off)
reg |= ANX7447_REG_R_AUX_RES_PULL_SRC;
else
reg &= ~(ANX7447_REG_R_AUX_RES_PULL_SRC);
- mux_write(port, ANX7447_REG_ANALOG_CTRL_9, reg);
+ mux_write(me, ANX7447_REG_ANALOG_CTRL_9, reg);
CPRINTS("C%d set aux_src to %s, reg = 0x%x",
- port, (on_off) ? "on" : "off", reg);
+ me->usb_port, (on_off) ? "on" : "off", reg);
}
#endif
@@ -555,12 +567,13 @@ static inline void anx7447_configure_aux_src(int port, int on_off)
*
* a2, a3, a10, a11, b2, b3, b10, b11 are pins on the USB-C connector.
*/
-static int anx7447_mux_set(int port, mux_state_t mux_state)
+static int anx7447_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
int cc_direction;
mux_state_t mux_type;
int sw_sel = 0x00, aux_sw = 0x00;
int rv;
+ int port = me->usb_port;
cc_direction = mux_state & USB_PD_MUX_POLARITY_INVERTED;
mux_type = mux_state & USB_PD_MUX_DOCK;
@@ -605,11 +618,11 @@ static int anx7447_mux_set(int port, mux_state_t mux_state)
* first. After the mux configured, should set mux to normal mode.
*/
#ifdef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD
- anx7447_mux_safemode(port, 1);
+ anx7447_mux_safemode(me, 1);
#endif
- 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);
+ rv = mux_write(me, ANX7447_REG_TCPC_SWITCH_0, sw_sel);
+ rv |= mux_write(me, ANX7447_REG_TCPC_SWITCH_1, sw_sel);
+ rv |= mux_write(me, ANX7447_REG_TCPC_AUX_SWITCH, aux_sw);
mux[port].state = mux_state;
@@ -619,18 +632,20 @@ static int anx7447_mux_set(int port, mux_state_t mux_state)
* normal mode, otherwise: keep safe mode.
*/
if (mux_type != USB_PD_MUX_NONE) {
- anx7447_configure_aux_src(port, 1);
- anx7447_mux_safemode(port, 0);
+ anx7447_configure_aux_src(me, 1);
+ anx7447_mux_safemode(me, 0);
} else
- anx7447_configure_aux_src(port, 0);
+ anx7447_configure_aux_src(me, 0);
#endif
return rv;
}
/* current mux state */
-static int anx7447_mux_get(int port, mux_state_t *mux_state)
+static int anx7447_mux_get(const struct usb_mux *me, mux_state_t *mux_state)
{
+ int port = me->usb_port;
+
*mux_state = mux[port].state;
return EC_SUCCESS;
@@ -650,7 +665,8 @@ static int anx7447_set_cc(int port, int pull)
}
/* Override for tcpci_tcpm_set_polarity */
-static int anx7447_set_polarity(int port, enum tcpc_cc_polarity polarity)
+static int anx7447_set_polarity(int port,
+ enum tcpc_cc_polarity polarity)
{
return tcpc_update8(port,
TCPC_REG_TCPC_CTRL,
diff --git a/driver/tcpm/anx7447.h b/driver/tcpm/anx7447.h
index 4da300884c..849b3c3189 100644
--- a/driver/tcpm/anx7447.h
+++ b/driver/tcpm/anx7447.h
@@ -3,6 +3,8 @@
* found in the LICENSE file.
*/
+#include "usb_mux.h"
+
/* USB Power delivery port management */
#ifndef __CROS_EC_USB_PD_TCPM_ANX7447_H
@@ -127,8 +129,9 @@ void anx7447_hpd_output_en(int port);
extern const struct tcpm_drv anx7447_tcpm_drv;
extern const struct usb_mux_driver anx7447_usb_mux_driver;
-void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq);
void anx7447_tcpc_clear_hpd_status(int port);
+void anx7447_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq);
/**
* Erase OCM flash if it's not empty
diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c
index 0e9635e6b1..938b65a14f 100644
--- a/driver/tcpm/anx74xx.c
+++ b/driver/tcpm/anx74xx.c
@@ -226,16 +226,18 @@ static void anx74xx_tcpc_discharge_vbus(int port, int enable)
*/
static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT];
-void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
+void anx74xx_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
int reg;
+ int port = me->usb_port;
- mux_read(port, ANX74XX_REG_HPD_CTRL_0, &reg);
+ mux_read(me, ANX74XX_REG_HPD_CTRL_0, &reg);
if (hpd_lvl)
reg |= ANX74XX_REG_HPD_OUT_DATA;
else
reg &= ~ANX74XX_REG_HPD_OUT_DATA;
- mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg);
+ mux_write(me, ANX74XX_REG_HPD_CTRL_0, reg);
if (hpd_irq) {
uint64_t now = get_time().val;
@@ -243,12 +245,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);
- mux_read(port, ANX74XX_REG_HPD_CTRL_0, &reg);
+ mux_read(me, ANX74XX_REG_HPD_CTRL_0, &reg);
reg &= ~ANX74XX_REG_HPD_OUT_DATA;
- mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg);
+ mux_write(me, ANX74XX_REG_HPD_CTRL_0, reg);
usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
reg |= ANX74XX_REG_HPD_OUT_DATA;
- mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg);
+ mux_write(me, ANX74XX_REG_HPD_CTRL_0, reg);
}
/* enforce 2-ms delay between HPD pulses */
hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
@@ -264,12 +266,13 @@ void anx74xx_tcpc_clear_hpd_status(int port)
}
#ifdef CONFIG_USB_PD_TCPM_MUX
-static int anx74xx_tcpm_mux_init(int port)
+static int anx74xx_tcpm_mux_init(const struct usb_mux *me)
{
/* Nothing to do here, ANX initializes its muxes
* as (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED)
*/
- anx[port].mux_state = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED;
+ anx[me->usb_port].mux_state = USB_PD_MUX_USB_ENABLED |
+ USB_PD_MUX_DP_ENABLED;
return EC_SUCCESS;
}
@@ -277,10 +280,11 @@ static int anx74xx_tcpm_mux_init(int port)
static int anx74xx_tcpm_mux_enter_safe_mode(int port)
{
int reg;
+ const struct usb_mux *me = &usb_muxes[port];
- if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, &reg))
+ if (mux_read(me, ANX74XX_REG_ANALOG_CTRL_2, &reg))
return EC_ERROR_UNKNOWN;
- if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg |
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_2, reg |
ANX74XX_REG_MODE_TRANS))
return EC_ERROR_UNKNOWN;
@@ -291,10 +295,11 @@ static int anx74xx_tcpm_mux_enter_safe_mode(int port)
static int anx74xx_tcpm_mux_exit_safe_mode(int port)
{
int reg;
+ const struct usb_mux *me = &usb_muxes[port];
- if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, &reg))
+ if (mux_read(me, ANX74XX_REG_ANALOG_CTRL_2, &reg))
return EC_ERROR_UNKNOWN;
- if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg &
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_2, reg &
~ANX74XX_REG_MODE_TRANS))
return EC_ERROR_UNKNOWN;
@@ -305,6 +310,7 @@ static int anx74xx_tcpm_mux_exit_safe_mode(int port)
static int anx74xx_tcpm_mux_exit(int port)
{
int reg;
+ const struct usb_mux *me = &usb_muxes[port];
/*
* Safe mode must be entered before any changes are made to the mux
@@ -318,18 +324,18 @@ static int anx74xx_tcpm_mux_exit(int port)
return EC_ERROR_UNKNOWN;
/* Disconnect aux from sbu */
- if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, &reg))
+ if (mux_read(me, ANX74XX_REG_ANALOG_CTRL_2, &reg))
return EC_ERROR_UNKNOWN;
- if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & 0xf))
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_2, reg & 0xf))
return EC_ERROR_UNKNOWN;
/* Clear Bit[7:0] R_SWITCH */
- if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, 0x0))
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_1, 0x0))
return EC_ERROR_UNKNOWN;
/* Clear Bit[7:4] R_SWITCH_H */
- if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, &reg))
+ if (mux_read(me, ANX74XX_REG_ANALOG_CTRL_5, &reg))
return EC_ERROR_UNKNOWN;
- if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg & 0x0f))
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_5, reg & 0x0f))
return EC_ERROR_UNKNOWN;
/* Exit safe mode */
@@ -345,6 +351,7 @@ static int anx74xx_mux_aux_to_sbu(int port, int polarity, int enabled)
int reg;
const int aux_mask = ANX74XX_REG_AUX_SWAP_SET_CC2 |
ANX74XX_REG_AUX_SWAP_SET_CC1;
+ const struct usb_mux *me = &usb_muxes[port];
/*
* Get the current value of analog_ctrl_2 register. Note, that safe mode
@@ -352,7 +359,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 (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, &reg))
+ if (mux_read(me, ANX74XX_REG_ANALOG_CTRL_2, &reg))
return EC_ERROR_UNKNOWN;
/* Assume aux_p/n lines are not connected */
@@ -366,25 +373,26 @@ 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 (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg))
+ if (mux_write(me, ANX74XX_REG_ANALOG_CTRL_2, reg))
return EC_ERROR_UNKNOWN;
return EC_SUCCESS;
}
-static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state)
+static int anx74xx_tcpm_mux_set(const struct usb_mux *me,
+ mux_state_t mux_state)
{
int ctrl5;
int ctrl1 = 0;
int rv;
- int port = i2c_addr;
+ int port = me->usb_port;
if (!(mux_state & ~USB_PD_MUX_POLARITY_INVERTED)) {
anx[port].mux_state = mux_state;
return anx74xx_tcpm_mux_exit(port);
}
- rv = mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, &ctrl5);
+ rv = mux_read(me, ANX74XX_REG_ANALOG_CTRL_5, &ctrl5);
if (rv)
return EC_ERROR_UNKNOWN;
ctrl5 &= 0x0f;
@@ -436,9 +444,9 @@ static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state)
return EC_ERROR_UNKNOWN;
/* Write updated pin assignment */
- rv = mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, ctrl1);
+ rv = mux_write(me, ANX74XX_REG_ANALOG_CTRL_1, ctrl1);
/* Write Rswitch config bits */
- rv |= mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, ctrl5);
+ rv |= mux_write(me, ANX74XX_REG_ANALOG_CTRL_5, ctrl5);
if (rv)
return EC_ERROR_UNKNOWN;
@@ -458,17 +466,18 @@ static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state)
}
/* current mux state */
-static int anx74xx_tcpm_mux_get(int port, mux_state_t *mux_state)
+static int anx74xx_tcpm_mux_get(const struct usb_mux *me,
+ mux_state_t *mux_state)
{
- *mux_state = anx[port].mux_state;
+ *mux_state = anx[me->usb_port].mux_state;
return EC_SUCCESS;
}
const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver = {
- .init = anx74xx_tcpm_mux_init,
- .set = anx74xx_tcpm_mux_set,
- .get = anx74xx_tcpm_mux_get,
+ .init = &anx74xx_tcpm_mux_init,
+ .set = &anx74xx_tcpm_mux_set,
+ .get = &anx74xx_tcpm_mux_get,
};
#endif /* CONFIG_USB_PD_TCPM_MUX */
@@ -764,6 +773,7 @@ static int anx74xx_tcpm_set_cc(int port, int pull)
static int anx74xx_tcpm_set_polarity(int port, enum tcpc_cc_polarity polarity)
{
int reg, mux_state, rv = EC_SUCCESS;
+ const struct usb_mux *me = &usb_muxes[port];
rv |= tcpc_read(port, ANX74XX_REG_CC_SOFTWARE_CTRL, &reg);
if (polarity_rm_dts(polarity)) /* Inform ANX to use CC2 */
@@ -779,7 +789,7 @@ static int anx74xx_tcpm_set_polarity(int port, enum tcpc_cc_polarity polarity)
mux_state = anx[port].mux_state & ~USB_PD_MUX_POLARITY_INVERTED;
if (polarity_rm_dts(polarity))
mux_state |= USB_PD_MUX_POLARITY_INVERTED;
- anx74xx_tcpm_mux_set(port, mux_state);
+ anx74xx_tcpm_mux_set(me, mux_state);
#endif
return rv;
}
diff --git a/driver/tcpm/anx74xx.h b/driver/tcpm/anx74xx.h
index 2648013abf..d7ba62bda3 100644
--- a/driver/tcpm/anx74xx.h
+++ b/driver/tcpm/anx74xx.h
@@ -5,6 +5,8 @@
* Author : Analogix Semiconductor.
*/
+#include "usb_mux.h"
+
/* USB Power delivery port management */
#ifndef __CROS_EC_USB_PD_TCPM_ANX74XX_H
@@ -216,8 +218,9 @@
extern const struct tcpm_drv anx74xx_tcpm_drv;
extern const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver;
void anx74xx_tcpc_set_vbus(int port, int enable);
-void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq);
void anx74xx_tcpc_clear_hpd_status(int port);
+void anx74xx_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq);
#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC
extern struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev;
diff --git a/driver/tcpm/anx7688.c b/driver/tcpm/anx7688.c
index bc3d1b8354..8b5a70cf73 100644
--- a/driver/tcpm/anx7688.c
+++ b/driver/tcpm/anx7688.c
@@ -144,12 +144,12 @@ static void anx7688_tcpc_alert(int port)
anx7688_update_hpd_enable(port);
}
-static int anx7688_mux_set(int port, mux_state_t mux_state)
+static int anx7688_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
int reg = 0;
int rv, polarity;
- rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
+ rv = mux_read(me, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
if (rv != EC_SUCCESS)
return rv;
@@ -160,14 +160,14 @@ static int anx7688_mux_set(int port, mux_state_t mux_state)
reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP;
/* ANX7688 needs to set bit0 */
- rv = mux_read(port, TCPC_REG_TCPC_CTRL, &polarity);
+ rv = mux_read(me, 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 mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg);
+ return mux_write(me, 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 77de4fca15..9151eaf841 100644
--- a/driver/tcpm/ps8xxx.c
+++ b/driver/tcpm/ps8xxx.c
@@ -17,6 +17,7 @@
#include "tcpci.h"
#include "tcpm.h"
#include "timer.h"
+#include "usb_mux.h"
#include "usb_pd.h"
#if !defined(CONFIG_USB_PD_TCPM_PS8751) && \
@@ -40,40 +41,42 @@
*/
static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT];
-static int dp_set_hpd(int port, int enable)
+static int dp_set_hpd(const struct usb_mux *me, int enable)
{
int reg;
int rv;
- rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, &reg);
+ rv = mux_read(me, MUX_IN_HPD_ASSERTION_REG, &reg);
if (rv)
return rv;
if (enable)
reg |= IN_HPD;
else
reg &= ~IN_HPD;
- return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg);
+ return mux_write(me, MUX_IN_HPD_ASSERTION_REG, reg);
}
-static int dp_set_irq(int port, int enable)
+static int dp_set_irq(const struct usb_mux *me, int enable)
{
-
int reg;
int rv;
- rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, &reg);
+ rv = mux_read(me, MUX_IN_HPD_ASSERTION_REG, &reg);
if (rv)
return rv;
if (enable)
reg |= HPD_IRQ;
else
reg &= ~HPD_IRQ;
- return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg);
+ return mux_write(me, MUX_IN_HPD_ASSERTION_REG, reg);
}
-void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
+void ps8xxx_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
- dp_set_hpd(port, hpd_lvl);
+ int port = me->usb_port;
+
+ dp_set_hpd(me, hpd_lvl);
if (hpd_irq) {
uint64_t now = get_time().val;
@@ -81,9 +84,9 @@ void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
if (now < hpd_deadline[port])
usleep(hpd_deadline[port] - now);
- dp_set_irq(port, 0);
+ dp_set_irq(me, 0);
usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
- dp_set_irq(port, hpd_irq);
+ dp_set_irq(me, hpd_irq);
}
/* enforce 2-ms delay between HPD pulses */
hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
@@ -380,26 +383,26 @@ struct i2c_stress_test_dev ps8xxx_i2c_stress_test_dev = {
};
#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */
-static int ps8xxx_mux_init(int port)
+static int ps8xxx_mux_init(const struct usb_mux *me)
{
- tcpci_tcpm_mux_init(port);
+ tcpci_tcpm_mux_init(me);
/* If this MUX is also the TCPC, then skip init */
- if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC))
+ if (!(me->flags & USB_MUX_FLAG_NOT_TCPC))
return EC_SUCCESS;
/* We always want to be a sink when this device is only being used as a mux
* to support external peripherals better.
*/
- return mux_write(port, TCPC_REG_ROLE_CTRL,
+ return mux_write(me, TCPC_REG_ROLE_CTRL,
TCPC_REG_ROLE_CTRL_SET(0, 1, TYPEC_CC_RD, TYPEC_CC_RD));
}
-static int ps8xxx_mux_enter_low_power_mode(int port)
+static int ps8xxx_mux_enter_low_power_mode(const struct usb_mux *me)
{
- mux_write(port, TCPC_REG_ROLE_CTRL,
+ mux_write(me, TCPC_REG_ROLE_CTRL,
TCPC_REG_ROLE_CTRL_SET(0, 0, TYPEC_CC_RP, TYPEC_CC_RP));
- return tcpci_tcpm_mux_enter_low_power(port);
+ return tcpci_tcpm_mux_enter_low_power(me);
}
/* This is meant for mux-only applications */
diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h
index ff78a74041..f865598e34 100644
--- a/driver/tcpm/ps8xxx.h
+++ b/driver/tcpm/ps8xxx.h
@@ -2,6 +2,7 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#include "usb_mux.h"
/* Parade Tech Type-C port controller */
@@ -93,7 +94,8 @@
#endif
extern const struct tcpm_drv ps8xxx_tcpm_drv;
-void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq);
+void ps8xxx_tcpc_update_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq);
#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC
extern struct i2c_stress_test_dev ps8xxx_i2c_stress_test_dev;
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 97768e6f1a..f8de27f20b 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -1099,19 +1099,19 @@ int tcpci_tcpm_init(int port)
* via mux init because tcpc_init won't run for the device. This is borrowed
* from tcpc_init.
*/
-int tcpci_tcpm_mux_init(int port)
+int tcpci_tcpm_mux_init(const struct usb_mux *me)
{
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))
+ if (!(me->flags & USB_MUX_FLAG_NOT_TCPC))
return EC_SUCCESS;
/* Wait for the device to exit low power state */
while (1) {
- error = mux_read(port, TCPC_REG_POWER_STATUS, &power_status);
+ error = mux_read(me, TCPC_REG_POWER_STATUS, &power_status);
/*
* If read succeeds and the uninitialized bit is clear, then
* initialization is complete.
@@ -1124,28 +1124,28 @@ int tcpci_tcpm_mux_init(int port)
}
/* Turn off all alerts and acknowledge any pending IRQ */
- error = mux_write16(port, TCPC_REG_ALERT_MASK, 0);
- error |= mux_write16(port, TCPC_REG_ALERT, 0xffff);
+ error = mux_write16(me, TCPC_REG_ALERT_MASK, 0);
+ error |= mux_write16(me, TCPC_REG_ALERT, 0xffff);
return error ? EC_ERROR_UNKNOWN : EC_SUCCESS;
}
-int tcpci_tcpm_mux_enter_low_power(int port)
+int tcpci_tcpm_mux_enter_low_power(const struct usb_mux *me)
{
/* If this MUX is also the TCPC, then skip low power */
- if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC))
+ if (!(me->flags & USB_MUX_FLAG_NOT_TCPC))
return EC_SUCCESS;
- return mux_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
+ return mux_write(me, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
}
-int tcpci_tcpm_mux_set(int port, mux_state_t mux_state)
+int tcpci_tcpm_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
- int reg = 0;
int rv;
+ int reg = 0;
/* Parameter is port only */
- rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
+ rv = mux_read(me, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
if (rv != EC_SUCCESS)
return rv;
@@ -1159,20 +1159,19 @@ int tcpci_tcpm_mux_set(int port, mux_state_t mux_state)
reg |= TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED;
/* Parameter is port only */
- return mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg);
+ return mux_write(me, TCPC_REG_CONFIG_STD_OUTPUT, reg);
}
/* Reads control register and updates mux_state accordingly */
-int tcpci_tcpm_mux_get(int port, mux_state_t *mux_state)
+int tcpci_tcpm_mux_get(const struct usb_mux *me, mux_state_t *mux_state)
{
- int reg = 0;
int rv;
+ int reg = 0;
*mux_state = 0;
/* Parameter is port only */
- rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
-
+ rv = mux_read(me, TCPC_REG_CONFIG_STD_OUTPUT, &reg);
if (rv != EC_SUCCESS)
return rv;
diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h
index 40b25f4fba..a4bc8f6b39 100644
--- a/driver/tcpm/tcpci.h
+++ b/driver/tcpm/tcpci.h
@@ -231,10 +231,10 @@ void tcpci_tcpc_discharge_vbus(int port, int enable);
#endif
void tcpci_tcpc_enable_auto_discharge_disconnect(int port, int enable);
-int tcpci_tcpm_mux_init(int i2c_addr);
-int tcpci_tcpm_mux_set(int i2c_addr, mux_state_t mux_state);
-int tcpci_tcpm_mux_get(int i2c_addr, mux_state_t *mux_state);
-int tcpci_tcpm_mux_enter_low_power(int port);
+int tcpci_tcpm_mux_init(const struct usb_mux *me);
+int tcpci_tcpm_mux_set(const struct usb_mux *me, mux_state_t mux_state);
+int tcpci_tcpm_mux_get(const struct usb_mux *me, mux_state_t *mux_state);
+int tcpci_tcpm_mux_enter_low_power(const struct usb_mux *me);
int tcpci_get_chip_info(int port, int live,
struct ec_response_pd_chip_info_v1 **chip_info);
#ifdef CONFIG_USBC_PPC
diff --git a/driver/usb_mux/amd_fp5.c b/driver/usb_mux/amd_fp5.c
index 3258552b49..1f61f7c765 100644
--- a/driver/usb_mux/amd_fp5.c
+++ b/driver/usb_mux/amd_fp5.c
@@ -11,7 +11,7 @@
#include "i2c.h"
#include "usb_mux.h"
-static inline int amd_fp5_mux_read(int port, uint8_t *val)
+static inline int amd_fp5_mux_read(const struct usb_mux *me, uint8_t *val)
{
uint8_t buf[3] = { 0 };
int rv;
@@ -21,23 +21,23 @@ static inline int amd_fp5_mux_read(int port, uint8_t *val)
if (rv)
return rv;
- *val = buf[port + 1];
+ *val = buf[me->usb_port + 1];
return EC_SUCCESS;
}
-static inline int amd_fp5_mux_write(int port, uint8_t val)
+static inline int amd_fp5_mux_write(const struct usb_mux *me, uint8_t val)
{
return i2c_write8(I2C_PORT_USB_MUX, AMD_FP5_MUX_I2C_ADDR_FLAGS,
- port, val);
+ me->usb_port, val);
}
-static int amd_fp5_init(int port)
+static int amd_fp5_init(const struct usb_mux *me)
{
return EC_SUCCESS;
}
-static int amd_fp5_set_mux(int port, mux_state_t mux_state)
+static int amd_fp5_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
uint8_t val = 0;
@@ -63,10 +63,10 @@ static int amd_fp5_set_mux(int port, mux_state_t mux_state)
val = (mux_state & USB_PD_MUX_POLARITY_INVERTED)
? AMD_FP5_MUX_DP_INVERTED : AMD_FP5_MUX_DP;
- return amd_fp5_mux_write(port, val);
+ return amd_fp5_mux_write(me, val);
}
-static int amd_fp5_get_mux(int port, mux_state_t *mux_state)
+static int amd_fp5_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
uint8_t val = AMD_FP5_MUX_SAFE;
@@ -78,12 +78,11 @@ static int amd_fp5_get_mux(int port, mux_state_t *mux_state)
if (!chipset_in_state(CHIPSET_STATE_HARD_OFF)) {
int rv;
- rv = amd_fp5_mux_read(port, &val);
+ rv = amd_fp5_mux_read(me, &val);
if (rv)
return rv;
}
-
switch (val) {
case AMD_FP5_MUX_USB:
*mux_state = USB_PD_MUX_USB_ENABLED;
@@ -115,19 +114,8 @@ static int amd_fp5_get_mux(int port, mux_state_t *mux_state)
return EC_SUCCESS;
}
-/*
- * The FP5 MUX can look like a retimer or a MUX. So create both tables
- * and use them as needed, until retimers become a type of MUX and
- * then we will only need one of these tables.
- *
- * TODO(b:147593660) Cleanup of retimers as muxes in a more
- * generalized mechanism
- */
-const struct usb_retimer_driver amd_fp5_usb_retimer = {
- .set = amd_fp5_set_mux,
-};
const struct usb_mux_driver amd_fp5_usb_mux_driver = {
- .init = amd_fp5_init,
- .set = amd_fp5_set_mux,
- .get = amd_fp5_get_mux,
+ .init = &amd_fp5_init,
+ .set = &amd_fp5_set_mux,
+ .get = &amd_fp5_get_mux,
};
diff --git a/driver/usb_mux/amd_fp5.h b/driver/usb_mux/amd_fp5.h
index ac1a7ce27e..7534ea0d8a 100644
--- a/driver/usb_mux/amd_fp5.h
+++ b/driver/usb_mux/amd_fp5.h
@@ -18,7 +18,4 @@
#define AMD_FP5_MUX_DP 0x0C
#define AMD_FP5_MUX_DP_INVERTED 0x1C
-extern const struct usb_mux_driver amd_fp5_usb_mux_driver;
-extern const struct usb_retimer_driver amd_fp5_usb_retimer;
-
#endif /* __CROS_EC_USB_MUX_AMD_FP5_H */
diff --git a/driver/usb_mux/anx7440.c b/driver/usb_mux/anx7440.c
index 1c9633c536..df3a9c2682 100644
--- a/driver/usb_mux/anx7440.c
+++ b/driver/usb_mux/anx7440.c
@@ -16,14 +16,16 @@
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
-static inline int anx7440_read(int port, uint8_t reg, int *val)
+static inline int anx7440_read(const struct usb_mux *me,
+ uint8_t reg, int *val)
{
- return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val);
+ return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val);
}
-static inline int anx7440_write(int port, uint8_t reg, uint8_t val)
+static inline int anx7440_write(const struct usb_mux *me,
+ uint8_t reg, uint8_t val)
{
- return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val);
+ return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val);
}
struct anx7440_id_t {
@@ -39,7 +41,7 @@ static const struct anx7440_id_t anx7440_device_ids[] = {
{ ANX7440_DEVICE_VERSION, ANX7440_REG_DEVICE_VERSION },
};
-static int anx7440_init(int port)
+static int anx7440_init(const struct usb_mux *me)
{
int i;
int val;
@@ -47,7 +49,7 @@ static int anx7440_init(int port)
/* Verify device id / version registers */
for (i = 0; i < ARRAY_SIZE(anx7440_device_ids); i++) {
- res = anx7440_read(port, anx7440_device_ids[i].reg, &val);
+ res = anx7440_read(me, anx7440_device_ids[i].reg, &val);
if (res)
return res;
@@ -59,11 +61,11 @@ static int anx7440_init(int port)
}
/* Writes control register to set switch mode */
-static int anx7440_set_mux(int port, mux_state_t mux_state)
+static int anx7440_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int reg, res;
- res = anx7440_read(port, ANX7440_REG_CHIP_CTRL, &reg);
+ res = anx7440_read(me, ANX7440_REG_CHIP_CTRL, &reg);
if (res)
return res;
@@ -75,16 +77,16 @@ static int anx7440_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
reg |= ANX7440_CHIP_CTRL_SW_FLIP;
- return anx7440_write(port, ANX7440_REG_CHIP_CTRL, reg);
+ return anx7440_write(me, ANX7440_REG_CHIP_CTRL, reg);
}
/* Reads control register and updates mux_state accordingly */
-static int anx7440_get_mux(int port, mux_state_t *mux_state)
+static int anx7440_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int reg, res;
*mux_state = 0;
- res = anx7440_read(port, ANX7440_REG_CHIP_CTRL, &reg);
+ res = anx7440_read(me, ANX7440_REG_CHIP_CTRL, &reg);
if (res)
return res;
diff --git a/driver/usb_mux/it5205.c b/driver/usb_mux/it5205.c
index e7911b80e3..95416547cd 100644
--- a/driver/usb_mux/it5205.c
+++ b/driver/usb_mux/it5205.c
@@ -14,14 +14,14 @@
#define MUX_STATE_DP_USB_MASK (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED)
-static int it5205_read(int port, uint8_t reg, int *val)
+static int it5205_read(const struct usb_mux *me, uint8_t reg, int *val)
{
- return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val);
+ return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val);
}
-static int it5205_write(int port, uint8_t reg, uint8_t val)
+static int it5205_write(const struct usb_mux *me, uint8_t reg, uint8_t val)
{
- return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val);
+ return i2c_write8(me->i2c_port, me->i2c_addr_flags, 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 port)
+static int it5205_init(const struct usb_mux *me)
{
int i, val, ret;
/* bit[0]: mux power on, bit[7-1]: reserved. */
- ret = it5205_write(port, IT5205_REG_MUXPDR, 0);
+ ret = it5205_write(me, 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(port, mux_chip_id_verify[i].reg, &val);
+ ret = it5205_read(me, mux_chip_id_verify[i].reg, &val);
if (ret)
return ret;
@@ -58,7 +58,7 @@ static int it5205_init(int port)
}
/* Writes control register to set switch mode */
-static int it5205_set_mux(int port, mux_state_t mux_state)
+static int it5205_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
uint8_t reg;
@@ -80,15 +80,15 @@ static int it5205_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
reg |= IT5205_POLARITY_INVERTED;
- return it5205_write(port, IT5205_REG_MUXCR, reg);
+ return it5205_write(me, IT5205_REG_MUXCR, reg);
}
/* Reads control register and updates mux_state accordingly */
-static int it5205_get_mux(int port, mux_state_t *mux_state)
+static int it5205_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int reg, ret;
- ret = it5205_read(port, IT5205_REG_MUXCR, &reg);
+ ret = it5205_read(me, IT5205_REG_MUXCR, &reg);
if (ret)
return ret;
@@ -113,18 +113,18 @@ static int it5205_get_mux(int port, mux_state_t *mux_state)
return EC_SUCCESS;
}
-static int it5205_enter_low_power_mode(int port)
+static int it5205_enter_low_power_mode(const struct usb_mux *me)
{
int rv;
/* Turn off all switches */
- rv = it5205_write(port, IT5205_REG_MUXCR, 0);
+ rv = it5205_write(me, IT5205_REG_MUXCR, 0);
if (rv)
return rv;
/* Power down mux */
- return it5205_write(port, IT5205_REG_MUXPDR, IT5205_MUX_POWER_DOWN);
+ return it5205_write(me, IT5205_REG_MUXPDR, IT5205_MUX_POWER_DOWN);
}
const struct usb_mux_driver it5205_usb_mux_driver = {
diff --git a/driver/usb_mux/pi3usb3x532.c b/driver/usb_mux/pi3usb3x532.c
index bf6d1f5a01..c3d22b8f61 100644
--- a/driver/usb_mux/pi3usb3x532.c
+++ b/driver/usb_mux/pi3usb3x532.c
@@ -11,7 +11,8 @@
#include "usb_mux.h"
#include "util.h"
-static int pi3usb3x532_read(int port, uint8_t reg, uint8_t *val)
+static int pi3usb3x532_read(const struct usb_mux *me,
+ uint8_t reg, uint8_t *val)
{
int read, res;
@@ -20,7 +21,7 @@ static int pi3usb3x532_read(int port, uint8_t reg, uint8_t *val)
* Second byte read will be vendor ID.
* Third byte read will be selection control.
*/
- res = i2c_read16(MUX_PORT(port), MUX_ADDR(port), 0, &read);
+ res = i2c_read16(me->i2c_port, me->i2c_addr_flags, 0, &read);
if (res)
return res;
@@ -32,32 +33,33 @@ static int pi3usb3x532_read(int port, uint8_t reg, uint8_t *val)
return EC_SUCCESS;
}
-static int pi3usb3x532_write(int port, uint8_t reg, uint8_t val)
+static int pi3usb3x532_write(const struct usb_mux *me,
+ uint8_t reg, uint8_t val)
{
if (reg != PI3USB3X532_REG_CONTROL)
return EC_ERROR_UNKNOWN;
- return i2c_write8(MUX_PORT(port), MUX_ADDR(port), 0, val);
+ return i2c_write8(me->i2c_port, me->i2c_addr_flags, 0, val);
}
-static int pi3usb3x532_reset(int port)
+static int pi3usb3x532_reset(const struct usb_mux *me)
{
return pi3usb3x532_write(
- port,
+ me,
PI3USB3X532_REG_CONTROL,
(PI3USB3X532_MODE_POWERDOWN & PI3USB3X532_CTRL_MASK) |
PI3USB3X532_CTRL_RSVD);
}
-static int pi3usb3x532_init(int port)
+static int pi3usb3x532_init(const struct usb_mux *me)
{
uint8_t val;
int res;
- res = pi3usb3x532_reset(port);
+ res = pi3usb3x532_reset(me);
if (res)
return res;
- res = pi3usb3x532_read(port, PI3USB3X532_REG_VENDOR, &val);
+ res = pi3usb3x532_read(me, PI3USB3X532_REG_VENDOR, &val);
if (res)
return res;
if (val != PI3USB3X532_VENDOR_ID)
@@ -67,7 +69,8 @@ static int pi3usb3x532_init(int port)
}
/* Writes control register to set switch mode */
-static int pi3usb3x532_set_mux(int port, mux_state_t mux_state)
+static int pi3usb3x532_set_mux(const struct usb_mux *me,
+ mux_state_t mux_state)
{
uint8_t reg = 0;
@@ -78,18 +81,19 @@ static int pi3usb3x532_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
reg |= PI3USB3X532_BIT_SWAP;
- return pi3usb3x532_write(port, PI3USB3X532_REG_CONTROL,
+ return pi3usb3x532_write(me, PI3USB3X532_REG_CONTROL,
reg | PI3USB3X532_CTRL_RSVD);
}
/* Reads control register and updates mux_state accordingly */
-static int pi3usb3x532_get_mux(int port, mux_state_t *mux_state)
+static int pi3usb3x532_get_mux(const struct usb_mux *me,
+ mux_state_t *mux_state)
{
uint8_t reg = 0;
uint8_t res;
*mux_state = 0;
- res = pi3usb3x532_read(port, PI3USB3X532_REG_CONTROL, &reg);
+ res = pi3usb3x532_read(me, PI3USB3X532_REG_CONTROL, &reg);
if (res)
return res;
diff --git a/driver/usb_mux/ps874x.c b/driver/usb_mux/ps874x.c
index 08f526d28a..fedb06b27c 100644
--- a/driver/usb_mux/ps874x.c
+++ b/driver/usb_mux/ps874x.c
@@ -11,32 +11,34 @@
#include "usb_mux.h"
#include "util.h"
-static inline int ps874x_read(int port, uint8_t reg, int *val)
+static inline int ps874x_read(const struct usb_mux *me,
+ uint8_t reg, int *val)
{
- return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port),
+ return i2c_read8(me->i2c_port, me->i2c_addr_flags,
reg, val);
}
-static inline int ps874x_write(int port, uint8_t reg, uint8_t val)
+static inline int ps874x_write(const struct usb_mux *me,
+ uint8_t reg, uint8_t val)
{
- return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port),
+ return i2c_write8(me->i2c_port, me->i2c_addr_flags,
reg, val);
}
-static int ps874x_init(int port)
+static int ps874x_init(const struct usb_mux *me)
{
int val;
int res;
/* Reset chip back to power-on state */
- res = ps874x_write(port, PS874X_REG_MODE, PS874X_MODE_POWER_DOWN);
+ res = ps874x_write(me, PS874X_REG_MODE, PS874X_MODE_POWER_DOWN);
if (res)
return res;
/*
* Verify revision / chip ID registers.
*/
- res = ps874x_read(port, PS874X_REG_REVISION_ID1, &val);
+ res = ps874x_read(me, PS874X_REG_REVISION_ID1, &val);
if (res)
return res;
@@ -52,19 +54,19 @@ static int ps874x_init(int port)
return EC_ERROR_UNKNOWN;
#endif
- res = ps874x_read(port, PS874X_REG_REVISION_ID2, &val);
+ res = ps874x_read(me, PS874X_REG_REVISION_ID2, &val);
if (res)
return res;
if (val != PS874X_REVISION_ID2)
return EC_ERROR_UNKNOWN;
- res = ps874x_read(port, PS874X_REG_CHIP_ID1, &val);
+ res = ps874x_read(me, PS874X_REG_CHIP_ID1, &val);
if (res)
return res;
if (val != PS874X_CHIP_ID1)
return EC_ERROR_UNKNOWN;
- res = ps874x_read(port, PS874X_REG_CHIP_ID2, &val);
+ res = ps874x_read(me, PS874X_REG_CHIP_ID2, &val);
if (res)
return res;
if (val != PS874X_CHIP_ID2)
@@ -74,7 +76,7 @@ static int ps874x_init(int port)
}
/* Writes control register to set switch mode */
-static int ps874x_set_mux(int port, mux_state_t mux_state)
+static int ps874x_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
uint8_t reg = 0;
@@ -85,16 +87,16 @@ static int ps874x_set_mux(int port, mux_state_t mux_state)
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
reg |= PS874X_MODE_POLARITY_INVERTED;
- return ps874x_write(port, PS874X_REG_MODE, reg);
+ return ps874x_write(me, PS874X_REG_MODE, reg);
}
/* Reads control register and updates mux_state accordingly */
-static int ps874x_get_mux(int port, mux_state_t *mux_state)
+static int ps874x_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int reg;
int res;
- res = ps874x_read(port, PS874X_REG_STATUS, &reg);
+ res = ps874x_read(me, PS874X_REG_STATUS, &reg);
if (res)
return res;
@@ -113,9 +115,10 @@ static int ps874x_get_mux(int port, mux_state_t *mux_state)
int ps874x_tune_usb_eq(int port, uint8_t tx, uint8_t rx)
{
int ret;
+ const struct usb_mux *me = &usb_muxes[port];
- ret = ps874x_write(port, PS874X_REG_USB_EQ_TX, tx);
- ret |= ps874x_write(port, PS874X_REG_USB_EQ_RX, rx);
+ ret = ps874x_write(me, PS874X_REG_USB_EQ_TX, tx);
+ ret |= ps874x_write(me, PS874X_REG_USB_EQ_RX, rx);
return ret;
}
diff --git a/driver/usb_mux/usb_mux.c b/driver/usb_mux/usb_mux.c
index 5bf057ed91..3d629a6ab0 100644
--- a/driver/usb_mux/usb_mux.c
+++ b/driver/usb_mux/usb_mux.c
@@ -32,100 +32,107 @@ enum mux_config_type {
USB_MUX_GET_MODE,
};
-/* Configure the retimer */
-static int configure_retimer(int port, enum mux_config_type config,
- mux_state_t mux_state)
+/* Configure the MUX */
+static int configure_mux(int port,
+ enum mux_config_type config,
+ mux_state_t *mux_state)
{
- int res = 0;
+ int rv = EC_SUCCESS;
+ const struct usb_mux *mux_ptr;
+
+ if (config == USB_MUX_SET_MODE ||
+ config == USB_MUX_GET_MODE) {
+ if (mux_state == NULL)
+ return EC_ERROR_INVAL;
- if (IS_ENABLED(CONFIG_USBC_MUX_RETIMER)) {
- const struct usb_retimer *retimer = &usb_retimers[port];
+ if (config == USB_MUX_GET_MODE)
+ *mux_state = USB_PD_MUX_NONE;
+ }
- if (!retimer->driver)
- return 0;
+ /*
+ * a MUX for a particular port can be a linked list chain of
+ * MUXes. So when we change one, we traverse the whole list
+ * to make sure they are all updated appropriately.
+ */
+ for (mux_ptr = &usb_muxes[port];
+ rv == EC_SUCCESS && mux_ptr != NULL;
+ mux_ptr = mux_ptr->next_mux) {
+ mux_state_t lcl_state;
+ const struct usb_mux_driver *drv = mux_ptr->driver;
switch (config) {
case USB_MUX_INIT:
- if (retimer->driver->init)
- res = retimer->driver->init(port);
+ if (drv && drv->init) {
+ rv = drv->init(mux_ptr);
+ if (rv)
+ break;
+ }
+
+ /* Apply board specific initialization */
+ if (mux_ptr->board_init)
+ rv = mux_ptr->board_init(mux_ptr);
+
break;
+
case USB_MUX_LOW_POWER:
- if (retimer->driver->enter_low_power_mode)
- res = retimer->driver->enter_low_power_mode(
- port);
+ if (drv && drv->enter_low_power_mode)
+ rv = drv->enter_low_power_mode(mux_ptr);
+
break;
+
case USB_MUX_SET_MODE:
- if (retimer->driver->set)
- res = retimer->driver->set(port, mux_state);
- break;
- default:
- break;
- }
- }
+ lcl_state = *mux_state;
- return res;
-}
+ if (mux_ptr->flags & USB_MUX_FLAG_SET_WITHOUT_FLIP)
+ lcl_state &= ~USB_PD_MUX_POLARITY_INVERTED;
-/* Configure the MUX */
-static int configure_mux(int port, enum mux_config_type config,
- mux_state_t *mux_state)
-{
- const struct usb_mux *mux = &usb_muxes[port];
- int res;
+ if (drv && drv->set) {
+ rv = drv->set(mux_ptr, lcl_state);
+ if (rv)
+ break;
+ }
- switch (config) {
- case USB_MUX_INIT:
- res = mux->driver->init(port);
- if (res)
- break;
+ /* Apply board specific setting */
+ if (mux_ptr->board_set)
+ rv = mux_ptr->board_set(mux_ptr, lcl_state);
- res = configure_retimer(port, config, USB_PD_MUX_NONE);
- if (res)
break;
- /* Apply board specific initialization */
- if (mux->board_init)
- res = mux->board_init(port);
-
- break;
- case USB_MUX_LOW_POWER:
- if (mux->driver->enter_low_power_mode) {
- res = mux->driver->enter_low_power_mode(port);
- if (res)
- break;
- }
- res = configure_retimer(port, config, USB_PD_MUX_NONE);
- break;
- case USB_MUX_SET_MODE:
- res = mux->driver->set(port, *mux_state);
- if (res)
+ case USB_MUX_GET_MODE:
+ /*
+ * This is doing a GET_CC on all of the MUXes in the
+ * chain and ORing them together. This will make sure
+ * if one of the MUX values has FLIP turned off that
+ * we will end up with the correct value in the end.
+ */
+ if (drv && drv->get) {
+ rv = drv->get(mux_ptr, &lcl_state);
+ if (rv)
+ break;
+ *mux_state |= lcl_state;
+ }
break;
- res = configure_retimer(port, config, *mux_state);
- break;
- case USB_MUX_GET_MODE:
- res = mux->driver->get(port, mux_state);
- break;
+ }
}
- if (res)
- CPRINTS("mux config:%d, port:%d, res:%d", config, port, res);
+ if (rv)
+ CPRINTS("mux config:%d, port:%d, rv:%d",
+ config, port, rv);
- return res;
+ return rv;
}
static void enter_low_power_mode(int port)
{
- mux_state_t mux_state = USB_PD_MUX_NONE;
-
/*
- * Set LPM flag regardless of method presence or method failure. We want
- * know know that we tried to put the device in low power mode so we can
- * re-initialize the device on the next access.
+ * Set LPM flag regardless of method presence or method failure. We
+ * want know know that we tried to put the device in low power mode
+ * so we can re-initialize the device on the next access.
*/
flags[port] |= USB_MUX_FLAG_IN_LPM;
/* Apply any low power customization if present */
- configure_mux(port, USB_MUX_LOW_POWER, &mux_state);
+ configure_mux(port, USB_MUX_LOW_POWER, NULL);
}
static inline void exit_low_power_mode(int port)
@@ -137,11 +144,9 @@ static inline void exit_low_power_mode(int port)
void usb_mux_init(int port)
{
- mux_state_t mux_state = USB_PD_MUX_NONE;
-
ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT);
- configure_mux(port, USB_MUX_INIT, &mux_state);
+ configure_mux(port, USB_MUX_INIT, NULL);
/* Device is always out of LPM after initialization. */
flags[port] &= ~USB_MUX_FLAG_IN_LPM;
@@ -225,16 +230,17 @@ void usb_mux_flip(int port)
void usb_mux_hpd_update(int port, int hpd_lvl, int hpd_irq)
{
- const struct usb_mux *mux = &usb_muxes[port];
mux_state_t mux_state;
+ const struct usb_mux *mux_ptr = &usb_muxes[port];
- if (mux->hpd_update)
- mux->hpd_update(port, hpd_lvl, hpd_irq);
+ for (; mux_ptr; mux_ptr = mux_ptr->next_mux)
+ if (mux_ptr->hpd_update)
+ mux_ptr->hpd_update(mux_ptr, hpd_lvl, hpd_irq);
if (!configure_mux(port, USB_MUX_GET_MODE, &mux_state)) {
mux_state |= (hpd_lvl ? USB_PD_MUX_HPD_LVL : 0) |
- (hpd_irq ? USB_PD_MUX_HPD_IRQ : 0);
- configure_retimer(port, USB_MUX_SET_MODE, mux_state);
+ (hpd_irq ? USB_PD_MUX_HPD_IRQ : 0);
+ configure_mux(port, USB_MUX_SET_MODE, &mux_state);
}
}
@@ -297,7 +303,7 @@ static enum ec_status hc_usb_pd_mux_info(struct host_cmd_handler_args *args)
const struct ec_params_usb_pd_mux_info *p = args->params;
struct ec_response_usb_pd_mux_info *r = args->response;
int port = p->port;
- const struct usb_mux *mux = &usb_muxes[port];
+ const struct usb_mux *me = &usb_muxes[port];
mux_state_t mux_state;
if (port >= board_get_usb_pd_port_count())
@@ -311,7 +317,7 @@ static enum ec_status hc_usb_pd_mux_info(struct host_cmd_handler_args *args)
/* Clear HPD IRQ event since we're about to inform host of it. */
if (IS_ENABLED(CONFIG_USB_MUX_VIRTUAL) &&
(r->flags & USB_PD_MUX_HPD_IRQ) &&
- (mux->hpd_update == &virtual_hpd_update)) {
+ (me->hpd_update == &virtual_hpd_update)) {
usb_mux_hpd_update(port, r->flags & USB_PD_MUX_HPD_LVL, 0);
}
diff --git a/driver/usb_mux/virtual.c b/driver/usb_mux/virtual.c
index 6f80157deb..5a2f4a62d3 100644
--- a/driver/usb_mux/virtual.c
+++ b/driver/usb_mux/virtual.c
@@ -33,7 +33,7 @@ static inline void virtual_mux_update_state(int port, mux_state_t mux_state)
}
}
-static int virtual_init(int port)
+static int virtual_init(const struct usb_mux *me)
{
return EC_SUCCESS;
}
@@ -42,8 +42,10 @@ static int virtual_init(int port)
* Set the state of our 'virtual' mux. The EC does not actually control this
* mux, so update the desired state, then notify the host of the update.
*/
-static int virtual_set_mux(int port, mux_state_t mux_state)
+static int virtual_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
+ int port = me->usb_port;
+
/* Current USB & DP mux status + existing HPD related mux status */
mux_state_t new_mux_state = (mux_state & ~USB_PD_MUX_HPD_STATE) |
(virtual_mux_state[port] & USB_PD_MUX_HPD_STATE);
@@ -58,15 +60,19 @@ static int virtual_set_mux(int port, mux_state_t mux_state)
* control this mux, and the EC has no way of knowing its actual status,
* we return the desired state here.
*/
-static int virtual_get_mux(int port, mux_state_t *mux_state)
+static int virtual_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
+ int port = me->usb_port;
+
*mux_state = virtual_mux_state[port];
return EC_SUCCESS;
}
-void virtual_hpd_update(int port, int hpd_lvl, int hpd_irq)
+void virtual_hpd_update(const struct usb_mux *me, int hpd_lvl, int hpd_irq)
{
+ int port = me->usb_port;
+
/* Current HPD related mux status + existing USB & DP mux status */
mux_state_t new_mux_state = (hpd_lvl ? USB_PD_MUX_HPD_LVL : 0) |
(hpd_irq ? USB_PD_MUX_HPD_IRQ : 0) |
diff --git a/include/config.h b/include/config.h
index 1e59237b5e..92c38fbc91 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3974,15 +3974,6 @@
#undef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2
/*
- * Type-C retimer mux configuration tends to be set on a specific
- * driver's need basis. After including the board/baseboard.h files
- * the drivers will be checked and if one of these are needed it will
- * automatically be included. This does not stop a board/basebord.h
- * configration from defining these as well.
- */
-#undef CONFIG_USBC_MUX_RETIMER
-
-/*
* Type-C retimer drivers to be used.
*/
#undef CONFIG_USBC_RETIMER_INTEL_BB
@@ -4336,6 +4327,9 @@
/******************************************************************************/
/* USB port switch */
+/* Allow run-time completion of the usb mux driver structure */
+#undef CONFIG_USB_MUX_RUNTIME_CONFIG
+
/* Support the AMD FP5 USB/DP Mux */
#undef CONFIG_USB_MUX_AMD_FP5
@@ -4960,19 +4954,6 @@
/*****************************************************************************/
/*
- * Define derived config options for Retimer chips. There are
- * for convenience. Any retimer driver that also needs USBC MUX Retimers
- * will not have to include it in their own board/baseboard.h file.
- */
-#if defined(CONFIG_USBC_RETIMER_INTEL_BB) || \
- defined(CONFIG_USBC_RETIMER_PI3DPX1207) || \
- defined(CONFIG_USBC_RETIMER_PS8802) || \
- defined(CONFIG_USBC_RETIMER_PS8818)
-#define CONFIG_USBC_MUX_RETIMER
-#endif
-
-/*****************************************************************************/
-/*
* Define CONFIG_LIBCRYPTOC if a board needs to read secret data from the
* anti-rollback block.
*/
diff --git a/include/usb_mux.h b/include/usb_mux.h
index 35350222f0..b606656b61 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -9,10 +9,15 @@
#define __CROS_EC_USB_MUX_H
#include "ec_commands.h"
+#include "i2c.h"
#include "tcpm.h"
#include "usb_charge.h"
#include "usb_pd.h"
+/* Flags used for usb_mux.flags */
+#define USB_MUX_FLAG_NOT_TCPC BIT(0) /* TCPC/MUX device used only as MUX */
+#define USB_MUX_FLAG_SET_WITHOUT_FLIP BIT(1) /* SET should not flip */
+
/*
* USB-C mux state
*
@@ -21,42 +26,36 @@
*/
typedef uint8_t mux_state_t;
-/*
- * 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) (usb_muxes[port].port_addr >> 8)
-#define MUX_ADDR(port) (usb_muxes[port].port_addr & 0xFF)
-
/* Mux driver function pointers */
+struct usb_mux;
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).
+ * 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 usb port of mux (not port_addr)
+ * @param me usb_mux
* @return EC_SUCCESS on success, non-zero error code on failure.
*/
- int (*init)(int port);
+ int (*init)(const struct usb_mux *me);
/**
* Set USB mux state.
*
- * @param port usb port of mux (not port_addr)
+ * @param me usb_mux
* @param mux_state State to set mux to.
* @return EC_SUCCESS on success, non-zero error code on failure.
*/
- int (*set)(int port, mux_state_t mux_state);
+ int (*set)(const struct usb_mux *me, mux_state_t mux_state);
/**
* Get current state of USB mux.
*
- * @param port usb port of mux (not port_addr)
+ * @param me usb_mux
* @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, mux_state_t *mux_state);
+ int (*get)(const struct usb_mux *me, mux_state_t *mux_state);
/**
* Optional method that is called after the mux fully disconnects.
@@ -65,46 +64,69 @@ struct usb_mux_driver {
* where the TCPC is actively used since the PD state machine
* will put the chip into lower power mode.
*
- * @param port usb port of mux (not port_addr)
+ * @param me usb_mux
* @return EC_SUCCESS on success, non-zero error code on failure.
*/
- int (*enter_low_power_mode)(int port);
+ int (*enter_low_power_mode)(const struct usb_mux *me);
};
-/* Flags used for usb_mux.flags */
-#define USB_MUX_FLAG_NOT_TCPC BIT(0) /* TCPC/MUX device used only as MUX */
-
/* Describes a USB mux present in the system */
struct usb_mux {
/*
- * Used by driver. Muxes that are also the TCPC do not need to specify
- * anything for this as they will use the values from tcpc_config_t. If
- * this mux is also a TCPC but not used as the TCPC then use the
- * MUX_PORT_AND_ADDR to pack the i2c port and i2c address into this
- * field and use the USB_MUX_FLAG_NOT_TCPC flag.
+ * This is index into usb_muxes that points to the start of the
+ * possible chain of usb_mux entries that this entry is on.
*/
- const int port_addr;
+ int usb_port;
+
+ /*
+ * I2C port and address. This is optional if your MUX is not
+ * an I2C interface. If this is the case, use usb_port to
+ * index an exernal array to track your connection parameters,
+ * if they are needed. One case of this would be a driver
+ * that will use usb_port as an index into tcpc_config_t to
+ * gather the necessary information to communicate with the MUX
+ */
+ uint16_t i2c_port;
+ uint16_t i2c_addr_flags;
/* Run-time flags with prefix USB_MUX_FLAG_ */
- const uint32_t flags;
+ uint32_t flags;
/* Mux driver */
const struct usb_mux_driver *driver;
+ /* Linked list chain of secondary MUXes. NULL terminated */
+ const struct usb_mux *next_mux;
+
/**
* Optional method for tuning for USB mux during mux->driver->init().
*
- * @param port usb port of mux (not port_addr)
+ * @param me usb_mux
* @return EC_SUCCESS on success, non-zero error code on failure.
*/
- int (*board_init)(int port);
+ int (*board_init)(const struct usb_mux *me);
/*
+ * USB mux/retimer board specific set mux_state.
+ *
+ * @param me usb_mux
+ * @param mux_state State to set mode to.
+ * @return EC_SUCCESS on success, non-zero error code on failure.
+ */
+ int (*board_set)(const struct usb_mux *me, mux_state_t mux_state);
+
+ /*
+ * TODO: Consider moving this to usb_mux_driver struct
+ *
* USB Type-C DP alt mode support. Notify Type-C controller
* there is DP dongle hot-plug.
- * TODO: Move this function to usb_mux_driver struct.
+ *
+ * @param me usb_mux
+ * @param hpd_lvl Level
+ * @param hpd_irq IRQ
*/
- void (*hpd_update)(int port, int hpd_lvl, int hpd_irq);
+ void (*hpd_update)(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq);
};
/* Supported USB mux drivers */
@@ -116,114 +138,47 @@ extern const struct usb_mux_driver ps874x_usb_mux_driver;
extern const struct usb_mux_driver tcpm_usb_mux_driver;
extern const struct usb_mux_driver virtual_usb_mux_driver;
-/* Supported hpd_update functions */
-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 */
+#ifdef CONFIG_USB_MUX_RUNTIME_CONFIG
extern struct usb_mux usb_muxes[];
+#else
+extern const struct usb_mux usb_muxes[];
+#endif
-/*
- * Retimer driver function pointers
- *
- * The retimer driver is driven by calls to the MUX API. These are not
- * called directly anywhere else in the code.
- */
-struct usb_retimer_driver {
- /**
- * Initialize USB retimer. This is called every time the MUX is
- * access after being put in a fully disconnected state (low power
- * mode).
- *
- * @param port usb port of redriver (not port_addr)
- * @return EC_SUCCESS on success, non-zero error code on failure.
- */
- int (*init)(int port);
-
- /**
- * Put USB retimer in low power mode. This is called when the MUX
- * is put into low power mode).
- *
- * @param port usb port of redriver (not port_addr)
- * @return EC_SUCCESS on success, non-zero error code on failure.
- */
- int (*enter_low_power_mode)(int port);
-
- /**
- * Set USB retimer state.
- *
- * @param port usb port of retimer (not port_addr)
- * @param mux_state State to set retimer mode to.
- * @return EC_SUCCESS on success, non-zero error code on failure.
- */
- int (*set)(int port, mux_state_t mux_state);
-};
-
-/* Describes a USB retimer present in the system */
-struct usb_retimer {
- /*
- * All of the fields are provided on an as needed basis.
- * If your retimer does not use the provided machanism then
- * values would not be set (defaulted to 0/NULL). This
- * defaulting includes the driver field, which would indicate
- * no retimer driver is to be called.
- */
-
- /* I2C port and slave address */
- const int i2c_port;
- uint16_t i2c_addr_flags;
-
- /* Driver interfaces for this retimer */
- const struct usb_retimer_driver *driver;
-
- /*
- * USB retimer board specific tune on set mux_state.
- *
- * @param port usb port of retimer (not port_addr)
- * @param mux_state State to set retimer mode to.
- * @return EC_SUCCESS on success, non-zero error code on failure.
- */
- int (*tune)(int port, mux_state_t mux_state);
-};
-
-/*
- * USB retimers present in system, ordered by PD port #, defined at
- * board-level
- */
-extern struct usb_retimer usb_retimers[];
+/* Supported hpd_update functions */
+void virtual_hpd_update(const struct usb_mux *me, int hpd_lvl, int hpd_irq);
/*
* 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)
+static inline int mux_write(const struct usb_mux *me, 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);
+ return me->flags & USB_MUX_FLAG_NOT_TCPC
+ ? i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val)
+ : tcpc_write(me->usb_port, reg, val);
}
-static inline int mux_read(int port, int reg, int *val)
+static inline int mux_read(const struct usb_mux *me, 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);
+ return me->flags & USB_MUX_FLAG_NOT_TCPC
+ ? i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val)
+ : tcpc_read(me->usb_port, reg, val);
}
-static inline int mux_write16(int port, int reg, int val)
+static inline int mux_write16(const struct usb_mux *me, 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);
+ return me->flags & USB_MUX_FLAG_NOT_TCPC
+ ? i2c_write16(me->i2c_port, me->i2c_addr_flags, reg, val)
+ : tcpc_write16(me->usb_port, reg, val);
}
-static inline int mux_read16(int port, int reg, int *val)
+static inline int mux_read16(const struct usb_mux *me, 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);
+ return me->flags & USB_MUX_FLAG_NOT_TCPC
+ ? i2c_read16(me->i2c_port, me->i2c_addr_flags, reg, val)
+ : tcpc_read16(me->usb_port, reg, val);
}
#endif /* CONFIG_USB_PD_TCPM_MUX */
diff --git a/test/usb_pd_int.c b/test/usb_pd_int.c
index b1701c5f96..280c7c192f 100644
--- a/test/usb_pd_int.c
+++ b/test/usb_pd_int.c
@@ -19,7 +19,7 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
.driver = &mock_usb_mux_driver,
}
diff --git a/test/usb_typec_drp_acc_trysrc.c b/test/usb_typec_drp_acc_trysrc.c
index c7a0790d1e..479e103c38 100644
--- a/test/usb_typec_drp_acc_trysrc.c
+++ b/test/usb_typec_drp_acc_trysrc.c
@@ -23,7 +23,7 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
.driver = &mock_usb_mux_driver,
}
diff --git a/util/ectool.c b/util/ectool.c
index 97e44779fe..2426d3ba3b 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -16,7 +16,6 @@
#include <signal.h>
#include <stdbool.h>
-#include "anx74xx.h"
#include "battery.h"
#include "comm-host.h"
#include "chipset.h"
@@ -31,7 +30,6 @@
#include "lock/gec_lock.h"
#include "misc_util.h"
#include "panic.h"
-#include "ps8xxx.h"
#include "usb_pd.h"
/* Maximum flash size (16 MB, conservative) */