summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2020-01-23 19:00:07 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-29 00:57:39 +0000
commit5f92ac0bde2b6108c4359ea453456d30ef36bdde (patch)
tree1560209defa8765c334178bc39f9432d0f5151a9
parent609366791c55586d051130363cafb0272ceb0800 (diff)
downloadchrome-ec-5f92ac0bde2b6108c4359ea453456d30ef36bdde.tar.gz
driver/retimer: Add support for ON Semi NB7V904M
This commit adds support for the ON Semiconductor NB7V904M USB Type-C Alt Mode Linear Redriver. BUG=b:147782066 BRANCH=None TEST=Enable on waddledoo, `make -j BOARD=waddledoo` Change-Id: Ia6fe76d0ad99bf7a8129e5d453ff12183990a50a Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2018707 Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Auto-Submit: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--driver/build.mk1
-rw-r--r--driver/retimer/nb7v904m.c143
-rw-r--r--driver/retimer/nb7v904m.h41
-rw-r--r--include/config.h1
4 files changed, 186 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index 6bd2689e8e..ee2afde542 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -136,6 +136,7 @@ driver-$(CONFIG_USB_PD_TCPM_RAA489000)+=tcpm/raa489000.o
# Type-C Retimer drivers
driver-$(CONFIG_USBC_RETIMER_INTEL_BB)+=retimer/bb_retimer.o
+driver-$(CONFIG_USBC_RETIMER_NB7V904M)+=retimer/nb7v904m.o
driver-$(CONFIG_USBC_RETIMER_PI3DPX1207)+=retimer/pi3dpx1207.o
driver-$(CONFIG_USBC_RETIMER_PS8802)+=retimer/ps8802.o
driver-$(CONFIG_USBC_RETIMER_PS8818)+=retimer/ps8818.o
diff --git a/driver/retimer/nb7v904m.c b/driver/retimer/nb7v904m.c
new file mode 100644
index 0000000000..81fd5abc93
--- /dev/null
+++ b/driver/retimer/nb7v904m.c
@@ -0,0 +1,143 @@
+/* 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.
+ *
+ * ON Semiconductor NB7V904M USB Type-C DisplayPort Alt Mode Redriver
+ */
+#include <stdbool.h>
+#include "common.h"
+#include "console.h"
+#include "ec_commands.h"
+#include "i2c.h"
+#include "nb7v904m.h"
+#include "usb_mux.h"
+
+#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
+
+static int nb7v904m_write(int port, int offset, int data)
+{
+ return i2c_write8(usb_retimers[port].i2c_port,
+ usb_retimers[port].i2c_addr_flags,
+ offset, data);
+
+}
+
+static int nb7v904m_read(int port, int offset, int *regval)
+{
+ return i2c_read8(usb_retimers[port].i2c_port,
+ usb_retimers[port].i2c_addr_flags,
+ offset, regval);
+
+}
+
+static int set_low_power_mode(int port, bool enable)
+{
+ int regval;
+ int rv;
+
+ rv = nb7v904m_read(port, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
+ if (rv)
+ return rv;
+
+ if (enable)
+ regval |= NB7V904M_CHIP_EN;
+ else
+ regval &= ~NB7V904M_CHIP_EN;
+
+ return nb7v904m_write(port, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
+}
+
+static int nb7v904m_enter_low_power_mode(int port)
+{
+ int rv = set_low_power_mode(port, 1);
+
+ if (rv)
+ CPRINTS("C%d: NB7V904M: Failed to enter low power mode!", port);
+ return rv;
+}
+
+static int nb7v904m_init(int port)
+{
+ int rv = set_low_power_mode(port, 0);
+
+ if (rv)
+ CPRINTS("C%d: NB7V904M: init failed!", port);
+ return rv;
+}
+
+static int nb7v904m_set_mux(int port, mux_state_t mux_state)
+{
+ int rv = EC_SUCCESS;
+ int regval;
+ int flipped = !!(mux_state & USB_PD_MUX_POLARITY_INVERTED);
+
+ /* Turn off redriver if it's not needed at all. */
+ if (mux_state == USB_PD_MUX_NONE)
+ return nb7v904m_enter_low_power_mode(port);
+
+ rv = nb7v904m_init(port);
+ if (rv)
+ return rv;
+
+ /* Clear operation mode field */
+ rv = nb7v904m_read(port, NB7V904M_REG_GEN_DEV_SETTINGS, &regval);
+ if (rv) {
+ CPRINTS("C%d %s: Failed to obtain dev settings!", port,
+ __func__);
+ return rv;
+ }
+ regval &= ~NB7V904M_OP_MODE_MASK;
+
+ if (mux_state & USB_PD_MUX_USB_ENABLED) {
+ /* USB with DP */
+ if (mux_state & USB_PD_MUX_DP_ENABLED) {
+ if (flipped)
+ regval |= NB7V904M_USB_DP_FLIPPED;
+ else
+ regval |= NB7V904M_USB_DP_NORMAL;
+ } else {
+ /* USB only */
+ regval |= NB7V904M_USB_ONLY;
+ }
+
+ } else if (mux_state & USB_PD_MUX_DP_ENABLED) {
+ /* 4 lanes DP */
+ regval |= NB7V904M_DP_ONLY;
+ }
+
+ if (mux_state & USB_PD_MUX_DP_ENABLED) {
+ /* Connect AUX */
+ rv = nb7v904m_write(port, NB7V904M_REG_AUX_CH_CTRL, flipped ?
+ NB7V904M_AUX_CH_FLIPPED :
+ NB7V904M_AUX_CH_NORMAL);
+ /* Enable all channels for DP */
+ regval |= NB7V904M_CH_EN_MASK;
+ } else {
+ /* Disconnect AUX since it's not being used. */
+ rv = nb7v904m_write(port, NB7V904M_REG_AUX_CH_CTRL,
+ NB7V904M_AUX_CH_HI_Z);
+
+ /* Disable the unused channels to save power */
+ regval &= ~NB7V904M_CH_EN_MASK;
+ if (flipped) {
+ /* Only enable channels A & B */
+ regval |= NB7V904M_CH_A_EN | NB7V904M_CH_B_EN;
+ } else {
+ /* Only enable channels C & D */
+ regval |= NB7V904M_CH_C_EN | NB7V904M_CH_D_EN;
+ }
+ }
+
+ rv |= nb7v904m_write(port, NB7V904M_REG_GEN_DEV_SETTINGS, regval);
+ if (rv)
+ CPRINTS("C%d: %s failed!", port, __func__);
+
+ return rv;
+}
+
+const struct usb_retimer_driver nb7v904m_usb_redriver_drv = {
+ .enter_low_power_mode = &nb7v904m_enter_low_power_mode,
+ .init = &nb7v904m_init,
+ .set = &nb7v904m_set_mux,
+};
diff --git a/driver/retimer/nb7v904m.h b/driver/retimer/nb7v904m.h
new file mode 100644
index 0000000000..4306615825
--- /dev/null
+++ b/driver/retimer/nb7v904m.h
@@ -0,0 +1,41 @@
+/* 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.
+ *
+ * ON Semiconductor NB7V904M USB Type-C DisplayPort Alt Mode Redriver
+ */
+
+#ifndef __CROS_EC_USB_REDRIVER_NB7V904M_H
+#define __CROS_EC_USB_REDRIVER_NB7V904M_H
+
+#include "compile_time_macros.h"
+#include "usb_mux.h"
+
+#define NB7V904M_I2C_ADDR0 0x19
+#define NB7V904M_I2C_ADDR1 0x1A
+#define NB7V904M_I2C_ADDR2 0x1C
+
+/* Registers */
+#define NB7V904M_REG_GEN_DEV_SETTINGS 0x00
+#define NB7V904M_REG_AUX_CH_CTRL 0x09
+
+/* 0x00 - General Device Settings */
+#define NB7V904M_CHIP_EN BIT(0)
+#define NB7V904M_USB_DP_NORMAL BIT(1)
+#define NB7V904M_USB_DP_FLIPPED 0
+#define NB7V904M_DP_ONLY BIT(2)
+#define NB7V904M_USB_ONLY (BIT(3) | BIT(1))
+#define NB7V904M_OP_MODE_MASK GENMASK(3, 1)
+#define NB7V904M_CH_A_EN BIT(4)
+#define NB7V904M_CH_B_EN BIT(5)
+#define NB7V904M_CH_C_EN BIT(6)
+#define NB7V904M_CH_D_EN BIT(7)
+#define NB7V904M_CH_EN_MASK GENMASK(7, 4)
+
+/* 0x09 - Auxiliary Channel Control */
+#define NB7V904M_AUX_CH_NORMAL 0
+#define NB7V904M_AUX_CH_FLIPPED BIT(0)
+#define NB7V904M_AUX_CH_HI_Z BIT(1)
+
+extern const struct usb_retimer_driver nb7v904m_usb_redriver_drv;
+#endif /* __CROS_EC_USB_REDRIVER_NB7V904M_H */
diff --git a/include/config.h b/include/config.h
index ae5318d311..7741c807eb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3893,6 +3893,7 @@
* Type-C retimer drivers to be used.
*/
#undef CONFIG_USBC_RETIMER_INTEL_BB
+#undef CONFIG_USBC_RETIMER_NB7V904M
#undef CONFIG_USBC_RETIMER_PI3DPX1207
#undef CONFIG_USBC_RETIMER_PS8802
#undef CONFIG_USBC_RETIMER_PS8818