drivers: usb: common: stm32: pwr: add power disable support

Add code to disable the USB power supply.

Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
This commit is contained in:
Mathieu Choplain
2025-12-11 15:22:44 +01:00
committed by Fabio Baltieri
parent 2120eb3027
commit dac9d3e1c3
3 changed files with 86 additions and 0 deletions

View File

@@ -15,4 +15,13 @@
*/
int stm32_usb_pwr_enable(void);
/**
* @brief Configures the Power Controller to disable
* USB-related regulators/etc if no controller is
* still active (refcounted).
*
* @returns 0 on success, negative error code otherwise.
*/
int stm32_usb_pwr_disable(void);
#endif /* ZEPHYR_DRIVERS_USB_COMMON_STM32_STM32_USB_COMMON_H_ */

View File

@@ -131,3 +131,73 @@ fini:
return err;
}
int stm32_usb_pwr_disable(void)
{
uint32_t new_count;
int err;
err = k_sem_take(&pwr_refcount_mutex, K_FOREVER);
if (err != 0) {
return err;
}
new_count = --usb_pwr_refcount;
if (new_count > 0) {
/* There are other users - don't disable now */
err = 0;
goto fini;
}
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_PWR_DisableUSBVoltageDetector();
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
# if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)
LL_PWR_DisableUSBEPODBooster();
while (LL_PWR_IsActiveFlag_USBBOOST() != 0) {
/* Wait for USB EPOD BOOST off */
}
LL_PWR_DisableUSBPowerSupply();
# endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) */
LL_PWR_DisableVddUSB();
#elif defined(CONFIG_SOC_SERIES_STM32N6X)
/* Disable Vdd33USB voltage monitoring */
LL_PWR_DisableVddUSBMonitoring();
/* Disable VDDUSB */
LL_PWR_DisableVddUSB();
#elif defined(CONFIG_SOC_SERIES_STM32WBAX)
/* Disable USB OTG booster */
LL_PWR_DisableUSBBooster();
while (LL_PWR_IsActiveFlag_USBBOOSTRDY()) {
/* Wait until USB OTG booster is off */
}
/* Disable USB OTG internal power */
LL_PWR_DisableUSBPWR();
/* Disable VDD11USB */
LL_PWR_DisableVdd11USB();
while (LL_PWR_IsActiveFlag_VDD11USBRDY()) {
/* Wait until VDD11USB supply is off */
}
/* Enable VDDUSB power isolation */
LL_PWR_DisableVddUSB();
#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV)
/* Enable VDDUSB power isolation */
LL_PWR_DisableVDDUSB();
#elif defined(PWR_CR2_USV)
/* Enable VDDUSB power isolation */
LL_PWR_DisableVddUSB();
#endif
fini:
k_sem_give(&pwr_refcount_mutex);
return err;
}

View File

@@ -954,6 +954,7 @@ static int udc_stm32_shutdown(const struct device *dev)
struct udc_stm32_data *priv = udc_get_private(dev);
const struct udc_stm32_config *cfg = dev->config;
HAL_StatusTypeDef status;
int err;
status = HAL_PCD_DeInit(&priv->pcd);
if (status != HAL_OK) {
@@ -966,6 +967,12 @@ static int udc_stm32_shutdown(const struct device *dev)
/* continue anyway */
}
err = stm32_usb_pwr_disable();
if (err != 0) {
LOG_ERR("Error disabling USB power: %d", err);
/* continue anyway */
}
if (irq_is_enabled(cfg->irqn)) {
irq_disable(cfg->irqn);
}