summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2018-04-04 10:38:50 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-04-10 19:12:48 -0700
commitdb8d6edf26ba3f78bbab2bcda7a98e249331b8c1 (patch)
tree8b15d0b02d9728dfab674cd65e0c7e27ba8c69b9
parentc8814430d65c440950446c573db0932707f02c89 (diff)
downloadchrome-ec-db8d6edf26ba3f78bbab2bcda7a98e249331b8c1.tar.gz
ppc: Add tcpci snk/src control via the COMMAND register
The ANX7447 has a sink/source control lines which can be connected to a PPC. The NX20P3483 PPC requires this control to set it's sink/source switch control. The ANX7447 contols these lines via the tcpci COMMAND register. This CL adds new tcpm_set functions to set either SNK or SRC control via the COMMAND register. BUG=b:77583452 BRANCH=NONE TEST=Tested on port 0 of Yorp with an external charger. Prior to this CL the PPC would remain in standby state because both snk/src control remained low. With these changes, verifed that snk_ctrl is driven high and vbus_sink_enable() function no longer returns an error. Change-Id: Icbea0d3edb63ad19f3d2c76636208497b6939a72 Signed-off-by: Scott Collyer <scollyer@google.com> Reviewed-on: https://chromium-review.googlesource.com/996239 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--driver/ppc/nx20p3483.c9
-rw-r--r--driver/tcpm/anx7447.c4
-rw-r--r--driver/tcpm/tcpci.c22
-rw-r--r--driver/tcpm/tcpci.h8
-rw-r--r--driver/tcpm/tcpm.h19
-rw-r--r--include/usb_pd_tcpm.h22
6 files changed, 84 insertions, 0 deletions
diff --git a/driver/ppc/nx20p3483.c b/driver/ppc/nx20p3483.c
index b9b355441b..6c89fa76d5 100644
--- a/driver/ppc/nx20p3483.c
+++ b/driver/ppc/nx20p3483.c
@@ -12,6 +12,7 @@
#include "hooks.h"
#include "i2c.h"
#include "system.h"
+#include "tcpm.h"
#include "usb_charge.h"
#include "usb_pd_tcpm.h"
#include "usbc_ppc.h"
@@ -129,6 +130,10 @@ static int nx20p3483_vbus_sink_enable(int port, int enable)
/* Set SNK mode based on enable */
gpio_set_level(ppc_chips[port].snk_gpio, enable);
+ } else {
+ rv = tcpm_set_snk_ctrl(port, enable);
+ if (rv)
+ return rv;
}
/* Verify switch status register */
@@ -158,6 +163,10 @@ static int nx20p3483_vbus_source_enable(int port, int enable)
/* Set SRC mode based on enable */
gpio_set_level(ppc_chips[port].src_gpio, enable);
+ } else {
+ rv = tcpm_set_src_ctrl(port, enable);
+ if (rv)
+ return rv;
}
/* Verify switch status register */
diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c
index 30266a3b6b..f16a5cba0a 100644
--- a/driver/tcpm/anx7447.c
+++ b/driver/tcpm/anx7447.c
@@ -381,6 +381,10 @@ const struct tcpm_drv anx7447_tcpm_drv = {
.drp_toggle = &tcpci_tcpc_drp_toggle,
#endif
.get_chip_info = &tcpci_get_chip_info,
+#ifdef CONFIG_USBC_PPC
+ .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl,
+ .set_src_ctrl = &tcpci_tcpm_set_src_ctrl,
+#endif
};
#ifdef CONFIG_USB_PD_TCPM_MUX
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 6eaf2cd8cd..60083e312c 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -169,6 +169,24 @@ int tcpci_tcpm_set_polarity(int port, int polarity)
TCPC_REG_TCPC_CTRL_SET(polarity));
}
+#ifdef CONFIG_USBC_PPC
+int tcpci_tcpm_set_snk_ctrl(int port, int enable)
+{
+ int cmd = enable ? TCPC_REG_COMMAND_SNK_CTRL_HIGH :
+ TCPC_REG_COMMAND_SNK_CTRL_LOW;
+
+ return tcpc_write(port, TCPC_REG_COMMAND, cmd);
+}
+
+int tcpci_tcpm_set_src_ctrl(int port, int enable)
+{
+ int cmd = enable ? TCPC_REG_COMMAND_SRC_CTRL_HIGH :
+ TCPC_REG_COMMAND_SRC_CTRL_LOW;
+
+ return tcpc_write(port, TCPC_REG_COMMAND, cmd);
+}
+#endif
+
int tcpci_tcpm_set_vconn(int port, int enable)
{
int reg, rv;
@@ -559,4 +577,8 @@ const struct tcpm_drv tcpci_tcpm_drv = {
.drp_toggle = &tcpci_tcpc_drp_toggle,
#endif
.get_chip_info = &tcpci_get_chip_info,
+#ifdef CONFIG_USBC_PPC
+ .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl,
+ .set_src_ctrl = &tcpci_tcpm_set_src_ctrl,
+#endif
};
diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h
index cc6fb3c4d1..c7cefc4ba4 100644
--- a/driver/tcpm/tcpci.h
+++ b/driver/tcpm/tcpci.h
@@ -81,6 +81,10 @@
#define TCPC_REG_FAULT_STATUS 0x1f
#define TCPC_REG_COMMAND 0x23
+#define TCPC_REG_COMMAND_SNK_CTRL_LOW 0x44
+#define TCPC_REG_COMMAND_SNK_CTRL_HIGH 0x55
+#define TCPC_REG_COMMAND_SRC_CTRL_LOW 0x66
+#define TCPC_REG_COMMAND_SRC_CTRL_HIGH 0x77
#define TCPC_REG_COMMAND_LOOK4CONNECTION 0x99
#define TCPC_REG_COMMAND_I2CIDLE 0xFF
@@ -148,5 +152,9 @@ int tcpci_tcpm_mux_set(int i2c_addr, mux_state_t mux_state);
int tcpci_tcpm_mux_get(int i2c_addr, mux_state_t *mux_state);
int tcpci_get_chip_info(int port, int renew,
struct ec_response_pd_chip_info **chip_info);
+#ifdef CONFIG_USBC_PPC
+int tcpci_tcpm_set_snk_ctrl(int port, int enable);
+int tcpci_tcpm_set_src_ctrl(int port, int enable);
+#endif
#endif /* __CROS_EC_USB_PD_TCPM_TCPCI_H */
diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h
index 34f1138c57..32ec76bbfc 100644
--- a/driver/tcpm/tcpm.h
+++ b/driver/tcpm/tcpm.h
@@ -13,6 +13,7 @@
#include "gpio.h"
#include "i2c.h"
#include "usb_pd_tcpm.h"
+#include "util.h"
#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \
!defined(CONFIG_USB_PD_DUAL_ROLE)
@@ -142,6 +143,24 @@ static inline int tcpm_transmit(int port, enum tcpm_transmit_type type,
return tcpc_config[port].drv->transmit(port, type, header, data);
}
+#ifdef CONFIG_USBC_PPC
+static inline int tcpm_set_snk_ctrl(int port, int enable)
+{
+ if (tcpc_config[port].drv->set_snk_ctrl != NULL)
+ return tcpc_config[port].drv->set_snk_ctrl(port, enable);
+ else
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+static inline int tcpm_set_src_ctrl(int port, int enable)
+{
+ if (tcpc_config[port].drv->set_snk_ctrl != NULL)
+ return tcpc_config[port].drv->set_src_ctrl(port, enable);
+ else
+ return EC_ERROR_UNIMPLEMENTED;
+}
+#endif
+
static inline void tcpc_alert(int port)
{
tcpc_config[port].drv->tcpc_alert(port);
diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h
index d8ad743caa..1b77e40450 100644
--- a/include/usb_pd_tcpm.h
+++ b/include/usb_pd_tcpm.h
@@ -220,6 +220,28 @@ struct tcpm_drv {
*/
int (*get_chip_info)(int port, int renew,
struct ec_response_pd_chip_info **info);
+
+#ifdef CONFIG_USBC_PPC
+ /**
+ * Send SinkVBUS or DisableSinkVBUS command
+ *
+ * @param port Type-C port number
+ * @enable true for enable, false for disable
+ *
+ * @return EC_SUCCESS or error
+ */
+ int (*set_snk_ctrl)(int port, int enable);
+
+ /**
+ * Send SourceVBUS or DisableSourceVBUS command
+ *
+ * @param port Type-C port number
+ * @enable true for enable, false for disable
+ *
+ * @return EC_SUCCESS or error
+ */
+ int (*set_src_ctrl)(int port, int enable);
+#endif
};
enum tcpc_alert_polarity {