1 /*
2  * Copyright (c) 2023-2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/atomic.h>
9 #include <zephyr/sys/byteorder.h>
10 
11 #include <zephyr/usb/usbd.h>
12 #include <zephyr/usb/usb_ch9.h>
13 #include <zephyr/usb/class/usbd_uac2.h>
14 #include <zephyr/drivers/usb/udc.h>
15 
16 #include "usbd_uac2_macros.h"
17 
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(usbd_uac2, CONFIG_USBD_UAC2_LOG_LEVEL);
20 
21 #define DT_DRV_COMPAT zephyr_uac2
22 
23 #define COUNT_UAC2_AS_ENDPOINTS(node)						\
24 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
25 		+ AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node) +			\
26 		AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node)))
27 #define COUNT_UAC2_ENDPOINTS(i)							\
28 	+ DT_PROP(DT_DRV_INST(i), interrupt_endpoint)				\
29 	DT_INST_FOREACH_CHILD(i, COUNT_UAC2_AS_ENDPOINTS)
30 #define UAC2_NUM_ENDPOINTS DT_INST_FOREACH_STATUS_OKAY(COUNT_UAC2_ENDPOINTS)
31 
32 /* Net buf is used mostly with external data. The main reason behind external
33  * data is avoiding unnecessary isochronous data copy operations.
34  *
35  * Allow up to 6 bytes per item to facilitate optional interrupt endpoint (which
36  * requires 6 bytes) and feedback endpoint (4 bytes on High-Speed, 3 bytes on
37  * Full-Speed). Because the total number of endpoints is really small (typically
38  * there will be just 2 isochronous endpoints; the upper bound originating from
39  * the USB specification itself is 30 non-control endpoints). Therefore, the
40  * "wasted memory" here is likely to be smaller than the memory overhead for
41  * more complex "only as much as needed" schemes (e.g. heap).
42  */
43 UDC_BUF_POOL_DEFINE(uac2_pool, UAC2_NUM_ENDPOINTS, 6,
44 		    sizeof(struct udc_buf_info), NULL);
45 
46 /* 5.2.2 Control Request Layout */
47 #define SET_CLASS_REQUEST_TYPE		0x21
48 #define GET_CLASS_REQUEST_TYPE		0xA1
49 
50 /* A.14 Audio Class-Specific Request Codes */
51 #define CUR				0x01
52 #define RANGE				0x02
53 #define MEM				0x03
54 
55 /* A.17.1 Clock Source Control Selectors */
56 #define CS_SAM_FREQ_CONTROL		0x01
57 #define CS_CLOCK_VALID_CONTROL		0x02
58 
59 #define CONTROL_ATTRIBUTE(setup)	(setup->bRequest)
60 #define CONTROL_ENTITY_ID(setup)	((setup->wIndex & 0xFF00) >> 8)
61 #define CONTROL_SELECTOR(setup)		((setup->wValue & 0xFF00) >> 8)
62 #define CONTROL_CHANNEL_NUMBER(setup)	(setup->wValue & 0x00FF)
63 
64 typedef enum {
65 	ENTITY_TYPE_INVALID,
66 	ENTITY_TYPE_CLOCK_SOURCE,
67 	ENTITY_TYPE_INPUT_TERMINAL,
68 	ENTITY_TYPE_OUTPUT_TERMINAL,
69 } entity_type_t;
70 
71 static size_t clock_frequencies(struct usbd_class_data *const c_data,
72 				const uint8_t id, const uint32_t **frequencies);
73 
74 /* UAC2 device runtime data */
75 struct uac2_ctx {
76 	const struct uac2_ops *ops;
77 	void *user_data;
78 	/* Bit set indicates the AudioStreaming interface has non-zero bandwidth
79 	 * alternate setting active.
80 	 */
81 	atomic_t as_active;
82 	atomic_t as_queued;
83 	uint32_t fb_queued;
84 };
85 
86 /* UAC2 device constant data */
87 struct uac2_cfg {
88 	struct usbd_class_data *const c_data;
89 	const struct usb_desc_header **descriptors;
90 	/* Entity 1 type is at entity_types[0] */
91 	const entity_type_t *entity_types;
92 	/* Array of indexes to data endpoint descriptor in descriptors set.
93 	 * First AudioStreaming interface is at ep_indexes[0]. Index is 0 if
94 	 * the interface is external interface (Type IV), i.e. no endpoint.
95 	 */
96 	const uint16_t *ep_indexes;
97 	/* Same as ep_indexes, but for explicit feedback endpoints. */
98 	const uint16_t *fb_indexes;
99 	/* First AudioStreaming interface Terminal ID is at as_terminals[0]. */
100 	const uint8_t *as_terminals;
101 	/* Number of interfaces (ep_indexes, fb_indexes and as_terminals size) */
102 	uint8_t num_ifaces;
103 	/* Number of entities (entity_type array size) */
104 	uint8_t num_entities;
105 };
106 
id_type(struct usbd_class_data * const c_data,uint8_t id)107 static entity_type_t id_type(struct usbd_class_data *const c_data, uint8_t id)
108 {
109 	const struct device *dev = usbd_class_get_private(c_data);
110 	const struct uac2_cfg *cfg = dev->config;
111 
112 	if ((id - 1) < cfg->num_entities) {
113 		return cfg->entity_types[id - 1];
114 	}
115 
116 	return ENTITY_TYPE_INVALID;
117 }
118 
119 static const struct usb_ep_descriptor *
get_as_data_ep(struct usbd_class_data * const c_data,int as_idx)120 get_as_data_ep(struct usbd_class_data *const c_data, int as_idx)
121 {
122 	const struct device *dev = usbd_class_get_private(c_data);
123 	const struct uac2_cfg *cfg = dev->config;
124 	const struct usb_desc_header *desc = NULL;
125 
126 	if ((as_idx >= 0) && (as_idx < cfg->num_ifaces) &&
127 	    cfg->ep_indexes[as_idx]) {
128 		desc = cfg->descriptors[cfg->ep_indexes[as_idx]];
129 	}
130 
131 	return (const struct usb_ep_descriptor *)desc;
132 }
133 
134 static const struct usb_ep_descriptor *
get_as_feedback_ep(struct usbd_class_data * const c_data,int as_idx)135 get_as_feedback_ep(struct usbd_class_data *const c_data, int as_idx)
136 {
137 	const struct device *dev = usbd_class_get_private(c_data);
138 	const struct uac2_cfg *cfg = dev->config;
139 	const struct usb_desc_header *desc = NULL;
140 
141 	if ((as_idx < cfg->num_ifaces) && cfg->fb_indexes[as_idx]) {
142 		desc = cfg->descriptors[cfg->fb_indexes[as_idx]];
143 	}
144 
145 	return (const struct usb_ep_descriptor *)desc;
146 }
147 
ep_to_as_interface(const struct device * dev,uint8_t ep,bool * fb)148 static int ep_to_as_interface(const struct device *dev, uint8_t ep, bool *fb)
149 {
150 	const struct uac2_cfg *cfg = dev->config;
151 	const struct usb_ep_descriptor *desc;
152 
153 	for (int i = 0; i < cfg->num_ifaces; i++) {
154 		if (!cfg->ep_indexes[i]) {
155 			/* If there is no data endpoint there cannot be feedback
156 			 * endpoint. Simply skip external interfaces.
157 			 */
158 			continue;
159 		}
160 
161 		desc = get_as_data_ep(cfg->c_data, i);
162 		if (desc && (ep == desc->bEndpointAddress)) {
163 			*fb = false;
164 			return i;
165 		}
166 
167 		desc = get_as_feedback_ep(cfg->c_data, i);
168 		if (desc && (ep == desc->bEndpointAddress)) {
169 			*fb = true;
170 			return i;
171 		}
172 	}
173 
174 	*fb = false;
175 	return -ENOENT;
176 }
177 
terminal_to_as_interface(const struct device * dev,uint8_t terminal)178 static int terminal_to_as_interface(const struct device *dev, uint8_t terminal)
179 {
180 	const struct uac2_cfg *cfg = dev->config;
181 
182 	for (int as_idx = 0; as_idx < cfg->num_ifaces; as_idx++) {
183 		if (terminal == cfg->as_terminals[as_idx]) {
184 			return as_idx;
185 		}
186 	}
187 
188 	return -ENOENT;
189 }
190 
usbd_uac2_set_ops(const struct device * dev,const struct uac2_ops * ops,void * user_data)191 void usbd_uac2_set_ops(const struct device *dev,
192 		       const struct uac2_ops *ops, void *user_data)
193 {
194 	struct uac2_ctx *ctx = dev->data;
195 
196 	__ASSERT(ops->sof_cb, "SOF callback is mandatory");
197 
198 	ctx->ops = ops;
199 	ctx->user_data = user_data;
200 }
201 
202 static struct net_buf *
uac2_buf_alloc(const uint8_t ep,void * data,uint16_t size)203 uac2_buf_alloc(const uint8_t ep, void *data, uint16_t size)
204 {
205 	struct net_buf *buf = NULL;
206 	struct udc_buf_info *bi;
207 
208 	__ASSERT(IS_UDC_ALIGNED(data), "Application provided unaligned buffer");
209 
210 	buf = net_buf_alloc_with_data(&uac2_pool, data, size, K_NO_WAIT);
211 	if (!buf) {
212 		return NULL;
213 	}
214 
215 	bi = udc_get_buf_info(buf);
216 	memset(bi, 0, sizeof(struct udc_buf_info));
217 	bi->ep = ep;
218 
219 	if (USB_EP_DIR_IS_OUT(ep)) {
220 		/* Buffer is empty, USB stack will write data from host */
221 		buf->len = 0;
222 	}
223 
224 	return buf;
225 }
226 
usbd_uac2_send(const struct device * dev,uint8_t terminal,void * data,uint16_t size)227 int usbd_uac2_send(const struct device *dev, uint8_t terminal,
228 		   void *data, uint16_t size)
229 {
230 	const struct uac2_cfg *cfg = dev->config;
231 	struct uac2_ctx *ctx = dev->data;
232 	struct net_buf *buf;
233 	const struct usb_ep_descriptor *desc;
234 	uint8_t ep = 0;
235 	int as_idx = terminal_to_as_interface(dev, terminal);
236 	int ret;
237 
238 	desc = get_as_data_ep(cfg->c_data, as_idx);
239 	if (desc) {
240 		ep = desc->bEndpointAddress;
241 	}
242 
243 	if (!ep) {
244 		LOG_ERR("No endpoint for terminal %d", terminal);
245 		return -ENOENT;
246 	}
247 
248 	if (!atomic_test_bit(&ctx->as_active, as_idx)) {
249 		/* Host is not interested in the data */
250 		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
251 		return 0;
252 	}
253 
254 	if (atomic_test_and_set_bit(&ctx->as_queued, as_idx)) {
255 		LOG_ERR("Previous send not finished yet on 0x%02x", ep);
256 		return -EAGAIN;
257 	}
258 
259 	buf = uac2_buf_alloc(ep, data, size);
260 	if (!buf) {
261 		/* This shouldn't really happen because netbuf should be large
262 		 * enough, but if it does all we loose is just single packet.
263 		 */
264 		LOG_ERR("No netbuf for send");
265 		atomic_clear_bit(&ctx->as_queued, as_idx);
266 		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
267 		return -ENOMEM;
268 	}
269 
270 	ret = usbd_ep_enqueue(cfg->c_data, buf);
271 	if (ret) {
272 		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
273 		net_buf_unref(buf);
274 		atomic_clear_bit(&ctx->as_queued, as_idx);
275 		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
276 	}
277 
278 	return ret;
279 }
280 
schedule_iso_out_read(struct usbd_class_data * const c_data,uint8_t ep,uint16_t mps,uint8_t terminal)281 static void schedule_iso_out_read(struct usbd_class_data *const c_data,
282 				  uint8_t ep, uint16_t mps, uint8_t terminal)
283 {
284 	const struct device *dev = usbd_class_get_private(c_data);
285 	const struct uac2_cfg *cfg = dev->config;
286 	struct uac2_ctx *ctx = dev->data;
287 	struct net_buf *buf;
288 	void *data_buf;
289 	int as_idx = terminal_to_as_interface(dev, terminal);
290 	int ret;
291 
292 	/* All calls to this function are internal to class, if terminal is not
293 	 * associated with interface there is a bug in class implementation.
294 	 */
295 	__ASSERT_NO_MSG((as_idx >= 0) && (as_idx < cfg->num_ifaces));
296 	/* Silence warning if asserts are not enabled */
297 	ARG_UNUSED(cfg);
298 
299 	if (!((as_idx >= 0) && atomic_test_bit(&ctx->as_active, as_idx))) {
300 		/* Host won't send data */
301 		return;
302 	}
303 
304 	if (atomic_test_and_set_bit(&ctx->as_queued, as_idx)) {
305 		/* Transfer already queued - do not requeue */
306 		return;
307 	}
308 
309 	/* Prepare transfer to read audio OUT data from host */
310 	data_buf = ctx->ops->get_recv_buf(dev, terminal, mps, ctx->user_data);
311 	if (!data_buf) {
312 		LOG_ERR("No data buffer for terminal %d", terminal);
313 		atomic_clear_bit(&ctx->as_queued, as_idx);
314 		return;
315 	}
316 
317 	buf = uac2_buf_alloc(ep, data_buf, mps);
318 	if (!buf) {
319 		LOG_ERR("No netbuf for read");
320 		/* Netbuf pool should be large enough, but if for some reason
321 		 * we are out of netbuf, there's nothing better to do than to
322 		 * pass the buffer back to application.
323 		 */
324 		ctx->ops->data_recv_cb(dev, terminal,
325 				       data_buf, 0, ctx->user_data);
326 		atomic_clear_bit(&ctx->as_queued, as_idx);
327 		return;
328 	}
329 
330 	ret = usbd_ep_enqueue(c_data, buf);
331 	if (ret) {
332 		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
333 		net_buf_unref(buf);
334 		atomic_clear_bit(&ctx->as_queued, as_idx);
335 	}
336 }
337 
write_explicit_feedback(struct usbd_class_data * const c_data,uint8_t ep,uint8_t terminal)338 static void write_explicit_feedback(struct usbd_class_data *const c_data,
339 				    uint8_t ep, uint8_t terminal)
340 {
341 	const struct device *dev = usbd_class_get_private(c_data);
342 	struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data);
343 	struct uac2_ctx *ctx = dev->data;
344 	struct net_buf *buf;
345 	struct udc_buf_info *bi;
346 	uint32_t fb_value;
347 	int as_idx = terminal_to_as_interface(dev, terminal);
348 	int ret;
349 
350 	__ASSERT_NO_MSG(as_idx >= 0);
351 
352 	buf = net_buf_alloc(&uac2_pool, K_NO_WAIT);
353 	if (!buf) {
354 		LOG_ERR("No buf for feedback");
355 		return;
356 	}
357 
358 	bi = udc_get_buf_info(buf);
359 	memset(bi, 0, sizeof(struct udc_buf_info));
360 	bi->ep = ep;
361 
362 	fb_value = ctx->ops->feedback_cb(dev, terminal, ctx->user_data);
363 
364 	/* REVISE: How to determine operating speed? Should we have separate
365 	 * class instances for high-speed and full-speed (because high-speed
366 	 * allows more sampling rates and/or bit depths)?
367 	 */
368 	if (usbd_bus_speed(uds_ctx) == USBD_SPEED_FS) {
369 		net_buf_add_le24(buf, fb_value);
370 	} else {
371 		net_buf_add_le32(buf, fb_value);
372 	}
373 
374 	ret = usbd_ep_enqueue(c_data, buf);
375 	if (ret) {
376 		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
377 		net_buf_unref(buf);
378 	} else {
379 		ctx->fb_queued |= BIT(as_idx);
380 	}
381 }
382 
uac2_update(struct usbd_class_data * const c_data,uint8_t iface,uint8_t alternate)383 void uac2_update(struct usbd_class_data *const c_data,
384 		 uint8_t iface, uint8_t alternate)
385 {
386 	const struct device *dev = usbd_class_get_private(c_data);
387 	struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data);
388 	const struct uac2_cfg *cfg = dev->config;
389 	struct uac2_ctx *ctx = dev->data;
390 	const struct usb_association_descriptor *iad;
391 	const struct usb_ep_descriptor *data_ep, *fb_ep;
392 	uint8_t as_idx;
393 	bool microframes;
394 
395 	LOG_DBG("iface %d alt %d", iface, alternate);
396 
397 	iad = (const struct usb_association_descriptor *)cfg->descriptors[0];
398 
399 	/* AudioControl interface (bFirstInterface) doesn't have alternate
400 	 * configurations, therefore the iface must be AudioStreaming.
401 	 */
402 	__ASSERT_NO_MSG((iface > iad->bFirstInterface) &&
403 			(iface < iad->bFirstInterface + iad->bInterfaceCount));
404 	as_idx = iface - iad->bFirstInterface - 1;
405 
406 	/* Audio class is forbidden on Low-Speed, therefore the only possibility
407 	 * for not using microframes is when device operates at Full-Speed.
408 	 */
409 	if (usbd_bus_speed(uds_ctx) == USBD_SPEED_FS) {
410 		microframes = false;
411 	} else {
412 		microframes = true;
413 	}
414 
415 	/* Notify application about terminal state change */
416 	ctx->ops->terminal_update_cb(dev, cfg->as_terminals[as_idx], alternate,
417 				     microframes, ctx->user_data);
418 
419 	if (alternate == 0) {
420 		/* Mark interface as inactive, any pending endpoint transfers
421 		 * were already cancelled by the USB stack.
422 		 */
423 		atomic_clear_bit(&ctx->as_active, as_idx);
424 		return;
425 	}
426 
427 	atomic_set_bit(&ctx->as_active, as_idx);
428 
429 	data_ep = get_as_data_ep(c_data, as_idx);
430 	/* External interfaces (i.e. NULL data_ep) do not have alternate
431 	 * configuration and therefore data_ep must be valid here.
432 	 */
433 	__ASSERT_NO_MSG(data_ep);
434 
435 	if (USB_EP_DIR_IS_OUT(data_ep->bEndpointAddress)) {
436 		schedule_iso_out_read(c_data, data_ep->bEndpointAddress,
437 				      sys_le16_to_cpu(data_ep->wMaxPacketSize),
438 				      cfg->as_terminals[as_idx]);
439 
440 		fb_ep = get_as_feedback_ep(c_data, as_idx);
441 		if (fb_ep) {
442 			write_explicit_feedback(c_data, fb_ep->bEndpointAddress,
443 						cfg->as_terminals[as_idx]);
444 		}
445 	}
446 }
447 
448 /* Table 5-6: 4-byte Control CUR Parameter Block */
layout3_cur_response(struct net_buf * const buf,uint16_t length,const uint32_t value)449 static void layout3_cur_response(struct net_buf *const buf, uint16_t length,
450 				 const uint32_t value)
451 {
452 	uint8_t tmp[4];
453 
454 	/* dCUR */
455 	sys_put_le32(value, tmp);
456 	net_buf_add_mem(buf, tmp, MIN(length, 4));
457 }
458 
459 /* Table 5-7: 4-byte Control RANGE Parameter Block */
layout3_range_response(struct net_buf * const buf,uint16_t length,const uint32_t * min,const uint32_t * max,const uint32_t * res,int n)460 static void layout3_range_response(struct net_buf *const buf, uint16_t length,
461 				   const uint32_t *min, const uint32_t *max,
462 				   const uint32_t *res, int n)
463 {
464 	uint16_t to_add;
465 	uint8_t tmp[4];
466 	int i;
467 	int item;
468 
469 	/* wNumSubRanges */
470 	sys_put_le16(n, tmp);
471 	to_add = MIN(length, 2);
472 	net_buf_add_mem(buf, tmp, to_add);
473 	length -= to_add;
474 
475 	/* Keep adding dMIN, dMAX, dRES as long as we have entries to add and
476 	 * we didn't reach wLength response limit.
477 	 */
478 	i = item = 0;
479 	while ((length > 0) && (i < n)) {
480 		to_add = MIN(length, 4);
481 		if (item == 0) {
482 			sys_put_le32(min[i], tmp);
483 		} else if (item == 1) {
484 			sys_put_le32(max[i], tmp);
485 		} else if (item == 2) {
486 			if (res) {
487 				sys_put_le32(res[i], tmp);
488 			} else {
489 				memset(tmp, 0, 4);
490 			}
491 		}
492 		net_buf_add_mem(buf, tmp, to_add);
493 		length -= to_add;
494 
495 		if (++item == 3) {
496 			item = 0;
497 			i++;
498 		}
499 	}
500 }
501 
get_clock_source_request(struct usbd_class_data * const c_data,const struct usb_setup_packet * const setup,struct net_buf * const buf)502 static int get_clock_source_request(struct usbd_class_data *const c_data,
503 				    const struct usb_setup_packet *const setup,
504 				    struct net_buf *const buf)
505 {
506 	const uint32_t *frequencies;
507 	size_t count;
508 
509 	/* Channel Number must be zero */
510 	if (CONTROL_CHANNEL_NUMBER(setup) != 0) {
511 		LOG_DBG("Clock source control with channel %d",
512 			CONTROL_CHANNEL_NUMBER(setup));
513 		errno = -EINVAL;
514 		return 0;
515 	}
516 
517 	count = clock_frequencies(c_data, CONTROL_ENTITY_ID(setup), &frequencies);
518 
519 	if (CONTROL_SELECTOR(setup) == CS_SAM_FREQ_CONTROL) {
520 		if (CONTROL_ATTRIBUTE(setup) == CUR) {
521 			if (count == 1) {
522 				layout3_cur_response(buf, setup->wLength,
523 						     frequencies[0]);
524 				return 0;
525 			}
526 			/* TODO: If there is more than one frequency supported,
527 			 * call registered application API to determine active
528 			 * sample rate.
529 			 */
530 		} else if (CONTROL_ATTRIBUTE(setup) == RANGE) {
531 			layout3_range_response(buf, setup->wLength, frequencies,
532 					       frequencies, NULL, count);
533 			return 0;
534 		}
535 	} else {
536 		LOG_DBG("Unhandled clock control selector 0x%02x",
537 			CONTROL_SELECTOR(setup));
538 	}
539 
540 	errno = -ENOTSUP;
541 	return 0;
542 }
543 
uac2_control_to_host(struct usbd_class_data * const c_data,const struct usb_setup_packet * const setup,struct net_buf * const buf)544 static int uac2_control_to_host(struct usbd_class_data *const c_data,
545 				const struct usb_setup_packet *const setup,
546 				struct net_buf *const buf)
547 {
548 	entity_type_t entity_type;
549 
550 	if ((CONTROL_ATTRIBUTE(setup) != CUR) &&
551 	    (CONTROL_ATTRIBUTE(setup) != RANGE)) {
552 		errno = -ENOTSUP;
553 		return 0;
554 	}
555 
556 	if (setup->bmRequestType == GET_CLASS_REQUEST_TYPE) {
557 		entity_type = id_type(c_data, CONTROL_ENTITY_ID(setup));
558 		if (entity_type == ENTITY_TYPE_CLOCK_SOURCE) {
559 			return get_clock_source_request(c_data, setup, buf);
560 		}
561 	}
562 
563 	errno = -ENOTSUP;
564 	return 0;
565 }
566 
uac2_request(struct usbd_class_data * const c_data,struct net_buf * buf,int err)567 static int uac2_request(struct usbd_class_data *const c_data, struct net_buf *buf,
568 			int err)
569 {
570 	const struct device *dev = usbd_class_get_private(c_data);
571 	const struct uac2_cfg *cfg = dev->config;
572 	struct uac2_ctx *ctx = dev->data;
573 	struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data);
574 	struct udc_buf_info *bi;
575 	uint8_t ep, terminal;
576 	uint16_t mps;
577 	int as_idx;
578 	bool is_feedback;
579 
580 	bi = udc_get_buf_info(buf);
581 	if (err) {
582 		if (err == -ECONNABORTED) {
583 			LOG_WRN("request ep 0x%02x, len %u cancelled",
584 				bi->ep, buf->len);
585 		} else {
586 			LOG_ERR("request ep 0x%02x, len %u failed",
587 				bi->ep, buf->len);
588 		}
589 	}
590 
591 	mps = buf->size;
592 	ep = bi->ep;
593 	as_idx = ep_to_as_interface(dev, ep, &is_feedback);
594 	__ASSERT_NO_MSG((as_idx >= 0) && (as_idx < cfg->num_ifaces));
595 	terminal = cfg->as_terminals[as_idx];
596 
597 	if (is_feedback) {
598 		ctx->fb_queued &= ~BIT(as_idx);
599 	} else {
600 		atomic_clear_bit(&ctx->as_queued, as_idx);
601 	}
602 
603 	if (USB_EP_DIR_IS_OUT(ep)) {
604 		ctx->ops->data_recv_cb(dev, terminal, buf->__buf, buf->len,
605 				       ctx->user_data);
606 	} else if (!is_feedback) {
607 		ctx->ops->buf_release_cb(dev, terminal, buf->__buf, ctx->user_data);
608 	}
609 
610 	usbd_ep_buf_free(uds_ctx, buf);
611 	if (err) {
612 		return 0;
613 	}
614 
615 	/* Reschedule the read or explicit feedback write */
616 	if (USB_EP_DIR_IS_OUT(ep)) {
617 		schedule_iso_out_read(c_data, ep, mps, terminal);
618 	}
619 
620 	return 0;
621 }
622 
uac2_sof(struct usbd_class_data * const c_data)623 static void uac2_sof(struct usbd_class_data *const c_data)
624 {
625 	const struct device *dev = usbd_class_get_private(c_data);
626 	const struct usb_ep_descriptor *data_ep;
627 	const struct usb_ep_descriptor *feedback_ep;
628 	const struct uac2_cfg *cfg = dev->config;
629 	struct uac2_ctx *ctx = dev->data;
630 	int as_idx;
631 
632 	ctx->ops->sof_cb(dev, ctx->user_data);
633 
634 	for (as_idx = 0; as_idx < cfg->num_ifaces; as_idx++) {
635 		/* Make sure OUT endpoint has read request pending. The request
636 		 * won't be pending only if there was buffer underrun, i.e. the
637 		 * application failed to supply receive buffer.
638 		 */
639 		data_ep = get_as_data_ep(c_data, as_idx);
640 		if (data_ep && USB_EP_DIR_IS_OUT(data_ep->bEndpointAddress)) {
641 			schedule_iso_out_read(c_data, data_ep->bEndpointAddress,
642 				sys_le16_to_cpu(data_ep->wMaxPacketSize),
643 				cfg->as_terminals[as_idx]);
644 		}
645 
646 		/* Skip interfaces without explicit feedback endpoint */
647 		feedback_ep = get_as_feedback_ep(c_data, as_idx);
648 		if (feedback_ep == NULL) {
649 			continue;
650 		}
651 
652 		/* We didn't get feedback write request callback yet, skip it
653 		 * for now to allow faster recovery (i.e. reduce workload to be
654 		 * done during this frame).
655 		 */
656 		if (ctx->fb_queued & BIT(as_idx)) {
657 			continue;
658 		}
659 
660 		/* Only send feedback if host has enabled alternate interface */
661 		if (!atomic_test_bit(&ctx->as_active, as_idx)) {
662 			continue;
663 		}
664 
665 		/* Make feedback available on every frame (value "sent" in
666 		 * previous SOF is "gone" even if USB host did not attempt to
667 		 * read it).
668 		 */
669 		write_explicit_feedback(c_data, feedback_ep->bEndpointAddress,
670 					cfg->as_terminals[as_idx]);
671 	}
672 }
673 
uac2_get_desc(struct usbd_class_data * const c_data,const enum usbd_speed speed)674 static void *uac2_get_desc(struct usbd_class_data *const c_data,
675 			   const enum usbd_speed speed)
676 {
677 	struct device *dev = usbd_class_get_private(c_data);
678 	const struct uac2_cfg *cfg = dev->config;
679 
680 	if (speed == USBD_SPEED_FS) {
681 		return cfg->descriptors;
682 	}
683 
684 	return NULL;
685 }
686 
uac2_init(struct usbd_class_data * const c_data)687 static int uac2_init(struct usbd_class_data *const c_data)
688 {
689 	const struct device *dev = usbd_class_get_private(c_data);
690 	struct uac2_ctx *ctx = dev->data;
691 
692 	if (ctx->ops == NULL) {
693 		LOG_ERR("Application did not register UAC2 ops");
694 		return -EINVAL;
695 	}
696 
697 	return 0;
698 }
699 
700 struct usbd_class_api uac2_api = {
701 	.update = uac2_update,
702 	.control_to_host = uac2_control_to_host,
703 	.request = uac2_request,
704 	.sof = uac2_sof,
705 	.get_desc = uac2_get_desc,
706 	.init = uac2_init,
707 };
708 
709 #define DEFINE_ENTITY_TYPES(node)						\
710 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
711 		ENTITY_TYPE_CLOCK_SOURCE					\
712 	))									\
713 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_input_terminal), (	\
714 		ENTITY_TYPE_INPUT_TERMINAL					\
715 	))									\
716 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_output_terminal), (	\
717 		ENTITY_TYPE_OUTPUT_TERMINAL					\
718 	))									\
719 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
720 		ENTITY_TYPE_INVALID						\
721 	))									\
722 	, /* Comma here causes unknown types to fail at compile time */
723 #define DEFINE_AS_EP_INDEXES(node)						\
724 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
725 		COND_CODE_1(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node),		\
726 			(UAC2_DESCRIPTOR_AS_DATA_EP_INDEX(node),), (0,))	\
727 	))
728 #define DEFINE_AS_FB_INDEXES(node)						\
729 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
730 		COND_CODE_1(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node),		\
731 			(UAC2_DESCRIPTOR_AS_FEEDBACK_EP_INDEX(node),), (0,))	\
732 	))
733 #define DEFINE_AS_TERMINALS(node)						\
734 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
735 		ENTITY_ID(DT_PROP(node, linked_terminal)),			\
736 	))
737 
738 #define FREQUENCY_TABLE_NAME(node, i)						\
739 	UTIL_CAT(frequencies_##i##_, ENTITY_ID(node))
740 #define DEFINE_CLOCK_SOURCES(node, i)						\
741 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
742 		static const uint32_t FREQUENCY_TABLE_NAME(node, i)[] =		\
743 				DT_PROP(node, sampling_frequencies);		\
744 	))
745 
746 #define DEFINE_LOOKUP_TABLES(i)							\
747 	static const entity_type_t entity_types_##i[] = {			\
748 		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_ENTITY_TYPES)	\
749 	};									\
750 	static const uint16_t ep_indexes_##i[] = {				\
751 		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_EP_INDEXES)	\
752 	};									\
753 	static const uint16_t fb_indexes_##i[] = {				\
754 		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_FB_INDEXES)	\
755 	};									\
756 	static const uint8_t as_terminals_##i[] = {				\
757 		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_TERMINALS)	\
758 	};									\
759 	DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(i, DEFINE_CLOCK_SOURCES, i)
760 
761 #define DEFINE_UAC2_CLASS_DATA(inst)						\
762 	DT_INST_FOREACH_CHILD(inst, VALIDATE_NODE)				\
763 	static struct uac2_ctx uac2_ctx_##inst;					\
764 	UAC2_DESCRIPTOR_ARRAYS(DT_DRV_INST(inst))				\
765 	static const struct usb_desc_header *uac2_descriptors_##inst[] = {	\
766 		UAC2_DESCRIPTOR_PTRS(DT_DRV_INST(inst))				\
767 	};									\
768 	USBD_DEFINE_CLASS(uac2_##inst, &uac2_api,				\
769 			  (void *)DEVICE_DT_GET(DT_DRV_INST(inst)), NULL);	\
770 	DEFINE_LOOKUP_TABLES(inst)						\
771 	static const struct uac2_cfg uac2_cfg_##inst = {			\
772 		.c_data = &uac2_##inst,						\
773 		.descriptors = uac2_descriptors_##inst,				\
774 		.entity_types = entity_types_##inst,				\
775 		.ep_indexes = ep_indexes_##inst,				\
776 		.fb_indexes = fb_indexes_##inst,				\
777 		.as_terminals = as_terminals_##inst,				\
778 		.num_ifaces = ARRAY_SIZE(ep_indexes_##inst),			\
779 		.num_entities = ARRAY_SIZE(entity_types_##inst),		\
780 	};									\
781 	BUILD_ASSERT(ARRAY_SIZE(ep_indexes_##inst) <= 32,			\
782 		"UAC2 implementation supports up to 32 AS interfaces");		\
783 	BUILD_ASSERT(ARRAY_SIZE(entity_types_##inst) <= 255,			\
784 		"UAC2 supports up to 255 entities");				\
785 	DEVICE_DT_DEFINE(DT_DRV_INST(inst), NULL, NULL,				\
786 		&uac2_ctx_##inst, &uac2_cfg_##inst,				\
787 		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
788 		NULL);
DT_INST_FOREACH_STATUS_OKAY(DEFINE_UAC2_CLASS_DATA)789 DT_INST_FOREACH_STATUS_OKAY(DEFINE_UAC2_CLASS_DATA)
790 
791 static size_t clock_frequencies(struct usbd_class_data *const c_data,
792 				const uint8_t id, const uint32_t **frequencies)
793 {
794 	const struct device *dev = usbd_class_get_private(c_data);
795 	size_t count;
796 
797 #define GET_FREQUENCY_TABLE(node, i)						\
798 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
799 		} else if (id == ENTITY_ID(node)) {				\
800 			*frequencies = FREQUENCY_TABLE_NAME(node, i);		\
801 			count = ARRAY_SIZE(FREQUENCY_TABLE_NAME(node, i));	\
802 	))
803 
804 	if (0) {
805 #define SELECT_FREQUENCY_TABLE(i)						\
806 	} else if (dev == DEVICE_DT_GET(DT_DRV_INST(i))) {			\
807 		if (0) {							\
808 			DT_INST_FOREACH_CHILD_VARGS(i, GET_FREQUENCY_TABLE, i)	\
809 		} else {							\
810 			*frequencies = NULL;					\
811 			count = 0;						\
812 		}
813 DT_INST_FOREACH_STATUS_OKAY(SELECT_FREQUENCY_TABLE)
814 	} else {
815 		*frequencies = NULL;
816 		count = 0;
817 	}
818 
819 	return count;
820 }
821