summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParker Lin <parkerlin@google.com>2021-03-02 13:26:46 +0800
committerCommit Bot <commit-bot@chromium.org>2021-04-29 08:39:17 +0000
commit4474767875fa4e149c64641b9f00678f79f1860e (patch)
tree39061480b51e83ed775486afecf7c0a7ad1ba594
parent2adbe4b949041fa54d35fc0f23866948d4c8d27d (diff)
downloadchrome-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.mk1
-rw-r--r--driver/usb_mux/anx3443.c99
-rw-r--r--driver/usb_mux/anx3443.h36
-rw-r--r--include/config.h6
-rw-r--r--util/config_allowed.txt1
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, &reg));
+
+ 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