diff options
author | Parker Lin <parkerlin@google.com> | 2021-03-02 13:26:46 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-29 08:39:17 +0000 |
commit | 4474767875fa4e149c64641b9f00678f79f1860e (patch) | |
tree | 39061480b51e83ed775486afecf7c0a7ad1ba594 | |
parent | 2adbe4b949041fa54d35fc0f23866948d4c8d27d (diff) | |
download | chrome-ec-4474767875fa4e149c64641b9f00678f79f1860e.tar.gz |
cherry: Add ANX3443 mux/retimer driver
Add basic support for ANX3443. Datasheets available in bug.
BUG=b:181282482
BRANCH=None
TEST=Build
Signed-off-by: Parker Lin <parkerlin@google.com>
Change-Id: Id779547704408b9563f803885cd755ae96d38ef7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2728001
Tested-by: Ting Shen <phoenixshen@chromium.org>
Reviewed-by: Eric Yilun Lin <yllin@google.com>
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/usb_mux/anx3443.c | 99 | ||||
-rw-r--r-- | driver/usb_mux/anx3443.h | 36 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | util/config_allowed.txt | 1 |
5 files changed, 143 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk index 88ffcf32c3..a5434c7357 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -169,6 +169,7 @@ driver-$(CONFIG_USBC_SS_MUX)+=usb_mux/usb_mux.o # USB muxes driver-$(CONFIG_USB_MUX_AMD_FP5)+=usb_mux/amd_fp5.o driver-$(CONFIG_USB_MUX_AMD_FP6)+=usb_mux/amd_fp6.o +driver-$(CONFIG_USB_MUX_ANX3443)+=usb_mux/anx3443.o driver-$(CONFIG_USB_MUX_ANX7440)+=usb_mux/anx7440.o driver-$(CONFIG_USB_MUX_ANX7451)+=usb_mux/anx7451.o driver-$(CONFIG_USB_MUX_IT5205)+=usb_mux/it5205.o diff --git a/driver/usb_mux/anx3443.c b/driver/usb_mux/anx3443.c new file mode 100644 index 0000000000..232f6e70c7 --- /dev/null +++ b/driver/usb_mux/anx3443.c @@ -0,0 +1,99 @@ +/* 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 "common.h" +#include "console.h" +#include "i2c.h" +#include "time.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 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_set_mux(const struct usb_mux *me, mux_state_t mux_state) +{ + int reg; + + /* 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_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; + + /* + * 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); + + /* Disable ultra-low power mode */ + RETURN_ERROR(anx3443_write(me, ANX3443_REG_ULTRA_LOW_POWER, + ANX3443_ULTRA_LOW_POWER_DIS)); + + /* Start mux in safe mode */ + RETURN_ERROR(anx3443_set_mux(me, USB_PD_MUX_NONE)); + + return EC_SUCCESS; +} + +static int anx3443_enter_low_power_mode(const struct usb_mux *me) +{ + /* Enable vendor-defined ultra-low power mode */ + return anx3443_write(me, ANX3443_REG_ULTRA_LOW_POWER, + ANX3443_ULTRA_LOW_POWER_EN); +} + +const struct usb_mux_driver anx3443_usb_mux_driver = { + .init = anx3443_init, + .set = anx3443_set_mux, + .get = anx3443_get_mux, + .enter_low_power_mode = anx3443_enter_low_power_mode, +}; diff --git a/driver/usb_mux/anx3443.h b/driver/usb_mux/anx3443.h new file mode 100644 index 0000000000..e60ffe2e25 --- /dev/null +++ b/driver/usb_mux/anx3443.h @@ -0,0 +1,36 @@ +/* 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 + + +/* 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/include/config.h b/include/config.h index afa6b777f6..0bd29366d3 100644 --- a/include/config.h +++ b/include/config.h @@ -4872,6 +4872,12 @@ #undef CONFIG_USB_MUX_AMD_FP6 /* + * Support the Analogix ANX3443 USB Type-C Active mux (6x4) with + * Integrated Re-timers for USB3.2/DisplayPort. + */ +#undef CONFIG_USB_MUX_ANX3443 + +/* * Support the Analogix ANX7440 USB Type-C Active mux with * Integrated Re-timers for USB3.1/DisplayPort. */ diff --git a/util/config_allowed.txt b/util/config_allowed.txt index 4560e32b57..33930362e8 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -1159,6 +1159,7 @@ CONFIG_USB_ISOCHRONOUS CONFIG_USB_MAXPOWER_MA CONFIG_USB_MUX_AMD_FP5 CONFIG_USB_MUX_AMD_FP6 +CONFIG_USB_MUX_ANX3443 CONFIG_USB_MUX_ANX7440 CONFIG_USB_MUX_ANX7451 CONFIG_USB_MUX_AP_ACK_REQUEST |