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