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:
committed by
Fabio Baltieri
parent
2120eb3027
commit
dac9d3e1c3
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user