1 /*
2 * Copyright (c) 2021-2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief New USB device controller (UDC) driver API
10 */
11
12 #ifndef ZEPHYR_INCLUDE_UDC_H
13 #define ZEPHYR_INCLUDE_UDC_H
14
15 #include <zephyr/kernel.h>
16 #include <zephyr/device.h>
17 #include <zephyr/net/buf.h>
18 #include <zephyr/sys/atomic.h>
19 #include <zephyr/usb/usb_ch9.h>
20
21 /**
22 * @brief Maximum packet size of control endpoint supported by the controller.
23 */
24 enum udc_mps0 {
25 UDC_MPS0_8,
26 UDC_MPS0_16,
27 UDC_MPS0_32,
28 UDC_MPS0_64,
29 };
30
31 /**
32 * USB device controller capabilities
33 *
34 * This structure is mainly intended for the USB device stack.
35 */
36 struct udc_device_caps {
37 /** USB high speed capable controller */
38 uint32_t hs : 1;
39 /** Controller supports USB remote wakeup */
40 uint32_t rwup : 1;
41 /** Controller performs status OUT stage automatically */
42 uint32_t out_ack : 1;
43 /** Controller expects device address to be set before status stage */
44 uint32_t addr_before_status : 1;
45 /** Maximum packet size for control endpoint */
46 enum udc_mps0 mps0 : 2;
47 };
48
49 /**
50 * @brief USB device actual speed
51 */
52 enum udc_bus_speed {
53 /** Device is probably not connected */
54 UDC_BUS_UNKNOWN,
55 /** Device is connected to a full speed bus */
56 UDC_BUS_SPEED_FS,
57 /** Device is connected to a high speed bus */
58 UDC_BUS_SPEED_HS,
59 /** Device is connected to a super speed bus */
60 UDC_BUS_SPEED_SS,
61 };
62
63 /**
64 * USB device controller endpoint capabilities
65 */
66 struct udc_ep_caps {
67 /** Maximum packet size of the endpoint buffer */
68 uint32_t mps : 16;
69 /** Control transfer capable endpoint (for completeness) */
70 uint32_t control : 1;
71 /** Interrupt transfer capable endpoint */
72 uint32_t interrupt : 1;
73 /** Bulk transfer capable endpoint */
74 uint32_t bulk : 1;
75 /** ISO transfer capable endpoint */
76 uint32_t iso : 1;
77 /** IN transfer capable endpoint */
78 uint32_t in : 1;
79 /** OUT transfer capable endpoint */
80 uint32_t out : 1;
81 };
82
83 /**
84 * USB device controller endpoint status
85 */
86 struct udc_ep_stat {
87 /** Endpoint is enabled */
88 uint32_t enabled : 1;
89 /** Endpoint is halted (returning STALL PID) */
90 uint32_t halted : 1;
91 /** Last submitted PID is DATA1 */
92 uint32_t data1 : 1;
93 /** If double buffering is supported, last used buffer is odd */
94 uint32_t odd : 1;
95 /** Endpoint is busy */
96 uint32_t busy : 1;
97 };
98
99 /**
100 * USB device controller endpoint configuration
101 *
102 * This structure is mandatory for configuration and management of endpoints.
103 * It is not exposed to higher layer and is used only by internal part
104 * of UDC API and driver.
105 */
106 struct udc_ep_config {
107 /** Endpoint requests FIFO */
108 struct k_fifo fifo;
109 /** Endpoint capabilities */
110 struct udc_ep_caps caps;
111 /** Endpoint status */
112 struct udc_ep_stat stat;
113 /** Endpoint address */
114 uint8_t addr;
115 /** Endpoint attributes */
116 uint8_t attributes;
117 /** Maximum packet size */
118 uint16_t mps;
119 /** Polling interval */
120 uint8_t interval;
121 };
122
123
124 /**
125 * @brief USB device controller event types
126 */
127 enum udc_event_type {
128 /** VBUS ready event. Signals that VBUS is in stable condition. */
129 UDC_EVT_VBUS_READY,
130 /** VBUS removed event. Signals that VBUS is below the valid range. */
131 UDC_EVT_VBUS_REMOVED,
132 /** Device resume event */
133 UDC_EVT_RESUME,
134 /** Device suspended event */
135 UDC_EVT_SUSPEND,
136 /** Port reset detected */
137 UDC_EVT_RESET,
138 /** Start of Frame event */
139 UDC_EVT_SOF,
140 /** Endpoint request result event */
141 UDC_EVT_EP_REQUEST,
142 /**
143 * Non-correctable error event, requires attention from higher
144 * levels or application.
145 */
146 UDC_EVT_ERROR,
147 };
148
149 /**
150 * USB device controller event
151 *
152 * Common structure for all events that originate from
153 * the UDC driver and are passed to higher layer using
154 * message queue and a callback (udc_event_cb_t) provided
155 * by higher layer during controller initialization (udc_init).
156 */
157 struct udc_event {
158 /** Event type */
159 enum udc_event_type type;
160 union {
161 /** Event value */
162 uint32_t value;
163 /** Event status value, if any */
164 int status;
165 /** Pointer to request used only for UDC_EVT_EP_REQUEST */
166 struct net_buf *buf;
167 };
168 /** Pointer to device struct */
169 const struct device *dev;
170 };
171
172 /**
173 * UDC endpoint buffer info
174 *
175 * This structure is mandatory for all UDC request.
176 * It contains the meta data about the request and is stored in
177 * user_data array of net_buf structure for each request.
178 */
179 struct udc_buf_info {
180 /** Endpoint to which request is associated */
181 uint8_t ep;
182 /** Flag marks setup transfer */
183 unsigned int setup : 1;
184 /** Flag marks data stage of setup transfer */
185 unsigned int data : 1;
186 /** Flag marks status stage of setup transfer */
187 unsigned int status : 1;
188 /** Flag marks ZLP at the end of a transfer */
189 unsigned int zlp : 1;
190 /** Flag marks request buffer claimed by the controller (TBD) */
191 unsigned int claimed : 1;
192 /** Flag marks request buffer is queued (TBD) */
193 unsigned int queued : 1;
194 /** Transfer owner (usually pointer to a class instance) */
195 void *owner;
196 /** Transfer result, 0 on success, other values on error */
197 int err;
198 } __packed;
199
200 /**
201 * @typedef udc_event_cb_t
202 * @brief Callback to submit UDC event to higher layer.
203 *
204 * At the higher level, the event is to be inserted into a message queue.
205 * (TBD) Maybe it is better to provide a pointer to k_msgq passed during
206 * initialization.
207 *
208 * @param[in] dev Pointer to device struct of the driver instance
209 * @param[in] event Point to event structure
210 *
211 * @return 0 on success, all other values should be treated as error.
212 */
213 typedef int (*udc_event_cb_t)(const struct device *dev,
214 const struct udc_event *const event);
215
216 /**
217 * @brief UDC driver API
218 * This is the mandatory API any USB device controller driver needs to expose
219 * with exception of:
220 * device_speed(), test_mode() are only required for HS controllers
221 */
222 struct udc_api {
223 enum udc_bus_speed (*device_speed)(const struct device *dev);
224 int (*ep_enqueue)(const struct device *dev,
225 struct udc_ep_config *const cfg,
226 struct net_buf *const buf);
227 int (*ep_dequeue)(const struct device *dev,
228 struct udc_ep_config *const cfg);
229 int (*ep_set_halt)(const struct device *dev,
230 struct udc_ep_config *const cfg);
231 int (*ep_clear_halt)(const struct device *dev,
232 struct udc_ep_config *const cfg);
233 int (*ep_try_config)(const struct device *dev,
234 struct udc_ep_config *const cfg);
235 int (*ep_enable)(const struct device *dev,
236 struct udc_ep_config *const cfg);
237 int (*ep_disable)(const struct device *dev,
238 struct udc_ep_config *const cfg);
239 int (*host_wakeup)(const struct device *dev);
240 int (*set_address)(const struct device *dev,
241 const uint8_t addr);
242 int (*test_mode)(const struct device *dev,
243 const uint8_t mode, const bool dryrun);
244 int (*enable)(const struct device *dev);
245 int (*disable)(const struct device *dev);
246 int (*init)(const struct device *dev);
247 int (*shutdown)(const struct device *dev);
248 int (*lock)(const struct device *dev);
249 int (*unlock)(const struct device *dev);
250 };
251
252 /**
253 * Controller is initialized by udc_init() and can generate the VBUS events,
254 * if capable, but shall not be recognizable by host.
255 */
256 #define UDC_STATUS_INITIALIZED 0
257 /**
258 * Controller is enabled and all API functions are available,
259 * controller is recognizable by host.
260 */
261 #define UDC_STATUS_ENABLED 1
262 /** Controller is suspended by the host */
263 #define UDC_STATUS_SUSPENDED 2
264
265 /**
266 * Common UDC driver data structure
267 *
268 * Mandatory structure for each UDC controller driver.
269 * To be implemented as device's private data (device->data).
270 */
271 struct udc_data {
272 /** LUT for endpoint management */
273 struct udc_ep_config *ep_lut[32];
274 /** Controller capabilities */
275 struct udc_device_caps caps;
276 /** Driver access mutex */
277 struct k_mutex mutex;
278 /** Callback to submit an UDC event to upper layer */
279 udc_event_cb_t event_cb;
280 /** USB device controller status */
281 atomic_t status;
282 /** Internal used Control Sequence Stage */
283 int stage;
284 /** Pointer to buffer containing setup packet */
285 struct net_buf *setup;
286 /** Driver private data */
287 void *priv;
288 };
289
290 /**
291 * @brief New USB device controller (UDC) driver API
292 * @defgroup udc_api USB device controller driver API
293 * @ingroup io_interfaces
294 * @{
295 */
296
297 /**
298 * @brief Checks whether the controller is initialized.
299 *
300 * @param[in] dev Pointer to device struct of the driver instance
301 *
302 * @return true if controller is initialized, false otherwise
303 */
udc_is_initialized(const struct device * dev)304 static inline bool udc_is_initialized(const struct device *dev)
305 {
306 struct udc_data *data = dev->data;
307
308 return atomic_test_bit(&data->status, UDC_STATUS_INITIALIZED);
309 }
310
311 /**
312 * @brief Checks whether the controller is enabled.
313 *
314 * @param[in] dev Pointer to device struct of the driver instance
315 *
316 * @return true if controller is enabled, false otherwise
317 */
udc_is_enabled(const struct device * dev)318 static inline bool udc_is_enabled(const struct device *dev)
319 {
320 struct udc_data *data = dev->data;
321
322 return atomic_test_bit(&data->status, UDC_STATUS_ENABLED);
323 }
324
325 /**
326 * @brief Checks whether the controller is suspended.
327 *
328 * @param[in] dev Pointer to device struct of the driver instance
329 *
330 * @return true if controller is suspended, false otherwise
331 */
udc_is_suspended(const struct device * dev)332 static inline bool udc_is_suspended(const struct device *dev)
333 {
334 struct udc_data *data = dev->data;
335
336 return atomic_test_bit(&data->status, UDC_STATUS_SUSPENDED);
337 }
338
339 /**
340 * @brief Initialize USB device controller
341 *
342 * Initialize USB device controller and control IN/OUT endpoint.
343 * After initialization controller driver should be able to detect
344 * power state of the bus and signal power state changes.
345 *
346 * @param[in] dev Pointer to device struct of the driver instance
347 * @param[in] event_cb Event callback from the higher layer (USB device stack)
348 *
349 * @return 0 on success, all other values should be treated as error.
350 * @retval -EINVAL on parameter error (no callback is passed)
351 * @retval -EALREADY already initialized
352 */
353 int udc_init(const struct device *dev, udc_event_cb_t event_cb);
354
355 /**
356 * @brief Enable USB device controller
357 *
358 * Enable powered USB device controller and allow host to
359 * recognize and enumerate the device.
360 *
361 * @param[in] dev Pointer to device struct of the driver instance
362 *
363 * @return 0 on success, all other values should be treated as error.
364 * @retval -EPERM controller is not initialized
365 * @retval -EALREADY already enabled
366 */
367 int udc_enable(const struct device *dev);
368
369 /**
370 * @brief Disable USB device controller
371 *
372 * Disable enabled USB device controller.
373 * The driver should continue to detect power state changes.
374 *
375 * @param[in] dev Pointer to device struct of the driver instance
376 *
377 * @return 0 on success, all other values should be treated as error.
378 * @retval -EALREADY already disabled
379 */
380 int udc_disable(const struct device *dev);
381
382 /**
383 * @brief Poweroff USB device controller
384 *
385 * Shut down the controller completely to reduce energy consumption
386 * or to change the role of the controller.
387 *
388 * @param[in] dev Pointer to device struct of the driver instance
389 *
390 * @return 0 on success, all other values should be treated as error.
391 * @retval -EALREADY controller is not initialized
392 */
393 int udc_shutdown(const struct device *dev);
394
395 /**
396 * @brief Get USB device controller capabilities
397 *
398 * Obtain the capabilities of the controller
399 * such as full speed (FS), high speed (HS), and more.
400 *
401 * @param[in] dev Pointer to device struct of the driver instance
402 *
403 * @return USB device controller capabilities.
404 */
udc_caps(const struct device * dev)405 static inline struct udc_device_caps udc_caps(const struct device *dev)
406 {
407 struct udc_data *data = dev->data;
408
409 return data->caps;
410 }
411
412 /**
413 * @brief Get actual USB device speed
414 *
415 * The function should be called after the reset event to determine
416 * the actual bus speed.
417 *
418 * @param[in] dev Pointer to device struct of the driver instance
419 *
420 * @return USB device controller capabilities.
421 */
422 enum udc_bus_speed udc_device_speed(const struct device *dev);
423
424 /**
425 * @brief Set USB device address.
426 *
427 * Set address of enabled USB device.
428 *
429 * @param[in] dev Pointer to device struct of the driver instance
430 * @param[in] addr USB device address
431 *
432 * @return 0 on success, all other values should be treated as error.
433 * @retval -EPERM controller is not enabled (or not initialized)
434 */
udc_set_address(const struct device * dev,const uint8_t addr)435 static inline int udc_set_address(const struct device *dev, const uint8_t addr)
436 {
437 const struct udc_api *api = dev->api;
438 int ret;
439
440 if (!udc_is_enabled(dev)) {
441 return -EPERM;
442 }
443
444 api->lock(dev);
445 ret = api->set_address(dev, addr);
446 api->unlock(dev);
447
448 return ret;
449 }
450
451 /**
452 * @brief Enable Test Mode.
453 *
454 * For compliance testing, high-speed controllers must support test modes.
455 * A particular test is enabled by a SetFeature(TEST_MODE) request.
456 * To disable a test mode, device needs to be power cycled.
457 *
458 * @param[in] dev Pointer to device struct of the driver instance
459 * @param[in] mode Test mode
460 * @param[in] dryrun Verify that a particular mode can be enabled, but do not
461 * enable test mode
462 *
463 * @return 0 on success, all other values should be treated as error.
464 * @retval -ENOTSUP Test mode is not supported
465 */
udc_test_mode(const struct device * dev,const uint8_t mode,const bool dryrun)466 static inline int udc_test_mode(const struct device *dev,
467 const uint8_t mode, const bool dryrun)
468 {
469 const struct udc_api *api = dev->api;
470 int ret;
471
472 if (!udc_is_enabled(dev)) {
473 return -EPERM;
474 }
475
476 if (api->test_mode != NULL) {
477 api->lock(dev);
478 ret = api->test_mode(dev, mode, dryrun);
479 api->unlock(dev);
480 } else {
481 ret = -ENOTSUP;
482 }
483
484 return ret;
485 }
486
487 /**
488 * @brief Initiate host wakeup procedure.
489 *
490 * Initiate host wakeup. Only possible when the bus is suspended.
491 *
492 * @param[in] dev Pointer to device struct of the driver instance
493 *
494 * @return 0 on success, all other values should be treated as error.
495 * @retval -EPERM controller is not enabled (or not initialized)
496 */
udc_host_wakeup(const struct device * dev)497 static inline int udc_host_wakeup(const struct device *dev)
498 {
499 const struct udc_api *api = dev->api;
500 int ret;
501
502 if (!udc_is_enabled(dev)) {
503 return -EPERM;
504 }
505
506 api->lock(dev);
507 ret = api->host_wakeup(dev);
508 api->unlock(dev);
509
510 return ret;
511 }
512
513 /**
514 * @brief Try an endpoint configuration.
515 *
516 * Try an endpoint configuration based on endpoint descriptor.
517 * This function may modify wMaxPacketSize descriptor fields
518 * of the endpoint. All properties of the descriptor,
519 * such as direction, and transfer type, should be set correctly.
520 * If wMaxPacketSize value is zero, it will be
521 * updated to maximum buffer size of the endpoint.
522 *
523 * @param[in] dev Pointer to device struct of the driver instance
524 * @param[in] ep Endpoint address (same as bEndpointAddress)
525 * @param[in] attributes Endpoint attributes (same as bmAttributes)
526 * @param[in] mps Maximum packet size (same as wMaxPacketSize)
527 * @param[in] interval Polling interval (same as bInterval)
528 *
529 * @return 0 on success, all other values should be treated as error.
530 * @retval -EINVAL on wrong parameter
531 * @retval -ENOTSUP endpoint configuration not supported
532 * @retval -ENODEV no endpoints available
533 */
534 int udc_ep_try_config(const struct device *dev,
535 const uint8_t ep,
536 const uint8_t attributes,
537 uint16_t *const mps,
538 const uint8_t interval);
539
540 /**
541 * @brief Configure and enable endpoint.
542 *
543 * Configure and make an endpoint ready for use.
544 * Valid for all endpoints except control IN/OUT.
545 *
546 * @param[in] dev Pointer to device struct of the driver instance
547 * @param[in] ep Endpoint address (same as bEndpointAddress)
548 * @param[in] attributes Endpoint attributes (same as bmAttributes)
549 * @param[in] mps Maximum packet size (same as wMaxPacketSize)
550 * @param[in] interval Polling interval (same as bInterval)
551 *
552 * @return 0 on success, all other values should be treated as error.
553 * @retval -EINVAL on wrong parameter (control IN/OUT endpoint)
554 * @retval -EPERM controller is not initialized
555 * @retval -ENODEV endpoint configuration not found
556 * @retval -EALREADY endpoint is already enabled
557 */
558 int udc_ep_enable(const struct device *dev,
559 const uint8_t ep,
560 const uint8_t attributes,
561 const uint16_t mps,
562 const uint8_t interval);
563
564 /**
565 * @brief Disable endpoint.
566 *
567 * Valid for all endpoints except control IN/OUT.
568 *
569 * @param[in] dev Pointer to device struct of the driver instance
570 * @param[in] ep Endpoint address
571 *
572 * @return 0 on success, all other values should be treated as error.
573 * @retval -EINVAL on wrong parameter (control IN/OUT endpoint)
574 * @retval -ENODEV endpoint configuration not found
575 * @retval -EALREADY endpoint is already disabled
576 * @retval -EPERM controller is not initialized
577 */
578 int udc_ep_disable(const struct device *dev, const uint8_t ep);
579
580 /**
581 * @brief Halt endpoint
582 *
583 * Valid for all endpoints.
584 *
585 * @param[in] dev Pointer to device struct of the driver instance
586 * @param[in] ep Endpoint address
587 *
588 * @return 0 on success, all other values should be treated as error.
589 * @retval -ENODEV endpoint configuration not found
590 * @retval -ENOTSUP not supported (e.g. isochronous endpoint)
591 * @retval -EPERM controller is not enabled
592 */
593 int udc_ep_set_halt(const struct device *dev, const uint8_t ep);
594
595 /**
596 * @brief Clear endpoint halt
597 *
598 * Valid for all endpoints.
599 *
600 * @param[in] dev Pointer to device struct of the driver instance
601 * @param[in] ep Endpoint address
602 *
603 * @return 0 on success, all other values should be treated as error.
604 * @retval -ENODEV endpoint configuration not found
605 * @retval -ENOTSUP not supported (e.g. isochronous endpoint)
606 * @retval -EPERM controller is not enabled
607 */
608 int udc_ep_clear_halt(const struct device *dev, const uint8_t ep);
609
610 /**
611 * @brief Queue USB device controller request
612 *
613 * Add request to the queue. If the queue is empty, the request
614 * buffer can be claimed by the controller immediately.
615 *
616 * @param[in] dev Pointer to device struct of the driver instance
617 * @param[in] buf Pointer to UDC request buffer
618 *
619 * @return 0 on success, all other values should be treated as error.
620 * @retval -ENODEV endpoint configuration not found
621 * @retval -EACCES endpoint is not enabled (TBD)
622 * @retval -EBUSY request can not be queued
623 * @retval -EPERM controller is not initialized
624 */
625 int udc_ep_enqueue(const struct device *dev, struct net_buf *const buf);
626
627 /**
628 * @brief Remove all USB device controller requests from endpoint queue
629 *
630 * UDC_EVT_EP_REQUEST event will be generated when the driver
631 * releases claimed buffer, no new requests will be claimed,
632 * all requests in the queue will passed as chained list of
633 * the event variable buf. The endpoint queue is empty after that.
634 *
635 * @param[in] dev Pointer to device struct of the driver instance
636 * @param[in] ep Endpoint address
637 *
638 * @return 0 on success, all other values should be treated as error.
639 * @retval -ENODEV endpoint configuration not found
640 * @retval -EACCES endpoint is not disabled
641 * @retval -EPERM controller is not initialized
642 */
643 int udc_ep_dequeue(const struct device *dev, const uint8_t ep);
644
645 /**
646 * @brief Allocate UDC request buffer
647 *
648 * Allocate a new buffer from common request buffer pool.
649 *
650 * @param[in] dev Pointer to device struct of the driver instance
651 * @param[in] ep Endpoint address
652 * @param[in] size Size of the request buffer
653 *
654 * @return pointer to allocated request or NULL on error.
655 */
656 struct net_buf *udc_ep_buf_alloc(const struct device *dev,
657 const uint8_t ep,
658 const size_t size);
659
660 /**
661 * @brief Free UDC request buffer
662 *
663 * Put the buffer back into the request buffer pool.
664 *
665 * @param[in] dev Pointer to device struct of the driver instance
666 * @param[in] buf Pointer to UDC request buffer
667 *
668 * @return 0 on success, all other values should be treated as error.
669 */
670 int udc_ep_buf_free(const struct device *dev, struct net_buf *const buf);
671
672 /**
673 * @brief Set ZLP flag in requests metadata.
674 *
675 * The controller should send a ZLP at the end of the transfer.
676 *
677 * @param[in] buf Pointer to UDC request buffer
678 */
udc_ep_buf_set_zlp(struct net_buf * const buf)679 static inline void udc_ep_buf_set_zlp(struct net_buf *const buf)
680 {
681 struct udc_buf_info *bi;
682
683 __ASSERT_NO_MSG(buf);
684 bi = (struct udc_buf_info *)net_buf_user_data(buf);
685 if (USB_EP_DIR_IS_IN(bi->ep)) {
686 bi->zlp = 1;
687 }
688 }
689
690 /**
691 * @brief Get requests metadata.
692 *
693 * @param[in] buf Pointer to UDC request buffer
694 *
695 * @return pointer to metadata structure.
696 */
udc_get_buf_info(const struct net_buf * const buf)697 static inline struct udc_buf_info *udc_get_buf_info(const struct net_buf *const buf)
698 {
699 __ASSERT_NO_MSG(buf);
700 return (struct udc_buf_info *)net_buf_user_data(buf);
701 }
702
703 /**
704 * @}
705 */
706
707 #endif /* ZEPHYR_INCLUDE_UDC_H */
708