summaryrefslogtreecommitdiff
path: root/driver/ppc/nx20p348x.c
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2020-02-11 11:33:52 -0700
committerCommit Bot <commit-bot@chromium.org>2020-02-12 14:32:45 +0000
commit65bf4e879f39229ddd69c7a993f95909dbf3f1d0 (patch)
tree5507d1c02737a4b82a8278532871c14c7d8fe888 /driver/ppc/nx20p348x.c
parentd4d347e52e4aa0357d246226fe74749311d9bf31 (diff)
downloadchrome-ec-65bf4e879f39229ddd69c7a993f95909dbf3f1d0.tar.gz
nx20p3483: vbus_source_enable failure correction
The nx20p3483 can not use the switch status register because TCPCI was used to enable the switch control. BUG=none BRANCH=none TEST=verify on TCPMv2 that USB3.1 gen 2 functions Change-Id: I5681996640568d74b51fdfc2d5dac20a97e4908a Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2051010 Reviewed-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'driver/ppc/nx20p348x.c')
-rw-r--r--driver/ppc/nx20p348x.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/driver/ppc/nx20p348x.c b/driver/ppc/nx20p348x.c
index 01c28f52eb..69edcafbe5 100644
--- a/driver/ppc/nx20p348x.c
+++ b/driver/ppc/nx20p348x.c
@@ -30,6 +30,10 @@ static int db_exit_fail_count[CONFIG_USB_PD_PORT_MAX_COUNT];
#define NX20P348X_FLAGS_SOURCE_ENABLED BIT(0)
static uint8_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
+#if !defined(CONFIG_USBC_PPC_NX20P3481) && !defined(CONFIG_USBC_PPC_NX20P3483)
+#error "Either the NX20P3481 or NX20P3483 must be selected"
+#endif
+
static int read_reg(uint8_t port, int reg, int *regval)
{
return i2c_read8(ppc_chips[port].i2c_port,
@@ -135,17 +139,15 @@ static int nx20p348x_vbus_sink_enable(int port, int enable)
enable = !!enable;
-#if defined(CONFIG_USBC_PPC_NX20P3481)
- rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
-#elif defined(CONFIG_USBC_PPC_NX20P3483)
- /*
- * We cannot use an EC GPIO for EN_SNK since an EC reset will float the
- * GPIO thus browning out the board (without a battery).
- */
- rv = tcpm_set_snk_ctrl(port, enable);
-#else
-#error "Either the NX20P3481 or NX20P3483 must be selected"
-#endif
+ if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481))
+ rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
+ else if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3483))
+ /*
+ * We cannot use an EC GPIO for EN_SNK since an EC reset
+ * will float the GPIO thus browning out the board (without
+ * a battery).
+ */
+ rv = tcpm_set_snk_ctrl(port, enable);
if (rv)
return rv;
@@ -173,17 +175,15 @@ static int nx20p348x_vbus_source_enable(int port, int enable)
enable = !!enable;
-#if defined(CONFIG_USBC_PPC_NX20P3481)
- rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
-#elif defined(CONFIG_USBC_PPC_NX20P3483)
- /*
- * For parity's sake, we should not use an EC GPIO for EN_SRC since we
- * cannot use it for EN_SNK (for brown out reason listed above).
- */
- rv = tcpm_set_src_ctrl(port, enable);
-#else
-#error "Either the NX20P3481 or NX20P3483 must be selected"
-#endif
+ if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481))
+ rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
+ else if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3483))
+ /*
+ * For parity's sake, we should not use an EC GPIO for
+ * EN_SRC since we cannot use it for EN_SNK (for brown
+ * out reason listed above).
+ */
+ rv = tcpm_set_src_ctrl(port, enable);
if (rv)
return rv;
@@ -200,15 +200,17 @@ static int nx20p348x_vbus_source_enable(int port, int enable)
* (15 msec) before the status will reflect the control command.
*/
msleep(NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC);
- rv = read_reg(port, NX20P348X_SWITCH_STATUS_REG, &status);
- if (rv) {
- flags[port] = previous_flags;
- return rv;
- }
- if ((status & NX20P348X_SWITCH_STATUS_MASK) != control) {
- flags[port] = previous_flags;
- return EC_ERROR_UNKNOWN;
+ if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481)) {
+ rv = read_reg(port, NX20P348X_SWITCH_STATUS_REG, &status);
+ if (rv) {
+ flags[port] = previous_flags;
+ return rv;
+ }
+ if ((status & NX20P348X_SWITCH_STATUS_MASK) != control) {
+ flags[port] = previous_flags;
+ return EC_ERROR_UNKNOWN;
+ }
}
return EC_SUCCESS;