diff options
author | Rob Barnes <robbarnes@google.com> | 2021-02-16 19:29:19 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-23 16:51:14 +0000 |
commit | 1039ba163b0d3287f08736e0f8b87805db6f21f1 (patch) | |
tree | 4488773491cfbc0582e83ee7d397eae34b7e8c79 /driver/usb_mux | |
parent | 136b94b135c584c63673a1f3806ddd9ea5dbf8ac (diff) | |
download | chrome-ec-1039ba163b0d3287f08736e0f8b87805db6f21f1.tar.gz |
guybrush: Add ANX7451 mux/retimer driver
Add basic support for ANX7451. Datasheets available in bug.
Support for tuning can be added later if needed.
BUG=b:179065240
BRANCH=None
TEST=Build
Change-Id: Ifafdec4412b73b0fd3f7de2131a8617bbfde6426
Signed-off-by: Rob Barnes <robbarnes@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2699667
Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'driver/usb_mux')
-rw-r--r-- | driver/usb_mux/anx7451.c | 92 | ||||
-rw-r--r-- | driver/usb_mux/anx7451.h | 37 |
2 files changed, 129 insertions, 0 deletions
diff --git a/driver/usb_mux/anx7451.c b/driver/usb_mux/anx7451.c new file mode 100644 index 0000000000..8af46f6388 --- /dev/null +++ b/driver/usb_mux/anx7451.c @@ -0,0 +1,92 @@ +/* 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. + * + * ANX7451: 10G Active Mux (4x4) with + * Integrated Re-timers for USB3.2/DisplayPort + */ + +#include "anx7451.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 anx7451_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 anx7451_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 anx7451_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 = ANX7451_ULP_CFG_MODE_EN; + if (mux_state & USB_PD_MUX_USB_ENABLED) + reg |= ANX7451_ULP_CFG_MODE_USB_EN; + if (mux_state & USB_PD_MUX_DP_ENABLED) + reg |= ANX7451_ULP_CFG_MODE_DP_EN; + if (mux_state & USB_PD_MUX_POLARITY_INVERTED) + reg |= ANX7451_ULP_CFG_MODE_FLIP; + + return anx7451_write(me, ANX7451_REG_ULP_CFG_MODE, reg); +} + +static int anx7451_get_mux(const struct usb_mux *me, mux_state_t *mux_state) +{ + int reg; + + *mux_state = 0; + RETURN_ERROR(anx7451_read(me, ANX7451_REG_ULP_CFG_MODE, ®)); + + if (reg & ANX7451_ULP_CFG_MODE_USB_EN) + *mux_state |= USB_PD_MUX_USB_ENABLED; + if (reg & ANX7451_ULP_CFG_MODE_DP_EN) + *mux_state |= USB_PD_MUX_DP_ENABLED; + if (reg & ANX7451_ULP_CFG_MODE_FLIP) + *mux_state |= USB_PD_MUX_POLARITY_INVERTED; + + return EC_SUCCESS; +} + +static int anx7451_init(const struct usb_mux *me) +{ + uint64_t now; + + /* + * ANX7451 requires 30ms to power on. EC and ANX7451 are on the same + * power rail, so just wait 30ms since EC boot. + */ + now = get_time().val; + if (now < ANX7451_I2C_READY_DELAY_MS*MSEC) + usleep(ANX7451_I2C_READY_DELAY_MS*MSEC - now); + + /* ULTRA_LOW_POWER must always be disabled (Fig 2-2) */ + RETURN_ERROR(anx7451_write(me, ANX7451_REG_ULTRA_LOW_POWER, + ANX7451_ULTRA_LOW_POWER_DIS)); + + /* Start mux in safe mode */ + RETURN_ERROR(anx7451_set_mux(me, USB_PD_MUX_NONE)); + + return EC_SUCCESS; +} + +const struct usb_mux_driver anx7451_usb_mux_driver = { + .init = anx7451_init, + .set = anx7451_set_mux, + .get = anx7451_get_mux + /* Low power mode is not supported on ANX7451 */ +}; diff --git a/driver/usb_mux/anx7451.h b/driver/usb_mux/anx7451.h new file mode 100644 index 0000000000..21e5d66bf9 --- /dev/null +++ b/driver/usb_mux/anx7451.h @@ -0,0 +1,37 @@ +/* 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. + * + * ANX7451: 10G Active Mux (4x4) with + * Integrated Re-timers for USB3.2/DisplayPort + */ + +#ifndef __CROS_EC_USB_MUX_ANX7451_H +#define __CROS_EC_USB_MUX_ANX7451_H + +#define ANX7451_I2C_READY_DELAY_MS 30 + +/* I2C interface addresses */ +#define ANX7451_I2C_ADDR0_FLAGS 0x10 +#define ANX7451_I2C_ADDR1_FLAGS 0x14 +#define ANX7451_I2C_ADDR2_FLAGS 0x16 +#define ANX7451_I2C_ADDR3_FLAGS 0x11 + +/* + * Ultra low power control register. + * On ANX7451, this register should always be 0 (disabled). + * See figure 2-2 in family programming guide. + */ +#define ANX7451_REG_ULTRA_LOW_POWER 0xE6 +/* #define ANX7451_ULTRA_LOW_POWER_EN 0x06 */ +#define ANX7451_ULTRA_LOW_POWER_DIS 0x00 + +/* Mux control register */ +#define ANX7451_REG_ULP_CFG_MODE 0xF8 +#define ANX7451_ULP_CFG_MODE_EN BIT(4) +#define ANX7451_ULP_CFG_MODE_SWAP BIT(3) +#define ANX7451_ULP_CFG_MODE_FLIP BIT(2) +#define ANX7451_ULP_CFG_MODE_DP_EN BIT(1) +#define ANX7451_ULP_CFG_MODE_USB_EN BIT(0) + +#endif /* __CROS_EC_USB_MUX_ANX7451_H */ |