diff options
Diffstat (limited to 'driver/usb_mux')
-rw-r--r-- | driver/usb_mux/amd_fp5.c | 162 | ||||
-rw-r--r-- | driver/usb_mux/amd_fp5.h | 21 | ||||
-rw-r--r-- | driver/usb_mux/amd_fp6.c | 233 | ||||
-rw-r--r-- | driver/usb_mux/amd_fp6.h | 31 | ||||
-rw-r--r-- | driver/usb_mux/anx3443.c | 162 | ||||
-rw-r--r-- | driver/usb_mux/anx3443.h | 40 | ||||
-rw-r--r-- | driver/usb_mux/anx7440.c | 112 | ||||
-rw-r--r-- | driver/usb_mux/anx7440.h | 40 | ||||
-rw-r--r-- | driver/usb_mux/anx7451.c | 153 | ||||
-rw-r--r-- | driver/usb_mux/anx7451.h | 58 | ||||
-rw-r--r-- | driver/usb_mux/it5205.c | 172 | ||||
-rw-r--r-- | driver/usb_mux/it5205.h | 66 | ||||
-rw-r--r-- | driver/usb_mux/pi3usb3x532.c | 132 | ||||
-rw-r--r-- | driver/usb_mux/pi3usb3x532.h | 78 | ||||
-rw-r--r-- | driver/usb_mux/ps8740.c | 127 | ||||
-rw-r--r-- | driver/usb_mux/ps8740.h | 91 | ||||
-rw-r--r-- | driver/usb_mux/ps8743.c | 158 | ||||
-rw-r--r-- | driver/usb_mux/ps8743.h | 32 | ||||
-rw-r--r-- | driver/usb_mux/ps8822.c | 134 | ||||
-rw-r--r-- | driver/usb_mux/ps8822.h | 66 | ||||
-rw-r--r-- | driver/usb_mux/tusb1064.c | 116 | ||||
-rw-r--r-- | driver/usb_mux/tusb1064.h | 130 | ||||
-rw-r--r-- | driver/usb_mux/usb_mux.c | 524 | ||||
-rw-r--r-- | driver/usb_mux/virtual.c | 125 |
24 files changed, 0 insertions, 2963 deletions
diff --git a/driver/usb_mux/amd_fp5.c b/driver/usb_mux/amd_fp5.c deleted file mode 100644 index b77edf2826..0000000000 --- a/driver/usb_mux/amd_fp5.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * AMD FP5 USB/DP Mux. - */ - -#include "amd_fp5.h" -#include "chipset.h" -#include "common.h" -#include "hooks.h" -#include "i2c.h" -#include "queue.h" -#include "timer.h" -#include "usb_mux.h" - -static mux_state_t saved_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static inline int amd_fp5_mux_read(const struct usb_mux *me, uint8_t *val) -{ - uint8_t buf[3] = { 0 }; - int rv; - - rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags, - NULL, 0, buf, 3); - if (rv) - return rv; - - *val = buf[me->usb_port + 1]; - - return EC_SUCCESS; -} - -static inline int amd_fp5_mux_write(const struct usb_mux *me, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, - me->usb_port, val); -} - -static int amd_fp5_init(const struct usb_mux *me) -{ - return EC_SUCCESS; -} - -static int amd_fp5_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - uint8_t val = 0; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - saved_mux_state[me->usb_port] = mux_state; - - /* - * This MUX is on the FP5 SoC. If that device is not powered then - * we either have to complain that it is not powered or if we were - * setting the state to OFF, then go ahead and report that we did - * it because a powered down MUX is off. - */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return (mux_state == USB_PD_MUX_NONE) - ? EC_SUCCESS - : EC_ERROR_NOT_POWERED; - - if ((mux_state & USB_PD_MUX_USB_ENABLED) && - (mux_state & USB_PD_MUX_DP_ENABLED)) - val = (mux_state & USB_PD_MUX_POLARITY_INVERTED) - ? AMD_FP5_MUX_DOCK_INVERTED : AMD_FP5_MUX_DOCK; - else if (mux_state & USB_PD_MUX_USB_ENABLED) - val = (mux_state & USB_PD_MUX_POLARITY_INVERTED) - ? AMD_FP5_MUX_USB_INVERTED : AMD_FP5_MUX_USB; - else if (mux_state & USB_PD_MUX_DP_ENABLED) - val = (mux_state & USB_PD_MUX_POLARITY_INVERTED) - ? AMD_FP5_MUX_DP_INVERTED : AMD_FP5_MUX_DP; - - return amd_fp5_mux_write(me, val); -} - -static int amd_fp5_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - uint8_t val = AMD_FP5_MUX_SAFE; - - /* - * This MUX is on the FP5 SoC. Only access the device if we - * have power. If that device is not powered then claim the - * state to be NONE, which is SAFE. - */ - if (!chipset_in_state(CHIPSET_STATE_HARD_OFF)) { - int rv; - - 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; - break; - case AMD_FP5_MUX_USB_INVERTED: - *mux_state = USB_PD_MUX_USB_ENABLED | - USB_PD_MUX_POLARITY_INVERTED; - break; - case AMD_FP5_MUX_DOCK: - *mux_state = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED; - break; - case AMD_FP5_MUX_DOCK_INVERTED: - *mux_state = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED - | USB_PD_MUX_POLARITY_INVERTED; - break; - case AMD_FP5_MUX_DP: - *mux_state = USB_PD_MUX_DP_ENABLED; - break; - case AMD_FP5_MUX_DP_INVERTED: - *mux_state = USB_PD_MUX_DP_ENABLED | - USB_PD_MUX_POLARITY_INVERTED; - break; - case AMD_FP5_MUX_SAFE: - default: - *mux_state = USB_PD_MUX_NONE; - break; - } - - return EC_SUCCESS; -} - -static struct queue const chipset_reset_queue - = QUEUE_NULL(CONFIG_USB_PD_PORT_MAX_COUNT, struct usb_mux *); - -static void amd_fp5_chipset_reset_delay(void) -{ - struct usb_mux *me; - int rv; - bool unused; - - while (queue_remove_unit(&chipset_reset_queue, &me)) { - rv = amd_fp5_set_mux(me, saved_mux_state[me->usb_port], - &unused); - if (rv) - ccprints("C%d restore mux rv:%d", me->usb_port, rv); - } -} -DECLARE_DEFERRED(amd_fp5_chipset_reset_delay); - -/* - * The AP's internal USB-C mux is reset when AP resets, so wait for - * it to be ready and then restore the previous setting. - */ -static int amd_fp5_chipset_reset(const struct usb_mux *me) -{ - queue_add_unit(&chipset_reset_queue, &me); - hook_call_deferred(&amd_fp5_chipset_reset_delay_data, 200 * MSEC); - return EC_SUCCESS; -} - -const struct usb_mux_driver amd_fp5_usb_mux_driver = { - .init = &amd_fp5_init, - .set = &amd_fp5_set_mux, - .get = &amd_fp5_get_mux, - .chipset_reset = &amd_fp5_chipset_reset, -}; diff --git a/driver/usb_mux/amd_fp5.h b/driver/usb_mux/amd_fp5.h deleted file mode 100644 index 7534ea0d8a..0000000000 --- a/driver/usb_mux/amd_fp5.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * AMD FP5 USB/DP Mux. - */ - -#ifndef __CROS_EC_USB_MUX_AMD_FP5_H -#define __CROS_EC_USB_MUX_AMD_FP5_H - -#define AMD_FP5_MUX_I2C_ADDR_FLAGS 0x5C - -#define AMD_FP5_MUX_SAFE 0x00 -#define AMD_FP5_MUX_USB 0x02 -#define AMD_FP5_MUX_USB_INVERTED 0x11 -#define AMD_FP5_MUX_DOCK 0x06 -#define AMD_FP5_MUX_DOCK_INVERTED 0x19 -#define AMD_FP5_MUX_DP 0x0C -#define AMD_FP5_MUX_DP_INVERTED 0x1C - -#endif /* __CROS_EC_USB_MUX_AMD_FP5_H */ diff --git a/driver/usb_mux/amd_fp6.c b/driver/usb_mux/amd_fp6.c deleted file mode 100644 index b2d5ae1fb4..0000000000 --- a/driver/usb_mux/amd_fp6.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * AMD FP6 USB/DP Mux. - */ - -#include "amd_fp6.h" -#include "chipset.h" -#include "common.h" -#include "hooks.h" -#include "i2c.h" -#include "queue.h" -#include "timer.h" -#include "usb_mux.h" - -#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -/* - * The recommendation from "3.3.2 Command Timeout" is 250ms, - * however empirical testing found that a 100ms timeout is sufficient. - */ -#define WRITE_CMD_TIMEOUT_MS 100 - -/* Command retry interval */ -#define CMD_RETRY_INTERVAL_MS 1000 - -/* - * Local data structure for saving mux state so it can be restored after - * an AP reset. - */ -static struct { - const struct usb_mux *mux; - uint8_t val; - bool write_pending; -} saved_mux_state[USBC_PORT_COUNT]; - -static int amd_fp6_mux_port0_read(const struct usb_mux *me, uint8_t *val) -{ - uint8_t payload[3] = { 0 }; - bool mux_ready; - - RETURN_ERROR(i2c_xfer(me->i2c_port, me->i2c_addr_flags, NULL, 0, - payload, 3)); - - /* - * payload[0]: Status/ID - * payload[1]: Port 0 Control/Status - * payload[2]: Port 1 Control/Status (unused on FP6) - */ - mux_ready = !!((payload[0] >> AMD_FP6_MUX_PD_STATUS_OFFSET) - & AMD_FP6_MUX_PD_STATUS_READY); - - if (!mux_ready) - return EC_ERROR_BUSY; - *val = payload[1]; - - return EC_SUCCESS; -} - -static int amd_fp6_mux_port0_write(const struct usb_mux *me, uint8_t write_val) -{ - uint8_t read_val; - uint8_t port_status; - timestamp_t start; - - /* Check if mux is ready */ - RETURN_ERROR(amd_fp6_mux_port0_read(me, &read_val)); - - /* Write control register */ - RETURN_ERROR( - i2c_write8(me->i2c_port, me->i2c_addr_flags, 0, write_val)); - - /* - * Read status until write command finishes or times out. - * The mux has an internal opaque timeout, which we wrap with our own - * timeout to be safe. - */ - start = get_time(); - while (time_since32(start) < WRITE_CMD_TIMEOUT_MS * MSEC) { - - RETURN_ERROR(amd_fp6_mux_port0_read(me, &read_val)); - port_status = read_val >> AMD_FP6_MUX_PORT_STATUS_OFFSET; - - if (port_status == AMD_FP6_MUX_PORT_CMD_COMPLETE) - return EC_SUCCESS; - else if (port_status == AMD_FP6_MUX_PORT_CMD_TIMEOUT) - return EC_ERROR_TIMEOUT; - else if (port_status == AMD_FP6_MUX_PORT_CMD_BUSY) - msleep(5); - else - return EC_ERROR_UNKNOWN; - } - - return EC_ERROR_TIMEOUT; -} - -/* - * Keep trying to write the saved mux state until successful or SOC leaves - * S0 power state. - */ -static void amd_fp6_set_mux_retry(void); -DECLARE_DEFERRED(amd_fp6_set_mux_retry); -static void amd_fp6_set_mux_retry(void) -{ - int rv; - bool try_again = false; - - /* - * Mux can only be written in S0, stop trying. - * Will try again on chipset_resume. - */ - if (!chipset_in_state(CHIPSET_STATE_ON)) - return; - - for (int i = 0; i < ARRAY_SIZE(saved_mux_state); i++) { - /* Make sure mux_state is initialized */ - if (saved_mux_state[i].mux == NULL || - !saved_mux_state[i].write_pending) - continue; - - rv = amd_fp6_mux_port0_write(saved_mux_state[i].mux, - saved_mux_state[i].val); - - if (rv) - try_again = true; - else - saved_mux_state[i].write_pending = false; - } - if (try_again) - hook_call_deferred(&amd_fp6_set_mux_retry_data, - CMD_RETRY_INTERVAL_MS * MSEC); -} - - -static int amd_fp6_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - uint8_t val; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - if (mux_state == USB_PD_MUX_NONE) - /* - * LOW_POWER must be set when connection mode is - * set to 00b (safe state) - */ - val = AMD_FP6_MUX_MODE_SAFE | AMD_FP6_MUX_LOW_POWER; - else if ((mux_state & USB_PD_MUX_USB_ENABLED) && - (mux_state & USB_PD_MUX_DP_ENABLED)) - val = AMD_FP6_MUX_MODE_DOCK; - else if (mux_state & USB_PD_MUX_USB_ENABLED) - val = AMD_FP6_MUX_MODE_USB; - else if (mux_state & USB_PD_MUX_DP_ENABLED) - val = AMD_FP6_MUX_MODE_DP; - else { - CPRINTSUSB("C%d: unhandled mux_state %x\n", me->usb_port, - mux_state); - return EC_ERROR_INVAL; - } - - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - val |= AMD_FP6_MUX_ORIENTATION; - - saved_mux_state[me->usb_port].mux = me; - saved_mux_state[me->usb_port].val = val; - - /* Mux is not powered in Z1 */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return (mux_state == USB_PD_MUX_NONE) ? EC_SUCCESS - : EC_ERROR_NOT_POWERED; - - saved_mux_state[me->usb_port].write_pending = true; - amd_fp6_set_mux_retry(); - - return EC_SUCCESS; -} - -static int amd_fp6_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - uint8_t val; - bool inverted; - uint8_t mode; - - /* Mux is not powered in Z1 */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return USB_PD_MUX_NONE; - - RETURN_ERROR(amd_fp6_mux_port0_read(me, &val)); - - mode = (val & AMD_FP6_MUX_MODE_MASK); - inverted = !!(val & AMD_FP6_MUX_ORIENTATION); - - if (mode == AMD_FP6_MUX_MODE_USB) - *mux_state = USB_PD_MUX_USB_ENABLED; - else if (mode == AMD_FP6_MUX_MODE_DP) - *mux_state = USB_PD_MUX_DP_ENABLED; - else if (mode == AMD_FP6_MUX_MODE_DOCK) - *mux_state = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED; - else /* AMD_FP6_MUX_MODE_SAFE */ - *mux_state = USB_PD_MUX_NONE; - - if (inverted) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -/* - * The FP6 USB Mux will not be ready for writing until *sometime* after S0. - */ -static void amd_fp6_chipset_resume(void) -{ - for (int i = 0; i < ARRAY_SIZE(saved_mux_state); i++) - saved_mux_state[i].write_pending = true; - hook_call_deferred(&amd_fp6_set_mux_retry_data, - CMD_RETRY_INTERVAL_MS * MSEC); -} -DECLARE_HOOK(HOOK_CHIPSET_RESUME, amd_fp6_chipset_resume, HOOK_PRIO_DEFAULT); - -static int amd_fp6_chipset_reset(const struct usb_mux *me) -{ - amd_fp6_chipset_resume(); - return EC_SUCCESS; -} - -const struct usb_mux_driver amd_fp6_usb_mux_driver = { - .set = &amd_fp6_set_mux, - .get = &amd_fp6_get_mux, - .chipset_reset = &amd_fp6_chipset_reset -}; diff --git a/driver/usb_mux/amd_fp6.h b/driver/usb_mux/amd_fp6.h deleted file mode 100644 index 913903e4c4..0000000000 --- a/driver/usb_mux/amd_fp6.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * AMD FP6 USB/DP Mux. - */ - -#ifndef __CROS_EC_USB_MUX_AMD_FP6_H -#define __CROS_EC_USB_MUX_AMD_FP6_H - -#define AMD_FP6_C0_MUX_I2C_ADDR 0x5C -#define AMD_FP6_C4_MUX_I2C_ADDR 0x52 - -#define AMD_FP6_MUX_MODE_SAFE 0x0 -#define AMD_FP6_MUX_MODE_USB 0x1 -#define AMD_FP6_MUX_MODE_DP 0x2 -#define AMD_FP6_MUX_MODE_DOCK 0x3 -#define AMD_FP6_MUX_MODE_MASK GENMASK(1, 0) - -#define AMD_FP6_MUX_ORIENTATION BIT(4) -#define AMD_FP6_MUX_LOW_POWER BIT(5) - -#define AMD_FP6_MUX_PORT_STATUS_OFFSET 6 -#define AMD_FP6_MUX_PORT_CMD_BUSY 0x0 -#define AMD_FP6_MUX_PORT_CMD_COMPLETE 0x1 -#define AMD_FP6_MUX_PORT_CMD_TIMEOUT 0x2 - -#define AMD_FP6_MUX_PD_STATUS_READY BIT(5) -#define AMD_FP6_MUX_PD_STATUS_OFFSET 1 - -#endif /* __CROS_EC_USB_MUX_AMD_FP6_H */ diff --git a/driver/usb_mux/anx3443.c b/driver/usb_mux/anx3443.c deleted file mode 100644 index 2e57f4d30c..0000000000 --- a/driver/usb_mux/anx3443.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ANX3443: 10G Active Mux (6x4) with - * Integrated Re-timers for USB3.2/DisplayPort - */ - -#include "anx3443.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "i2c.h" -#include "time.h" -#include "usb_mux.h" -#include "util.h" - -/* - * Empirical testing found it takes ~12ms to wake mux. - * Setting timeout to 20ms for some buffer. - */ -#define ANX3443_I2C_WAKE_TIMEOUT_MS 20 -#define ANX3443_I2C_WAKE_RETRY_DELAY_US 500 - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -static inline int anx3443_read(const struct usb_mux *me, - uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static inline int anx3443_write(const struct usb_mux *me, - uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static int anx3443_power_off(const struct usb_mux *me) -{ - /* - * The mux will not send an acknowledgment when powered off, so ignore - * response and always return success. - */ - anx3443_write(me, ANX3443_REG_POWER_CNTRL, ANX3443_POWER_CNTRL_OFF); - return EC_SUCCESS; -} - -static int anx3443_wake_up(const struct usb_mux *me) -{ - timestamp_t start; - int rv; - int val; - - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return EC_ERROR_NOT_POWERED; - - /* Keep reading top register until mux wakes up or timesout */ - start = get_time(); - do { - rv = anx3443_read(me, 0x0, &val); - if (!rv) - break; - usleep(ANX3443_I2C_WAKE_RETRY_DELAY_US); - } while (time_since32(start) < ANX3443_I2C_WAKE_TIMEOUT_MS * MSEC); - if (rv) { - CPRINTS("ANX3443: Failed to wake mux rv:%d", rv); - return EC_ERROR_TIMEOUT; - } - - /* ULTRA_LOW_POWER must always be disabled (Fig 2-2) */ - RETURN_ERROR(anx3443_write(me, ANX3443_REG_ULTRA_LOW_POWER, - ANX3443_ULTRA_LOW_POWER_DIS)); - - return EC_SUCCESS; -} - -static int anx3443_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - int reg; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - /* Mux is not powered in Z1 */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return (mux_state == USB_PD_MUX_NONE) ? EC_SUCCESS - : EC_ERROR_NOT_POWERED; - - /* To disable both DP and USB the mux must be powered off. */ - if (!(mux_state & (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED))) - return anx3443_power_off(me); - - RETURN_ERROR(anx3443_wake_up(me)); - - /* ULP_CFG_MODE_EN overrides pin control. Always set it */ - reg = ANX3443_ULP_CFG_MODE_EN; - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= ANX3443_ULP_CFG_MODE_USB_EN; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= ANX3443_ULP_CFG_MODE_DP_EN; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= ANX3443_ULP_CFG_MODE_FLIP; - - return anx3443_write(me, ANX3443_REG_ULP_CFG_MODE, reg); -} - -static int anx3443_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg; - - /* Mux is not powered in Z1 */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return USB_PD_MUX_NONE; - - RETURN_ERROR(anx3443_wake_up(me)); - - *mux_state = 0; - RETURN_ERROR(anx3443_read(me, ANX3443_REG_ULP_CFG_MODE, ®)); - - if (reg & ANX3443_ULP_CFG_MODE_USB_EN) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & ANX3443_ULP_CFG_MODE_DP_EN) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & ANX3443_ULP_CFG_MODE_FLIP) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -static int anx3443_init(const struct usb_mux *me) -{ - uint64_t now; - bool unused; - - /* - * ANX3443 requires 30ms to power on. EC and ANX3443 are on the same - * power rail, so just wait 30ms since EC boot. - */ - now = get_time().val; - if (now < ANX3443_I2C_READY_DELAY) - usleep(ANX3443_I2C_READY_DELAY - now); - - RETURN_ERROR(anx3443_wake_up(me)); - - /* - * Note that bypassing the usb_mux API is okay for internal driver calls - * since the task calling init already holds this port's mux lock. - */ - /* Default to USB mode */ - RETURN_ERROR(anx3443_set_mux(me, USB_PD_MUX_USB_ENABLED, &unused)); - - return EC_SUCCESS; -} - -const struct usb_mux_driver anx3443_usb_mux_driver = { - .init = anx3443_init, - .set = anx3443_set_mux, - .get = anx3443_get_mux, -}; diff --git a/driver/usb_mux/anx3443.h b/driver/usb_mux/anx3443.h deleted file mode 100644 index b505f993ea..0000000000 --- a/driver/usb_mux/anx3443.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ANX3443: 10G Active Mux (6x4) with - * Integrated Re-timers for USB3.2/DisplayPort - */ - -#ifndef __CROS_EC_USB_MUX_ANX3443_H -#define __CROS_EC_USB_MUX_ANX3443_H - -#define ANX3443_I2C_READY_DELAY (30 * MSEC) - -/* I2C interface addresses */ -#define ANX3443_I2C_ADDR0_FLAGS 0x10 -#define ANX3443_I2C_ADDR1_FLAGS 0x14 -#define ANX3443_I2C_ADDR2_FLAGS 0x16 -#define ANX3443_I2C_ADDR3_FLAGS 0x11 - -/* This register is not documented in datasheet. */ -#define ANX3443_REG_POWER_CNTRL 0x2B -#define ANX3443_POWER_CNTRL_OFF 0xFF - - -/* Ultra low power control register */ -#define ANX3443_REG_ULTRA_LOW_POWER 0xE6 -#define ANX3443_ULTRA_LOW_POWER_EN 0x06 -#define ANX3443_ULTRA_LOW_POWER_DIS 0x00 - -/* Mux control register */ -#define ANX3443_REG_ULP_CFG_MODE 0xF8 -#define ANX3443_ULP_CFG_MODE_EN BIT(4) -#define ANX3443_ULP_CFG_MODE_SWAP BIT(3) -#define ANX3443_ULP_CFG_MODE_FLIP BIT(2) -#define ANX3443_ULP_CFG_MODE_DP_EN BIT(1) -#define ANX3443_ULP_CFG_MODE_USB_EN BIT(0) - -extern const struct usb_mux_driver anx3443_usb_mux_driver; - -#endif /* __CROS_EC_USB_MUX_ANX3443_H */ diff --git a/driver/usb_mux/anx7440.c b/driver/usb_mux/anx7440.c deleted file mode 100644 index 89e593217d..0000000000 --- a/driver/usb_mux/anx7440.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Analogix ANX7440 USB Type-C Active mux with - * Integrated Re-timers for USB3.1/DisplayPort. - */ - -#include "anx7440.h" -#include "common.h" -#include "console.h" -#include "i2c.h" -#include "usb_mux.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -static inline int anx7440_read(const struct usb_mux *me, - uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static inline int anx7440_write(const struct usb_mux *me, - uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -struct anx7440_id_t { - uint8_t val; - uint8_t reg; -}; - -static const struct anx7440_id_t anx7440_device_ids[] = { - { ANX7440_VENDOR_ID_L, ANX7440_REG_VENDOR_ID_L }, - { ANX7440_VENDOR_ID_H, ANX7440_REG_VENDOR_ID_H }, - { ANX7440_DEVICE_ID_L, ANX7440_REG_DEVICE_ID_L }, - { ANX7440_DEVICE_ID_H, ANX7440_REG_DEVICE_ID_H }, - { ANX7440_DEVICE_VERSION, ANX7440_REG_DEVICE_VERSION }, -}; - -static int anx7440_init(const struct usb_mux *me) -{ - int i; - int val; - int res; - - /* Verify device id / version registers */ - for (i = 0; i < ARRAY_SIZE(anx7440_device_ids); i++) { - res = anx7440_read(me, anx7440_device_ids[i].reg, &val); - if (res) - return res; - - if (val != anx7440_device_ids[i].val) - return EC_ERROR_UNKNOWN; - } - - return EC_SUCCESS; -} - -/* Writes control register to set switch mode */ -static int anx7440_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - int reg, res; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - res = anx7440_read(me, ANX7440_REG_CHIP_CTRL, ®); - if (res) - return res; - - reg &= ~ANX7440_CHIP_CTRL_SW_OP_MODE_CLEAR; - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= ANX7440_CHIP_CTRL_SW_OP_MODE_USB; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= ANX7440_CHIP_CTRL_SW_OP_MODE_DP; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= ANX7440_CHIP_CTRL_SW_FLIP; - - return anx7440_write(me, ANX7440_REG_CHIP_CTRL, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int anx7440_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg, res; - - *mux_state = 0; - res = anx7440_read(me, ANX7440_REG_CHIP_CTRL, ®); - if (res) - return res; - - if (reg & ANX7440_CHIP_CTRL_OP_MODE_FINAL_USB) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & ANX7440_CHIP_CTRL_OP_MODE_FINAL_DP) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & ANX7440_CHIP_CTRL_FINAL_FLIP) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -const struct usb_mux_driver anx7440_usb_mux_driver = { - .init = anx7440_init, - .set = anx7440_set_mux, - .get = anx7440_get_mux, - /* TODO(b/146683781): add low power mode */ -}; diff --git a/driver/usb_mux/anx7440.h b/driver/usb_mux/anx7440.h deleted file mode 100644 index 2147e3146a..0000000000 --- a/driver/usb_mux/anx7440.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Analogix ANX7440 USB Type-C Active mux with - * Integrated Re-timers for USB3.1/DisplayPort. - */ - -#ifndef __CROS_EC_USB_MUX_ANX7440_H -#define __CROS_EC_USB_MUX_ANX7440_H - -/* I2C interface address */ -#define ANX7440_I2C_ADDR1_FLAGS 0x10 -#define ANX7440_I2C_ADDR2_FLAGS 0x12 -#define I2C_ADDR_USB_MUX0_FLAGS ANX7440_I2C_ADDR1_FLAGS -#define I2C_ADDR_USB_MUX1_FLAGS ANX7440_I2C_ADDR2_FLAGS - -/* Vendor / Device Id registers and expected fused values */ -#define ANX7440_REG_VENDOR_ID_L 0x00 -#define ANX7440_VENDOR_ID_L 0xaa -#define ANX7440_REG_VENDOR_ID_H 0x01 -#define ANX7440_VENDOR_ID_H 0xaa -#define ANX7440_REG_DEVICE_ID_L 0x02 -#define ANX7440_DEVICE_ID_L 0x40 -#define ANX7440_REG_DEVICE_ID_H 0x03 -#define ANX7440_DEVICE_ID_H 0x74 -#define ANX7440_REG_DEVICE_VERSION 0x04 -#define ANX7440_DEVICE_VERSION 0xCB - -/* Chip control register for checking mux state */ -#define ANX7440_REG_CHIP_CTRL 0x05 -#define ANX7440_CHIP_CTRL_FINAL_FLIP BIT(6) -#define ANX7440_CHIP_CTRL_OP_MODE_FINAL_DP BIT(5) -#define ANX7440_CHIP_CTRL_OP_MODE_FINAL_USB BIT(4) -#define ANX7440_CHIP_CTRL_SW_FLIP BIT(2) -#define ANX7440_CHIP_CTRL_SW_OP_MODE_DP BIT(1) -#define ANX7440_CHIP_CTRL_SW_OP_MODE_USB BIT(0) -#define ANX7440_CHIP_CTRL_SW_OP_MODE_CLEAR 0x7 - -#endif /* __CROS_EC_USB_MUX_ANX7440_H */ diff --git a/driver/usb_mux/anx7451.c b/driver/usb_mux/anx7451.c deleted file mode 100644 index 42fdb1f078..0000000000 --- a/driver/usb_mux/anx7451.c +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ANX7451: 10G Active Mux (4x4) with - * Integrated Re-timers for USB3.2/DisplayPort - */ - -#include "anx7451.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "i2c.h" -#include "time.h" -#include "usb_mux.h" -#include "util.h" - -/* - * Empirical testing found it takes ~12ms to wake mux. - * Setting timeout to 20ms for some buffer. - */ -#define ANX7451_I2C_WAKE_TIMEOUT_MS 20 -#define ANX7451_I2C_WAKE_RETRY_DELAY_US 500 - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -static inline int anx7451_read(const struct usb_mux *me, - uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static inline int anx7451_write(const struct usb_mux *me, - uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static int anx7451_power_off(const struct usb_mux *me) -{ - /* - * The mux will not send an acknowledgment when powered off, so ignore - * response and always return success. - */ - anx7451_write(me, ANX7451_REG_POWER_CNTRL, ANX7451_POWER_CNTRL_OFF); - return EC_SUCCESS; -} - -static int anx7451_wake_up(const struct usb_mux *me) -{ - timestamp_t start; - int rv; - int val; - uint16_t usb_i2c_addr = board_anx7451_get_usb_i2c_addr(me); - - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return EC_ERROR_NOT_POWERED; - - /* Keep reading top register until mux wakes up or timesout */ - start = get_time(); - do { - rv = anx7451_read(me, 0x0, &val); - if (!rv) - break; - usleep(ANX7451_I2C_WAKE_RETRY_DELAY_US); - } while (time_since32(start) < ANX7451_I2C_WAKE_TIMEOUT_MS * MSEC); - if (rv) { - CPRINTS("ANX7451: Failed to wake mux rv:%d", rv); - return EC_ERROR_TIMEOUT; - } - - /* ULTRA_LOW_POWER must always be disabled (Fig 2-2) */ - RETURN_ERROR(anx7451_write(me, ANX7451_REG_ULTRA_LOW_POWER, - ANX7451_ULTRA_LOW_POWER_DIS)); - - /* - * Configure ANX7451 USB I2C address. - * Shift 1 bit to make 7 bit address an 8 bit address. - */ - RETURN_ERROR( - anx7451_write(me, ANX7451_REG_USB_I2C_ADDR, usb_i2c_addr << 1)); - - /* b/185276137: Fix ANX7451 upstream AUX FLIP */ - RETURN_ERROR(i2c_write8(me->i2c_port, usb_i2c_addr, - ANX7451_REG_USB_AUX_FLIP_CTRL, - ANX7451_USB_AUX_FLIP_EN)); - - return EC_SUCCESS; -} - -static int anx7451_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - int reg; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - /* - * Mux is not powered in Z1, and will start up in USB mode. Ensure any - * mux sets when off get run again so we don't leave the retimer on with - * the None mode set - */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return EC_ERROR_NOT_POWERED; - - /* To disable both DP and USB the mux must be powered off. */ - if (!(mux_state & (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED))) - return anx7451_power_off(me); - - RETURN_ERROR(anx7451_wake_up(me)); - - /* ULP_CFG_MODE_EN overrides pin control. Always set it */ - reg = ANX7451_ULP_CFG_MODE_EN; - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= ANX7451_ULP_CFG_MODE_USB_EN; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= ANX7451_ULP_CFG_MODE_DP_EN; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= ANX7451_ULP_CFG_MODE_FLIP; - - return anx7451_write(me, ANX7451_REG_ULP_CFG_MODE, reg); -} - -static int anx7451_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg; - - /* Mux is not powered in Z1 */ - if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) - return USB_PD_MUX_NONE; - - RETURN_ERROR(anx7451_wake_up(me)); - - *mux_state = 0; - RETURN_ERROR(anx7451_read(me, ANX7451_REG_ULP_CFG_MODE, ®)); - - if (reg & ANX7451_ULP_CFG_MODE_USB_EN) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & ANX7451_ULP_CFG_MODE_DP_EN) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & ANX7451_ULP_CFG_MODE_FLIP) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -const struct usb_mux_driver anx7451_usb_mux_driver = { - .set = anx7451_set_mux, - .get = anx7451_get_mux, - /* Low power mode is not supported on ANX7451 */ -}; diff --git a/driver/usb_mux/anx7451.h b/driver/usb_mux/anx7451.h deleted file mode 100644 index 7eefb6e79e..0000000000 --- a/driver/usb_mux/anx7451.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ANX7451: 10G Active Mux (4x4) with - * Integrated Re-timers for USB3.2/DisplayPort - */ - -#ifndef __CROS_EC_USB_MUX_ANX7451_H -#define __CROS_EC_USB_MUX_ANX7451_H - -#include "usb_mux.h" - -/* I2C interface addresses */ -#define ANX7451_I2C_ADDR0_FLAGS 0x10 -#define ANX7451_I2C_ADDR1_FLAGS 0x14 -#define ANX7451_I2C_ADDR2_FLAGS 0x16 -#define ANX7451_I2C_ADDR3_FLAGS 0x11 - -/* This register is not documented in datasheet. */ -#define ANX7451_REG_POWER_CNTRL 0x2B -#define ANX7451_POWER_CNTRL_OFF 0xFF - -/* - * Ultra low power control register. - * On ANX7451, this register should always be 0 (disabled). - * See figure 2-2 in family programming guide. - */ -#define ANX7451_REG_ULTRA_LOW_POWER 0xE6 -/* #define ANX7451_ULTRA_LOW_POWER_EN 0x06 */ -#define ANX7451_ULTRA_LOW_POWER_DIS 0x00 - -/* Mux control register */ -#define ANX7451_REG_ULP_CFG_MODE 0xF8 -#define ANX7451_ULP_CFG_MODE_EN BIT(4) -#define ANX7451_ULP_CFG_MODE_SWAP BIT(3) -#define ANX7451_ULP_CFG_MODE_FLIP BIT(2) -#define ANX7451_ULP_CFG_MODE_DP_EN BIT(1) -#define ANX7451_ULP_CFG_MODE_USB_EN BIT(0) - -/* Register to set USB I2C address, defaults to 0x29 (7-bit) */ -#define ANX7451_REG_USB_I2C_ADDR 0x38 - -/* ANX7451 AUX FLIP control */ -#define ANX7451_REG_USB_AUX_FLIP_CTRL 0xA4 -#define ANX7451_USB_AUX_FLIP_EN 0x20 - -extern const struct usb_mux_driver anx7451_usb_mux_driver; - -/* - * ANX7451 uses a separate i2c address for USB configuration registers. - * This address is not controlled by address straps and defaults to 0x29. - * This address may conflict with other ANX74* parts. Implement - * board_anx7451_get_usb_i2c_addr to set a non-conflicting 7-bit address. - */ -uint16_t board_anx7451_get_usb_i2c_addr(const struct usb_mux *me); - -#endif /* __CROS_EC_USB_MUX_ANX7451_H */ diff --git a/driver/usb_mux/it5205.c b/driver/usb_mux/it5205.c deleted file mode 100644 index 0cfecdeda0..0000000000 --- a/driver/usb_mux/it5205.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ITE IT5205 Type-C USB alternate mode mux. - */ - -#include "common.h" -#include "i2c.h" -#include "it5205.h" -#include "util.h" - -#define MUX_STATE_DP_USB_MASK (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED) - -static int it5205_read(const struct usb_mux *me, uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static int it5205_write(const struct usb_mux *me, uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val); -} - -static int it5205h_sbu_update(const struct usb_mux *me, uint8_t reg, - uint8_t mask, enum mask_update_action action) -{ - return i2c_update8(me->i2c_port, IT5205H_SBU_I2C_ADDR_FLAGS, - reg, mask, action); -} - -static int it5205h_sbu_field_update(const struct usb_mux *me, uint8_t reg, - uint8_t field_mask, uint8_t set_value) -{ - return i2c_field_update8(me->i2c_port, IT5205H_SBU_I2C_ADDR_FLAGS, - reg, field_mask, set_value); -} - -struct mux_chip_id_t { - uint8_t chip_id; - uint8_t reg; -}; - -static const struct mux_chip_id_t mux_chip_id_verify[] = { - { '5', IT5205_REG_CHIP_ID3}, - { '2', IT5205_REG_CHIP_ID2}, - { '0', IT5205_REG_CHIP_ID1}, - { '5', IT5205_REG_CHIP_ID0}, -}; - -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(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(me, mux_chip_id_verify[i].reg, &val); - if (ret) - return ret; - - if (val != mux_chip_id_verify[i].chip_id) - return EC_ERROR_UNKNOWN; - } - - if (IS_ENABLED(CONFIG_USB_MUX_IT5205H_SBU_OVP)) { - RETURN_ERROR(it5205h_sbu_field_update(me, IT5205H_REG_VSR, - IT5205H_VREF_SELECT_MASK, - IT5205H_VREF_SELECT_3_3V)); - - RETURN_ERROR(it5205h_sbu_field_update(me, IT5205H_REG_CSBUOVPSR, - IT5205H_OVP_SELECT_MASK, - IT5205H_OVP_3_68V)); - - RETURN_ERROR(it5205h_sbu_update(me, IT5205H_REG_ISR, - IT5205H_ISR_CSBU_MASK, MASK_CLR)); - - RETURN_ERROR(it5205h_enable_csbu_switch(me, true)); - } - - return EC_SUCCESS; -} - -enum ec_error_list it5205h_enable_csbu_switch(const struct usb_mux *me, bool en) -{ - return it5205h_sbu_update(me, IT5205H_REG_CSBUSR, - IT5205H_CSBUSR_SWITCH, en ? MASK_SET : MASK_CLR); -} - -/* Writes control register to set switch mode */ -static int it5205_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - uint8_t reg; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - switch (mux_state & MUX_STATE_DP_USB_MASK) { - case USB_PD_MUX_USB_ENABLED: - reg = IT5205_USB; - break; - case USB_PD_MUX_DP_ENABLED: - reg = IT5205_DP; - break; - case MUX_STATE_DP_USB_MASK: - reg = IT5205_DP_USB; - break; - default: - reg = 0; - break; - } - - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= IT5205_POLARITY_INVERTED; - - return it5205_write(me, IT5205_REG_MUXCR, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int it5205_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg, ret; - - ret = it5205_read(me, IT5205_REG_MUXCR, ®); - if (ret) - return ret; - - switch (reg & IT5205_DP_USB_CTRL_MASK) { - case IT5205_USB: - *mux_state = USB_PD_MUX_USB_ENABLED; - break; - case IT5205_DP: - *mux_state = USB_PD_MUX_DP_ENABLED; - break; - case IT5205_DP_USB: - *mux_state = MUX_STATE_DP_USB_MASK; - break; - default: - *mux_state = 0; - break; - } - - if (reg & IT5205_POLARITY_INVERTED) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -static int it5205_enter_low_power_mode(const struct usb_mux *me) -{ - int rv; - - /* Turn off all switches */ - rv = it5205_write(me, IT5205_REG_MUXCR, 0); - - if (rv) - return rv; - - /* Power down mux */ - return it5205_write(me, IT5205_REG_MUXPDR, IT5205_MUX_POWER_DOWN); -} - -const struct usb_mux_driver it5205_usb_mux_driver = { - .init = &it5205_init, - .set = &it5205_set_mux, - .get = &it5205_get_mux, - .enter_low_power_mode = &it5205_enter_low_power_mode, -}; diff --git a/driver/usb_mux/it5205.h b/driver/usb_mux/it5205.h deleted file mode 100644 index 0fb9f009f6..0000000000 --- a/driver/usb_mux/it5205.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * ITE IT5205 Type-C USB alternate mode mux. - */ - -#ifndef __CROS_EC_IT5205_H -#define __CROS_EC_IT5205_H - -#include "stdbool.h" -#include "usb_mux.h" -#include "usb_mux/it5205_public.h" - -/* Chip ID registers */ -#define IT5205_REG_CHIP_ID3 0x4 -#define IT5205_REG_CHIP_ID2 0x5 -#define IT5205_REG_CHIP_ID1 0x6 -#define IT5205_REG_CHIP_ID0 0x7 - -/* MUX power down register */ -#define IT5205_REG_MUXPDR 0x10 -#define IT5205_MUX_POWER_DOWN BIT(0) - -/* MUX control register */ -#define IT5205_REG_MUXCR 0x11 -#define IT5205_POLARITY_INVERTED BIT(4) - -#define IT5205_DP_USB_CTRL_MASK 0x0f -#define IT5205_DP 0x0f -#define IT5205_DP_USB 0x03 -#define IT5205_USB 0x07 - - -/* IT5205-H SBU module */ - -/* I2C address for SBU switch control */ -#define IT5205H_SBU_I2C_ADDR_FLAGS 0x6a - -/* Vref Select Register */ -#define IT5205H_REG_VSR 0x10 -#define IT5205H_VREF_SELECT_MASK 0x30 -#define IT5205H_VREF_SELECT_3_3V 0x00 -#define IT5205H_VREF_SELECT_OFF 0x20 - -/* CSBU OVP Select Register */ -#define IT5205H_REG_CSBUOVPSR 0x1e -#define IT5205H_OVP_SELECT_MASK 0x30 -#define IT5205H_OVP_3_90V 0x00 -#define IT5205H_OVP_3_68V 0x10 -#define IT5205H_OVP_3_62V 0x20 -#define IT5205H_OVP_3_57V 0x30 - -/* CSBU Switch Register */ -#define IT5205H_REG_CSBUSR 0x22 -#define IT5205H_CSBUSR_SWITCH BIT(0) - -/* Interrupt Switch Register */ -#define IT5205H_REG_ISR 0x25 -#define IT5205H_ISR_CSBU_MASK BIT(4) -#define IT5205H_ISR_CSBU_OVP BIT(0) - -enum ec_error_list it5205h_enable_csbu_switch(const struct usb_mux *me, - bool en); - -#endif /* __CROS_EC_IT5205_H */ diff --git a/driver/usb_mux/pi3usb3x532.c b/driver/usb_mux/pi3usb3x532.c deleted file mode 100644 index 2435157967..0000000000 --- a/driver/usb_mux/pi3usb3x532.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright 2015 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Pericom PI3USB3X532 USB port switch driver. - */ - -#include "common.h" -#include "i2c.h" -#include "pi3usb3x532.h" -#include "usb_mux.h" -#include "util.h" - -static int pi3usb3x532_read(const struct usb_mux *me, - uint8_t reg, uint8_t *val) -{ - int read, res; - - /* - * First byte read will be i2c address (ignored). - * Second byte read will be vendor ID. - * Third byte read will be selection control. - */ - res = i2c_read16(me->i2c_port, me->i2c_addr_flags, 0, &read); - if (res) - return res; - - if (reg == PI3USB3X532_REG_VENDOR) - *val = read & 0xff; - else /* reg == PI3USB3X532_REG_CONTROL */ - *val = (read >> 8) & 0xff; - - return EC_SUCCESS; -} - -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(me->i2c_port, me->i2c_addr_flags, 0, val); -} - -int pi3usb3x532_check_vendor(const struct usb_mux *me, int *val) -{ - int res; - uint8_t read; - - res = pi3usb3x532_read(me, PI3USB3X532_REG_VENDOR, &read); - if (res) - return res; - - *val = read; - - return EC_SUCCESS; -} - -static int pi3usb3x532_reset(const struct usb_mux *me) -{ - return pi3usb3x532_write( - me, - PI3USB3X532_REG_CONTROL, - (PI3USB3X532_MODE_POWERDOWN & PI3USB3X532_CTRL_MASK) | - PI3USB3X532_CTRL_RSVD); -} - -static int pi3usb3x532_init(const struct usb_mux *me) -{ - uint8_t val; - int res; - - res = pi3usb3x532_reset(me); - if (res) - return res; - res = pi3usb3x532_read(me, PI3USB3X532_REG_VENDOR, &val); - if (res) - return res; - if (val != PI3USB3X532_VENDOR_ID) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - -/* Writes control register to set switch mode */ -static int pi3usb3x532_set_mux(const struct usb_mux *me, - mux_state_t mux_state, - bool *ack_required) -{ - uint8_t reg = 0; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= PI3USB3X532_MODE_USB; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= PI3USB3X532_MODE_DP; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= PI3USB3X532_BIT_SWAP; - - return pi3usb3x532_write(me, PI3USB3X532_REG_CONTROL, - reg | PI3USB3X532_CTRL_RSVD); -} - -/* Reads control register and updates mux_state accordingly */ -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(me, PI3USB3X532_REG_CONTROL, ®); - if (res) - return res; - - if (reg & PI3USB3X532_MODE_USB) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & PI3USB3X532_MODE_DP) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & PI3USB3X532_BIT_SWAP) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -const struct usb_mux_driver pi3usb3x532_usb_mux_driver = { - .init = pi3usb3x532_init, - .set = pi3usb3x532_set_mux, - .get = pi3usb3x532_get_mux, -}; diff --git a/driver/usb_mux/pi3usb3x532.h b/driver/usb_mux/pi3usb3x532.h deleted file mode 100644 index 6b398fdace..0000000000 --- a/driver/usb_mux/pi3usb3x532.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2015 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Pericom PI3USB3X532 USB port switch driver. - * - * Supported switches: - * - PI3USB30532 - * - PI3USB31532 - */ - -#ifndef __CROS_EC_PI3USB3X532_H -#define __CROS_EC_PI3USB3X532_H - -#include "usb_pd.h" -#include "usb_mux.h" - -/* I2C Addresses */ -#define PI3USB3X532_I2C_ADDR0 0x54 -#define PI3USB3X532_I2C_ADDR1 0x55 -#define PI3USB3X532_I2C_ADDR2 0x56 -#define PI3USB3X532_I2C_ADDR3 0x57 - -/* USB switch registers */ -#define PI3USB3X532_REG_ADDR 0x00 -#define PI3USB3X532_REG_VENDOR 0x01 -#define PI3USB3X532_REG_CONTROL 0x02 -/* Control register field */ -#define PI3USB3X532_CTRL_MASK 0x7 -#define PI3USB3X532_CTRL_RSVD 0 -/* Switch vendor ID */ -#define PI3USB3X532_VENDOR_ID 0 - -/* PI3USB3X532 control flags */ -#define PI3USB3X532_BIT_SWAP BIT(0) -#define PI3USB3X532_BIT_DP BIT(1) -#define PI3USB3X532_BIT_USB BIT(2) - -/* PI3USB3X532 modes */ -/* Power down, switch open */ -#define PI3USB3X532_MODE_POWERDOWN 0 -/* Keep power on, switch open */ -#define PI3USB3X532_MODE_POWERON 1 -/* 4-lane DP 1.2 - * dp0~3 : rx2, tx2, tx1, rx1 - * hpd+/-: rfu1, rfu2 - */ -#define PI3USB3X532_MODE_DP PI3USB3X532_BIT_DP -/* 4-lane DP 1.2 swap - * dp0~3 : rx1, tx1, tx2, rx2 - * hpd+/-: rfu2, rfu1 - */ -#define PI3USB3X532_MODE_DP_SWAP (PI3USB3X532_MODE_DP | PI3USB3X532_BIT_SWAP) -/* USB3 - * tx/rx : tx1, rx1 - */ -#define PI3USB3X532_MODE_USB PI3USB3X532_BIT_USB -/* USB3 swap - * tx/rx : tx2, rx2 - */ -#define PI3USB3X532_MODE_USB_SWAP (PI3USB3X532_MODE_USB | PI3USB3X532_BIT_SWAP) -/* 2-lane DP 1.2 + USB3 - * tx/rx : tx1, rx1 - * dp0~1 : rx2, tx2 - * hpd+/-: rfu1, rfu2 - */ -#define PI3USB3X532_MODE_DP_USB (PI3USB3X532_BIT_DP | PI3USB3X532_BIT_USB) -/* 2-lane DP 1.2 + USB3, swap - * tx/rx : tx2, rx2 - * dp0-1 : rx1, tx1 - * hpd+/-: rfu2, rfu1 - */ -#define PI3USB3X532_MODE_DP_USB_SWAP (PI3USB3X532_MODE_DP_USB | \ - PI3USB3X532_BIT_SWAP) - -/* Get Vendor ID */ -int pi3usb3x532_check_vendor(const struct usb_mux *me, int *val); -#endif /* __CROS_EC_PI3USB3X532_H */ diff --git a/driver/usb_mux/ps8740.c b/driver/usb_mux/ps8740.c deleted file mode 100644 index 618c74cd65..0000000000 --- a/driver/usb_mux/ps8740.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8740 (and PS8742) - * USB Type-C Redriving Switch for USB Host / DisplayPort. - */ - -#include "common.h" -#include "i2c.h" -#include "ps8740.h" -#include "usb_mux.h" -#include "util.h" - -int ps8740_read(const struct usb_mux *me, uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, - reg, val); -} - -int ps8740_write(const struct usb_mux *me, uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, - reg, val); -} - -static int ps8740_init(const struct usb_mux *me) -{ - int id1; - int id2; - int res; - - /* Reset chip back to power-on state */ - res = ps8740_write(me, PS8740_REG_MODE, PS8740_MODE_POWER_DOWN); - if (res) - return res; - - /* - * Verify chip ID registers. - */ - res = ps8740_read(me, PS8740_REG_CHIP_ID1, &id1); - if (res) - return res; - - res = ps8740_read(me, PS8740_REG_CHIP_ID2, &id2); - if (res) - return res; - - if (id1 != PS8740_CHIP_ID1 || id2 != PS8740_CHIP_ID2) - return EC_ERROR_UNKNOWN; - - /* - * Verify revision ID registers. - */ - res = ps8740_read(me, PS8740_REG_REVISION_ID1, &id1); - if (res) - return res; - - res = ps8740_read(me, PS8740_REG_REVISION_ID2, &id2); - if (res) - return res; - - if (id1 != PS8740_REVISION_ID1) - return EC_ERROR_UNKNOWN; - /* PS8740 may have REVISION_ID2 as 0xa or 0xb */ - if (id2 != PS8740_REVISION_ID2_0 && id2 != PS8740_REVISION_ID2_1) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - -/* Writes control register to set switch mode */ -static int ps8740_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - uint8_t reg = 0; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= PS8740_MODE_USB_ENABLED; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= PS8740_MODE_DP_ENABLED; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= PS8740_MODE_POLARITY_INVERTED; - - return ps8740_write(me, PS8740_REG_MODE, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int ps8740_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg; - int res; - - res = ps8740_read(me, PS8740_REG_STATUS, ®); - if (res) - return res; - - *mux_state = 0; - if (reg & PS8740_STATUS_USB_ENABLED) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & PS8740_STATUS_DP_ENABLED) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & PS8740_STATUS_POLARITY_INVERTED) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -/* Tune USB Tx/Rx Equalization */ -int ps8740_tune_usb_eq(const struct usb_mux *me, uint8_t tx, uint8_t rx) -{ - int ret; - - ret = ps8740_write(me, PS8740_REG_USB_EQ_TX, tx); - ret |= ps8740_write(me, PS8740_REG_USB_EQ_RX, rx); - - return ret; -} - -const struct usb_mux_driver ps8740_usb_mux_driver = { - .init = ps8740_init, - .set = ps8740_set_mux, - .get = ps8740_get_mux, -}; diff --git a/driver/usb_mux/ps8740.h b/driver/usb_mux/ps8740.h deleted file mode 100644 index 3a669b5ad9..0000000000 --- a/driver/usb_mux/ps8740.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8740 (and PS8742) - * USB Type-C Redriving Switch for USB Host / DisplayPort. - */ - -#ifndef __CROS_EC_PS8740_H -#define __CROS_EC_PS8740_H - -#include "usb_mux.h" - -#define PS8740_I2C_ADDR0_FLAG 0x10 -#define PS8740_I2C_ADDR1_FLAG 0x11 -#define PS8740_I2C_ADDR2_FLAG 0x19 -#define PS8740_I2C_ADDR3_FLAG 0x1a - -/* Mode register for setting mux */ -#define PS8740_REG_MODE 0x00 -#define PS8740_MODE_POLARITY_INVERTED BIT(4) -#define PS8740_MODE_USB_ENABLED BIT(5) -#define PS8740_MODE_DP_ENABLED BIT(6) -#ifdef CONFIG_USB_MUX_PS8740 - #define PS8740_MODE_POWER_DOWN BIT(7) -#elif defined(CONFIG_USB_MUX_PS8742) - #define PS8740_MODE_CE_DP_ENABLED BIT(7) - /* To reset the state machine to default */ - #define PS8740_MODE_POWER_DOWN 0 -#endif - -/* Status register for checking mux state */ -#define PS8740_REG_STATUS 0x09 -#define PS8740_STATUS_POLARITY_INVERTED BIT(2) -#define PS8740_STATUS_USB_ENABLED BIT(3) -#define PS8740_STATUS_DP_ENABLED BIT(4) -#define PS8740_STATUS_HPD_ASSERTED BIT(7) - -/* Chip ID / revision registers and expected fused values */ -#define PS8740_REG_REVISION_ID1 0xf0 -#define PS8740_REG_REVISION_ID2 0xf1 -#define PS8740_REG_CHIP_ID1 0xf2 -#define PS8740_REG_CHIP_ID2 0xf3 -#ifdef CONFIG_USB_MUX_PS8740 - #define PS8740_REVISION_ID1 0x00 - #define PS8740_REVISION_ID2_0 0x0a - #define PS8740_REVISION_ID2_1 0x0b - #define PS8740_CHIP_ID1 0x40 -#elif defined(CONFIG_USB_MUX_PS8742) - #define PS8740_REVISION_ID1 0x01 - #define PS8740_REVISION_ID2_0 0x0a - #define PS8740_REVISION_ID2_1 0x0a - #define PS8740_CHIP_ID1 0x42 -#endif -#define PS8740_CHIP_ID2 0x87 - -/* USB equalization settings for Host to Mux */ -#define PS8740_REG_USB_EQ_TX 0x32 -#define PS8740_USB_EQ_TX_10_1_DB 0x00 -#define PS8740_USB_EQ_TX_14_3_DB 0x20 -#define PS8740_USB_EQ_TX_8_5_DB 0x40 -#define PS8740_USB_EQ_TX_6_5_DB 0x60 -#define PS8740_USB_EQ_TX_11_5_DB 0x80 -#define PS8740_USB_EQ_TX_9_5_DB 0xc0 -#define PS8740_USB_EQ_TX_7_5_DB 0xe0 -#define PS8740_USB_EQ_TERM_100_OHM (0 << 2) -#define PS8740_USB_EQ_TERM_85_OHM BIT(2) - -/* USB equalization settings for Connector to Mux */ -#define PS8740_REG_USB_EQ_RX 0x3b -#define PS8740_USB_EQ_RX_4_4_DB 0x00 -#define PS8740_USB_EQ_RX_7_0_DB 0x10 -#define PS8740_USB_EQ_RX_8_2_DB 0x20 -#define PS8740_USB_EQ_RX_9_4_DB 0x30 -#define PS8740_USB_EQ_RX_10_2_DB 0x40 -#define PS8740_USB_EQ_RX_11_4_DB 0x50 -#define PS8740_USB_EQ_RX_14_3_DB 0x60 -#define PS8740_USB_EQ_RX_14_8_DB 0x70 -#define PS8740_USB_EQ_RX_15_2_DB 0x80 -#define PS8740_USB_EQ_RX_15_5_DB 0x90 -#define PS8740_USB_EQ_RX_16_2_DB 0xa0 -#define PS8740_USB_EQ_RX_17_3_DB 0xb0 -#define PS8740_USB_EQ_RX_18_4_DB 0xc0 -#define PS8740_USB_EQ_RX_20_1_DB 0xd0 -#define PS8740_USB_EQ_RX_21_3_DB 0xe0 - -int ps8740_tune_usb_eq(const struct usb_mux *me, uint8_t tx, uint8_t rx); -int ps8740_write(const struct usb_mux *me, uint8_t reg, uint8_t val); -int ps8740_read(const struct usb_mux *me, uint8_t reg, int *val); - -#endif /* __CROS_EC_PS8740_H */ diff --git a/driver/usb_mux/ps8743.c b/driver/usb_mux/ps8743.c deleted file mode 100644 index f618bb009f..0000000000 --- a/driver/usb_mux/ps8743.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8743 USB Type-C Redriving Switch for USB Host / DisplayPort. - */ - -#include "common.h" -#include "i2c.h" -#include "ps8743.h" -#include "usb_mux.h" -#include "util.h" - -int ps8743_read(const struct usb_mux *me, uint8_t reg, int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags, - reg, val); -} - -int ps8743_write(const struct usb_mux *me, uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, - reg, val); -} - -int ps8743_check_chip_id(const struct usb_mux *me, int *val) -{ - int id1; - int id2; - int res; - - /* - * Verify chip ID registers. - */ - res = ps8743_read(me, PS8743_REG_CHIP_ID1, &id1); - if (res) - return res; - - res = ps8743_read(me, PS8743_REG_CHIP_ID2, &id2); - if (res) - return res; - - *val = (id2 << 8) + id1; - - return EC_SUCCESS; -} - -static int ps8743_init(const struct usb_mux *me) -{ - int id1; - int id2; - int res; - - /* Reset chip back to power-on state */ - res = ps8743_write(me, PS8743_REG_MODE, PS8743_MODE_POWER_DOWN); - if (res) - return res; - - /* - * Verify chip ID registers. - */ - res = ps8743_read(me, PS8743_REG_CHIP_ID1, &id1); - if (res) - return res; - - res = ps8743_read(me, PS8743_REG_CHIP_ID2, &id2); - if (res) - return res; - - if (id1 != PS8743_CHIP_ID1 || id2 != PS8743_CHIP_ID2) - return EC_ERROR_UNKNOWN; - - /* - * Verify revision ID registers. - */ - res = ps8743_read(me, PS8743_REG_REVISION_ID1, &id1); - if (res) - return res; - - res = ps8743_read(me, PS8743_REG_REVISION_ID2, &id2); - if (res) - return res; - - /* - * From Parade: PS8743 may have REVISION_ID1 as 0 or 1 - * Rev 1 is derived from Rev 0 and have same functionality. - */ - if (id1 != PS8743_REVISION_ID1_0 && id1 != PS8743_REVISION_ID1_1) - return EC_ERROR_UNKNOWN; - if (id2 != PS8743_REVISION_ID2) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - -/* Writes control register to set switch mode */ -static int ps8743_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - /* - * For CE_DP, CE_USB, and FLIP, disable pin control and enable I2C - * control. - */ - uint8_t reg = (PS8743_MODE_IN_HPD_CONTROL | - PS8743_MODE_DP_REG_CONTROL | - PS8743_MODE_USB_REG_CONTROL | - PS8743_MODE_FLIP_REG_CONTROL); - - /* This driver does not use host command ACKs */ - *ack_required = false; - - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= PS8743_MODE_USB_ENABLE; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= PS8743_MODE_DP_ENABLE | PS8743_MODE_IN_HPD_ASSERT; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= PS8743_MODE_FLIP_ENABLE; - - return ps8743_write(me, PS8743_REG_MODE, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int ps8743_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg; - int res; - - res = ps8743_read(me, PS8743_REG_STATUS, ®); - if (res) - return res; - - *mux_state = 0; - if (reg & PS8743_STATUS_USB_ENABLED) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & PS8743_STATUS_DP_ENABLED) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & PS8743_STATUS_POLARITY_INVERTED) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -/* Tune USB Tx/Rx Equalization */ -int ps8743_tune_usb_eq(const struct usb_mux *me, uint8_t tx, uint8_t rx) -{ - int ret; - - ret = ps8743_write(me, PS8743_REG_USB_EQ_TX, tx); - ret |= ps8743_write(me, PS8743_REG_USB_EQ_RX, rx); - - return ret; -} - -const struct usb_mux_driver ps8743_usb_mux_driver = { - .init = ps8743_init, - .set = ps8743_set_mux, - .get = ps8743_get_mux, -}; diff --git a/driver/usb_mux/ps8743.h b/driver/usb_mux/ps8743.h deleted file mode 100644 index 741b93e98a..0000000000 --- a/driver/usb_mux/ps8743.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8743 USB Type-C Redriving Switch for USB Host / DisplayPort. - */ - -#ifndef __CROS_EC_PS8743_H -#define __CROS_EC_PS8743_H - -#include "usb_mux.h" -#include "usb_mux/ps8743_public.h" - -/* Status register for checking mux state */ -#define PS8743_REG_STATUS 0x09 -#define PS8743_STATUS_POLARITY_INVERTED BIT(2) -#define PS8743_STATUS_USB_ENABLED BIT(3) -#define PS8743_STATUS_DP_ENABLED BIT(4) -#define PS8743_STATUS_HPD_ASSERTED BIT(7) - -/* Chip ID / revision registers and expected fused values */ -#define PS8743_REG_REVISION_ID1 0xf0 -#define PS8743_REG_REVISION_ID2 0xf1 -#define PS8743_REG_CHIP_ID1 0xf2 -#define PS8743_REG_CHIP_ID2 0xf3 -#define PS8743_REVISION_ID1_0 0x00 -#define PS8743_REVISION_ID1_1 0x01 -#define PS8743_REVISION_ID2 0x0b -#define PS8743_CHIP_ID1 0x41 -#define PS8743_CHIP_ID2 0x87 - -#endif /* __CROS_EC_PS8743_H */ diff --git a/driver/usb_mux/ps8822.c b/driver/usb_mux/ps8822.c deleted file mode 100644 index 7f25db37f4..0000000000 --- a/driver/usb_mux/ps8822.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8822 - * USB Type-C Redriving Switch for USB Host / DisplayPort. - */ - -#include "common.h" -#include "i2c.h" -#include "ps8822.h" -#include "usb_mux.h" -#include "util.h" - -static int ps8822_read(const struct usb_mux *me, int page, uint8_t reg, - int *val) -{ - return i2c_read8(me->i2c_port, me->i2c_addr_flags + page, - reg, val); -} - -static int ps8822_write(const struct usb_mux *me, int page, uint8_t reg, - int val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags + page, - reg, val); -} - -int ps8822_set_dp_rx_eq(const struct usb_mux *me, int db) -{ - int dpeq_reg; - int rv; - - /* Read DP EQ register */ - rv = ps8822_read(me, PS8822_REG_PAGE1, PS8822_REG_DP_EQ, - &dpeq_reg); - if (rv) - return rv; - - if (db < PS8822_DPEQ_LEVEL_UP_9DB || db > PS8822_DPEQ_LEVEL_UP_21DB) - return EC_ERROR_INVAL; - - /* Disable auto eq */ - dpeq_reg &= ~PS8822_DP_EQ_AUTO_EN; - - /* Set gain to the requested value */ - dpeq_reg &= ~(PS8822_DPEQ_LEVEL_UP_MASK << - PS8822_REG_DP_EQ_SHIFT); - dpeq_reg |= (db << PS8822_REG_DP_EQ_SHIFT); - - /* Apply new EQ setting */ - return ps8822_write(me, PS8822_REG_PAGE1, PS8822_REG_DP_EQ, - dpeq_reg); -} - -static int ps8822_init(const struct usb_mux *me) -{ - char id[PS8822_ID_LEN + 1]; - int reg; - int i; - int rv = 0; - - /* Read ID registers */ - for (i = 0; i < PS8822_ID_LEN; i++) { - rv |= ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_DEV_ID1 + i, - ®); - if (!rv) - id[i] = reg; - } - - if (!rv) { - id[PS8822_ID_LEN] = '\0'; - /* Set mode register to default value */ - rv = ps8822_write(me, PS8822_REG_PAGE0, PS8822_REG_MODE, 0); - rv |= strcasecmp("PS8822", id); - } - - return rv; -} - -/* Writes control register to set switch mode */ -static int ps8822_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - int reg; - int rv; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - rv = ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_MODE, ®); - if (rv) - return rv; - - /* Assume standby, preserve PIN_E config bit */ - reg &= ~(PS8822_MODE_ALT_DP_EN | PS8822_MODE_USB_EN | PS8822_MODE_FLIP); - - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= PS8822_MODE_USB_EN; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= PS8822_MODE_ALT_DP_EN; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= PS8822_MODE_FLIP; - - return ps8822_write(me, PS8822_REG_PAGE0, PS8822_REG_MODE, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int ps8822_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - int reg; - int res; - - res = ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_MODE, ®); - if (res) - return res; - - *mux_state = 0; - if (reg & PS8822_MODE_USB_EN) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & PS8822_MODE_ALT_DP_EN) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & PS8822_MODE_FLIP) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - - -const struct usb_mux_driver ps8822_usb_mux_driver = { - .init = ps8822_init, - .set = ps8822_set_mux, - .get = ps8822_get_mux, -}; diff --git a/driver/usb_mux/ps8822.h b/driver/usb_mux/ps8822.h deleted file mode 100644 index 86b911db70..0000000000 --- a/driver/usb_mux/ps8822.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Parade PS8822 - * USB Type-C Retiming Switch for USB Device / DisplayPort Sink - */ - -#ifndef __CROS_EC_PS8822_H -#define __CROS_EC_PS8822_H - -#include "usb_mux.h" - -#define PS8822_I2C_ADDR0_FLAG 0x10 -#define PS8822_I2C_ADDR1_FLAG 0x18 -#define PS8822_I2C_ADDR2_FLAG 0x58 -#define PS8822_I2C_ADDR3_FLAG 0x60 - -#define PS8822_REG_PAGE0 0x00 - -/* Mode register for setting mux */ -#define PS8822_REG_MODE 0x01 -#define PS8822_MODE_ALT_DP_EN BIT(7) -#define PS8822_MODE_USB_EN BIT(6) -#define PS8822_MODE_FLIP BIT(5) -#define PS8822_MODE_PIN_E BIT(4) - -#define PS8822_REG_CONFIG 0x02 -#define PS8822_CONFIG_HPD_IN_DIS BIT(7) -#define PS8822_CONFIG_DP_PLUG BIT(6) - -#define PS8822_REG_DEV_ID1 0x06 -#define PS8822_REG_DEV_ID2 0x07 -#define PS8822_REG_DEV_ID3 0x08 -#define PS8822_REG_DEV_ID4 0x09 -#define PS8822_REG_DEV_ID5 0x0A -#define PS8822_REG_DEV_ID6 0x0B - -#define PS8822_ID_LEN 6 - -#define PS8822_REG_PAGE1 0x01 -#define PS8822_REG_DP_EQ 0xB6 -#define PS8822_DP_EQ_AUTO_EN BIT(7) - -#define PS8822_DPEQ_LEVEL_UP_9DB 0x00 -#define PS8822_DPEQ_LEVEL_UP_11DB 0x01 -#define PS8822_DPEQ_LEVEL_UP_12DB 0x02 -#define PS8822_DPEQ_LEVEL_UP_14DB 0x03 -#define PS8822_DPEQ_LEVEL_UP_17DB 0x04 -#define PS8822_DPEQ_LEVEL_UP_18DB 0x05 -#define PS8822_DPEQ_LEVEL_UP_19DB 0x06 -#define PS8822_DPEQ_LEVEL_UP_20DB 0x07 -#define PS8822_DPEQ_LEVEL_UP_21DB 0x08 -#define PS8822_DPEQ_LEVEL_UP_MASK 0x0F -#define PS8822_REG_DP_EQ_SHIFT 3 - -/** - * Set DP Rx Equalization value - * - * @param *me pointer to usb_mux descriptor - * @param db requested gain setting for DP Rx path - * @return EC_SUCCESS if db param is valid and I2C is successful - */ -int ps8822_set_dp_rx_eq(const struct usb_mux *me, int db); - -#endif /* __CROS_EC_PS8822_H */ diff --git a/driver/usb_mux/tusb1064.c b/driver/usb_mux/tusb1064.c deleted file mode 100644 index 1c0f0e4701..0000000000 --- a/driver/usb_mux/tusb1064.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "i2c.h" -#include "tusb1064.h" -#include "usb_mux.h" - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -/* - * configuration bits which never change in the General Register - * e.g. REG_GENERAL_DP_EN_CTRL or REG_GENERAL_EQ_OVERRIDE - */ -#define REG_GENERAL_STATIC_BITS REG_GENERAL_EQ_OVERRIDE - -static int tusb1064_read(const struct usb_mux *me, uint8_t reg, uint8_t *val) -{ - int buffer = 0xee; - int res = i2c_read8(me->i2c_port, me->i2c_addr_flags, - (int)reg, &buffer); - *val = buffer; - return res; -} - -static int tusb1064_write(const struct usb_mux *me, uint8_t reg, uint8_t val) -{ - return i2c_write8(me->i2c_port, me->i2c_addr_flags, - (int)reg, (int)val); -} - -/* Writes control register to set switch mode */ -static int tusb1064_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - int reg = REG_GENERAL_STATIC_BITS; - - /* This driver does not use host command ACKs */ - *ack_required = false; - - if (mux_state & USB_PD_MUX_USB_ENABLED) - reg |= REG_GENERAL_CTLSEL_USB3; - if (mux_state & USB_PD_MUX_DP_ENABLED) - reg |= REG_GENERAL_CTLSEL_ANYDP; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - reg |= REG_GENERAL_FLIPSEL; - - return tusb1064_write(me, TUSB1064_REG_GENERAL, reg); -} - -/* Reads control register and updates mux_state accordingly */ -static int tusb1064_get_mux(const struct usb_mux *me, mux_state_t *mux_state) -{ - uint8_t reg; - int res; - - res = tusb1064_read(me, TUSB1064_REG_GENERAL, ®); - if (res) - return EC_ERROR_INVAL; - - *mux_state = 0; - if (reg & REG_GENERAL_CTLSEL_USB3) - *mux_state |= USB_PD_MUX_USB_ENABLED; - if (reg & REG_GENERAL_CTLSEL_ANYDP) - *mux_state |= USB_PD_MUX_DP_ENABLED; - if (reg & REG_GENERAL_FLIPSEL) - *mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -/* Generic driver init function */ -static int tusb1064_init(const struct usb_mux *me) -{ - int res; - uint8_t reg; - bool unused; - - /* Default to "Floating Pin" DP Equalization */ - reg = TUSB1064_DP1EQ(TUSB1064_DP_EQ_RX_10_0_DB) | - TUSB1064_DP3EQ(TUSB1064_DP_EQ_RX_10_0_DB); - res = tusb1064_write(me, TUSB1064_REG_DP1DP3EQ_SEL, reg); - if (res) - return res; - - reg = TUSB1064_DP0EQ(TUSB1064_DP_EQ_RX_10_0_DB) | - TUSB1064_DP2EQ(TUSB1064_DP_EQ_RX_10_0_DB); - res = tusb1064_write(me, TUSB1064_REG_DP0DP2EQ_SEL, reg); - if (res) - return res; - - /* - * Note that bypassing the usb_mux API is okay for internal driver calls - * since the task calling init already holds this port's mux lock. - */ - /* Disconnect USB3.1 and DP */ - res = tusb1064_set_mux(me, USB_PD_MUX_NONE, &unused); - if (res) - return res; - - /* Disable AUX mux override */ - res = tusb1064_write(me, TUSB1064_REG_AUXDPCTRL, 0); - if (res) - return res; - - return EC_SUCCESS; -} - -const struct usb_mux_driver tusb1064_usb_mux_driver = { - /* CAUTION: This is an UFP/RX/SINK redriver mux */ - .init = tusb1064_init, - .set = tusb1064_set_mux, - .get = tusb1064_get_mux, -}; diff --git a/driver/usb_mux/tusb1064.h b/driver/usb_mux/tusb1064.h deleted file mode 100644 index e860cc539a..0000000000 --- a/driver/usb_mux/tusb1064.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_TUSB1064_H -#define __CROS_EC_TUSB1064_H - -#include <stdint.h> -#include "usb_mux.h" - -/* - * TUSB1064 Has 16 possible device addresses which are selected by A1|A0 lines - * using 4 level inputs. - * 0 -> tied directly to GND - * R -> tied to GND via a 20k pulldown - * F -> floating - * 1 -> tied to VCC - */ -#define TUSB1064_I2C_ADDR0_FLAGS 0x44 -#define TUSB1064_I2C_ADDR1_FLAGS 0x45 -#define TUSB1064_I2C_ADDR2_FLAGS 0x46 -#define TUSB1064_I2C_ADDR3_FLAGS 0x47 -#define TUSB1064_I2C_ADDR4_FLAGS 0x20 -#define TUSB1064_I2C_ADDR5_FLAGS 0x21 -#define TUSB1064_I2C_ADDR6_FLAGS 0x22 -#define TUSB1064_I2C_ADDR7_FLAGS 0x23 -#define TUSB1064_I2C_ADDR8_FLAGS 0x10 -#define TUSB1064_I2C_ADDR9_FLAGS 0x11 -#define TUSB1064_I2C_ADDR10_FLAGS 0x12 -#define TUSB1064_I2C_ADDR11_FLAGS 0x13 -#define TUSB1064_I2C_ADDR12_FLAGS 0x0C -#define TUSB1064_I2C_ADDR13_FLAGS 0x0D -#define TUSB1064_I2C_ADDR14_FLAGS 0x0E -#define TUSB1064_I2C_ADDR15_FLAGS 0x0F - -/* TUSB1064 General Register */ -#define TUSB1064_REG_GENERAL 0x0a -#define REG_GENERAL_CTLSEL_USB3 BIT(0) -#define REG_GENERAL_CTLSEL_ANYDP BIT(1) -#define REG_GENERAL_FLIPSEL BIT(2) -#define REG_GENERAL_DP_EN_CTRL BIT(3) -#define REG_GENERAL_EQ_OVERRIDE BIT(4) - -/* AUX and DP Lane Control Register */ -#define TUSB1064_REG_AUXDPCTRL 0x13 -#define TUSB1064_AUXDPCTRL_AUX_SNOOP_DISABLE BIT(7) -#define TUSB1064_AUXDPCTRL_AUX_SBU_OVR 0x30 -#define TUSB1064_AUXDPCTRL_DP3_DISABLE BIT(3) -#define TUSB1064_AUXDPCTRL_DP2_DISABLE BIT(2) -#define TUSB1064_AUXDPCTRL_DP1_DISABLE BIT(1) -#define TUSB1064_AUXDPCTRL_DP0_DISABLE BIT(0) - -/* Receiver Equalization GPIO Control */ -#define TUSB1064_REG_DP1DP3EQ_SEL 0x10 -#define TUSB1064_REG_DP0DP2EQ_SEL 0x11 - -/* DP Receiver equalization settings */ -#define TUSB1064_DP_EQ_RX_NEG_0_3_DB 0x0 -#define TUSB1064_DP_EQ_RX_1_6_DB 0x1 -#define TUSB1064_DP_EQ_RX_3_0_DB 0x2 -#define TUSB1064_DP_EQ_RX_4_4_DB 0x3 -#define TUSB1064_DP_EQ_RX_5_4_DB 0x4 -#define TUSB1064_DP_EQ_RX_6_5_DB 0x5 -#define TUSB1064_DP_EQ_RX_7_3_DB 0x6 -#define TUSB1064_DP_EQ_RX_8_1_DB 0x7 -#define TUSB1064_DP_EQ_RX_8_9_DB 0x8 -#define TUSB1064_DP_EQ_RX_9_5_DB 0x9 -#define TUSB1064_DP_EQ_RX_10_0_DB 0xA -#define TUSB1064_DP_EQ_RX_10_6_DB 0xB -#define TUSB1064_DP_EQ_RX_11_0_DB 0xC -#define TUSB1064_DP_EQ_RX_11_4_DB 0xD -#define TUSB1064_DP_EQ_RX_11_8_DB 0xE -#define TUSB1064_DP_EQ_RX_12_1_DB 0xF - -#ifndef TUSB1064_DP1EQ -#define TUSB1064_DP1EQ(nr) ((nr) << 4) -#endif -#ifndef TUSB1064_DP3EQ -#define TUSB1064_DP3EQ(nr) ((nr) << 0) -#endif -#ifndef TUSB1064_DP0EQ -#define TUSB1064_DP0EQ(nr) ((nr) << 4) -#endif -#ifndef TUSB1064_DP2EQ -#define TUSB1064_DP2EQ(nr) ((nr) << 0) -#endif - - -/* TUSB1064 Receiver Equalization GPIO Control */ -#define TUSB1064_REG_SSRX2RX1EQ_SEL 0x20 -#define TUSB1064_REG_SSTXEQ_SEL 0x21 - -/* USB equalization settings for Mux DFP (TX) */ -#define TUSB1064_USB_EQ_DFP_NEG_3_0_DB 0x0 -#define TUSB1064_USB_EQ_DFP_NEG_0_8_DB 0x1 -#define TUSB1064_USB_EQ_DFP_NEG_0_7_DB 0x2 -#define TUSB1064_USB_EQ_DFP_2_2_DB 0x3 -#define TUSB1064_USB_EQ_DFP_3_3_DB 0x4 -#define TUSB1064_USB_EQ_DFP_4_3_DB 0x5 -#define TUSB1064_USB_EQ_DFP_5_1_DB 0x6 -#define TUSB1064_USB_EQ_DFP_6_0_DB 0x7 -#define TUSB1064_USB_EQ_DFP_6_7_DB 0x8 -#define TUSB1064_USB_EQ_DFP_7_3_DB 0x9 -#define TUSB1064_USB_EQ_DFP_7_8_DB 0xA -#define TUSB1064_USB_EQ_DFP_8_3_DB 0xB -#define TUSB1064_USB_EQ_DFP_8_6_DB 0xC -#define TUSB1064_USB_EQ_DFP_9_0_DB 0xD -#define TUSB1064_USB_EQ_DFP_9_3_DB 0xE -#define TUSB1064_USB_EQ_DFP_9_7_DB 0xF - -/* USB equalization settings for Mux UFP (RX) */ -#define TUSB1064_USB_EQ_UFP_NEG_1_5_DB 0x0 -#define TUSB1064_USB_EQ_UFP_0_7_DB 0x1 -#define TUSB1064_USB_EQ_UFP_2_2_DB 0x2 -#define TUSB1064_USB_EQ_UFP_3_7_DB 0x3 -#define TUSB1064_USB_EQ_UFP_4_7_DB 0x4 -#define TUSB1064_USB_EQ_UFP_5_8_DB 0x5 -#define TUSB1064_USB_EQ_UFP_6_6_DB 0x6 -#define TUSB1064_USB_EQ_UFP_7_4_DB 0x7 -#define TUSB1064_USB_EQ_UFP_8_1_DB 0x8 -#define TUSB1064_USB_EQ_UFP_8_7_DB 0x9 -#define TUSB1064_USB_EQ_UFP_9_2_DB 0xA -#define TUSB1064_USB_EQ_UFP_9_7_DB 0xB -#define TUSB1064_USB_EQ_UFP_10_0_DB 0xC -#define TUSB1064_USB_EQ_UFP_10_4_DB 0xD -#define TUSB1064_USB_EQ_UFP_10_7_DB 0xE -#define TUSB1064_USB_EQ_UFP_11_1_DB 0xF - -#endif /* __CROS_EC_TUSB1064_H */ diff --git a/driver/usb_mux/usb_mux.c b/driver/usb_mux/usb_mux.c deleted file mode 100644 index 155ba8fb3e..0000000000 --- a/driver/usb_mux/usb_mux.c +++ /dev/null @@ -1,524 +0,0 @@ -/* Copyright 2015 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* USB mux high-level driver. */ - -#include "atomic.h" -#include "common.h" -#include "console.h" -#include "chipset.h" -#include "hooks.h" -#include "host_command.h" -#include "task.h" -#include "timer.h" -#include "usb_mux.h" -#include "usbc_ppc.h" -#include "util.h" - -#ifdef CONFIG_COMMON_RUNTIME -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#else -#define CPRINTS(format, args...) -#define CPRINTF(format, args...) -#endif - -static int enable_debug_prints; - -/* - * Flags will reset to 0 after sysjump; This works for current flags as LPM will - * get reset in the init method which is called during PD task startup. - */ -static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* Device is in low power mode. */ -#define USB_MUX_FLAG_IN_LPM BIT(0) - -/* Device initialized at least once */ -#define USB_MUX_FLAG_INIT BIT(1) - -/* Coordinate mux accesses by-port among the tasks */ -static mutex_t mux_lock[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* Coordinate which task requires an ACK event */ -static task_id_t ack_task[CONFIG_USB_PD_PORT_MAX_COUNT] = { - [0 ... CONFIG_USB_PD_PORT_MAX_COUNT - 1] = TASK_ID_INVALID }; - -enum mux_config_type { - USB_MUX_INIT, - USB_MUX_LOW_POWER, - USB_MUX_SET_MODE, - USB_MUX_GET_MODE, - USB_MUX_CHIPSET_RESET, - USB_MUX_HPD_UPDATE, -}; - -#ifdef CONFIG_ZEPHYR -static int init_mux_mutex(const struct device *dev) -{ - int port; - - ARG_UNUSED(dev); - for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) - k_mutex_init(&mux_lock[port]); - return 0; -} -SYS_INIT(init_mux_mutex, POST_KERNEL, 50); -#endif /* CONFIG_ZEPHYR */ - -/* Configure the MUX */ -static int configure_mux(int port, - enum mux_config_type config, - mux_state_t *mux_state) -{ - 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 (config == USB_MUX_GET_MODE) - *mux_state = USB_PD_MUX_NONE; - } - - /* - * 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; - bool ack_required = false; - - /* Action time! Lock this mux */ - mutex_lock(&mux_lock[port]); - - switch (config) { - case USB_MUX_INIT: - 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 (drv && drv->enter_low_power_mode) - rv = drv->enter_low_power_mode(mux_ptr); - - break; - - case USB_MUX_CHIPSET_RESET: - if (drv && drv->chipset_reset) - rv = drv->chipset_reset(mux_ptr); - - break; - - case USB_MUX_SET_MODE: - lcl_state = *mux_state; - - if (mux_ptr->flags & USB_MUX_FLAG_SET_WITHOUT_FLIP) - lcl_state &= ~USB_PD_MUX_POLARITY_INVERTED; - - if (drv && drv->set) { - rv = drv->set(mux_ptr, lcl_state, - &ack_required); - if (rv) - break; - } - - if (ack_required) - ack_task[port] = task_get_current(); - - /* Apply board specific setting */ - if (mux_ptr->board_set) - rv = mux_ptr->board_set(mux_ptr, lcl_state); - - break; - - 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; - - case USB_MUX_HPD_UPDATE: - if (mux_ptr->hpd_update) - mux_ptr->hpd_update(mux_ptr, *mux_state); - - } - - /* Unlock before any host command waits */ - mutex_unlock(&mux_lock[port]); - - if (ack_required) { - /* This should only be called from the PD task */ - assert(port == TASK_ID_TO_PD_PORT(task_get_current())); - - /* - * Note: This task event could be generalized for more - * purposes beyond host command ACKs. For now, these - * wait times are tuned for the purposes of the TCSS - * mux, but could be made configurable for other - * purposes. - */ - task_wait_event_mask(PD_EVENT_AP_MUX_DONE, 100*MSEC); - ack_task[port] = TASK_ID_INVALID; - - usleep(12.5 * MSEC); - } - } - - if (rv) - CPRINTS("mux config:%d, port:%d, rv:%d", - config, port, rv); - - return rv; -} - -static void enter_low_power_mode(int port) -{ - /* - * 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. - */ - atomic_or(&flags[port], USB_MUX_FLAG_IN_LPM); - - /* Apply any low power customization if present */ - configure_mux(port, USB_MUX_LOW_POWER, NULL); -} - -static int exit_low_power_mode(int port) -{ - /* If we are in low power, initialize device (which clears LPM flag) */ - if (flags[port] & USB_MUX_FLAG_IN_LPM) - usb_mux_init(port); - - if (!(flags[port] & USB_MUX_FLAG_INIT)) { - CPRINTS("C%d: USB_MUX_FLAG_INIT not set", port); - return EC_ERROR_UNKNOWN; - } - - if (flags[port] & USB_MUX_FLAG_IN_LPM) { - CPRINTS("C%d: USB_MUX_FLAG_IN_LPM not cleared", port); - return EC_ERROR_NOT_POWERED; - } - - return EC_SUCCESS; -} - -void usb_mux_init(int port) -{ - int rv; - - ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); - - if (port >= board_get_usb_pd_port_count()) { - return; - } - - rv = configure_mux(port, USB_MUX_INIT, NULL); - - if (rv == EC_SUCCESS) - atomic_or(&flags[port], USB_MUX_FLAG_INIT); - - /* - * Mux may fail initialization if it's not powered. Mark this port - * as in LPM mode to try initialization again. - */ - if (rv == EC_ERROR_NOT_POWERED) - atomic_or(&flags[port], USB_MUX_FLAG_IN_LPM); - else - atomic_clear_bits(&flags[port], USB_MUX_FLAG_IN_LPM); -} - -/* - * TODO(crbug.com/505480): Setting muxes often involves I2C transcations, - * which can block. Consider implementing an asynchronous task. - */ -void usb_mux_set(int port, mux_state_t mux_mode, - enum usb_switch usb_mode, int polarity) -{ - mux_state_t mux_state; - const int should_enter_low_power_mode = - (mux_mode == USB_PD_MUX_NONE && - usb_mode == USB_SWITCH_DISCONNECT); - - if (port >= board_get_usb_pd_port_count()) { - return; - } - - /* Perform initialization if not initialized yet */ - if (!(flags[port] & USB_MUX_FLAG_INIT)) - usb_mux_init(port); - - /* Configure USB2.0 */ - if (IS_ENABLED(CONFIG_USB_CHARGER)) - usb_charger_set_switches(port, usb_mode); - - /* - * Don't wake device up just to put it back to sleep. Low power mode - * flag is only set if the mux set() operation succeeded previously for - * the same disconnected state. - */ - if (should_enter_low_power_mode && (flags[port] & USB_MUX_FLAG_IN_LPM)) - return; - - if (exit_low_power_mode(port) != EC_SUCCESS) - return; - - /* Configure superspeed lanes */ - mux_state = ((mux_mode != USB_PD_MUX_NONE) && polarity) - ? mux_mode | USB_PD_MUX_POLARITY_INVERTED - : mux_mode; - - if (configure_mux(port, USB_MUX_SET_MODE, &mux_state)) - return; - - if (enable_debug_prints) - CPRINTS( - "usb/dp mux: port(%d) typec_mux(%d) usb2(%d) polarity(%d)", - port, mux_mode, usb_mode, polarity); - - /* - * If we are completely disconnecting the mux, then we should put it in - * its lowest power state. - */ - if (should_enter_low_power_mode) - enter_low_power_mode(port); -} - -mux_state_t usb_mux_get(int port) -{ - mux_state_t mux_state; - int rv; - - if (port >= board_get_usb_pd_port_count()) { - return USB_PD_MUX_NONE; - } - - /* Perform initialization if not initialized yet */ - if (!(flags[port] & USB_MUX_FLAG_INIT)) - usb_mux_init(port); - - if (flags[port] & USB_MUX_FLAG_IN_LPM) - return USB_PD_MUX_NONE; - - rv = configure_mux(port, USB_MUX_GET_MODE, &mux_state); - - return rv ? USB_PD_MUX_NONE : mux_state; -} - -void usb_mux_flip(int port) -{ - mux_state_t mux_state; - - if (port >= board_get_usb_pd_port_count()) { - return; - } - - /* Perform initialization if not initialized yet */ - if (!(flags[port] & USB_MUX_FLAG_INIT)) - usb_mux_init(port); - - if (exit_low_power_mode(port) != EC_SUCCESS) - return; - - if (configure_mux(port, USB_MUX_GET_MODE, &mux_state)) - return; - - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - mux_state &= ~USB_PD_MUX_POLARITY_INVERTED; - else - mux_state |= USB_PD_MUX_POLARITY_INVERTED; - - configure_mux(port, USB_MUX_SET_MODE, &mux_state); -} - -void usb_mux_hpd_update(int port, mux_state_t hpd_state) -{ - if (port >= board_get_usb_pd_port_count()) { - return; - } - - /* Perform initialization if not initialized yet */ - if (!(flags[port] & USB_MUX_FLAG_INIT)) - usb_mux_init(port); - - if (exit_low_power_mode(port) != EC_SUCCESS) - return; - - configure_mux(port, USB_MUX_HPD_UPDATE, &hpd_state); -} - -int usb_mux_retimer_fw_update_port_info(void) -{ - int i; - int port_info = 0; - const struct usb_mux *mux_ptr; - - for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { - mux_ptr = &usb_muxes[i]; - while (mux_ptr) { - if (mux_ptr->driver && - mux_ptr->driver->is_retimer_fw_update_capable && - mux_ptr->driver->is_retimer_fw_update_capable()) - port_info |= BIT(i); - mux_ptr = mux_ptr->next_mux; - } - } - return port_info; -} - -static void mux_chipset_reset(void) -{ - int port; - - for (port = 0; port < board_get_usb_pd_port_count(); ++port) - configure_mux(port, USB_MUX_CHIPSET_RESET, NULL); -} -DECLARE_HOOK(HOOK_CHIPSET_RESET, mux_chipset_reset, HOOK_PRIO_DEFAULT); - -/* - * For muxes which have powered off in G3, clear any cached INIT and LPM flags - * since the chip will need reset. - */ -static void usb_mux_reset_in_g3(void) -{ - int port; - const struct usb_mux *mux_ptr; - - for (port = 0; port < board_get_usb_pd_port_count(); port++) { - mux_ptr = &usb_muxes[port]; - - while (mux_ptr) { - if (mux_ptr->flags & USB_MUX_FLAG_RESETS_IN_G3) { - atomic_clear_bits(&flags[port], - USB_MUX_FLAG_INIT | - USB_MUX_FLAG_IN_LPM); - } - mux_ptr = mux_ptr->next_mux; - } - } -} -DECLARE_HOOK(HOOK_CHIPSET_HARD_OFF, usb_mux_reset_in_g3, HOOK_PRIO_DEFAULT); - -#ifdef CONFIG_CMD_TYPEC -static int command_typec(int argc, char **argv) -{ - const char * const mux_name[] = {"none", "usb", "dp", "dock"}; - char *e; - int port; - mux_state_t mux = USB_PD_MUX_NONE; - int i; - - if (argc == 2 && !strcasecmp(argv[1], "debug")) { - enable_debug_prints = 1; - return EC_SUCCESS; - } - - if (argc < 2) - return EC_ERROR_PARAM_COUNT; - - port = strtoi(argv[1], &e, 10); - if (*e || port >= board_get_usb_pd_port_count()) - return EC_ERROR_PARAM1; - - if (argc < 3) { - mux_state_t mux_state; - - mux_state = usb_mux_get(port); - ccprintf("Port %d: USB=%d DP=%d POLARITY=%s HPD_IRQ=%d " - "HPD_LVL=%d SAFE=%d TBT=%d USB4=%d\n", port, - !!(mux_state & USB_PD_MUX_USB_ENABLED), - !!(mux_state & USB_PD_MUX_DP_ENABLED), - mux_state & USB_PD_MUX_POLARITY_INVERTED ? - "INVERTED" : "NORMAL", - !!(mux_state & USB_PD_MUX_HPD_IRQ), - !!(mux_state & USB_PD_MUX_HPD_LVL), - !!(mux_state & USB_PD_MUX_SAFE_MODE), - !!(mux_state & USB_PD_MUX_TBT_COMPAT_ENABLED), - !!(mux_state & USB_PD_MUX_USB4_ENABLED)); - - return EC_SUCCESS; - } - - for (i = 0; i < ARRAY_SIZE(mux_name); i++) - if (!strcasecmp(argv[2], mux_name[i])) - mux = i; - usb_mux_set(port, mux, mux == USB_PD_MUX_NONE ? - USB_SWITCH_DISCONNECT : - USB_SWITCH_CONNECT, - polarity_rm_dts(pd_get_polarity(port))); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(typec, command_typec, - "[port|debug] [none|usb|dp|dock]", - "Control type-C connector muxing"); -#endif - -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; - mux_state_t mux_state; - - if (port >= board_get_usb_pd_port_count()) - return EC_RES_INVALID_PARAM; - - if (configure_mux(port, USB_MUX_GET_MODE, &mux_state)) - return EC_RES_ERROR; - - r->flags = mux_state; - - /* 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)) { - usb_mux_hpd_update(port, r->flags & USB_PD_MUX_HPD_LVL); - } - - args->response_size = sizeof(*r); - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_INFO, - hc_usb_pd_mux_info, - EC_VER_MASK(0)); - -static enum ec_status hc_usb_pd_mux_ack(struct host_cmd_handler_args *args) -{ - __maybe_unused const struct ec_params_usb_pd_mux_ack *p = args->params; - - if (!IS_ENABLED(CONFIG_USB_MUX_AP_ACK_REQUEST)) - return EC_RES_INVALID_COMMAND; - - if (ack_task[p->port] != TASK_ID_INVALID) - task_set_event(ack_task[p->port], PD_EVENT_AP_MUX_DONE); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_ACK, - hc_usb_pd_mux_ack, - EC_VER_MASK(0)); diff --git a/driver/usb_mux/virtual.c b/driver/usb_mux/virtual.c deleted file mode 100644 index dbece4faf9..0000000000 --- a/driver/usb_mux/virtual.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Virtual USB mux driver for host-controlled USB muxes. - */ - -#include "common.h" -#include "console.h" -#include "host_command.h" -#include "task.h" -#include "timer.h" -#include "usb_mux.h" -#include "util.h" - -/* - * USB PD protocol configures the USB & DP mux state and USB PD policy - * configures the HPD mux state. Both states are independent of each other - * may differ when the PD role changes when in dock mode. - */ -#define USB_PD_MUX_HPD_STATE (USB_PD_MUX_HPD_LVL | USB_PD_MUX_HPD_IRQ) -#define USB_PD_MUX_USB_DP_STATE (USB_PD_MUX_USB_ENABLED | \ - USB_PD_MUX_DP_ENABLED | USB_PD_MUX_POLARITY_INVERTED | \ - USB_PD_MUX_SAFE_MODE | USB_PD_MUX_TBT_COMPAT_ENABLED | \ - USB_PD_MUX_USB4_ENABLED) - -static mux_state_t virtual_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static inline void virtual_mux_update_state(int port, mux_state_t mux_state, - bool *ack_required) -{ - mux_state_t previous_mux_state = virtual_mux_state[port]; - - virtual_mux_state[port] = mux_state; - - /* - * Initialize ack_required to false to start, and set on necessary - * conditions - */ - *ack_required = false; - - if (!IS_ENABLED(CONFIG_HOSTCMD_EVENTS)) - return; - - host_set_single_event(EC_HOST_EVENT_USB_MUX); - - if (!IS_ENABLED(CONFIG_USB_MUX_AP_ACK_REQUEST)) - return; - - /* - * EC waits for the ACK from kernel indicating that TCSS Mux - * configuration is completed. This mechanism is implemented for - * entering, exiting the safe mode and entering the disconnect mode - * This is needed to remove timing senstivity between BB retimer and - * TCSS Mux to allow better synchronization between them and thereby - * remain in the same state for achieving proper safe state - * terminations. - */ - - /* TODO(b/186777984): Wait for an ACK for all mux state change */ - - if ((!(previous_mux_state & USB_PD_MUX_SAFE_MODE) && - (mux_state & USB_PD_MUX_SAFE_MODE)) || - ((previous_mux_state & USB_PD_MUX_SAFE_MODE) && - !(mux_state & USB_PD_MUX_SAFE_MODE)) || - ((previous_mux_state != USB_PD_MUX_NONE) && - (mux_state == USB_PD_MUX_NONE))) - *ack_required = true; -} - -static int virtual_init(const struct usb_mux *me) -{ - return EC_SUCCESS; -} - -/* - * 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(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) -{ - 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); - - virtual_mux_update_state(port, new_mux_state, ack_required); - - return EC_SUCCESS; -} - -/* - * Get the state of our 'virtual' mux. Since we the EC does not actually - * 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(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(const struct usb_mux *me, mux_state_t mux_state) -{ - int port = me->usb_port; - bool unused; - - /* Current HPD related mux status + existing USB & DP mux status */ - mux_state_t new_mux_state = mux_state | - (virtual_mux_state[port] & USB_PD_MUX_USB_DP_STATE); - - /* HPD ACK isn't required for the EC to continue with its tasks */ - virtual_mux_update_state(port, new_mux_state, &unused); -} - -const struct usb_mux_driver virtual_usb_mux_driver = { - .init = virtual_init, - .set = virtual_set_mux, - .get = virtual_get_mux, -}; |