summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2018-01-22 17:46:05 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-01 18:08:36 -0800
commite127855f27ace32faa948ee8ab052ccb98e42dd6 (patch)
tree45d3fc814a6b41cec5fac0f24230bc672d245143
parent1b87ee65ac8f3cd895da6ef2e219670d2f9779ec (diff)
downloadchrome-ec-e127855f27ace32faa948ee8ab052ccb98e42dd6.tar.gz
ppc: Add Vconn and CC polarity settings.
BUG=b:72292985 BRANCH=None TEST=Flash meowth; Verify with twinkie that Vconn is provided for a sink that requires it. Change-Id: I8168d2e4c46e04810dcf5c2898b2c337424eefec Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/888224 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/usb_pd_protocol.c39
-rw-r--r--common/usbc_ppc.c16
-rw-r--r--driver/ppc/sn5s330.c36
-rw-r--r--driver/ppc/sn5s330.h3
-rw-r--r--include/usbc_ppc.h34
5 files changed, 120 insertions, 8 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 78578aaf9f..c7a7bbe6e9 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -317,6 +317,29 @@ static inline int pd_is_vbus_present(int port)
}
#endif
+static void set_polarity(int port, int polarity)
+{
+ tcpm_set_polarity(port, polarity);
+#ifdef CONFIG_USBC_PPC
+ ppc_set_polarity(port, polarity);
+#endif /* defined(CONFIG_USBC_PPC) */
+}
+
+#ifdef CONFIG_USBC_VCONN
+static void set_vconn(int port, int enable)
+{
+#ifdef CONFIG_USBC_PPC
+ /*
+ * USB-C PPCs can source their own Vconn. No need to tell the TCPC
+ * to source its own.
+ */
+ ppc_set_vconn(port, enable);
+#else /* !defined(CONFIG_USBC_PPC) */
+ tcpm_set_vconn(port, enable);
+#endif /* defined(CONFIG_USBC_PPC) */
+}
+#endif /* defined(CONFIG_USBC_VCONN) */
+
static inline void set_state(int port, enum pd_states next_state)
{
enum pd_states last_state = pd[port].task_state;
@@ -355,8 +378,8 @@ static inline void set_state(int port, enum pd_states next_state)
CHARGE_CEIL_NONE);
#endif
#ifdef CONFIG_USBC_VCONN
- tcpm_set_vconn(port, 0);
-#endif
+ set_vconn(port, 0);
+#endif /* defined(CONFIG_USBC_VCONN) */
#else /* CONFIG_USB_PD_DUAL_ROLE */
if (next_state == PD_STATE_SRC_DISCONNECTED) {
#endif
@@ -2180,7 +2203,7 @@ void pd_task(void *u)
#endif
(PD_ROLE_DEFAULT(port) == PD_ROLE_SOURCE &&
pd[port].task_state == PD_STATE_SRC_READY))) {
- tcpm_set_polarity(port, pd[port].polarity);
+ set_polarity(port, pd[port].polarity);
tcpm_set_msg_header(port, pd[port].power_role,
pd[port].data_role);
tcpm_set_rx_enable(port, 1);
@@ -2311,7 +2334,7 @@ void pd_task(void *u)
if (new_cc_state == PD_CC_UFP_ATTACHED ||
new_cc_state == PD_CC_DEBUG_ACC) {
pd[port].polarity = (cc1 != TYPEC_CC_VOLT_RD);
- tcpm_set_polarity(port, pd[port].polarity);
+ set_polarity(port, pd[port].polarity);
/* initial data role for source is DFP */
pd_set_data_role(port, PD_ROLE_DFP);
@@ -2336,7 +2359,7 @@ void pd_task(void *u)
tcpm_set_rx_enable(port, 1);
#ifdef CONFIG_USBC_VCONN
- tcpm_set_vconn(port, 1);
+ set_vconn(port, 1);
pd[port].flags |= PD_FLAGS_VCONN_ON;
#endif
@@ -2794,7 +2817,7 @@ void pd_task(void *u)
/* We are attached */
pd[port].polarity = get_snk_polarity(cc1, cc2);
- tcpm_set_polarity(port, pd[port].polarity);
+ set_polarity(port, pd[port].polarity);
/* reset message ID on connection */
pd[port].msg_id = 0;
/* initial data role for sink is UFP */
@@ -3128,7 +3151,7 @@ void pd_task(void *u)
if (pd[port].last_state != pd[port].task_state) {
if (!(pd[port].flags & PD_FLAGS_VCONN_ON)) {
/* Turn VCONN on and wait for it */
- tcpm_set_vconn(port, 1);
+ set_vconn(port, 1);
set_state_timeout(port,
get_time().val + PD_VCONN_SWAP_DELAY,
PD_STATE_VCONN_SWAP_READY);
@@ -3160,7 +3183,7 @@ void pd_task(void *u)
READY_RETURN_STATE(port));
} else {
/* Turn VCONN off and wait for it */
- tcpm_set_vconn(port, 0);
+ set_vconn(port, 0);
pd[port].flags &= ~PD_FLAGS_VCONN_ON;
set_state_timeout(port,
get_time().val + PD_VCONN_SWAP_DELAY,
diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c
index 4cea6813bc..6ff79a17bf 100644
--- a/common/usbc_ppc.c
+++ b/common/usbc_ppc.c
@@ -42,6 +42,14 @@ int ppc_is_sourcing_vbus(int port)
return ppc_chips[port].drv->is_sourcing_vbus(port);
}
+int ppc_set_polarity(int port, int polarity)
+{
+ if ((port < 0) || (port >= ppc_cnt))
+ return EC_ERROR_INVAL;
+
+ return ppc_chips[port].drv->set_polarity(port, polarity);
+}
+
int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp)
{
if ((port < 0) || (port >= ppc_cnt))
@@ -58,6 +66,14 @@ int ppc_discharge_vbus(int port, int enable)
return ppc_chips[port].drv->discharge_vbus(port, enable);
}
+int ppc_set_vconn(int port, int enable)
+{
+ if ((port < 0) || (port >= ppc_cnt))
+ return EC_ERROR_INVAL;
+
+ return ppc_chips[port].drv->set_vconn(port, enable);
+}
+
int ppc_vbus_sink_enable(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
index bdc9d3af7d..90f90528ef 100644
--- a/driver/ppc/sn5s330.c
+++ b/driver/ppc/sn5s330.c
@@ -455,6 +455,23 @@ static int sn5s330_is_sourcing_vbus(int port)
return is_sourcing_vbus;
}
+static int sn5s330_set_polarity(int port, int polarity)
+{
+ int regval;
+ int status;
+
+ status = read_reg(port, SN5S330_FUNC_SET4, &regval);
+ if (status)
+ return status;
+
+ if (polarity)
+ regval |= SN5S330_CC_POLARITY; /* CC2 active. */
+ else
+ regval &= ~SN5S330_CC_POLARITY; /* CC1 active. */
+
+ return write_reg(port, SN5S330_FUNC_SET4, regval);
+}
+
static int sn5s330_set_vbus_source_current_limit(int port,
enum tcpc_rp_value rp)
{
@@ -515,6 +532,23 @@ static int sn5s330_discharge_vbus(int port, int enable)
return EC_SUCCESS;
}
+static int sn5s330_set_vconn(int port, int enable)
+{
+ int regval;
+ int status;
+
+ status = read_reg(port, SN5S330_FUNC_SET4, &regval);
+ if (status)
+ return status;
+
+ if (enable)
+ regval |= SN5S330_VCONN_EN;
+ else
+ regval &= ~SN5S330_VCONN_EN;
+
+ return write_reg(port, SN5S330_FUNC_SET4, regval);
+}
+
static int sn5s330_vbus_sink_enable(int port, int enable)
{
return sn5s330_pp_fet_enable(port, SN5S330_PP2, !!enable);
@@ -588,6 +622,8 @@ const struct ppc_drv sn5s330_drv = {
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
.is_vbus_present = &sn5s330_is_vbus_present,
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
+ .set_polarity = &sn5s330_set_polarity,
.set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit,
.discharge_vbus = &sn5s330_discharge_vbus,
+ .set_vconn = &sn5s330_set_vconn,
};
diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h
index e8850faf57..2e4b36cbca 100644
--- a/driver/ppc/sn5s330.h
+++ b/driver/ppc/sn5s330.h
@@ -95,6 +95,9 @@ enum sn5s330_pp_idx {
#define SN5S330_SET_RCP_MODE_PP1 (1 << 5)
#define SN5S330_SET_RCP_MODE_PP2 (1 << 6)
+/* FUNC_SET_4 */
+#define SN5S330_VCONN_EN (1 << 0)
+#define SN5S330_CC_POLARITY (1 << 1)
#define SN5S330_CC_EN (1 << 4)
/* FUNC_SET_9 */
diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h
index eec8362959..54142b2921 100644
--- a/include/usbc_ppc.h
+++ b/include/usbc_ppc.h
@@ -49,6 +49,15 @@ struct ppc_drv {
int (*vbus_source_enable)(int port, int enable);
/**
+ * Inform the PPC of the polarity of the CC pins.
+ *
+ * @param port: The Type-C port number.
+ * @param polarity: 1: CC2 used for comms, 0: CC1 used for comms.
+ * @return EC_SUCCESS on success, error otherwise.
+ */
+ int (*set_polarity)(int port, int polarity);
+
+ /**
* Set the Vbus source path current limit
*
* @param port: The Type-C port number.
@@ -66,6 +75,14 @@ struct ppc_drv {
*/
int (*discharge_vbus)(int port, int enable);
+ /**
+ * Turn on/off the VCONN FET.
+ *
+ * @param port: The Type-C port number.
+ * @param enable: 1: enable VCONN FET 0: disable VCONN FET.
+ */
+ int (*set_vconn)(int port, int enable);
+
#ifdef CONFIG_CMD_PPC_DUMP
/**
* Perform a register dump of the PPC.
@@ -121,6 +138,15 @@ int ppc_is_vbus_present(int port);
int ppc_is_sourcing_vbus(int port);
/**
+ * Inform the PPC of the polarity of the CC pins.
+ *
+ * @param port: The Type-C port number.
+ * @param polarity: 1: CC2 used for comms, 0: CC1 used for comms.
+ * @return EC_SUCCESS on success, error otherwise.
+ */
+int ppc_set_polarity(int port, int polarity);
+
+/**
* Set the Vbus source path current limit
*
* @param port: The Type-C port number.
@@ -130,6 +156,14 @@ int ppc_is_sourcing_vbus(int port);
int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp);
/**
+ * Turn on/off the VCONN FET.
+ *
+ * @param port: The Type-C port number.
+ * @param enable: 1: enable VCONN FET 0: disable VCONN FET.
+ */
+int ppc_set_vconn(int port, int enable);
+
+/**
* Discharge PD VBUS on src/sink disconnect & power role swap
*
* @param port: The Type-C port number.