Re: [PATCH v8 0/2] ALSA: usb-audio: the Topping M62's vendor controls

From: Mikhail Gavrilov

Date: Thu Sep 03 2026 - 06:38:30 EST


On Thu, 03 Sep 2026 12:02:57 +0200, Takashi Iwai wrote:
>
> > Would you rather see this as a driver-local clear, as
> > HID_CONNECT_DRIVER plus the clear, or as something usbhid ought to
> > offer to drivers that resynchronise on resume?
>
> I think it's rather a question to HID people...

Jiri, Benjamin -- putting it to you then, with enough context to answer
it without reading the rest of the thread. The wider design question,
whether this belongs in a HID driver at all, is settled with Takashi
upstream in this thread; what follows is narrower than that.

The device is a Topping M62 USB audio interface, 152a:875c. Its
analogue gains, output volumes and source selectors are not described
by the USB Audio Class; they are reached over a vendor protocol on a
HID-class interface whose report descriptor is a fig leaf -- a Generic
Desktop application collection, eight usages stretched over sixteen
unnamed bytes in and out, no report ID -- so hid-generic can only make
a nonexistent pointer of it. The plan under discussion is a small HID
driver that speaks that protocol and hands the values to snd-usb-audio
as mixer controls. It wants raw input reports and nothing else: no
input device, no hiddev.

The trouble is that asking usbhid for input reports arms the device for
remote wakeup, and there is no way to ask for one without the other.
usbhid_open() sets

usbhid->intf->needs_remote_wakeup = 1;

and usbhid_start() sets the same on the HID_QUIRK_ALWAYS_POLL path, so
both roads to hid_start_in() go through it.

This card does not offer remote wakeup: bmAttributes is 0xc0, and
there is no power/wakeup attribute under its sysfs node, so
device_can_wakeup() is false. usb_suspend_both() then refuses
autosuspend, and not merely for that interface:

if (w && !device_can_wakeup(&udev->dev)) {
dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n");
return -EOPNOTSUPP;
}

So binding this driver would forbid runtime suspend to the whole
device, including its audio interfaces. An earlier revision of this
series had to fix runtime suspend once already, and I would rather not
hand it back.

What makes this feel like the wrong flag rather than an unlucky device
is that the driver does not depend on the device to wake anything. The
card stops reporting to a host it has not heard from, so the driver's
resume path subscribes again and asks for the whole state; a knob
turned on the front panel while the host slept is picked up on the way
back, by asking, not by being told. A device-initiated wakeup would be
of no use to it.

Three shapes, and I do not know which you would want:

(a) the driver clears intf->needs_remote_wakeup after hid_hw_open(),
with a comment saying why. The field is not private -- cdc-acm
and usbnet both set it directly -- but clearing it from outside
usbhid is unusual enough that I did not want to just post it;

(b) the same, plus HID_CONNECT_DRIVER instead of HID_CONNECT_HIDRAW.
A hidraw open calls hid_hw_open() again and sets the flag back,
so (a) only holds if userspace cannot open the device. That is a
real cost here: the hidraw node is how this protocol was read in
the first place, and how the parts the driver does not expose --
the mixer matrix, the mutes, the EQ -- stay reachable at all;

(c) something in usbhid, so that a driver which resynchronises on
resume can say so once and have both roads to hid_start_in()
honour it. That would cover any driver in this position rather
than this one.

Or a fourth I have not seen: is there an existing way to take raw input
reports from usbhid without arming the device?

I lean to (c) as the honest fix and (a) as what I can post today, but
this is your subsystem and I would rather ask than guess.

--
Mikhail