diff options
author | Nathan K <nkolluru@google.com> | 2020-09-17 19:23:09 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-01-20 10:37:07 +0000 |
commit | e67f0cd7000d82b1818a3a60b2cef66f629c77fd (patch) | |
tree | 5cb9e26f07a9f2912bdd1d8019b0297dcc1d1963 /driver/usb_mux | |
parent | 8b88ec0e0f448c2ce833f862aa7d4680adcc0289 (diff) | |
download | chrome-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.c | 107 | ||||
-rw-r--r-- | driver/usb_mux/tusb1064.h | 107 |
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, ®); + 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 */ |