Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions subsys/usb/device/class/audio/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,56 @@
common);

switch (cb_status) {
case USB_DC_CONNECTED: {
/* Patch bInterval in the isochronous endpoint descriptor once
* the bus speed is known, before the host reads the config
* descriptor.
*
* bInterval=4 interpretation depends on bus speed:
* High-speed: 2^(4-1) = 8 micro-frames = 1 ms → correct
* Full-speed: 4 frames = 4 ms → drain rate drops to 25%,
* causing ring buffer overflow and broken audio.
*
* Walk: std_ac_interface → cs_ac_interface (desc_hdr) →
* input_terminal → feature_unit → output_terminal →
* as_alt_0 → as_alt_1 → as_cs_interface → format → std_ep
*
* param points to the speed byte: 0 = High-speed, 1 = Full-speed
* (from DSTS.ENUMSPD in usb_dw_handle_enum_done). */

Check warning on line 379 in subsys/usb/device/class/audio/audio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

BLOCK_COMMENT_STYLE

subsys/usb/device/class/audio/audio.c:379 Block comments use a trailing */ on a separate line
if (param != NULL) {
bool is_full_speed = (*param != 0);
const struct cs_ac_if_descriptor *hdr =
audio_dev_data->desc_hdr;
const uint8_t *p = (const uint8_t *)hdr;

/* Walk one streaming interface chain (first IN ep). */
p += hdr->bLength; /* → input_terminal */
p += p[0]; /* → feature_unit */
p += p[0]; /* → output_terminal (feature_unit is variable-length) */

Check warning on line 389 in subsys/usb/device/class/audio/audio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE_COMMENT

subsys/usb/device/class/audio/audio.c:389 line length of 115 exceeds 100 columns
p += OUTPUT_TERMINAL_DESC_SIZE; /* → as_alt_0 (passive, bNumEndpoints=0) */

Check warning on line 390 in subsys/usb/device/class/audio/audio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE_COMMENT

subsys/usb/device/class/audio/audio.c:390 line length of 101 exceeds 100 columns
p += USB_PASSIVE_IF_DESC_SIZE; /* → as_alt_1 (active, bNumEndpoints=1) */
p += USB_PASSIVE_IF_DESC_SIZE; /* → as_cs_interface */
p += p[0]; /* → format */
p += p[0]; /* → std_ep */
/* p now points at std_ep (std_as_ad_endpoint_descriptor) */
struct std_as_ad_endpoint_descriptor *ep =
(struct std_as_ad_endpoint_descriptor *)p;

/* Full-speed: bInterval = 1 → poll every frame (1 ms).
* High-speed: bInterval = 4 → poll every 2^(4-1)=8 µf (1 ms). */

Check warning on line 400 in subsys/usb/device/class/audio/audio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

BLOCK_COMMENT_STYLE

subsys/usb/device/class/audio/audio.c:400 Block comments use a trailing */ on a separate line
ep->bInterval = is_full_speed ? 1U : 4U;

/* NOTE: n==2 (bidirectional headset) has a different
* descriptor layout (two extra terminal + feature_unit
* blocks before the first streaming interface); it is not
* handled here because the current UAC use-case is
* Microphone-only (bInCollection == 1). */

Check warning on line 407 in subsys/usb/device/class/audio/audio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

BLOCK_COMMENT_STYLE

subsys/usb/device/class/audio/audio.c:407 Block comments use a trailing */ on a separate line

LOG_INF("USB audio: %s-speed, bInterval patched to %u",
is_full_speed ? "Full" : "High", ep->bInterval);
}
break;
}
case USB_DC_SOF:
audio_dc_sof(cfg, audio_dev_data);
break;
Expand Down
Loading