Bug 217501 - Apple USB-C 3.5mm dongle cannot output 41000hz
Summary: Apple USB-C 3.5mm dongle cannot output 41000hz
Status: NEEDINFO
Alias: None
Product: Drivers
Classification: Unclassified
Component: USB (show other bugs)
Hardware: All Linux
: P3 normal
Assignee: Default virtual assignee for Drivers/USB
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-29 06:25 UTC by AT
Modified: 2025-01-04 08:10 UTC (History)
5 users (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments
alsa-info.sh (57.45 KB, text/plain)
2023-05-29 07:11 UTC, AT
Details
lspci (4.10 KB, text/plain)
2023-05-29 07:11 UTC, AT
Details
lsmod (5.86 KB, text/plain)
2023-05-29 07:12 UTC, AT
Details
usb descriptor info of Apple USB-C dongle (26.06 KB, text/plain)
2023-06-11 16:15 UTC, Tatsuyuki Ishi
Details

Description AT 2023-05-29 06:25:48 UTC
Overview:
With an A2049 Apple USB-C to 3.5mm DAC dongle, I have the same issue as outlined in this link: ALSA won't detect 44100Hz as an available sample rate:
https://github.com/mikebrady/shairport-sync/issues/1504


Steps to Reproduce:
Play a 44.1Khz audio file.


Actual Results:
Pipewire reports that the output is locked to 48000hz, and ALSA reports that this is the only detected supported rate:

$ cat /proc/asound/card0/stream0
Playback:
  Status: Running
    Interface = 1
    Altset = 1
    Packet Size = 288
    Momentary freq = 48000 Hz (0x30.0000)
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 0x02 (2 OUT) (SYNC)
    Rates: 48000 - 48000 (continuous)
    Bits: 0
    Channel map: FL FR
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 0x02 (2 OUT) (SYNC)
    Rates: 48000 - 48000 (continuous)
    Bits: 0
    Channel map: FL FR


Expected Result:
It should be switching between 44100-48000hz, the only two rates it supports.


Build Date and Hardware:
Running Arch Linux with kernel 6.3.4-arch1-1, alsa-lib 1.2.9-1.
AMD Ryzen 3600 on a MSI B450M Mortar Max motherboard


Additional Information:
It seems like a regression between Linux 4.x and 5.x, and halfway through the above thread the user "quantonian" added the device to the ALSA quirks table and has posted a patch:

https://github.com/mikebrady/shairport-sync/issues/1504#issuecomment-1193355701

Thanks if this can be fixed in the kernel. The dongle in question is US $9:
https://www.apple.com/shop/product/MU7E2AM/A/usb-c-to-35-mm-headphone-jack-adapter
Comment 1 Bagas Sanjaya 2023-05-29 07:06:06 UTC
(In reply to AT from comment #0)
> Overview:
> With an A2049 Apple USB-C to 3.5mm DAC dongle, I have the same issue as
> outlined in this link: ALSA won't detect 44100Hz as an available sample rate:
> https://github.com/mikebrady/shairport-sync/issues/1504
> 
> 
> Steps to Reproduce:
> Play a 44.1Khz audio file.
> 
> 
> Actual Results:
> Pipewire reports that the output is locked to 48000hz, and ALSA reports that
> this is the only detected supported rate:
> 
> $ cat /proc/asound/card0/stream0
> Playback:
>   Status: Running
>     Interface = 1
>     Altset = 1
>     Packet Size = 288
>     Momentary freq = 48000 Hz (0x30.0000)
>   Interface 1
>     Altset 1
>     Format: S24_3LE
>     Channels: 2
>     Endpoint: 0x02 (2 OUT) (SYNC)
>     Rates: 48000 - 48000 (continuous)
>     Bits: 0
>     Channel map: FL FR
>   Interface 1
>     Altset 2
>     Format: S16_LE
>     Channels: 2
>     Endpoint: 0x02 (2 OUT) (SYNC)
>     Rates: 48000 - 48000 (continuous)
>     Bits: 0
>     Channel map: FL FR
> 
> 
> Expected Result:
> It should be switching between 44100-48000hz, the only two rates it supports.
> 
> 
> Build Date and Hardware:
> Running Arch Linux with kernel 6.3.4-arch1-1, alsa-lib 1.2.9-1.
> AMD Ryzen 3600 on a MSI B450M Mortar Max motherboard
> 
> 
> Additional Information:
> It seems like a regression between Linux 4.x and 5.x, and halfway through
> the above thread the user "quantonian" added the device to the ALSA quirks
> table and has posted a patch:
> 
> https://github.com/mikebrady/shairport-sync/issues/1504#issuecomment-
> 1193355701
> 
> Thanks if this can be fixed in the kernel. The dongle in question is US $9:
> https://www.apple.com/shop/product/MU7E2AM/A/usb-c-to-35-mm-headphone-jack-
> adapter

lspci? lsmod?
Comment 2 AT 2023-05-29 07:11:23 UTC
Created attachment 304346 [details]
alsa-info.sh
Comment 3 AT 2023-05-29 07:11:47 UTC
Created attachment 304347 [details]
lspci
Comment 4 AT 2023-05-29 07:12:22 UTC
Created attachment 304348 [details]
lsmod
Comment 5 AT 2023-05-29 07:21:18 UTC
Have attached those along with the output of the alsa-info.sh script which includes USB info.

Here's some further notes linked from within the Github issue, same 48000-48000 rates reported with Raspbian kernel 5.10 but 44100,48000 reported with kernel 4.19:

https://www.audiosciencereview.com/forum/index.php?threads/review-apple-vs-google-usb-c-headphone-adapters.5541/page-32
Comment 6 Bagas Sanjaya 2023-05-29 07:40:23 UTC
Can you perform bisection between v4.9 and v5.10?
Comment 7 AT 2023-05-29 08:38:01 UTC
(In reply to Bagas Sanjaya from comment #6)
> Can you perform bisection between v4.9 and v5.10?

I have an old kernel 5.6.0 built from AMDGPU drm-next (out of necessity when I assembled this computer), and it still has the same issue with rates 48000-48000. Sorry, can't go much further back without GPU crashing/unsupported.
Comment 8 Takashi Iwai 2023-06-09 14:11:54 UTC
Could you try the older kernel (at best git bisect) without native graphics?  Only for debugging the USB-audio, we don't need the proper graphics, but EFI framebuffer should suffice.
Comment 9 Tatsuyuki Ishi 2023-06-11 15:55:19 UTC
Looking at the commit log, a reasonable guess is BADD support [1].

The spec literally says:

All BADD AudioStreaming interfaces shall only support 48 kHz. They shall support both 16 bits and 24 bits sample sizes.

though, not sure if that implies a capability downgrade from previous versions.

[1]: https://github.com/torvalds/linux/commit/17156f23e93c0f59e06dd2aaffd06221341caaee
Comment 10 Tatsuyuki Ishi 2023-06-11 16:15:15 UTC
Created attachment 304396 [details]
usb descriptor info of Apple USB-C dongle

It seems we're indeed selecting the BADD config when another UAC3 config exists.

In the attached descriptor info, BADD is bConfigurationValue=2, while bConfigurationValue=3 has more advanced control over clocks and others.
Comment 11 Tatsuyuki Ishi 2023-06-11 16:15:41 UTC
The current logic selects the *first* UAC3 config, see [1].

[1]: https://github.com/torvalds/linux/blob/022ce8862dff83c859089cd14bc4dca0733e2f90/drivers/usb/core/generic.c#L121-L144
Comment 12 AT 2023-06-12 01:05:06 UTC
(In reply to Takashi Iwai from comment #8)
> Could you try the older kernel (at best git bisect) without native graphics?
> Only for debugging the USB-audio, we don't need the proper graphics, but EFI
> framebuffer should suffice.

Sorry will be heading away from home for the next few weeks, but it sounds like progress is being made with your BADD/UAC3 suggestion, thanks!
Comment 13 Takashi Iwai 2023-06-12 07:23:45 UTC
(In reply to Tatsuyuki Ishi from comment #9)
> Looking at the commit log, a reasonable guess is BADD support [1].

Yes, it would explain the behavior.  But the puzzling part is that I don't remember any changes related with BADD profile selection in the recent changes.
Maybe the "regression" meant here was so old (about 2018/2019), the introduction of BADD profile support in 4.18 kernel.
Comment 14 Will Mortensen 2025-01-02 09:02:21 UTC
(In reply to Takashi Iwai from comment #13)
> (In reply to Tatsuyuki Ishi from comment #9)
> > Looking at the commit log, a reasonable guess is BADD support [1].
> 
> Yes, it would explain the behavior.  But the puzzling part is that I don't
> remember any changes related with BADD profile selection in the recent
> changes.
> Maybe the "regression" meant here was so old (about 2018/2019), the
> introduction of BADD profile support in 4.18 kernel.

I think the regression was not the BADD changes per se, but rather these commits attempting to prefer the UAC3 configuration(s):

https://github.com/torvalds/linux/commit/f13912d3f014a7f2fa5c35d25ee8c3f96bda6272
https://github.com/torvalds/linux/commit/ff2a8c532c14fd22fb26a36574d9ff199afbbe54
https://github.com/torvalds/linux/commit/25b0161450363ed7fe9fe618cda202e15817311a

Looking at the descriptors from comment #10 (and on my own adapters), there are three configurations in this order: UAC2, UAC3 BADD, full UAC3. This seems to accord with the UAC3 spec which says:

> The first USB Configuration descriptor (index 0) exposed by the Device shall
> contain an Audio Interface Association (AIA), which is compliant with ADC 1.0
> or ADC 2.0. [...] If the Audio Function contains at least one USB Audio
> Streaming Interface, the Device shall have another Configuration descriptor
> that exposes an AIA which is BADD 3.0 compliant. A Device shall only have a
> single AIA of this type. However, this same BADD compliant AIA may need to be
> duplicated in more than one Configuration descriptor. [...] The Device may
> have one or more Configurations that expose one or more AIAs which shall be
> compliant with ADC 3.0. This way the Audio Function may provide functionality
> beyond what is available in BADD 3.0 operating mode. 

So the spec requires the UAC1/2 config to come first, and then the BADD and any other UAC3 configs in some order. (It doesn't seem to require the BADD to come before the other UAC3 configs.)

I think prior to the above commits, the first (UAC2) config was selected, which provided more or less full functionality. After each of those commits, the BADD config was selected instead, regressing the available features. I don't think the full UAC3 config was ever selected. It seems like other UAC3 devices would encounter the same issue unless they put the full UAC3 config first.

If I understand correctly, the distinction between BADD vs. full UAC3 is indicated only in the IAD. It seems like in order to find the relevant IAD from within usb_choose_configuration(), we would need to do something like find_iad() from drivers/usb/core/message.c? Or should we just use the config's first IAD since usb_choose_configuration() is only looking at the first interface anyway? I'm totally new to USB but I guess the whole function is a bit of a hack regardless? :-)
Comment 15 Takashi Iwai 2025-01-02 09:48:43 UTC
A good spot after long time!

As it seems like an issue in the USB core side, let's toss to USB devs.

Note You need to log in before you can comment on or make changes to this bug.