summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-06-26 12:27:23 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-30 17:18:40 +0000
commit4a56579f21e5aced3673d694fc45811cfd439d84 (patch)
treecbd532f3ad1e54b12f665197718a3a4f68a1cf83
parent1ef8c7dc2096405e815797fd06dec628a39b4e33 (diff)
downloadchrome-ec-4a56579f21e5aced3673d694fc45811cfd439d84.tar.gz
usb_mux: Add support for Parade PS8740 chip
Initial support for Parade PS8740 Type-C redriving switch. BUG=chrome-os-partner:41696 TEST=Manual on Glados in subsequent commit. Verify set() and get() functions set and return consistent values. Verify that USB SS device functions when muxes are set to dock or USB. BRANCH=None Change-Id: Iedbe53cc76f30ecd969c2ca99a7377ed3b193729 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/282280 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--driver/build.mk1
-rw-r--r--driver/ps8740.h35
-rw-r--r--driver/usb_mux_ps8740.c114
-rw-r--r--include/config.h3
-rw-r--r--include/usb_mux.h1
5 files changed, 154 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index 97d80521b3..2331badec3 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -67,6 +67,7 @@ driver-$(CONFIG_USBC_SS_MUX)+=usb_mux.o
# USB muxes
driver-$(CONFIG_USB_MUX_PI3USB30532)+=usb_mux_pi3usb30532.o
+driver-$(CONFIG_USB_MUX_PS8740)+=usb_mux_ps8740.o
# Firmware Update
driver-$(CONFIG_SB_FIRMWARE_UPDATE)+=battery/sb_fw_update.o
diff --git a/driver/ps8740.h b/driver/ps8740.h
new file mode 100644
index 0000000000..ec27a7bf50
--- /dev/null
+++ b/driver/ps8740.h
@@ -0,0 +1,35 @@
+/* Copyright 2015 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.
+ *
+ * Parade PS8740 USB port switch driver.
+ */
+
+#ifndef __CROS_EC_PS8740_H
+#define __CROS_EC_PS8740_H
+
+/* Mode register for setting mux */
+#define PS8740_REG_MODE 0x00
+#define PS8740_MODE_POLARITY_INVERTED (1 << 4)
+#define PS8740_MODE_USB_ENABLED (1 << 5)
+#define PS8740_MODE_DP_ENABLED (1 << 6)
+#define PS8740_MODE_POWER_DOWN (1 << 7)
+
+/* Status register for checking mux state */
+#define PS8740_REG_STATUS 0x09
+#define PS8740_STATUS_POLARITY_INVERTED (1 << 2)
+#define PS8740_STATUS_USB_ENABLED (1 << 3)
+#define PS8740_STATUS_DP_ENABLED (1 << 4)
+#define PS8740_STATUS_HPD_ASSERTED (1 << 7)
+
+/* Chip ID / revision registers and expected fused values */
+#define PS8740_REG_REVISION_ID1 0xf0
+#define PS8740_REVISION_ID1 0x00
+#define PS8740_REG_REVISION_ID2 0xf1
+#define PS8740_REVISION_ID2 0x0a
+#define PS8740_REG_CHIP_ID1 0xf2
+#define PS8740_CHIP_ID1 0x40
+#define PS8740_REG_CHIP_ID2 0xf3
+#define PS8740_CHIP_ID2 0x87
+
+#endif /* __CROS_EC_PS8740_H */
diff --git a/driver/usb_mux_ps8740.c b/driver/usb_mux_ps8740.c
new file mode 100644
index 0000000000..2023c2dea4
--- /dev/null
+++ b/driver/usb_mux_ps8740.c
@@ -0,0 +1,114 @@
+/* Copyright 2015 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.
+ *
+ * Parade PS8740 USB port switch driver.
+ */
+
+#include "common.h"
+#include "i2c.h"
+#include "ps8740.h"
+#include "usb_mux.h"
+#include "util.h"
+
+static int ps8740_read(int i2c_addr, uint8_t reg, uint8_t *val)
+{
+ int read, res;
+
+ res = i2c_read8(I2C_PORT_USB_MUX, i2c_addr, reg, &read);
+ if (res)
+ return res;
+
+ *val = read;
+ return EC_SUCCESS;
+}
+
+static int ps8740_write(int i2c_addr, uint8_t reg, uint8_t val)
+{
+ return i2c_write8(I2C_PORT_USB_MUX, i2c_addr, reg, val);
+}
+
+static int ps8740_reset(int i2c_addr)
+{
+ return ps8740_write(i2c_addr, PS8740_REG_MODE, PS8740_MODE_POWER_DOWN);
+}
+
+static int ps8740_init(int i2c_addr)
+{
+ uint8_t val;
+ int res;
+
+ /* Reset chip back to power-on state */
+ res = ps8740_reset(i2c_addr);
+ if (res)
+ return res;
+
+ /* Verify revision / chip ID registers */
+ res = ps8740_read(i2c_addr, PS8740_REG_REVISION_ID1, &val);
+ if (res)
+ return res;
+ if (val != PS8740_REVISION_ID1)
+ return EC_ERROR_UNKNOWN;
+
+ res = ps8740_read(i2c_addr, PS8740_REG_REVISION_ID2, &val);
+ if (res)
+ return res;
+ if (val != PS8740_REVISION_ID2)
+ return EC_ERROR_UNKNOWN;
+
+ res = ps8740_read(i2c_addr, PS8740_REG_CHIP_ID1, &val);
+ if (res)
+ return res;
+ if (val != PS8740_CHIP_ID1)
+ return EC_ERROR_UNKNOWN;
+
+ res = ps8740_read(i2c_addr, PS8740_REG_CHIP_ID2, &val);
+ if (res)
+ return res;
+ if (val != PS8740_CHIP_ID2)
+ return EC_ERROR_UNKNOWN;
+
+ return EC_SUCCESS;
+}
+
+/* Writes control register to set switch mode */
+static int ps8740_set_mux(int i2c_addr, mux_state_t mux_state)
+{
+ uint8_t reg = 0;
+
+ if (mux_state & MUX_USB_ENABLED)
+ reg |= PS8740_MODE_USB_ENABLED;
+ if (mux_state & MUX_DP_ENABLED)
+ reg |= PS8740_MODE_DP_ENABLED;
+ if (mux_state & MUX_POLARITY_INVERTED)
+ reg |= PS8740_MODE_POLARITY_INVERTED;
+
+ return ps8740_write(i2c_addr, PS8740_REG_MODE, reg);
+}
+
+/* Reads control register and updates mux_state accordingly */
+static int ps8740_get_mux(int i2c_addr, mux_state_t *mux_state)
+{
+ uint8_t reg;
+ int res;
+
+ *mux_state = 0;
+ res = ps8740_read(i2c_addr, PS8740_REG_STATUS, &reg);
+ if (res)
+ return res;
+
+ if (reg & PS8740_STATUS_USB_ENABLED)
+ *mux_state |= MUX_USB_ENABLED;
+ if (reg & PS8740_STATUS_DP_ENABLED)
+ *mux_state |= MUX_DP_ENABLED;
+ if (reg & PS8740_STATUS_POLARITY_INVERTED)
+ *mux_state |= MUX_POLARITY_INVERTED;
+
+ return EC_SUCCESS;
+}
+
+const struct usb_mux_driver ps8740_usb_mux_driver = {
+ .init = ps8740_init,
+ .set = ps8740_set_mux,
+ .get = ps8740_get_mux,
+};
diff --git a/include/config.h b/include/config.h
index 76436708ca..2699335996 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1633,6 +1633,9 @@
/* Support the Pericom PI3USB30532 USB3.0/DP1.2 Matrix Switch */
#undef CONFIG_USB_MUX_PI3USB30532
+/* Support the Parade PS8740 Type-C Redriving Switch */
+#undef CONFIG_USB_MUX_PS8740
+
/*****************************************************************************/
/* USB GPIO config */
#undef CONFIG_USB_GPIO
diff --git a/include/usb_mux.h b/include/usb_mux.h
index d451e9cf1c..d94c0c4606 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -69,6 +69,7 @@ struct usb_mux {
/* Supported USB mux drivers */
extern const struct usb_mux_driver pi3usb30532_usb_mux_driver;
+extern const struct usb_mux_driver ps8740_usb_mux_driver;
/* USB muxes present in system, ordered by PD port #, defined at board-level */
extern struct usb_mux usb_muxes[];