From 760caca89bfe3d91fe7d66b8d435a105664fd0d3 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Thu, 25 Jan 2018 10:45:22 -0700 Subject: usb pd: Adding PPC vbus discharge path Boards with a PPC will use the PPC to discharge the VBUS line instead of the TCPC or GPIO discharge path. BRANCH=none BUG=b:72179253 TEST=Fall time after device removal on grunt within spec now Change-Id: I822923a1cedb32a20efc3610cce4437ade3387f0 Signed-off-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/886563 Reviewed-by: Edward Hill --- common/usb_pd_policy.c | 3 +++ common/usbc_ppc.c | 8 ++++++++ driver/ppc/sn5s330.c | 24 ++++++++++++++++++++++++ driver/ppc/sn5s330.h | 1 + include/config.h | 24 +++++++++++++++--------- include/usbc_ppc.h | 18 ++++++++++++++++++ 6 files changed, 69 insertions(+), 9 deletions(-) diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 936ad6980f..01784e87ad 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -21,6 +21,7 @@ #include "util.h" #include "usb_api.h" #include "usb_pd.h" +#include "usbc_ppc.h" #include "version.h" #ifdef CONFIG_COMMON_RUNTIME @@ -1035,6 +1036,8 @@ void pd_set_vbus_discharge(int port, int enable) #endif /* CONFIG_USB_PD_PORT_COUNT */ #elif defined(CONFIG_USB_PD_DISCHARGE_TCPC) tcpc_discharge_vbus(port, enable); +#elif defined(CONFIG_USB_PD_DISCHARGE_PPC) + ppc_discharge_vbus(port, enable); #else #error "PD discharge implementation not defined" #endif diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c index 3c6d437152..34cfbabf50 100644 --- a/common/usbc_ppc.c +++ b/common/usbc_ppc.c @@ -50,6 +50,14 @@ int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp) return ppc_chips[port].drv->set_vbus_source_current_limit(port, rp); } +int ppc_discharge_vbus(int port, int enable) +{ + if ((port < 0) || (port >= ppc_cnt)) + return EC_ERROR_INVAL; + + return ppc_chips[port].drv->discharge_vbus(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 1f4d20eb76..d21dba0f66 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -480,6 +480,29 @@ static int sn5s330_set_vbus_source_current_limit(int port, return status; } +static int sn5s330_discharge_vbus(int port, int enable) +{ + int regval; + int status; + + status = get_func_set3(port, ®val); + if (status) + return status; + + if (enable) + regval |= SN5S330_VBUS_DISCH_EN; + else + regval &= ~SN5S330_VBUS_DISCH_EN; + + status = write_reg(port, SN5S330_FUNC_SET3, regval); + if (status) { + CPRINTS("Failed to %s vbus", enable ? "enable" : "disable"); + return status; + } + + return EC_SUCCESS; +} + static int sn5s330_vbus_sink_enable(int port, int enable) { return sn5s330_pp_fet_enable(port, SN5S330_PP2, !!enable); @@ -540,4 +563,5 @@ const struct ppc_drv sn5s330_drv = { .is_vbus_present = &sn5s330_is_vbus_present, #endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ .set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit, + .discharge_vbus = &sn5s330_discharge_vbus, }; diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index d3d3248a80..18f1929c0f 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -91,6 +91,7 @@ enum sn5s330_pp_idx { /* FUNC_SET_3 */ #define SN5S330_PP1_EN (1 << 0) #define SN5S330_PP2_EN (1 << 1) +#define SN5S330_VBUS_DISCH_EN (1 << 2) #define SN5S330_SET_RCP_MODE_PP1 (1 << 5) #define SN5S330_SET_RCP_MODE_PP2 (1 << 6) diff --git a/include/config.h b/include/config.h index 5b2697ae93..c6a57bcf13 100644 --- a/include/config.h +++ b/include/config.h @@ -2634,22 +2634,20 @@ /* * Define if this board can enable VBUS discharge (eg. through a GPIO-controlled * discharge circuit, or through port controller registers) to discharge VBUS - * rapidly on disconnect. + * rapidly on disconnect. Will be defined automatically when one of the below + * options is defined. */ #undef CONFIG_USB_PD_DISCHARGE -/* - * Define (along with CONFIG_USB_PD_DISCHARGE) if discharge circuit is - * EC GPIO-controlled. - */ +/* Define if discharge circuit is EC GPIO-controlled. */ #undef CONFIG_USB_PD_DISCHARGE_GPIO -/* - * Define (along with CONFIG_USB_PD_DISCHARGE) if discharge circuit is - * using PD discharge registers. - */ +/* Define if discharge circuit is using PD discharge registers on TCPC. */ #undef CONFIG_USB_PD_DISCHARGE_TCPC +/* Define if discharge circuit is using PD discharge registers on PPC. */ +#undef CONFIG_USB_PD_DISCHARGE_PPC + /* Define if this board can act as a dual-role PD port (source and sink) */ #undef CONFIG_USB_PD_DUAL_ROLE @@ -3273,6 +3271,14 @@ #endif #endif /* CONFIG_EC_EC_COMM_BATTERY */ +/*****************************************************************************/ +/* Define derived USB PD Discharge common path */ +#if defined(CONFIG_USB_PD_DISCHARGE_GPIO) || \ + defined(CONFIG_USB_PD_DISCHARGE_TCPC) || \ + defined(CONFIG_USB_PD_DISCHARGE_PPC) +#define CONFIG_USB_PD_DISCHARGE +#endif + /*****************************************************************************/ /* * Handle task-dependent configs. diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h index c005540e99..4fbb913a11 100644 --- a/include/usbc_ppc.h +++ b/include/usbc_ppc.h @@ -57,6 +57,15 @@ struct ppc_drv { */ int (*set_vbus_source_current_limit)(int port, enum tcpc_rp_value rp); + /** + * Discharge PD VBUS on src/sink disconnect & power role swap + * + * @param port: The Type-C port number. + * @param enable: 1 -> discharge vbus, 0 -> stop discharging vbus + * @return EC_SUCCESS on success, error otherwise. + */ + int (*discharge_vbus)(int port, int enable); + #ifdef CONFIG_CMD_PPC_DUMP /** * Perform a register dump of the PPC. @@ -130,6 +139,15 @@ int ppc_is_sourcing_vbus(int port); */ int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp); +/** + * Discharge PD VBUS on src/sink disconnect & power role swap + * + * @param port: The Type-C port number. + * @param enable: 1 -> discharge vbus, 0 -> stop discharging vbus + * @return EC_SUCCESS on success, error otherwise. + */ +int ppc_discharge_vbus(int port, int enable); + /** * Turn on/off the charge path FET, such that current flows into the * system. -- cgit v1.2.1