Skip to content

Commit b117155

Browse files
jfischer-nofabiobaltieri
authored andcommitted
drivers: udc_dwc2: add vendor quirks to support Nordic USBHS controller
Add vendor quirks to support Nordic USBHS controller. Signed-off-by: Johann Fischer <[email protected]>
1 parent 6d06a8c commit b117155

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

drivers/usb/udc/Kconfig.dwc2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ config UDC_DWC2
55
bool "DWC2 USB device controller driver"
66
default y
77
depends on DT_HAS_SNPS_DWC2_ENABLED
8+
select NRFS if NRFS_HAS_VBUS_DETECTOR_SERVICE
9+
select NRFS_VBUS_DETECTOR_SERVICE_ENABLED if NRFS_HAS_VBUS_DETECTOR_SERVICE
810
help
911
DWC2 USB device controller driver.
1012

drivers/usb/udc/udc_dwc2_vendor_quirks.h

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <stdint.h>
1313
#include <zephyr/device.h>
14+
#include <zephyr/drivers/usb/udc.h>
1415

1516
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_fsotg)
1617

@@ -107,6 +108,142 @@ DT_INST_FOREACH_STATUS_OKAY(QUIRK_STM32F4_FSOTG_DEFINE)
107108

108109
#endif /*DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_fsotg) */
109110

111+
#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbhs)
112+
113+
#define DT_DRV_COMPAT snps_dwc2
114+
115+
#include <nrfs_backend_ipc_service.h>
116+
#include <nrfs_usb.h>
117+
118+
#define USBHS_DT_WRAPPER_REG_ADDR(n) UINT_TO_POINTER(DT_INST_REG_ADDR_BY_NAME(n, wrapper))
119+
120+
static void usbhs_vbus_handler(nrfs_usb_evt_t const *p_evt, void *const context)
121+
{
122+
const struct device *dev = context;
123+
124+
switch (p_evt->type) {
125+
case NRFS_USB_EVT_VBUS_STATUS_CHANGE:
126+
LOG_DBG("USBHS new status, pll_ok = %d vreg_ok = %d vbus_detected = %d",
127+
p_evt->usbhspll_ok, p_evt->vregusb_ok, p_evt->vbus_detected);
128+
129+
if (p_evt->usbhspll_ok && p_evt->vregusb_ok && p_evt->vbus_detected) {
130+
udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
131+
} else {
132+
udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0);
133+
}
134+
135+
break;
136+
case NRFS_USB_EVT_REJECT:
137+
LOG_ERR("Request rejected");
138+
break;
139+
default:
140+
LOG_ERR("Unknown event type 0x%x", p_evt->type);
141+
break;
142+
}
143+
}
144+
145+
static inline int usbhs_enable_nrfs_service(const struct device *dev)
146+
{
147+
nrfs_err_t nrfs_err;
148+
int err;
149+
150+
err = nrfs_backend_wait_for_connection(K_MSEC(1000));
151+
if (err) {
152+
LOG_INF("NRFS backend connection timeout");
153+
return err;
154+
}
155+
156+
nrfs_err = nrfs_usb_init(usbhs_vbus_handler);
157+
if (nrfs_err != NRFS_SUCCESS) {
158+
LOG_ERR("Failed to init NRFS VBUS handler: %d", nrfs_err);
159+
return -EIO;
160+
}
161+
162+
nrfs_err = nrfs_usb_enable_request((void *)dev);
163+
if (nrfs_err != NRFS_SUCCESS) {
164+
LOG_ERR("Failed to enable NRFS VBUS service: %d", nrfs_err);
165+
return -EIO;
166+
}
167+
168+
return 0;
169+
}
170+
171+
static inline int usbhs_enable_core(const struct device *dev)
172+
{
173+
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
174+
175+
wrapper->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk;
176+
wrapper->TASKS_START = 1UL;
177+
178+
/* Enable interrupts */
179+
wrapper->INTENSET = 1UL;
180+
181+
return 0;
182+
}
183+
184+
static inline int usbhs_disable_core(const struct device *dev)
185+
{
186+
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
187+
188+
/* Disable interrupts */
189+
wrapper->INTENCLR = 1UL;
190+
191+
wrapper->ENABLE = 0UL;
192+
wrapper->TASKS_START = 1UL;
193+
194+
return 0;
195+
}
196+
197+
static inline int usbhs_disable_nrfs_service(const struct device *dev)
198+
{
199+
nrfs_err_t nrfs_err;
200+
201+
nrfs_err = nrfs_usb_disable_request((void *)dev);
202+
if (nrfs_err != NRFS_SUCCESS) {
203+
LOG_ERR("Failed to disable NRFS VBUS service: %d", nrfs_err);
204+
return -EIO;
205+
}
206+
207+
nrfs_usb_uninit();
208+
209+
return 0;
210+
}
211+
212+
static inline int usbhs_irq_clear(const struct device *dev)
213+
{
214+
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
215+
216+
wrapper->EVENTS_CORE = 0UL;
217+
218+
return 0;
219+
}
220+
221+
static inline int usbhs_init_caps(const struct device *dev)
222+
{
223+
struct udc_data *data = dev->data;
224+
225+
data->caps.can_detect_vbus = true;
226+
data->caps.hs = true;
227+
228+
return 0;
229+
}
230+
231+
#define QUIRK_NRF_USBHS_DEFINE(n) \
232+
struct dwc2_vendor_quirks dwc2_vendor_quirks_##n = { \
233+
.init = usbhs_enable_nrfs_service, \
234+
.pre_enable = usbhs_enable_core, \
235+
.disable = usbhs_disable_core, \
236+
.shutdown = usbhs_disable_nrfs_service, \
237+
.irq_clear = usbhs_irq_clear, \
238+
.caps = usbhs_init_caps, \
239+
};
240+
241+
DT_INST_FOREACH_STATUS_OKAY(QUIRK_NRF_USBHS_DEFINE)
242+
243+
#undef DT_DRV_COMPAT
244+
245+
#endif /*DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbhs) */
246+
110247
/* Add next vendor quirks definition above this line */
111248

112249
#endif /* ZEPHYR_DRIVERS_USB_UDC_DWC2_VENDOR_QUIRKS_H */

0 commit comments

Comments
 (0)