Linux Input/HID development
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Cc: linux-sound@vger.kernel.org, tiwai@suse.com, perex@perex.cz,
	g@b4.vu, jikos@kernel.org, bentiss@kernel.org,
	linux-input@vger.kernel.org
Subject: Re: snd-usb-audio: exposing a vendor HID control channel as mixer controls (Topping M62, 152a:875c)
Date: Thu, 13 Aug 2026 09:24:10 +0200	[thread overview]
Message-ID: <87y0eaxz39.wl-tiwai@suse.de> (raw)
In-Reply-To: <20260812171036.144085-1-mikhail.v.gavrilov@gmail.com>

On Wed, 12 Aug 2026 19:10:34 +0200,
Mikhail Gavrilov wrote:
> 
> Hello,
> 
> I would like to add ALSA mixer controls for the analogue input gain of a
> USB audio interface whose control channel is a vendor-specific HID
> interface, and I would like to agree on the shape before writing code,
> because it crosses into drivers/hid.
> 
> The device is a Topping Professional M62, USB 152a:875c. In its
> multichannel modes it presents 10 playback and 16 capture channels on
> interfaces 1 and 2, a DFU interface, and interface 4 of class 3 (HID)
> with a vendor-defined usage page, one 16-byte Input report and one
> 16-byte Output report, and no report IDs.
> 
> The problem: the microphone preamplifier gain, 0..88 dB per the
> specification, is not reachable through ALSA. The card does expose a
> 'Mic Capture Volume', but a gain ladder measured in silence shows that
> control to be a digital trim after the converter. The recorded noise
> floor is flat at about -172 dBFS at the bottom of its range, far below
> any converter's own noise floor, so what is being measured there is the
> sample word running out of bits; above that the floor rises with unity
> slope, i.e. one fixed analogue noise being divided down. The analogue
> stage is reachable only over the HID interface, which is what the
> vendor's own application uses.
> 
> I have the protocol. It was reverse engineered from captures of the
> vendor application's traffic, the same way sound/usb/mixer_scarlett2.c
> describes in its header. Frames are 15 bytes:
> 
>   22 33 | 20 01 01 | target | property | s32 big endian | CRC | 66 77
> 
> with CRC-16/MODBUS over bytes 2..10, stored big endian. Rebuilding
> every frame of a capture from the decoded fields reproduces all 2619 of
> them byte for byte. Inbound reports are that frame plus one pad byte.
> The device stays silent until the host sends a subscription frame,
> after which it reports every state change including front-panel button
> presses, and it answers a "report your state" frame with a full dump.
> The analogue gain of each microphone input is a single property carrying
> whole decibels, 0..88, so a plain TLV_DB_SCALE fits it.
> 
> The constraint, and my question. This device accepts nothing on the
> control pipe: SET_REPORT and GET_REPORT both stall with EPIPE, for
> report types Output, Input and Feature alike. So the pattern used by
> snd_soundblaster_e1_switch_update() in sound/usb/mixer_quirks.c, which
> sends HID_REQ_SET_REPORT through snd_usb_ctl_msg(), is not available
> here. The only usable transport is the interrupt endpoints of interface
> 4, which usbhid binds.
> 
> Would it be acceptable for a mixer quirk in sound/usb to own that
> interface? Concretely: an entry in hid_ignore_list so that usbhid stays
> away, the quirk claiming interface 4, an interrupt IN URB whose
> completion handler parses the vendor frame, updates cached values and
> calls snd_ctl_notify(), and usb_interrupt_msg() in the put callbacks.
> The notification half looks like what snd_usb_mixer_status_create()
> already does for the audio control interface's status endpoint. Or would
> you prefer a different layout for this?
> 
> A first patch would be deliberately minimal: two controls for the
> analogue gain of the two microphone inputs, with a dB TLV, and nothing
> else. The line-level inputs and the outputs use index scales with a
> piecewise taper, which I have measured but would rather submit
> separately.
> 
> For context, an ALSA UCM configuration for the same card is already
> proposed as alsa-project/alsa-ucm-conf#826. That is what would designate
> the new control as the capture volume, so that userspace moves the
> hardware gain instead of the digital trim.
> 
> I can post the full protocol notes and the captures if that would be
> useful.

I believe we can judge better with the comparison of the actual code.
You can try implementing PoC's for both usb-audio mixer quirk and a
HID driver, then compare which would fit better.  If either of them
looks significantly harder, you don't fulfill the implementation, of
course.

My gut feeling is that we can take it as a mixer quirk, but it really
depends on the complexity.


thanks,

Takashi

      reply	other threads:[~2026-08-13  7:24 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 17:10 snd-usb-audio: exposing a vendor HID control channel as mixer controls (Topping M62, 152a:875c) Mikhail Gavrilov
2026-08-13  7:24 ` Takashi Iwai [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y0eaxz39.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=bentiss@kernel.org \
    --cc=g@b4.vu \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=mikhail.v.gavrilov@gmail.com \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox