1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief New experimental USB device stack APIs and structures
10  *
11  * This file contains the USB device stack APIs and structures.
12  */
13 
14 #ifndef ZEPHYR_INCLUDE_USBD_H_
15 #define ZEPHYR_INCLUDE_USBD_H_
16 
17 #include <zephyr/device.h>
18 #include <zephyr/usb/usb_ch9.h>
19 #include <zephyr/net/buf.h>
20 #include <zephyr/sys/byteorder.h>
21 #include <zephyr/sys/slist.h>
22 #include <zephyr/logging/log.h>
23 #include <zephyr/sys/iterable_sections.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /**
30  * @brief New USB device stack core API
31  * @defgroup usbd_api USB device core API
32  * @ingroup usb
33  * @{
34  */
35 
36 /*
37  * The USB Unicode bString is encoded in UTF16LE, which means it takes up
38  * twice the amount of bytes than the same string encoded in ASCII7.
39  * Use this macro to determine the length of the bString array.
40  *
41  * bString length without null character:
42  *   bString_length = (sizeof(initializer_string) - 1) * 2
43  * or:
44  *   bString_length = sizeof(initializer_string) * 2 - 2
45  */
46 #define USB_BSTRING_LENGTH(s)		(sizeof(s) * 2 - 2)
47 
48 /*
49  * The length of the string descriptor (bLength) is calculated from the
50  * size of the two octets bLength and bDescriptorType plus the
51  * length of the UTF16LE string:
52  *
53  *   bLength = 2 + bString_length
54  *   bLength = 2 + sizeof(initializer_string) * 2 - 2
55  *   bLength = sizeof(initializer_string) * 2
56  * Use this macro to determine the bLength of the string descriptor.
57  */
58 #define USB_STRING_DESCRIPTOR_LENGTH(s)	(sizeof(s) * 2)
59 
60 /* Used internally to keep descriptors in order */
61 enum usbd_desc_usage_type {
62 	USBD_DUT_STRING_LANG,
63 	USBD_DUT_STRING_MANUFACTURER,
64 	USBD_DUT_STRING_PRODUCT,
65 	USBD_DUT_STRING_SERIAL_NUMBER,
66 	USBD_DUT_STRING_INTERFACE,
67 };
68 
69 /**
70  * Descriptor node
71  *
72  * Descriptor node is used to manage descriptors that are not
73  * directly part of a structure, such as string or bos descriptors.
74  */
75 struct usbd_desc_node {
76 	/** slist node struct */
77 	sys_dnode_t node;
78 	/** Descriptor index, required for string descriptors */
79 	unsigned int idx : 8;
80 	/** Descriptor usage type (not bDescriptorType) */
81 	unsigned int utype : 8;
82 	/** If not set, string descriptor must be converted to UTF16LE */
83 	unsigned int utf16le : 1;
84 	/** If not set, device stack obtains SN using the hwinfo API */
85 	unsigned int custom_sn : 1;
86 	/** Pointer to a descriptor */
87 	void *desc;
88 };
89 
90 /**
91  * Device configuration node
92  *
93  * Configuration node is used to manage device configurations,
94  * at least one configuration is required. It does not have an index,
95  * instead bConfigurationValue of the descriptor is used for
96  * identification.
97  */
98 struct usbd_config_node {
99 	/** slist node struct */
100 	sys_snode_t node;
101 	/** Pointer to configuration descriptor */
102 	void *desc;
103 	/** List of registered classes (functions) */
104 	sys_slist_t class_list;
105 };
106 
107 /* TODO: Kconfig option USBD_NUMOF_INTERFACES_MAX? */
108 #define USBD_NUMOF_INTERFACES_MAX	16U
109 
110 /**
111  * USB device support middle layer runtime state
112  *
113  * Part of USB device states without suspended and powered
114  * states, as it is better to track them separately.
115  */
116 enum usbd_ch9_state {
117 	USBD_STATE_DEFAULT = 0,
118 	USBD_STATE_ADDRESS,
119 	USBD_STATE_CONFIGURED,
120 };
121 
122 
123 /**
124  * USB device support middle layer runtime data
125  */
126 struct usbd_ch9_data {
127 	/** Setup packet, up-to-date for the respective control request */
128 	struct usb_setup_packet setup;
129 	/** Control type, internaly used for stage verification */
130 	int ctrl_type;
131 	/** Protocol state of the USB device stack */
132 	enum usbd_ch9_state state;
133 	/** Halted endpoints bitmap */
134 	uint32_t ep_halt;
135 	/** USB device stack selected configuration */
136 	uint8_t configuration;
137 	/** Indicate new device address */
138 	bool new_address;
139 	/** Array to track interfaces alternate settings */
140 	uint8_t alternate[USBD_NUMOF_INTERFACES_MAX];
141 };
142 
143 /**
144  * USB device support status
145  */
146 struct usbd_status {
147 	/** USB device support is initialized */
148 	unsigned int initialized : 1;
149 	/** USB device support is enabled */
150 	unsigned int enabled : 1;
151 	/** USB device is suspended */
152 	unsigned int suspended : 1;
153 	/** USB remote wake-up feature is enabled */
154 	unsigned int rwup : 1;
155 };
156 
157 /**
158  * USB device support runtime context
159  *
160  * Main structure that organizes all descriptors, configuration,
161  * and interfaces. An UDC device must be assigned to this structure.
162  */
163 struct usbd_contex {
164 	/** Name of the USB device */
165 	const char *name;
166 	/** Access mutex */
167 	struct k_mutex mutex;
168 	/** Pointer to UDC device */
169 	const struct device *dev;
170 	/** Middle layer runtime data */
171 	struct usbd_ch9_data ch9_data;
172 	/** slist to manage descriptors like string, bos */
173 	sys_dlist_t descriptors;
174 	/** slist to manage device configurations */
175 	sys_slist_t configs;
176 	/** Status of the USB device support */
177 	struct usbd_status status;
178 	/** Pointer to device descriptor */
179 	void *desc;
180 };
181 
182 /**
183  * @brief Vendor Requests Table
184  */
185 struct usbd_cctx_vendor_req {
186 	/** Array of vendor requests supportd by the class */
187 	const uint8_t *reqs;
188 	/** Length of the array */
189 	uint8_t len;
190 };
191 
192 /** USB Class instance registered flag */
193 #define USBD_CCTX_REGISTERED		0
194 
195 struct usbd_class_node;
196 
197 /**
198  * @brief USB device support class instance API
199  */
200 struct usbd_class_api {
201 	/** Feature halt state update handler */
202 	void (*feature_halt)(struct usbd_class_node *const node,
203 			     uint8_t ep, bool halted);
204 
205 	/** Configuration update handler */
206 	void (*update)(struct usbd_class_node *const node,
207 		       uint8_t iface, uint8_t alternate);
208 
209 	/** USB control request handler to device */
210 	int (*control_to_dev)(struct usbd_class_node *const node,
211 			      const struct usb_setup_packet *const setup,
212 			      const struct net_buf *const buf);
213 
214 	/** USB control request handler to host */
215 	int (*control_to_host)(struct usbd_class_node *const node,
216 			       const struct usb_setup_packet *const setup,
217 			       struct net_buf *const buf);
218 
219 	/** Endpoint request completion event handler */
220 	int (*request)(struct usbd_class_node *const node,
221 		       struct net_buf *buf, int err);
222 
223 	/** USB power management handler suspended */
224 	void (*suspended)(struct usbd_class_node *const node);
225 
226 	/** USB power management handler resumed */
227 	void (*resumed)(struct usbd_class_node *const node);
228 
229 	/** Class associated configuration is selected */
230 	void (*enable)(struct usbd_class_node *const node);
231 
232 	/** Class associated configuration is disabled */
233 	void (*disable)(struct usbd_class_node *const node);
234 
235 	/** Initialization of the class implementation */
236 	int (*init)(struct usbd_class_node *const node);
237 
238 	/** Shutdown of the class implementation */
239 	void (*shutdown)(struct usbd_class_node *const node);
240 };
241 
242 /**
243  * @brief USB device support class data
244  */
245 struct usbd_class_data {
246 	/** Pointer to USB device stack context structure */
247 	struct usbd_contex *uds_ctx;
248 	/** Pointer to a class implementation descriptor that should end with
249 	 *  a nil descriptor (bLength = 0 and bDescriptorType = 0).
250 	 */
251 	void *desc;
252 	/** Supported vendor request table, can be NULL */
253 	const struct usbd_cctx_vendor_req *v_reqs;
254 	/** Bitmap of all endpoints assigned to the instance.
255 	 *  The IN endpoints are mapped in the upper halfword.
256 	 */
257 	uint32_t ep_assigned;
258 	/** Bitmap of the enabled endpoints of the instance.
259 	 *  The IN endpoints are mapped in the upper halfword.
260 	 */
261 	uint32_t ep_active;
262 	/** Bitmap of the bInterfaceNumbers of the class instance */
263 	uint32_t iface_bm;
264 	/** Variable to store the state of the class instance */
265 	atomic_t state;
266 	/** Pointer to private data */
267 	void *priv;
268 };
269 
270 struct usbd_class_node {
271 	/** Node information for the slist. */
272 	sys_snode_t node;
273 	/** Name of the USB device class instance */
274 	const char *name;
275 	/** Pointer to device support class API */
276 	const struct usbd_class_api *api;
277 	/** Pointer to USB device support class data */
278 	struct usbd_class_data *data;
279 };
280 
281 #define USBD_DEVICE_DEFINE(device_name, uhc_dev, vid, pid)		\
282 	static struct usb_device_descriptor				\
283 	desc_##device_name = {						\
284 		.bLength = sizeof(struct usb_device_descriptor),	\
285 		.bDescriptorType = USB_DESC_DEVICE,			\
286 		.bcdUSB = sys_cpu_to_le16(USB_SRN_2_0),			\
287 		.bDeviceClass = USB_BCC_MISCELLANEOUS,			\
288 		.bDeviceSubClass = 2,					\
289 		.bDeviceProtocol = 1,					\
290 		.bMaxPacketSize0 = USB_CONTROL_EP_MPS,			\
291 		.idVendor = vid,					\
292 		.idProduct = pid,					\
293 		.bcdDevice = sys_cpu_to_le16(USB_BCD_DRN),		\
294 		.iManufacturer = 0,					\
295 		.iProduct = 0,						\
296 		.iSerialNumber = 0,					\
297 		.bNumConfigurations = 0,				\
298 	};								\
299 	static STRUCT_SECTION_ITERABLE(usbd_contex, device_name) = {	\
300 		.name = STRINGIFY(device_name),				\
301 		.dev = uhc_dev,						\
302 		.desc = &desc_##device_name,				\
303 	}
304 
305 #define USBD_CONFIGURATION_DEFINE(name, attrib, power)			\
306 	static struct usb_cfg_descriptor				\
307 	cfg_desc_##name = {						\
308 		.bLength = sizeof(struct usb_cfg_descriptor),		\
309 		.bDescriptorType = USB_DESC_CONFIGURATION,		\
310 		.wTotalLength = 0,					\
311 		.bNumInterfaces = 0,					\
312 		.bConfigurationValue = 1,				\
313 		.iConfiguration = 0,					\
314 		.bmAttributes = USB_SCD_RESERVED | (attrib),		\
315 		.bMaxPower = (power),					\
316 	};								\
317 	BUILD_ASSERT((power) < 256, "Too much power");			\
318 	static struct usbd_config_node name = {				\
319 		.desc = &cfg_desc_##name,				\
320 	}
321 
322 /**
323  * @brief Create a string descriptor node and language string descriptor
324  *
325  * This macro defines a descriptor node and a string descriptor that,
326  * when added to the device context, is automatically used as the language
327  * string descriptor zero. Both descriptor node and descriptor are defined with
328  * static-storage-class specifier. Default and currently only supported
329  * language ID is 0x0409 English (United States).
330  * If string descriptors are used, it is necessary to add this descriptor
331  * as the first one to the USB device context.
332  *
333  * @param name Language string descriptor node identifier.
334  */
335 #define USBD_DESC_LANG_DEFINE(name)					\
336 	static struct usb_string_descriptor				\
337 	string_desc_##name = {						\
338 		.bLength = sizeof(struct usb_string_descriptor),	\
339 		.bDescriptorType = USB_DESC_STRING,			\
340 		.bString = sys_cpu_to_le16(0x0409),			\
341 	};								\
342 	static struct usbd_desc_node name = {				\
343 		.idx = 0,						\
344 		.utype = USBD_DUT_STRING_LANG,				\
345 		.desc = &string_desc_##name,				\
346 	}
347 
348 #define USBD_DESC_STRING_DEFINE(d_name, d_string, d_utype)		\
349 	struct usb_string_descriptor_##d_name {				\
350 		uint8_t bLength;					\
351 		uint8_t bDescriptorType;				\
352 		uint8_t bString[USB_BSTRING_LENGTH(d_string)];		\
353 	} __packed;							\
354 	static struct usb_string_descriptor_##d_name			\
355 	string_desc_##d_name = {					\
356 		.bLength = USB_STRING_DESCRIPTOR_LENGTH(d_string),	\
357 		.bDescriptorType = USB_DESC_STRING,			\
358 		.bString = d_string,					\
359 	};								\
360 	static struct usbd_desc_node d_name = {				\
361 		.utype = d_utype,					\
362 		.desc = &string_desc_##d_name,				\
363 	}
364 
365 /**
366  * @brief Create a string descriptor node and manufacturer string descriptor
367  *
368  * This macro defines a descriptor node and a string descriptor that,
369  * when added to the device context, is automatically used as the manufacturer
370  * string descriptor. Both descriptor node and descriptor are defined with
371  * static-storage-class specifier.
372  *
373  * @param d_name   String descriptor node identifier.
374  * @param d_string ASCII7 encoded manufacturer string literal
375  */
376 #define USBD_DESC_MANUFACTURER_DEFINE(d_name, d_string)			\
377 	USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_MANUFACTURER)
378 
379 /**
380  * @brief Create a string descriptor node and product string descriptor
381  *
382  * This macro defines a descriptor node and a string descriptor that,
383  * when added to the device context, is automatically used as the product
384  * string descriptor. Both descriptor node and descriptor are defined with
385  * static-storage-class specifier.
386  *
387  * @param d_name   String descriptor node identifier.
388  * @param d_string ASCII7 encoded product string literal
389  */
390 #define USBD_DESC_PRODUCT_DEFINE(d_name, d_string)			\
391 	USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_PRODUCT)
392 
393 /**
394  * @brief Create a string descriptor node and serial number string descriptor
395  *
396  * This macro defines a descriptor node and a string descriptor that,
397  * when added to the device context, is automatically used as the serial number
398  * string descriptor. The string literal parameter is used as a placeholder,
399  * the unique number is obtained from hwinfo. Both descriptor node and descriptor
400  * are defined with static-storage-class specifier.
401  *
402  * @param d_name   String descriptor node identifier.
403  * @param d_string ASCII7 encoded serial number string literal placeholder
404  */
405 #define USBD_DESC_SERIAL_NUMBER_DEFINE(d_name, d_string)		\
406 	USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_SERIAL_NUMBER)
407 
408 #define USBD_DEFINE_CLASS(class_name, class_api, class_data)		\
409 	static STRUCT_SECTION_ITERABLE(usbd_class_node, class_name) = {	\
410 		.name = STRINGIFY(class_name),				\
411 		.api = class_api,					\
412 		.data = class_data,					\
413 	}
414 
415 /** @brief Helper to declare request table of usbd_cctx_vendor_req
416  *
417  *  @param _reqs Pointer to the vendor request field
418  *  @param _len  Number of supported vendor requests
419  */
420 #define VENDOR_REQ_DEFINE(_reqs, _len) \
421 	{ \
422 		.reqs = (const uint8_t *)(_reqs), \
423 		.len = (_len), \
424 	}
425 
426 /** @brief Helper to declare supported vendor requests
427  *
428  *  @param _reqs Variable number of vendor requests
429  */
430 #define USBD_VENDOR_REQ(_reqs...) \
431 	VENDOR_REQ_DEFINE(((uint8_t []) { _reqs }), \
432 			  sizeof((uint8_t []) { _reqs }))
433 
434 
435 /**
436  * @brief Add common USB descriptor
437  *
438  * Add common descriptor like string or bos.
439  *
440  * @param[in] uds_ctx Pointer to USB device support context
441  * @param[in] dn      Pointer to USB descriptor node
442  *
443  * @return 0 on success, other values on fail.
444  */
445 int usbd_add_descriptor(struct usbd_contex *uds_ctx,
446 			struct usbd_desc_node *dn);
447 
448 /**
449  * @brief Add a USB device configuration
450  *
451  * @param[in] uds_ctx Pointer to USB device support context
452  * @param[in] cd      Pointer to USB configuration node
453  *
454  * @return 0 on success, other values on fail.
455  */
456 int usbd_add_configuration(struct usbd_contex *uds_ctx,
457 			   struct usbd_config_node *cd);
458 
459 /**
460  * @brief Register an USB class instance
461  *
462  * An USB class implementation can have one or more instances.
463  * To identify the instances we use device drivers API.
464  * Device names have a prefix derived from the name of the class,
465  * for example CDC_ACM for CDC ACM class instance,
466  * and can also be easily identified in the shell.
467  * Class instance can only be registered when the USB device stack
468  * is disabled.
469  * Registered instances are initialized at initialization
470  * of the USB device stack, and the interface descriptors
471  * of each instance are adapted to the whole context.
472  *
473  * @param[in] uds_ctx Pointer to USB device support context
474  * @param[in] name    Class instance name
475  * @param[in] cfg     Configuration value (similar to bConfigurationValue)
476  *
477  * @return 0 on success, other values on fail.
478  */
479 int usbd_register_class(struct usbd_contex *uds_ctx,
480 			const char *name,
481 			uint8_t cfg);
482 
483 /**
484  * @brief Unregister an USB class instance
485  *
486  * USB class instance will be removed and will not appear
487  * on the next start of the stack. Instance can only be unregistered
488  * when the USB device stack is disabled.
489  *
490  * @param[in] uds_ctx Pointer to USB device support context
491  * @param[in] name    Class instance name
492  * @param[in] cfg     Configuration value (similar to bConfigurationValue)
493  *
494  * @return 0 on success, other values on fail.
495  */
496 int usbd_unregister_class(struct usbd_contex *uds_ctx,
497 			  const char *name,
498 			  uint8_t cfg);
499 
500 /**
501  * @brief Initialize USB device
502  *
503  * Initialize USB device descriptors and configuration,
504  * initialize USB device controller.
505  * Class instances should be registered before they are involved.
506  * However, the stack should also initialize without registered instances,
507  * even if the host would complain about missing interfaces.
508  *
509  * @param[in] uds_ctx Pointer to USB device support context
510  *
511  * @return 0 on success, other values on fail.
512  */
513 int usbd_init(struct usbd_contex *uds_ctx);
514 
515 /**
516  * @brief Enable the USB device support and registered class instances
517  *
518  * This function enables the USB device support.
519  *
520  * @param[in] uds_ctx Pointer to USB device support context
521  *
522  * @return 0 on success, other values on fail.
523  */
524 int usbd_enable(struct usbd_contex *uds_ctx);
525 
526 /**
527  * @brief Disable the USB device support
528  *
529  * This function disables the USB device support.
530  *
531  * @param[in] uds_ctx Pointer to USB device support context
532  *
533  * @return 0 on success, other values on fail.
534  */
535 int usbd_disable(struct usbd_contex *uds_ctx);
536 
537 /**
538  * @brief Shutdown the USB device support
539  *
540  * This function completely disables the USB device support.
541  *
542  * @param[in] uds_ctx Pointer to USB device support context
543  *
544  * @return 0 on success, other values on fail.
545  */
546 int usbd_shutdown(struct usbd_contex *const uds_ctx);
547 
548 /**
549  * @brief Halt endpoint
550  *
551  * @param[in] uds_ctx Pointer to USB device support context
552  * @param[in] ep      Endpoint address
553  *
554  * @return 0 on success, or error from udc_ep_set_halt()
555  */
556 int usbd_ep_set_halt(struct usbd_contex *uds_ctx, uint8_t ep);
557 
558 /**
559  * @brief Clear endpoint halt
560  *
561  * @param[in] uds_ctx Pointer to USB device support context
562  * @param[in] ep      Endpoint address
563  *
564  * @return 0 on success, or error from udc_ep_clear_halt()
565  */
566 int usbd_ep_clear_halt(struct usbd_contex *uds_ctx, uint8_t ep);
567 
568 /**
569  * @brief Checks whether the endpoint is halted.
570  *
571  * @param[in] uds_ctx Pointer to USB device support context
572  * @param[in] ep      Endpoint address
573  *
574  * @return true if endpoint is halted, false otherwise
575  */
576 bool usbd_ep_is_halted(struct usbd_contex *uds_ctx, uint8_t ep);
577 
578 /**
579  * @brief Allocate buffer for USB device control request
580  *
581  * Allocate a new buffer from controller's driver buffer pool.
582  *
583  * @param[in] uds_ctx Pointer to USB device support context
584  * @param[in] ep      Endpoint address
585  * @param[in] size    Size of the request buffer
586  *
587  * @return pointer to allocated request or NULL on error.
588  */
589 struct net_buf *usbd_ep_ctrl_buf_alloc(struct usbd_contex *const uds_ctx,
590 				       const uint8_t ep, const size_t size);
591 
592 /**
593  * @brief Allocate buffer for USB device request
594  *
595  * Allocate a new buffer from controller's driver buffer pool.
596  *
597  * @param[in] c_nd   Pointer to USB device class node
598  * @param[in] ep     Endpoint address
599  * @param[in] size   Size of the request buffer
600  *
601  * @return pointer to allocated request or NULL on error.
602  */
603 struct net_buf *usbd_ep_buf_alloc(const struct usbd_class_node *const c_nd,
604 				  const uint8_t ep, const size_t size);
605 
606 /**
607  * @brief Queue USB device control request
608  *
609  * Add control request to the queue.
610  *
611  * @param[in] uds_ctx Pointer to USB device support context
612  * @param[in] buf     Pointer to UDC request buffer
613  *
614  * @return 0 on success, all other values should be treated as error.
615  */
616 int usbd_ep_ctrl_enqueue(struct usbd_contex *const uds_ctx,
617 			 struct net_buf *const buf);
618 
619 /**
620  * @brief Queue USB device request
621  *
622  * Add request to the queue.
623  *
624  * @param[in] c_nd   Pointer to USB device class node
625  * @param[in] buf    Pointer to UDC request buffer
626  *
627  * @return 0 on success, or error from udc_ep_enqueue()
628  */
629 int usbd_ep_enqueue(const struct usbd_class_node *const c_nd,
630 		    struct net_buf *const buf);
631 
632 /**
633  * @brief Remove all USB device controller requests from endpoint queue
634  *
635  * @param[in] uds_ctx Pointer to USB device support context
636  * @param[in] ep      Endpoint address
637  *
638  * @return 0 on success, or error from udc_ep_dequeue()
639  */
640 int usbd_ep_dequeue(struct usbd_contex *uds_ctx, const uint8_t ep);
641 
642 /**
643  * @brief Free USB device request buffer
644  *
645  * Put the buffer back into the request buffer pool.
646  *
647  * @param[in] uds_ctx Pointer to USB device support context
648  * @param[in] buf     Pointer to UDC request buffer
649  *
650  * @return 0 on success, all other values should be treated as error.
651  */
652 int usbd_ep_buf_free(struct usbd_contex *uds_ctx, struct net_buf *buf);
653 
654 /**
655  * @brief Checks whether the USB device controller is suspended.
656  *
657  * @param[in] uds_ctx Pointer to USB device support context
658  *
659  * @return true if endpoint is halted, false otherwise
660  */
661 bool usbd_is_suspended(struct usbd_contex *uds_ctx);
662 
663 /**
664  * @brief Initiate the USB remote wakeup (TBD)
665  *
666  * @return 0 on success, other values on fail.
667  */
668 int usbd_wakeup_request(struct usbd_contex *uds_ctx);
669 
670 /**
671  * @brief Set USB device descriptor value bcdUSB
672  *
673  * @param[in] uds_ctx Pointer to USB device support context
674  * @param[in] bcd     bcdUSB value
675  *
676  * @return 0 on success, other values on fail.
677  */
678 int usbd_device_set_bcd(struct usbd_contex *const uds_ctx,
679 			 const uint16_t bcd);
680 
681 /**
682  * @brief Set USB device descriptor value idVendor
683  *
684  * @param[in] uds_ctx Pointer to USB device support context
685  * @param[in] vid     idVendor value
686  *
687  * @return 0 on success, other values on fail.
688  */
689 int usbd_device_set_vid(struct usbd_contex *const uds_ctx,
690 			 const uint16_t vid);
691 
692 /**
693  * @brief Set USB device descriptor value idProduct
694  *
695  * @param[in] uds_ctx Pointer to USB device support context
696  * @param[in] pid     idProduct value
697  *
698  * @return 0 on success, other values on fail.
699  */
700 int usbd_device_set_pid(struct usbd_contex *const uds_ctx,
701 			const uint16_t pid);
702 
703 /**
704  * @brief Set USB device descriptor value bDeviceClass
705  *
706  * @param[in] uds_ctx Pointer to USB device support context
707  * @param[in] value   bDeviceClass value
708  *
709  * @return 0 on success, other values on fail.
710  */
711 int usbd_device_set_class(struct usbd_contex *const uds_ctx,
712 			  const uint8_t value);
713 
714 /**
715  * @brief Set USB device descriptor value bDeviceSubClass
716  *
717  * @param[in] uds_ctx Pointer to USB device support context
718  * @param[in] value   bDeviceSubClass value
719  *
720  * @return 0 on success, other values on fail.
721  */
722 int usbd_device_set_subclass(struct usbd_contex *const uds_ctx,
723 			     const uint8_t value);
724 
725 /**
726  * @brief Set USB device descriptor value bDeviceProtocol
727  *
728  * @param[in] uds_ctx Pointer to USB device support context
729  * @param[in] value   bDeviceProtocol value
730  *
731  * @return 0 on success, other values on fail.
732  */
733 int usbd_device_set_proto(struct usbd_contex *const uds_ctx,
734 			  const uint8_t value);
735 
736 /**
737  * @brief Setup USB device configuration attribute Remote Wakeup
738  *
739  * @param[in] uds_ctx Pointer to USB device support context
740  * @param[in] cfg     Configuration number
741  * @param[in] enable  Sets attribute if true, clears it otherwise
742  *
743  * @return 0 on success, other values on fail.
744  */
745 int usbd_config_attrib_rwup(struct usbd_contex *const uds_ctx,
746 			    const uint8_t cfg, const bool enable);
747 
748 /**
749  * @brief Setup USB device configuration attribute Self-powered
750  *
751  * @param[in] uds_ctx Pointer to USB device support context
752  * @param[in] cfg     Configuration number
753  * @param[in] enable  Sets attribute if true, clears it otherwise
754  *
755  * @return 0 on success, other values on fail.
756  */
757 int usbd_config_attrib_self(struct usbd_contex *const uds_ctx,
758 			    const uint8_t cfg, const bool enable);
759 
760 /**
761  * @brief Setup USB device configuration power consumption
762  *
763  * @param[in] uds_ctx Pointer to USB device support context
764  * @param[in] cfg     Configuration number
765  * @param[in] power   Maximum power consumption value (bMaxPower)
766  *
767  * @return 0 on success, other values on fail.
768  */
769 int usbd_config_maxpower(struct usbd_contex *const uds_ctx,
770 			 const uint8_t cfg, const uint8_t power);
771 /**
772  * @}
773  */
774 
775 #ifdef __cplusplus
776 }
777 #endif
778 
779 #endif /* ZEPHYR_INCLUDE_USBD_H_ */
780