drivers: udc_nrf: rework controller initialization

udc_init() only initializes and enables the USB regulator. This is
enough to detect VBUS changes, the USB controller is enabled in
udc_enable(). Deinitialization happens correspondingly in reverse order.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2024-04-12 15:36:15 +02:00 committed by Fabio Baltieri
parent 4c360f38d1
commit ba2e257d06
1 changed files with 39 additions and 34 deletions

View File

@ -470,14 +470,14 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt)
switch (pwr_evt) {
case NRFX_POWER_USB_EVT_DETECTED:
LOG_DBG("POWER event detected");
udc_submit_event(udc_nrf_dev, UDC_EVT_VBUS_READY, 0);
break;
case NRFX_POWER_USB_EVT_READY:
LOG_INF("POWER event ready");
udc_submit_event(udc_nrf_dev, UDC_EVT_VBUS_READY, 0);
LOG_DBG("POWER event ready");
nrf_usbd_common_start(true);
break;
case NRFX_POWER_USB_EVT_REMOVED:
LOG_INF("POWER event removed");
LOG_DBG("POWER event removed");
udc_submit_event(udc_nrf_dev, UDC_EVT_VBUS_REMOVED, 0);
break;
default:
@ -631,9 +631,26 @@ static int udc_nrf_host_wakeup(const struct device *dev)
static int udc_nrf_enable(const struct device *dev)
{
unsigned int key;
int ret;
nrf_usbd_common_enable();
ret = nrf_usbd_common_init(usbd_event_handler);
if (ret != NRFX_SUCCESS) {
LOG_ERR("nRF USBD driver initialization failed");
return -EIO;
}
if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT,
USB_EP_TYPE_CONTROL, UDC_NRF_EP0_SIZE, 0)) {
LOG_ERR("Failed to enable control endpoint");
return -EIO;
}
if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN,
USB_EP_TYPE_CONTROL, UDC_NRF_EP0_SIZE, 0)) {
LOG_ERR("Failed to enable control endpoint");
return -EIO;
}
sys_notify_init_spinwait(&hfxo_cli.notify);
ret = onoff_request(hfxo_mgr, &hfxo_cli);
@ -642,6 +659,11 @@ static int udc_nrf_enable(const struct device *dev)
return ret;
}
/* Disable interrupts until USBD is enabled */
key = irq_lock();
nrf_usbd_common_enable();
irq_unlock(key);
return 0;
}
@ -651,6 +673,18 @@ static int udc_nrf_disable(const struct device *dev)
nrf_usbd_common_disable();
if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
LOG_ERR("Failed to disable control endpoint");
return -EIO;
}
if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
LOG_ERR("Failed to disable control endpoint");
return -EIO;
}
nrf_usbd_common_uninit();
ret = onoff_cancel_or_release(hfxo_mgr, &hfxo_cli);
if (ret < 0) {
LOG_ERR("Failed to stop HFXO %d", ret);
@ -663,7 +697,6 @@ static int udc_nrf_disable(const struct device *dev)
static int udc_nrf_init(const struct device *dev)
{
const struct udc_nrf_config *cfg = dev->config;
int ret;
hfxo_mgr = z_nrf_clock_control_get_onoff(cfg->clock);
@ -683,25 +716,7 @@ static int udc_nrf_init(const struct device *dev)
(void)nrfx_power_init(&cfg->pwr);
nrfx_power_usbevt_init(&cfg->evt);
ret = nrf_usbd_common_init(usbd_event_handler);
if (ret != NRFX_SUCCESS) {
LOG_ERR("nRF USBD driver initialization failed");
return -EIO;
}
nrfx_power_usbevt_enable();
if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT,
USB_EP_TYPE_CONTROL, UDC_NRF_EP0_SIZE, 0)) {
LOG_ERR("Failed to enable control endpoint");
return -EIO;
}
if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN,
USB_EP_TYPE_CONTROL, UDC_NRF_EP0_SIZE, 0)) {
LOG_ERR("Failed to enable control endpoint");
return -EIO;
}
LOG_INF("Initialized");
return 0;
@ -711,18 +726,7 @@ static int udc_nrf_shutdown(const struct device *dev)
{
LOG_INF("shutdown");
if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
LOG_ERR("Failed to disable control endpoint");
return -EIO;
}
if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
LOG_ERR("Failed to disable control endpoint");
return -EIO;
}
nrfx_power_usbevt_disable();
nrf_usbd_common_uninit();
nrfx_power_usbevt_uninit();
#ifdef CONFIG_HAS_HW_NRF_USBREG
irq_disable(USBREGULATOR_IRQn);
@ -794,6 +798,7 @@ static int udc_nrf_driver_init(const struct device *dev)
data->caps.rwup = true;
data->caps.out_ack = true;
data->caps.mps0 = UDC_NRF_MPS0;
data->caps.can_detect_vbus = true;
return 0;
}