[PATCH v2 0/2] ALSA: usb-audio: the Topping M62's vendor controls
From: Mikhail Gavrilov
Date: Sun Aug 23 2026 - 10:22:39 EST
v2, and the road is the mixer quirk. The HID driver is dropped from
this posting; it is in the RFC thread if anyone wants to argue for it.
The cost of this road is accepted knowingly: with the hid_ignore_list
entry there is no hidraw node, so a future Linux control application
would have no channel of its own to the card.
Changes since the RFC:
- guard() and __free() as you asked. The spinlock is guard() where a
whole function holds it and scoped_guard() elsewhere; one goto that
would have jumped out of a guarded scope is gone, replaced by a
flag, since the cleanup runs either way but the jump reads like a
trap.
- The OTG input's gain is in. It was the one gap the RFC cover letter
named: it has no front panel control, so it never announced itself.
A capture of the vendor application moving it names it target 0x27
on the same taper family as Bluetooth, and the indices it dwelt on
match the decibels it displayed.
- The subscription is renewed every two seconds. It lapses: a
listener that subscribed once got the meters and the identification
block and then very little, while one that kept repeating got the
gains too, about five seconds in. The vendor application does the
same.
- New in 2/2: the outputs' source selectors, as enumerated controls.
A correction to my own follow-up, which said the HID road leaves a
hidraw node open for a future vendor application while the quirk closes
it. Half of that is wrong: the HID driver as posted calls
hid_hw_start(hdev, 0), which creates no hidraw either. It would take
one word to fix there and cannot be fixed on this road at all, so the
comparison stands, but the archive should not carry a claim the code
did not support.
Which raises a form neither posting covered: snd-usb-audio could
register the hid_driver itself. usbhid stays the transport, so hidraw
survives and no hid_ignore_list entry is needed; the controls still
land on the card the device already has, because it is all one module
holding the mixer pointer; and the claim helper in card.c goes away.
The cost is that snd-usb-audio would depend on the HID core, and I find
no precedent for that direction -- the reverse exists, hid-prodikeys
registers a card of its own. The probe-order and disconnect questions
do not disappear, but they stay inside one module. I mention it rather
than implement it: you have picked a road, and I would rather ask
whether this is a better one than send a fourth variant unasked.
About 2/2 and one thing in it I am not comfortable with. Each output
listens to one source chosen inside the card -- a mix, an input, or one
playback bus straight from USB -- and the device NEVER reports that
choice. Not to this driver, and not to the vendor's own application,
which pushes its whole workspace on connect rather than reading
anything. So the control can be written but not read, and the item list
starts with "Unknown", which is what it shows until a hand has chosen;
selecting it is refused. If there is a convention for this that I have
missed, I would rather use it.
Both patches are on mainline 98f21c54f995 and have been exercised on
the hardware: values arrive by themselves after probe, a front panel
knob still reaches the driver ten minutes later, and a write reaches
the analogue stage -- recording one source at gain 30 and at gain 60
differs by 29.7 dB against the 30.0 dB the taper table predicts, which
also confirms the decoded scale. For 2/2, the audible test: point an
output away from the bus being played and it goes silent, point it back
and the sound returns. Tested on a KASAN and lockdep kernel, including
unplug while a stream was running; no reports.
Mikhail Gavrilov (2):
ALSA: usb-audio: expose the Topping M62's analogue gains as mixer
controls
ALSA: usb-audio: let the M62's outputs say what they listen to
MAINTAINERS | 6 +
drivers/hid/hid-ids.h | 3 +
drivers/hid/hid-quirks.c | 2 +
sound/usb/Makefile | 1 +
sound/usb/card.c | 14 +
sound/usb/mixer_quirks.c | 5 +
sound/usb/mixer_topping.c | 636 ++++++++++++++++++++++++++++++++++++++
sound/usb/mixer_topping.h | 7 +
sound/usb/usbaudio.h | 3 +
9 files changed, 677 insertions(+)
create mode 100644 sound/usb/mixer_topping.c
create mode 100644 sound/usb/mixer_topping.h
base-commit: 2709dd5ae32f0828f386327c76bba9f39f63a1c6
--
2.55.0