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