I have a Topping D30Pro USB DAC which works (mostly) fine once logged in, but during boot (systemd), right around “Reached Target Sound Card”, it starts outputting, what I’d have to guess, a continuous sawtooth sound wave. My workaround has been to mute the device until I’m logged in, because it’s loud. In any case, the login process fixes the issue.
I’ve lived with this since I bought the device more than a year ago. Recently, I’ve found myself motivated to find out the root cause.
Right around it occurs, dmesg
outputs the following:
usb 1-8: 1:3 : unsupported format bits 0x100000000
The code responsible for this line is here in the kernel. As far as I understand, the format of the third alternate setting of the first interface, which is DSD, cannot be recognised:
$ cat /proc/asound/card0/stream0
Topping D30 Pro at usb-0000:00:14.0-8, high speed : USB Audio
Playback:
Status: Running
Interface = 1
Altset = 1
Packet Size = 72
Momentary freq = 44099 Hz (0x5.8328)
Feedback Format = 16.16
Interface 1
Altset 1
Format: S32_LE
Channels: 2
...
Interface 1
Altset 3
Format: SPECIAL DSD_U32_BE
Channels: 2
Endpoint: 0x01 (1 OUT) (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
Data packet interval: 125 us
Bits: 32
DSD raw: DOP=0, bitrev=0
Channel map: FL FR
Sync Endpoint: 0x81 (1 IN)
Sync EP Interface: 1
Sync EP Altset: 3
Implicit Feedback Mode: No
The thing is, I can play DSD files just fine with PipeWire:
$ pw-dsdplay DSD128.dsf -v
dsffile: opened file "DSD128.dsf" channels:2 rate:5644800 samples:7098793984 bitorder:lsb
...
At this point, my best guess is that the quirk applied for my device isn’t working during boot. Why it only happens during boot, I have no idea.
For what it’s worth; there is absolutely no issue when booting/using FreeBSD or Windows. It does happen whichever Linux distro I’ve tried to boot using LiveCD (Debian, Fedora, Arch, Ubuntu, …) so it seems distro-agnostic, but I’m on 6.4.12-arch1-1
.
As my next step, I was thinking about compiling a new kernel with added print statements for the structs used in the function, but then I found out about Kprobe-based Event Tracing, which seems to be a better way to debug, but it seems the events I’m trying to trace aren’t supported and I would have to compile anyway.
Is there an easier way to debug this that I’m not aware of? Maybe a flag I overlooked? One that, ideally, doesn’t involve endless reboots and compilations? I have never had the issue anywhere else, though, so not sure how it would be possible.
Thanks!