1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "udc_common.h"
8
9 #include <soc.h>
10 #include <zephyr/drivers/pinctrl.h>
11 #include <zephyr/drivers/clock_control/renesas_ra_cgc.h>
12 #include <zephyr/drivers/usb/udc.h>
13 #include "r_usb_device.h"
14
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(udc_renesas_ra, CONFIG_UDC_DRIVER_LOG_LEVEL);
17
18 struct udc_renesas_ra_config {
19 const struct pinctrl_dev_config *pcfg;
20 size_t num_of_eps;
21 struct udc_ep_config *ep_cfg_in;
22 struct udc_ep_config *ep_cfg_out;
23 void (*make_thread)(const struct device *dev);
24 int speed_idx;
25 };
26
27 struct udc_renesas_ra_data {
28 struct k_thread thread_data;
29 struct st_usbd_instance_ctrl udc;
30 struct st_usbd_cfg udc_cfg;
31 };
32
33 enum udc_renesas_ra_event_type {
34 /* An event generated by the HAL driver */
35 UDC_RENESAS_RA_EVT_HAL,
36 /* Shim driver event to trigger next transfer */
37 UDC_RENESAS_RA_EVT_XFER,
38 /* Let controller perform status stage */
39 UDC_RENESAS_RA_EVT_STATUS,
40 };
41
42 struct udc_renesas_ra_evt {
43 enum udc_renesas_ra_event_type type;
44 usbd_event_t hal_evt;
45 uint8_t ep;
46 };
47
48 K_MSGQ_DEFINE(drv_msgq, sizeof(struct udc_renesas_ra_evt), CONFIG_UDC_RENESAS_RA_MAX_QMESSAGES,
49 sizeof(uint32_t));
50
51 extern void usb_device_isr(void);
52
udc_renesas_ra_event_handler(usbd_callback_arg_t * p_args)53 static void udc_renesas_ra_event_handler(usbd_callback_arg_t *p_args)
54 {
55 const struct device *dev = p_args->p_context;
56 struct udc_renesas_ra_evt evt;
57
58 switch (p_args->event.event_id) {
59 case USBD_EVENT_BUS_RESET:
60 udc_submit_event(dev, UDC_EVT_RESET, 0);
61 break;
62
63 case USBD_EVENT_VBUS_RDY:
64 udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
65 break;
66
67 case USBD_EVENT_VBUS_REMOVED:
68 udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0);
69 break;
70
71 case USBD_EVENT_SUSPEND:
72 udc_submit_event(dev, UDC_EVT_SUSPEND, 0);
73 break;
74
75 case USBD_EVENT_RESUME:
76 udc_submit_event(dev, UDC_EVT_RESUME, 0);
77 break;
78
79 case USBD_EVENT_SOF:
80 udc_submit_event(dev, UDC_EVT_SOF, 0);
81 break;
82
83 default:
84 evt.type = UDC_RENESAS_RA_EVT_HAL;
85 evt.hal_evt = p_args->event;
86 k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
87 break;
88 }
89 }
90
udc_renesas_ra_interrupt_handler(void * arg)91 static void udc_renesas_ra_interrupt_handler(void *arg)
92 {
93 ARG_UNUSED(arg);
94 usb_device_isr();
95 }
96
udc_event_xfer_next(const struct device * dev,const uint8_t ep)97 static void udc_event_xfer_next(const struct device *dev, const uint8_t ep)
98 {
99 struct udc_renesas_ra_data *data = udc_get_private(dev);
100 struct net_buf *buf;
101
102 if (udc_ep_is_busy(dev, ep)) {
103 return;
104 }
105
106 buf = udc_buf_peek(dev, ep);
107 if (buf != NULL) {
108 int err;
109
110 if (USB_EP_DIR_IS_IN(ep)) {
111 err = R_USBD_XferStart(&data->udc, ep, buf->data, buf->len);
112 } else {
113 err = R_USBD_XferStart(&data->udc, ep, buf->data, buf->size);
114 }
115
116 if (err != FSP_SUCCESS) {
117 LOG_ERR("ep 0x%02x error", ep);
118 udc_submit_ep_event(dev, buf, -ECONNREFUSED);
119 } else {
120 udc_ep_set_busy(dev, ep, true);
121 }
122 }
123 }
124
usbd_ctrl_feed_dout(const struct device * dev,const size_t length)125 static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length)
126 {
127 struct udc_ep_config *cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
128 struct net_buf *buf;
129 struct udc_renesas_ra_data *data = udc_get_private(dev);
130
131 buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length);
132 if (buf == NULL) {
133 return -ENOMEM;
134 }
135
136 k_fifo_put(&cfg->fifo, buf);
137
138 if (FSP_SUCCESS != R_USBD_XferStart(&data->udc, cfg->addr, buf->data, buf->size)) {
139 return -EIO;
140 }
141
142 return 0;
143 }
144
udc_event_xfer_setup(const struct device * dev,struct udc_renesas_ra_evt * evt)145 static int udc_event_xfer_setup(const struct device *dev, struct udc_renesas_ra_evt *evt)
146 {
147 struct net_buf *buf;
148 int err;
149
150 struct usb_setup_packet *setup_packet =
151 (struct usb_setup_packet *)&evt->hal_evt.setup_received;
152
153 buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, sizeof(struct usb_setup_packet));
154 if (buf == NULL) {
155 LOG_ERR("Failed to allocate for setup");
156 return -ENOMEM;
157 }
158
159 udc_ep_buf_set_setup(buf);
160 net_buf_add_mem(buf, setup_packet, sizeof(struct usb_setup_packet));
161
162 /* Update to next stage of control transfer */
163 udc_ctrl_update_stage(dev, buf);
164
165 if (udc_ctrl_stage_is_data_out(dev)) {
166 /* Allocate and feed buffer for data OUT stage */
167 LOG_DBG("s:%p|feed for -out-", buf);
168 err = usbd_ctrl_feed_dout(dev, udc_data_stage_length(buf));
169 if (err == -ENOMEM) {
170 err = udc_submit_ep_event(dev, buf, err);
171 }
172 } else if (udc_ctrl_stage_is_data_in(dev)) {
173 err = udc_ctrl_submit_s_in_status(dev);
174 } else {
175 err = udc_ctrl_submit_s_status(dev);
176 }
177
178 return err;
179 }
180
udc_event_xfer_ctrl_in(const struct device * dev,struct net_buf * const buf)181 static void udc_event_xfer_ctrl_in(const struct device *dev, struct net_buf *const buf)
182 {
183 if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) {
184 /* Status stage finished, notify upper layer */
185 udc_ctrl_submit_status(dev, buf);
186 }
187
188 /* Update to next stage of control transfer */
189 udc_ctrl_update_stage(dev, buf);
190
191 if (udc_ctrl_stage_is_status_out(dev)) {
192 /* IN transfer finished, perform status stage OUT and release buffer */
193 usbd_ctrl_feed_dout(dev, 0);
194 net_buf_unref(buf);
195 }
196 }
197
udc_event_status_in(const struct device * dev)198 static void udc_event_status_in(const struct device *dev)
199 {
200 struct udc_renesas_ra_data *data = udc_get_private(dev);
201 struct net_buf *buf;
202
203 buf = udc_buf_get(dev, USB_CONTROL_EP_IN);
204 if (unlikely(buf == NULL)) {
205 LOG_DBG("ep 0x%02x queue is empty", USB_CONTROL_EP_IN);
206 return;
207 }
208
209 /* Perform status stage IN */
210 R_USBD_XferStart(&data->udc, USB_CONTROL_EP_IN, NULL, 0);
211
212 udc_event_xfer_ctrl_in(dev, buf);
213 }
214
udc_event_xfer_ctrl_out(const struct device * dev,struct net_buf * const buf,uint32_t len)215 static void udc_event_xfer_ctrl_out(const struct device *dev, struct net_buf *const buf,
216 uint32_t len)
217 {
218 net_buf_add(buf, len);
219
220 if (udc_ctrl_stage_is_status_out(dev)) {
221 /* Status stage finished, notify upper layer */
222 udc_ctrl_submit_status(dev, buf);
223 }
224
225 /* Update to next stage of control transfer */
226 udc_ctrl_update_stage(dev, buf);
227
228 if (udc_ctrl_stage_is_status_in(dev)) {
229 udc_ctrl_submit_s_out_status(dev, buf);
230 }
231 }
232
udc_event_xfer_complete(const struct device * dev,struct udc_renesas_ra_evt * evt)233 static void udc_event_xfer_complete(const struct device *dev, struct udc_renesas_ra_evt *evt)
234 {
235 struct net_buf *buf;
236 struct udc_renesas_ra_data *data = udc_get_private(dev);
237
238 uint8_t ep = evt->hal_evt.xfer_complete.ep_addr;
239 usbd_xfer_result_t result = evt->hal_evt.xfer_complete.result;
240 uint32_t len = evt->hal_evt.xfer_complete.len;
241
242 udc_ep_set_busy(dev, ep, false);
243
244 buf = udc_buf_peek(dev, ep);
245 if (buf == NULL) {
246 return;
247 }
248
249 if (result != USBD_XFER_RESULT_SUCCESS) {
250 goto error;
251 }
252
253 if (USB_EP_DIR_IS_IN(ep) && udc_ep_buf_has_zlp(buf)) {
254 /* Send ZLP, notification about transfer complete should come again */
255 udc_ep_buf_clear_zlp(buf);
256 if (FSP_SUCCESS != R_USBD_XferStart(&data->udc, ep, NULL, 0)) {
257 goto error;
258 }
259
260 return;
261 }
262
263 buf = udc_buf_get(dev, ep);
264
265 if (ep == USB_CONTROL_EP_IN) {
266 udc_event_xfer_ctrl_in(dev, buf);
267 } else if (ep == USB_CONTROL_EP_OUT) {
268 udc_event_xfer_ctrl_out(dev, buf, len);
269 } else {
270 if (USB_EP_DIR_IS_OUT(ep)) {
271 net_buf_add(buf, len);
272 }
273 udc_submit_ep_event(dev, buf, 0);
274 }
275
276 return;
277 error:
278 udc_submit_ep_event(dev, buf, -EIO);
279 }
280
renesas_ra_thread_handler(void * const arg)281 static ALWAYS_INLINE void renesas_ra_thread_handler(void *const arg)
282 {
283 const struct device *dev = (const struct device *)arg;
284
285 LOG_DBG("Driver %p thread started", dev);
286 while (true) {
287 struct udc_renesas_ra_evt evt;
288
289 k_msgq_get(&drv_msgq, &evt, K_FOREVER);
290 switch (evt.type) {
291 case UDC_RENESAS_RA_EVT_HAL: {
292 switch (evt.hal_evt.event_id) {
293 case USBD_EVENT_SETUP_RECEIVED:
294 udc_event_xfer_setup(dev, &evt);
295 break;
296
297 case USBD_EVENT_XFER_COMPLETE:
298 udc_event_xfer_complete(dev, &evt);
299 break;
300
301 default:
302 break;
303 }
304 break;
305 }
306
307 case UDC_RENESAS_RA_EVT_XFER:
308 udc_event_xfer_next(dev, evt.ep);
309 break;
310
311 case UDC_RENESAS_RA_EVT_STATUS:
312 udc_event_status_in(dev);
313 break;
314
315 default:
316 break;
317 }
318 }
319 }
320
udc_renesas_ra_ep_enqueue(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * buf)321 static int udc_renesas_ra_ep_enqueue(const struct device *dev, struct udc_ep_config *const cfg,
322 struct net_buf *buf)
323 {
324 struct udc_renesas_ra_evt evt = {};
325
326 LOG_DBG("%p enqueue %p", dev, buf);
327
328 udc_buf_put(cfg, buf);
329
330 evt.ep = cfg->addr;
331 if (cfg->addr == USB_CONTROL_EP_IN && buf->len == 0) {
332 evt.type = UDC_RENESAS_RA_EVT_STATUS;
333 } else {
334 evt.type = UDC_RENESAS_RA_EVT_XFER;
335 }
336
337 k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
338
339 if (cfg->stat.halted) {
340 LOG_DBG("ep 0x%02x halted", cfg->addr);
341 }
342
343 return 0;
344 }
345
udc_renesas_ra_ep_dequeue(const struct device * dev,struct udc_ep_config * const cfg)346 static int udc_renesas_ra_ep_dequeue(const struct device *dev, struct udc_ep_config *const cfg)
347 {
348 struct udc_renesas_ra_data *data = udc_get_private(dev);
349 unsigned int lock_key;
350 struct net_buf *buf;
351
352 lock_key = irq_lock();
353
354 buf = udc_buf_get_all(dev, cfg->addr);
355 if (buf != NULL) {
356 udc_submit_ep_event(dev, buf, -ECONNABORTED);
357 }
358
359 if (FSP_SUCCESS != R_USBD_XferAbort(&data->udc, cfg->addr)) {
360 return -EIO;
361 }
362
363 udc_ep_set_busy(dev, cfg->addr, false);
364
365 irq_unlock(lock_key);
366
367 return 0;
368 }
369
udc_renesas_ra_ep_enable(const struct device * dev,struct udc_ep_config * const cfg)370 static int udc_renesas_ra_ep_enable(const struct device *dev, struct udc_ep_config *const cfg)
371 {
372 struct udc_renesas_ra_data *data = udc_get_private(dev);
373 usbd_desc_endpoint_t ep_desc;
374
375 if (USB_EP_GET_IDX(cfg->addr) == 0) {
376 return 0;
377 }
378
379 ep_desc.bLength = sizeof(struct usb_ep_descriptor);
380 ep_desc.bDescriptorType = USB_DESC_ENDPOINT;
381 ep_desc.bEndpointAddress = cfg->addr;
382 ep_desc.bmAttributes = cfg->attributes;
383 ep_desc.wMaxPacketSize = cfg->mps;
384 ep_desc.bInterval = cfg->interval;
385
386 if (FSP_SUCCESS != R_USBD_EdptOpen(&data->udc, &ep_desc)) {
387 return -EIO;
388 }
389
390 LOG_DBG("Enable ep 0x%02x", cfg->addr);
391
392 return 0;
393 }
394
udc_renesas_ra_ep_disable(const struct device * dev,struct udc_ep_config * const cfg)395 static int udc_renesas_ra_ep_disable(const struct device *dev, struct udc_ep_config *const cfg)
396 {
397 struct udc_renesas_ra_data *data = udc_get_private(dev);
398
399 if (USB_EP_GET_IDX(cfg->addr) == 0) {
400 return 0;
401 }
402
403 if (FSP_SUCCESS != R_USBD_EdptClose(&data->udc, cfg->addr)) {
404 return -EIO;
405 }
406
407 LOG_DBG("Disable ep 0x%02x", cfg->addr);
408
409 return 0;
410 }
411
udc_renesas_ra_ep_set_halt(const struct device * dev,struct udc_ep_config * const cfg)412 static int udc_renesas_ra_ep_set_halt(const struct device *dev, struct udc_ep_config *const cfg)
413 {
414 struct udc_renesas_ra_data *data = udc_get_private(dev);
415
416 LOG_DBG("Set halt ep 0x%02x", cfg->addr);
417
418 if (FSP_SUCCESS != R_USBD_EdptStall(&data->udc, cfg->addr)) {
419 return -EIO;
420 }
421
422 cfg->stat.halted = true;
423
424 return 0;
425 }
426
udc_renesas_ra_ep_clear_halt(const struct device * dev,struct udc_ep_config * const cfg)427 static int udc_renesas_ra_ep_clear_halt(const struct device *dev, struct udc_ep_config *const cfg)
428 {
429 struct udc_renesas_ra_data *data = udc_get_private(dev);
430
431 LOG_DBG("Clear halt ep 0x%02x", cfg->addr);
432
433 if (FSP_SUCCESS != R_USBD_EdptClearStall(&data->udc, cfg->addr)) {
434 return -EIO;
435 }
436
437 cfg->stat.halted = false;
438
439 return 0;
440 }
441
udc_renesas_ra_set_address(const struct device * dev,const uint8_t addr)442 static int udc_renesas_ra_set_address(const struct device *dev, const uint8_t addr)
443 {
444 /* The USB controller will automatically perform a response to the SET_ADRRESS request. */
445 LOG_DBG("Set new address %u for %p", addr, dev);
446
447 return 0;
448 }
449
udc_renesas_ra_host_wakeup(const struct device * dev)450 static int udc_renesas_ra_host_wakeup(const struct device *dev)
451 {
452 struct udc_renesas_ra_data *data = udc_get_private(dev);
453
454 if (FSP_SUCCESS != R_USBD_RemoteWakeup(&data->udc)) {
455 return -EIO;
456 }
457
458 LOG_DBG("Remote wakeup from %p", dev);
459
460 return 0;
461 }
462
udc_renesas_ra_device_speed(const struct device * dev)463 static enum udc_bus_speed udc_renesas_ra_device_speed(const struct device *dev)
464 {
465 struct udc_data *data = dev->data;
466
467 return data->caps.hs ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS;
468 }
469
udc_renesas_ra_enable(const struct device * dev)470 static int udc_renesas_ra_enable(const struct device *dev)
471 {
472 struct udc_renesas_ra_data *data = udc_get_private(dev);
473
474 if (FSP_SUCCESS != R_USBD_Connect(&data->udc)) {
475 return -EIO;
476 }
477
478 LOG_DBG("Enable device %p", dev);
479
480 return 0;
481 }
482
udc_renesas_ra_disable(const struct device * dev)483 static int udc_renesas_ra_disable(const struct device *dev)
484 {
485 struct udc_renesas_ra_data *data = udc_get_private(dev);
486
487 if (FSP_SUCCESS != R_USBD_Disconnect(&data->udc)) {
488 return -EIO;
489 }
490
491 LOG_DBG("Enable device %p", dev);
492
493 return 0;
494 }
495
udc_renesas_ra_init(const struct device * dev)496 static int udc_renesas_ra_init(const struct device *dev)
497 {
498 struct udc_renesas_ra_data *data = udc_get_private(dev);
499
500 #if !USBHS_PHY_CLOCK_SOURCE_IS_XTAL
501 if (data->udc_cfg.usb_speed == USBD_SPEED_HS) {
502 LOG_ERR("High-speed operation is not supported in case PHY clock source is not "
503 "XTAL");
504 return -ENOTSUP;
505 }
506
507 uint32_t uclk_src = RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(DT_NODELABEL(uclk)));
508 uint32_t uclk_div = DT_PROP_OR(DT_NODELABEL(uclk), div, 1);
509 uint32_t u60clk_src = RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(DT_NODELABEL(u60clk)));
510 uint32_t u60clk_div = DT_PROP_OR(DT_NODELABEL(u60clk), div, 1);
511
512 if (uclk_src == BSP_CLOCKS_CLOCK_DISABLED || u60clk_src == BSP_CLOCKS_CLOCK_DISABLED) {
513 LOG_ERR("PHY clock is not working");
514 return -EINVAL;
515 }
516
517 uint32_t uclk_clock_rate = R_BSP_SourceClockHzGet(uclk_src) / uclk_div;
518 uint32_t u60clk_clock_rate = R_BSP_SourceClockHzGet(u60clk_src) / u60clk_div;
519
520 if (uclk_clock_rate != 48000000) {
521 LOG_ERR("Setting for uclk should be 48Mhz");
522 return -ENOTSUP;
523 }
524
525 if (u60clk_clock_rate != 60000000) {
526 LOG_ERR("Setting for u60clk should be 60Mhz");
527 return -ENOTSUP;
528 }
529 #endif
530
531 if (!(data->udc_cfg.usb_speed == USBD_SPEED_HS ||
532 data->udc_cfg.usb_speed == USBD_SPEED_FS)) {
533 LOG_ERR("USB device mode support full-speed and high-speed only");
534 return -ENOTSUP;
535 }
536
537 if (FSP_SUCCESS != R_USBD_Open(&data->udc, &data->udc_cfg)) {
538 return -EIO;
539 }
540
541 if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT, USB_EP_TYPE_CONTROL, 64, 0)) {
542 LOG_ERR("Failed to enable control endpoint");
543 return -EIO;
544 }
545
546 if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN, USB_EP_TYPE_CONTROL, 64, 0)) {
547 LOG_ERR("Failed to enable control endpoint");
548 return -EIO;
549 }
550
551 irq_enable(data->udc_cfg.hs_irq);
552
553 return 0;
554 }
555
udc_renesas_ra_shutdown(const struct device * dev)556 static int udc_renesas_ra_shutdown(const struct device *dev)
557 {
558 struct udc_renesas_ra_data *data = udc_get_private(dev);
559
560 if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
561 LOG_ERR("Failed to disable control endpoint");
562 return -EIO;
563 }
564
565 if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
566 LOG_ERR("Failed to disable control endpoint");
567 return -EIO;
568 }
569
570 if (FSP_SUCCESS != R_USBD_Close(&data->udc)) {
571 return -EIO;
572 }
573
574 return 0;
575 }
576
udc_renesas_ra_driver_preinit(const struct device * dev)577 static int udc_renesas_ra_driver_preinit(const struct device *dev)
578 {
579 const struct udc_renesas_ra_config *config = dev->config;
580 struct udc_data *data = dev->data;
581 uint16_t mps = 1023;
582 int err;
583
584 err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
585 if (err < 0) {
586 return err;
587 }
588
589 k_mutex_init(&data->mutex);
590
591 data->caps.rwup = true;
592 data->caps.mps0 = UDC_MPS0_64;
593 if (config->speed_idx == UDC_BUS_SPEED_HS) {
594 data->caps.hs = true;
595 mps = 1024;
596 }
597
598 for (int i = 0; i < config->num_of_eps; i++) {
599 config->ep_cfg_out[i].caps.out = 1;
600 if (i == 0) {
601 config->ep_cfg_out[i].caps.control = 1;
602 config->ep_cfg_out[i].caps.mps = 64;
603 } else {
604 config->ep_cfg_out[i].caps.bulk = 1;
605 config->ep_cfg_out[i].caps.interrupt = 1;
606 config->ep_cfg_out[i].caps.iso = 1;
607 config->ep_cfg_out[i].caps.mps = mps;
608 }
609
610 config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i;
611 err = udc_register_ep(dev, &config->ep_cfg_out[i]);
612 if (err != 0) {
613 LOG_ERR("Failed to register endpoint");
614 return err;
615 }
616 }
617
618 for (int i = 0; i < config->num_of_eps; i++) {
619 config->ep_cfg_in[i].caps.in = 1;
620 if (i == 0) {
621 config->ep_cfg_in[i].caps.control = 1;
622 config->ep_cfg_in[i].caps.mps = 64;
623 } else {
624 config->ep_cfg_in[i].caps.bulk = 1;
625 config->ep_cfg_in[i].caps.interrupt = 1;
626 config->ep_cfg_in[i].caps.iso = 1;
627 config->ep_cfg_in[i].caps.mps = mps;
628 }
629
630 config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i;
631 err = udc_register_ep(dev, &config->ep_cfg_in[i]);
632 if (err != 0) {
633 LOG_ERR("Failed to register endpoint");
634 return err;
635 }
636 }
637
638 config->make_thread(dev);
639 LOG_INF("Device %p (max. speed %d)", dev, config->speed_idx);
640
641 return 0;
642 }
643
udc_renesas_ra_lock(const struct device * dev)644 static int udc_renesas_ra_lock(const struct device *dev)
645 {
646 return udc_lock_internal(dev, K_FOREVER);
647 }
648
udc_renesas_ra_unlock(const struct device * dev)649 static int udc_renesas_ra_unlock(const struct device *dev)
650 {
651 return udc_unlock_internal(dev);
652 }
653
654 static const struct udc_api udc_renesas_ra_api = {
655 .lock = udc_renesas_ra_lock,
656 .unlock = udc_renesas_ra_unlock,
657 .device_speed = udc_renesas_ra_device_speed,
658 .init = udc_renesas_ra_init,
659 .enable = udc_renesas_ra_enable,
660 .disable = udc_renesas_ra_disable,
661 .shutdown = udc_renesas_ra_shutdown,
662 .set_address = udc_renesas_ra_set_address,
663 .host_wakeup = udc_renesas_ra_host_wakeup,
664 .ep_enable = udc_renesas_ra_ep_enable,
665 .ep_disable = udc_renesas_ra_ep_disable,
666 .ep_set_halt = udc_renesas_ra_ep_set_halt,
667 .ep_clear_halt = udc_renesas_ra_ep_clear_halt,
668 .ep_enqueue = udc_renesas_ra_ep_enqueue,
669 .ep_dequeue = udc_renesas_ra_ep_dequeue,
670 };
671
672 #define DT_DRV_COMPAT renesas_ra_udc
673
674 #define USB_MODULE_NUMBER(n) ((DT_REG_ADDR(DT_INST_PARENT(n))) == R_USB_HS0_BASE ? 1 : 0)
675
676 #define RENESAS_RA_USB_IRQ_CONFIG_FUNC(n) \
677 static int udc_renesas_ra_irq_config_func_##n(const struct device *dev) \
678 { \
679 struct udc_renesas_ra_data *data = udc_get_private(dev); \
680 \
681 data->udc_cfg.hs_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_ir, irq); \
682 data->udc_cfg.hsirq_d0 = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_d0, irq); \
683 data->udc_cfg.hsirq_d1 = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_d1, irq); \
684 data->udc_cfg.hsipl = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_ir, priority); \
685 data->udc_cfg.hsipl_d0 = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_d0, priority); \
686 data->udc_cfg.hsipl_d1 = DT_IRQ_BY_NAME(DT_INST_PARENT(n), usbhs_d1, priority); \
687 \
688 R_ICU->IELSR[DT_IRQ_BY_NAME(DT_NODELABEL(usbhs), usbhs_ir, irq)] = \
689 ELC_EVENT_USBHS_USB_INT_RESUME; \
690 IRQ_CONNECT(DT_IRQ_BY_NAME(DT_NODELABEL(usbhs), usbhs_ir, irq), \
691 DT_IRQ_BY_NAME(DT_NODELABEL(usbhs), usbhs_ir, priority), \
692 udc_renesas_ra_interrupt_handler, DEVICE_DT_INST_GET(n), 0); \
693 return 0; \
694 }
695
696 #define UDC_RENESAS_RA_DEVICE_DEFINE(n) \
697 PINCTRL_DT_DEFINE(DT_INST_PARENT(n)); \
698 K_THREAD_STACK_DEFINE(udc_renesas_ra_stack_##n, CONFIG_UDC_RENESAS_RA_STACK_SIZE); \
699 RENESAS_RA_USB_IRQ_CONFIG_FUNC(n); \
700 \
701 static void udc_renesas_ra_thread_##n(void *dev, void *arg1, void *arg2) \
702 { \
703 renesas_ra_thread_handler(dev); \
704 } \
705 \
706 static void udc_renesas_ra_make_thread_##n(const struct device *dev) \
707 { \
708 struct udc_renesas_ra_data *priv = udc_get_private(dev); \
709 \
710 k_thread_create(&priv->thread_data, udc_renesas_ra_stack_##n, \
711 K_THREAD_STACK_SIZEOF(udc_renesas_ra_stack_##n), \
712 udc_renesas_ra_thread_##n, (void *)dev, NULL, NULL, \
713 K_PRIO_COOP(CONFIG_UDC_RENESAS_RA_THREAD_PRIORITY), K_ESSENTIAL, \
714 K_NO_WAIT); \
715 k_thread_name_set(&priv->thread_data, dev->name); \
716 } \
717 \
718 static struct udc_ep_config ep_cfg_in##n[DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints)]; \
719 static struct udc_ep_config \
720 ep_cfg_out##n[DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints)]; \
721 \
722 static const struct udc_renesas_ra_config udc_renesas_ra_config_##n = { \
723 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(n)), \
724 .num_of_eps = DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints), \
725 .ep_cfg_in = ep_cfg_in##n, \
726 .ep_cfg_out = ep_cfg_out##n, \
727 .make_thread = udc_renesas_ra_make_thread_##n, \
728 .speed_idx = DT_ENUM_IDX_OR(DT_INST_PARENT(n), maximum_speed, UDC_BUS_SPEED_HS), \
729 }; \
730 \
731 static struct udc_renesas_ra_data udc_priv_##n = { \
732 .udc_cfg = { \
733 .module_number = USB_MODULE_NUMBER(n), \
734 .usb_speed = DT_ENUM_IDX_OR(DT_INST_PARENT(n), maximum_speed, \
735 UDC_BUS_SPEED_HS), \
736 .p_context = DEVICE_DT_INST_GET(n), \
737 .p_callback = udc_renesas_ra_event_handler, \
738 }}; \
739 \
740 static struct udc_data udc_data_##n = { \
741 .mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex), \
742 .priv = &udc_priv_##n, \
743 }; \
744 int udc_renesas_ra_driver_preinit##n(const struct device *dev) \
745 { \
746 udc_renesas_ra_irq_config_func_##n(dev); \
747 return udc_renesas_ra_driver_preinit(dev); \
748 } \
749 \
750 DEVICE_DT_INST_DEFINE(n, udc_renesas_ra_driver_preinit##n, NULL, &udc_data_##n, \
751 &udc_renesas_ra_config_##n, POST_KERNEL, \
752 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &udc_renesas_ra_api);
753
754 DT_INST_FOREACH_STATUS_OKAY(UDC_RENESAS_RA_DEVICE_DEFINE)
755