ALSA: usb-audio: Re-read descriptors for Xiaomi 2717:d005

The Xiaomi 2717:d005 USB audio transmitter supports Sound 2 Pro and
Sound 2 Max speakers. This issue was reproduced with two Sound 2 Pro
speakers paired in stereo. After a USB replug, Linux detects the
transmitter and exposes a hardware volume control, but moving the volume
slider changes neither the audible level nor the speakers' volume LEDs.
Windows controls the same speakers with its in-box USB Audio driver.
USB captures show standard UAC2 volume SET_CUR requests on both systems.

Re-reading the device descriptor (18 bytes), configuration header
(9 bytes), and full configuration descriptor (184 bytes on the tested
unit) after 2717:d005 is configured restores hardware volume control.
The USBFS sequence recovered the device after multiple replug tests.
Reading only the device descriptor did not restore volume control.

Perform these reads when snd-usb-audio first probes 2717:d005. Use the
configuration header's wTotalLength for the final read. If a read fails,
warn and continue probing so that playback remains available.

Tested on 7.2.6-zen2-1-zen with the existing userspace workaround
disabled. After a physical USB replug, the quirk ran when 2717:d005
appeared, and both audible volume and the speakers' LEDs followed the
KDE volume slider.

Signed-off-by: Xucheng Pan <panxucc@gmail.com>
Link: https://patch.msgid.link/20260923152552.943151-1-panxucc@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Xucheng Pan 2026-09-23 23:25:52 +08:00 committed by Takashi Iwai
parent 1bbc033983
commit 2d1d019ddd

View File

@ -871,6 +871,49 @@ static int snd_usb_cm1a_boot_quirk(struct usb_device *dev)
return 0;
}
/*
* The Xiaomi audio connector ignores UAC2 volume changes after reconnecting
* until the device and configuration descriptors have been read again.
*/
#define XIAOMI_AUDIO_MAX_CONFIG_SIZE 1024
static void snd_usb_xiaomi_boot_quirk(struct usb_device *dev)
{
u8 *buf __free(kfree) = kmalloc(XIAOMI_AUDIO_MAX_CONFIG_SIZE, GFP_KERNEL);
struct usb_config_descriptor *config;
unsigned int length;
int ret;
if (!buf)
return;
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, buf,
USB_DT_DEVICE_SIZE);
if (ret != USB_DT_DEVICE_SIZE) {
dev_warn(&dev->dev, "device descriptor re-read failed: %d\n", ret);
return;
}
ret = usb_get_descriptor(dev, USB_DT_CONFIG, 0, buf,
USB_DT_CONFIG_SIZE);
if (ret != USB_DT_CONFIG_SIZE) {
dev_warn(&dev->dev, "configuration header re-read failed: %d\n", ret);
return;
}
config = (struct usb_config_descriptor *)buf;
length = le16_to_cpu(config->wTotalLength);
if (length < USB_DT_CONFIG_SIZE ||
length > XIAOMI_AUDIO_MAX_CONFIG_SIZE) {
dev_warn(&dev->dev, "unexpected configuration length: %u\n", length);
return;
}
ret = usb_get_descriptor(dev, USB_DT_CONFIG, 0, buf, length);
if (ret != (int)length)
dev_warn(&dev->dev, "configuration descriptor re-read failed: %d\n", ret);
}
/*
* Some sound cards from Native Instruments are in fact compliant to the USB
* audio standard of version 2 and other approved USB standards, even though
@ -1743,6 +1786,9 @@ int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
return snd_usb_motu_m_series_boot_quirk(dev);
case USB_ID(0x1397, 0x1234): /* Behringer CM1A */
return snd_usb_cm1a_boot_quirk(dev);
case USB_ID(0x2717, 0xd005): /* Xiaomi audio connector */
snd_usb_xiaomi_boot_quirk(dev);
return 0;
}
return 0;