summaryrefslogtreecommitdiff
path: root/common/usb_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usb_common.c')
-rw-r--r--common/usb_common.c40
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 */