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