diff --git a/board/host/gpio.inc b/board/host/gpio.inc index 324721068b..5a08172a07 100644 --- a/board/host/gpio.inc +++ b/board/host/gpio.inc @@ -29,3 +29,5 @@ GPIO(BASE_CHG_VDD_EN, PIN(0, 12), 0) /* Fingerprint */ GPIO(SPI1_NSS, PIN(0, 13), GPIO_OUT_HIGH) + +GPIO(USB_C0_DISCHARGE, PIN(0, 15), 0) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 5bc0bbe077..2be1e1043d 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -4405,7 +4405,6 @@ int pd_charge_from_device(uint16_t vid, uint16_t pid) (pid == USB_PID1_APPLE || pid == USB_PID2_APPLE)); } -#ifdef CONFIG_USB_PD_DISCHARGE void pd_set_vbus_discharge(int port, int enable) { static struct mutex discharge_lock[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -4413,25 +4412,35 @@ void pd_set_vbus_discharge(int port, int enable) mutex_lock(&discharge_lock[port]); enable &= !board_vbus_source_enabled(port); -#ifdef CONFIG_USB_PD_DISCHARGE_GPIO -#if CONFIG_USB_PD_PORT_MAX_COUNT == 0 - gpio_set_level(GPIO_USB_C0_DISCHARGE, enable); -#elif CONFIG_USB_PD_PORT_MAX_COUNT == 1 - gpio_set_level(GPIO_USB_C1_DISCHARGE, enable); -#elif CONFIG_USB_PD_PORT_MAX_COUNT == 2 - gpio_set_level(GPIO_USB_C2_DISCHARGE, enable); -#elif CONFIG_USB_PD_PORT_MAX_COUNT == 3 - gpio_set_level(GPIO_USB_C3_DISCHARGE, enable); + if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_GPIO)) { + switch (port) { +#if defined(CONFIG_USB_PD_DISCHARGE_GPIO) && CONFIG_USB_PD_PORT_MAX_COUNT >= 3 + case 2: + gpio_set_level(GPIO_USB_C2_DISCHARGE, enable); + break; #endif -#else - if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_TCPC)) +#if defined(CONFIG_USB_PD_DISCHARGE_GPIO) && CONFIG_USB_PD_PORT_MAX_COUNT >= 2 + case 1: + gpio_set_level(GPIO_USB_C1_DISCHARGE, enable); + break; +#endif +#if defined(CONFIG_USB_PD_DISCHARGE_GPIO) && CONFIG_USB_PD_PORT_MAX_COUNT >= 1 + case 0: + gpio_set_level(GPIO_USB_C0_DISCHARGE, enable); + break; +#endif + default: + CPRINTF("Could not discharge port %d via GPIO", port); + break; + } + } else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_TCPC)) { tcpc_discharge_vbus(port, enable); - else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_PPC)) + } else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_PPC)) { ppc_discharge_vbus(port, enable); -#endif + } + mutex_unlock(&discharge_lock[port]); } -#endif /* CONFIG_USB_PD_DISCHARGE */ /* VDM utility functions */ #ifdef CONFIG_USB_PD_ALT_MODE_DFP diff --git a/fuzz/usb_pd_fuzz.c b/fuzz/usb_pd_fuzz.c index ba74148229..eeb72586b4 100644 --- a/fuzz/usb_pd_fuzz.c +++ b/fuzz/usb_pd_fuzz.c @@ -186,6 +186,11 @@ void run_test(void) } } +int board_vbus_source_enabled(int port) +{ + return 0; +} + int test_fuzz_one_input(const uint8_t *data, unsigned int size) { int i; diff --git a/test/test_config.h b/test/test_config.h index 8a947d1717..045f399803 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -295,6 +295,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #undef CONFIG_USB_TYPEC_SM #define CONFIG_USBC_VCONN #define PD_VCONN_SWAP_DELAY 5000 /* us */ +#define CONFIG_USB_PD_DISCHARGE_GPIO #endif /* Common TypeC tests defines */ diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c index b2457a8298..c6a1dc0af7 100644 --- a/test/usb_pe_drp.c +++ b/test/usb_pe_drp.c @@ -25,6 +25,11 @@ const struct svdm_response svdm_rsp = { .modes = NULL, }; +int board_vbus_source_enabled(int port) +{ + return 0; +} + /** * Test section */ @@ -120,11 +125,23 @@ static int test_pe_frs(void) return EC_SUCCESS; } +static int test_vbus_gpio_discharge(void) +{ + pd_set_vbus_discharge(PORT0, 1); + TEST_EQ(gpio_get_level(GPIO_USB_C0_DISCHARGE), 1, "%d"); + + pd_set_vbus_discharge(PORT0, 0); + TEST_EQ(gpio_get_level(GPIO_USB_C0_DISCHARGE), 0, "%d"); + + return EC_SUCCESS; +} + void run_test(void) { test_reset(); RUN_TEST(test_pe_frs); + RUN_TEST(test_vbus_gpio_discharge); /* Do basic state machine sanity checks last. */ RUN_TEST(test_pe_no_parent_cycles);