summaryrefslogtreecommitdiff
path: root/driver/usb_mux
diff options
context:
space:
mode:
authorNathan K <nkolluru@google.com>2020-09-17 19:23:09 -0700
committerCommit Bot <commit-bot@chromium.org>2021-01-20 10:37:07 +0000
commite67f0cd7000d82b1818a3a60b2cef66f629c77fd (patch)
tree5cb9e26f07a9f2912bdd1d8019b0297dcc1d1963 /driver/usb_mux
parent8b88ec0e0f448c2ce833f862aa7d4680adcc0289 (diff)
downloadchrome-ec-e67f0cd7000d82b1818a3a60b2cef66f629c77fd.tar.gz
usb_mux: add a full TUSB1064 driver
The TUSB1064 driver code is modified to implement a real usb_mux driver. This part is a UFP side (RX Equalizer) USB-C switch contrary to most other usb_mux part we have (used in the DFP). It is used in the servo_v4p1. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BUG=b:168621142 BRANCH=servo TEST=use the sink mode enabled by 'cc pdsnk', connect to a USB-C Chromebook try both video output on USB-C->mini-DP and USB 3.0. Change-Id: Ie15d246ba7b6601db0d387e8ffda54f0ec36ba99 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2416764 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'driver/usb_mux')
-rw-r--r--driver/usb_mux/tusb1064.c107
-rw-r--r--driver/usb_mux/tusb1064.h107
2 files changed, 214 insertions, 0 deletions
diff --git a/driver/usb_mux/tusb1064.c b/driver/usb_mux/tusb1064.c
new file mode 100644
index 0000000000..6bbf323b3c
--- /dev/null
+++ b/driver/usb_mux/tusb1064.c
@@ -0,0 +1,107 @@
+/* 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)
+{
+ int reg = REG_GENERAL_STATIC_BITS;
+
+ 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, &reg);
+ 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;
+
+ /* 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;
+
+ /* Disconnect USB3.1 and DP */
+ res = tusb1064_set_mux(me, USB_PD_MUX_NONE);
+ 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
new file mode 100644
index 0000000000..9f5873d8ab
--- /dev/null
+++ b/driver/usb_mux/tusb1064.h
@@ -0,0 +1,107 @@
+/* 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"
+
+#define TUSB1064_ADDR_FLAGS 0x12
+
+/* 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 */