diff options
Diffstat (limited to 'common/usb_common.c')
-rw-r--r-- | common/usb_common.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/common/usb_common.c b/common/usb_common.c index 814a209da3..308f4109b7 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -840,3 +840,43 @@ static void pd_usb_billboard_deferred(void) } } DECLARE_DEFERRED(pd_usb_billboard_deferred); + +#ifdef CONFIG_USB_PD_DISCHARGE +static void gpio_discharge_vbus(int port, int enable) +{ +#ifdef CONFIG_USB_PD_DISCHARGE_GPIO + enum gpio_signal dischg_gpio[] = { + GPIO_USB_C0_DISCHARGE, +#if CONFIG_USB_PD_PORT_MAX_COUNT > 1 + GPIO_USB_C1_DISCHARGE, +#endif +#if CONFIG_USB_PD_PORT_MAX_COUNT > 2 + GPIO_USB_C2_DISCHARGE, +#endif + }; + BUILD_ASSERT(ARRAY_SIZE(dischg_gpio) == CONFIG_USB_PD_PORT_MAX_COUNT); + + gpio_set_level(dischg_gpio[port], enable); +#endif /* CONFIG_USB_PD_DISCHARGE_GPIO */ +} + +void pd_set_vbus_discharge(int port, int enable) +{ + static struct mutex discharge_lock[CONFIG_USB_PD_PORT_MAX_COUNT]; + + if (port >= board_get_usb_pd_port_count()) + return; + + mutex_lock(&discharge_lock[port]); + enable &= !board_vbus_source_enabled(port); + + if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_GPIO)) + gpio_discharge_vbus(port, enable); + else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_TCPC)) + tcpc_discharge_vbus(port, enable); + else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_PPC)) + ppc_discharge_vbus(port, enable); + + mutex_unlock(&discharge_lock[port]); +} +#endif /* CONFIG_USB_PD_DISCHARGE */ |