drivers: udc_dwc2: add vendor quirks to support Nordic USBHS controller
Add vendor quirks to support Nordic USBHS controller. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
parent
6d06a8cea9
commit
b117155320
2 changed files with 139 additions and 0 deletions
|
@ -5,6 +5,8 @@ config UDC_DWC2
|
|||
bool "DWC2 USB device controller driver"
|
||||
default y
|
||||
depends on DT_HAS_SNPS_DWC2_ENABLED
|
||||
select NRFS if NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||
select NRFS_VBUS_DETECTOR_SERVICE_ENABLED if NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||
help
|
||||
DWC2 USB device controller driver.
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/usb/udc.h>
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_fsotg)
|
||||
|
||||
|
@ -107,6 +108,142 @@ DT_INST_FOREACH_STATUS_OKAY(QUIRK_STM32F4_FSOTG_DEFINE)
|
|||
|
||||
#endif /*DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_fsotg) */
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbhs)
|
||||
|
||||
#define DT_DRV_COMPAT snps_dwc2
|
||||
|
||||
#include <nrfs_backend_ipc_service.h>
|
||||
#include <nrfs_usb.h>
|
||||
|
||||
#define USBHS_DT_WRAPPER_REG_ADDR(n) UINT_TO_POINTER(DT_INST_REG_ADDR_BY_NAME(n, wrapper))
|
||||
|
||||
static void usbhs_vbus_handler(nrfs_usb_evt_t const *p_evt, void *const context)
|
||||
{
|
||||
const struct device *dev = context;
|
||||
|
||||
switch (p_evt->type) {
|
||||
case NRFS_USB_EVT_VBUS_STATUS_CHANGE:
|
||||
LOG_DBG("USBHS new status, pll_ok = %d vreg_ok = %d vbus_detected = %d",
|
||||
p_evt->usbhspll_ok, p_evt->vregusb_ok, p_evt->vbus_detected);
|
||||
|
||||
if (p_evt->usbhspll_ok && p_evt->vregusb_ok && p_evt->vbus_detected) {
|
||||
udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
|
||||
} else {
|
||||
udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
case NRFS_USB_EVT_REJECT:
|
||||
LOG_ERR("Request rejected");
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unknown event type 0x%x", p_evt->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int usbhs_enable_nrfs_service(const struct device *dev)
|
||||
{
|
||||
nrfs_err_t nrfs_err;
|
||||
int err;
|
||||
|
||||
err = nrfs_backend_wait_for_connection(K_MSEC(1000));
|
||||
if (err) {
|
||||
LOG_INF("NRFS backend connection timeout");
|
||||
return err;
|
||||
}
|
||||
|
||||
nrfs_err = nrfs_usb_init(usbhs_vbus_handler);
|
||||
if (nrfs_err != NRFS_SUCCESS) {
|
||||
LOG_ERR("Failed to init NRFS VBUS handler: %d", nrfs_err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
nrfs_err = nrfs_usb_enable_request((void *)dev);
|
||||
if (nrfs_err != NRFS_SUCCESS) {
|
||||
LOG_ERR("Failed to enable NRFS VBUS service: %d", nrfs_err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int usbhs_enable_core(const struct device *dev)
|
||||
{
|
||||
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
|
||||
|
||||
wrapper->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk;
|
||||
wrapper->TASKS_START = 1UL;
|
||||
|
||||
/* Enable interrupts */
|
||||
wrapper->INTENSET = 1UL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int usbhs_disable_core(const struct device *dev)
|
||||
{
|
||||
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
|
||||
|
||||
/* Disable interrupts */
|
||||
wrapper->INTENCLR = 1UL;
|
||||
|
||||
wrapper->ENABLE = 0UL;
|
||||
wrapper->TASKS_START = 1UL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int usbhs_disable_nrfs_service(const struct device *dev)
|
||||
{
|
||||
nrfs_err_t nrfs_err;
|
||||
|
||||
nrfs_err = nrfs_usb_disable_request((void *)dev);
|
||||
if (nrfs_err != NRFS_SUCCESS) {
|
||||
LOG_ERR("Failed to disable NRFS VBUS service: %d", nrfs_err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
nrfs_usb_uninit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int usbhs_irq_clear(const struct device *dev)
|
||||
{
|
||||
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
|
||||
|
||||
wrapper->EVENTS_CORE = 0UL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int usbhs_init_caps(const struct device *dev)
|
||||
{
|
||||
struct udc_data *data = dev->data;
|
||||
|
||||
data->caps.can_detect_vbus = true;
|
||||
data->caps.hs = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define QUIRK_NRF_USBHS_DEFINE(n) \
|
||||
struct dwc2_vendor_quirks dwc2_vendor_quirks_##n = { \
|
||||
.init = usbhs_enable_nrfs_service, \
|
||||
.pre_enable = usbhs_enable_core, \
|
||||
.disable = usbhs_disable_core, \
|
||||
.shutdown = usbhs_disable_nrfs_service, \
|
||||
.irq_clear = usbhs_irq_clear, \
|
||||
.caps = usbhs_init_caps, \
|
||||
};
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(QUIRK_NRF_USBHS_DEFINE)
|
||||
|
||||
#undef DT_DRV_COMPAT
|
||||
|
||||
#endif /*DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbhs) */
|
||||
|
||||
/* Add next vendor quirks definition above this line */
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_USB_UDC_DWC2_VENDOR_QUIRKS_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue