usb: device_next: uac2: Convert class to descriptor set Convert to new descriptor interface, present only Full-Speed descriptors to the USB stack. Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
diff --git a/subsys/usb/device_next/class/usbd_uac2.c b/subsys/usb/device_next/class/usbd_uac2.c index b04ac2e..d8b5ed0 100644 --- a/subsys/usb/device_next/class/usbd_uac2.c +++ b/subsys/usb/device_next/class/usbd_uac2.c
@@ -86,18 +86,19 @@ /* UAC2 device constant data */ struct uac2_cfg { struct usbd_class_node *const node; + const struct usb_desc_header **descriptors; /* Entity 1 type is at entity_types[0] */ const entity_type_t *entity_types; - /* Array of offsets to data endpoint bEndpointAddress in descriptors. - * First AudioStreaming interface is at ep_offsets[0]. Offset is 0 if + /* Array of indexes to data endpoint descriptor in descriptors set. + * First AudioStreaming interface is at ep_indexes[0]. Index is 0 if * the interface is external interface (Type IV), i.e. no endpoint. */ - const uint16_t *ep_offsets; - /* Same as ep_offsets, but for explicit feedback endpoints. */ - const uint16_t *fb_offsets; + const uint16_t *ep_indexes; + /* Same as ep_indexes, but for explicit feedback endpoints. */ + const uint16_t *fb_indexes; /* First AudioStreaming interface Terminal ID is at as_terminals[0]. */ const uint8_t *as_terminals; - /* Number of interfaces (ep_offsets, fb_offset and as_terminals size) */ + /* Number of interfaces (ep_indexes, fb_indexes and as_terminals size) */ uint8_t num_ifaces; /* Number of entities (entity_type array size) */ uint8_t num_entities; @@ -120,15 +121,13 @@ { const struct device *dev = node->data->priv; const struct uac2_cfg *cfg = dev->config; - const uint8_t *desc = node->data->desc; + const struct usb_desc_header *desc = NULL; - if ((as_idx < cfg->num_ifaces) && cfg->ep_offsets[as_idx]) { - return CONTAINER_OF(&desc[cfg->ep_offsets[as_idx]], - const struct usb_ep_descriptor, - bEndpointAddress); + if ((as_idx < cfg->num_ifaces) && cfg->ep_indexes[as_idx]) { + desc = cfg->descriptors[cfg->ep_indexes[as_idx]]; } - return NULL; + return (const struct usb_ep_descriptor *)desc; } static const struct usb_ep_descriptor * @@ -136,36 +135,36 @@ { const struct device *dev = node->data->priv; const struct uac2_cfg *cfg = dev->config; - const uint8_t *desc = node->data->desc; + const struct usb_desc_header *desc = NULL; - if ((as_idx < cfg->num_ifaces) && cfg->fb_offsets[as_idx]) { - return CONTAINER_OF(&desc[cfg->fb_offsets[as_idx]], - const struct usb_ep_descriptor, - bEndpointAddress); + if ((as_idx < cfg->num_ifaces) && cfg->fb_indexes[as_idx]) { + desc = cfg->descriptors[cfg->fb_indexes[as_idx]]; } - return NULL; + return (const struct usb_ep_descriptor *)desc; } static int ep_to_as_interface(const struct device *dev, uint8_t ep, bool *fb) { const struct uac2_cfg *cfg = dev->config; - const uint8_t *desc = cfg->node->data->desc; + const struct usb_ep_descriptor *desc; for (int i = 0; i < cfg->num_ifaces; i++) { - if (!cfg->ep_offsets[i]) { + if (!cfg->ep_indexes[i]) { /* If there is no data endpoint there cannot be feedback * endpoint. Simply skip external interfaces. */ continue; } - if (ep == desc[cfg->ep_offsets[i]]) { + desc = get_as_data_ep(cfg->node, i); + if (desc && (ep == desc->bEndpointAddress)) { *fb = false; return i; } - if (cfg->fb_offsets[i] && (ep == desc[cfg->fb_offsets[i]])) { + desc = get_as_feedback_ep(cfg->node, i); + if (desc && (ep == desc->bEndpointAddress)) { *fb = true; return i; } @@ -226,15 +225,16 @@ void *data, uint16_t size) { const struct uac2_cfg *cfg = dev->config; - const uint8_t *desc = cfg->node->data->desc; struct uac2_ctx *ctx = dev->data; struct net_buf *buf; + const struct usb_ep_descriptor *desc; uint8_t ep = 0; int as_idx = terminal_to_as_interface(dev, terminal); int ret; - if ((as_idx >= 0) && cfg->ep_offsets[as_idx]) { - ep = desc[cfg->ep_offsets[as_idx]]; + desc = get_as_data_ep(cfg->node, as_idx); + if (desc) { + ep = desc->bEndpointAddress; } if (!ep) { @@ -387,7 +387,7 @@ LOG_DBG("iface %d alt %d", iface, alternate); - iad = (const struct usb_association_descriptor *)node->data->desc; + iad = (const struct usb_association_descriptor *)cfg->descriptors[0]; /* AudioControl interface (bFirstInterface) doesn't have alternate * configurations, therefore the iface must be AudioStreaming. @@ -617,8 +617,8 @@ { struct device *dev = node->data->priv; const struct usb_ep_descriptor *data_ep; + const struct usb_ep_descriptor *feedback_ep; const struct uac2_cfg *cfg = dev->config; - const uint8_t *desc = node->data->desc; struct uac2_ctx *ctx = dev->data; int as_idx; @@ -637,7 +637,8 @@ } /* Skip interfaces without explicit feedback endpoint */ - if (cfg->fb_offsets[as_idx] == 0) { + feedback_ep = get_as_feedback_ep(node, as_idx); + if (feedback_ep == NULL) { continue; } @@ -658,11 +659,24 @@ * previous SOF is "gone" even if USB host did not attempt to * read it). */ - write_explicit_feedback(node, desc[cfg->fb_offsets[as_idx]], + write_explicit_feedback(node, feedback_ep->bEndpointAddress, cfg->as_terminals[as_idx]); } } +static void *uac2_get_desc(struct usbd_class_node *const node, + const enum usbd_speed speed) +{ + struct device *dev = usbd_class_get_private(node); + const struct uac2_cfg *cfg = dev->config; + + if (speed == USBD_SPEED_FS) { + return cfg->descriptors; + } + + return NULL; +} + static int uac2_init(struct usbd_class_node *const node) { struct device *dev = node->data->priv; @@ -681,6 +695,7 @@ .control_to_host = uac2_control_to_host, .request = uac2_request, .sof = uac2_sof, + .get_desc = uac2_get_desc, .init = uac2_init, }; @@ -698,15 +713,15 @@ ENTITY_TYPE_INVALID \ )) \ , /* Comma here causes unknown types to fail at compile time */ -#define DEFINE_AS_EP_OFFSETS(node) \ +#define DEFINE_AS_EP_INDEXES(node) \ IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), ( \ COND_CODE_1(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), \ - (UAC2_DESCRIPTOR_AS_DATA_EP_OFFSET(node),), (0,)) \ + (UAC2_DESCRIPTOR_AS_DATA_EP_INDEX(node),), (0,)) \ )) -#define DEFINE_AS_FB_OFFSETS(node) \ +#define DEFINE_AS_FB_INDEXES(node) \ IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), ( \ COND_CODE_1(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), \ - (UAC2_DESCRIPTOR_AS_FEEDBACK_EP_OFFSET(node),), (0,)) \ + (UAC2_DESCRIPTOR_AS_FEEDBACK_EP_INDEX(node),), (0,)) \ )) #define DEFINE_AS_TERMINALS(node) \ IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), ( \ @@ -725,11 +740,11 @@ static const entity_type_t entity_types_##i[] = { \ DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_ENTITY_TYPES) \ }; \ - static const uint16_t ep_offsets_##i[] = { \ - DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_EP_OFFSETS) \ + static const uint16_t ep_indexes_##i[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_EP_INDEXES) \ }; \ - static const uint16_t fb_offsets_##i[] = { \ - DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_FB_OFFSETS) \ + static const uint16_t fb_indexes_##i[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_FB_INDEXES) \ }; \ static const uint8_t as_terminals_##i[] = { \ DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_TERMINALS) \ @@ -739,26 +754,26 @@ #define DEFINE_UAC2_CLASS_DATA(inst) \ DT_INST_FOREACH_CHILD(inst, VALIDATE_NODE) \ static struct uac2_ctx uac2_ctx_##inst; \ - static uint8_t uac2_descriptor_##inst[] = { \ - UAC2_DESCRIPTORS(DT_DRV_INST(inst)) \ - 0x00, 0x00 /* terminator required by USBD stack */ \ + UAC2_DESCRIPTOR_ARRAYS(DT_DRV_INST(inst)) \ + static const struct usb_desc_header *uac2_descriptors_##inst[] = { \ + UAC2_DESCRIPTOR_PTRS(DT_DRV_INST(inst)) \ }; \ static struct usbd_class_data uac2_class_##inst = { \ - .desc = (struct usb_desc_header *)uac2_descriptor_##inst, \ .priv = (void *)DEVICE_DT_GET(DT_DRV_INST(inst)), \ }; \ USBD_DEFINE_CLASS(uac2_##inst, &uac2_api, &uac2_class_##inst); \ DEFINE_LOOKUP_TABLES(inst) \ static const struct uac2_cfg uac2_cfg_##inst = { \ .node = &uac2_##inst, \ + .descriptors = uac2_descriptors_##inst, \ .entity_types = entity_types_##inst, \ - .ep_offsets = ep_offsets_##inst, \ - .fb_offsets = fb_offsets_##inst, \ + .ep_indexes = ep_indexes_##inst, \ + .fb_indexes = fb_indexes_##inst, \ .as_terminals = as_terminals_##inst, \ - .num_ifaces = ARRAY_SIZE(ep_offsets_##inst), \ + .num_ifaces = ARRAY_SIZE(ep_indexes_##inst), \ .num_entities = ARRAY_SIZE(entity_types_##inst), \ }; \ - BUILD_ASSERT(ARRAY_SIZE(ep_offsets_##inst) <= 32, \ + BUILD_ASSERT(ARRAY_SIZE(ep_indexes_##inst) <= 32, \ "UAC2 implementation supports up to 32 AS interfaces"); \ BUILD_ASSERT(ARRAY_SIZE(entity_types_##inst) <= 255, \ "UAC2 supports up to 255 entities"); \