* [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
@ 2026-05-31 15:45 Rong Zhang
2026-05-31 15:45 ` [PATCH v4 1/3] " Rong Zhang
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Rong Zhang @ 2026-05-31 15:45 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan
Cc: Takashi Iwai, Steve Smith, linux-sound, linux-doc, linux-kernel,
Rong Zhang
Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
identify devices with sticky mixers. Unfortunately, even though most
devices with sticky GET_CUR also have corresponding sticky SET_CUR,
which I actually met more since the commit had been merged, there is
also a rare case that some devices may have volume mixers that responds
to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
check to consider the mixer to be sticky and unnecessarily disable it.
As the sticky check can't distinguish between sticky mixers and working
SET_CUR but broken GET_CUR, add QUIRK_FLAG_MIXER_GET_CUR_BROKEN to tell
that the device should fall into the second category when GET_CUR
returns a constant value. In this case, the sticky check becomes
non-fatal and only disables GET_CUR instead of the whole mixer. The
current volume will then be provided by the internal cache that stores
the last set volume.
An info message prompting users to check MIXER_GET_CUR_BROKEN for
potential sticky mixers is also added, so that users can learn how to do
some experiments to determine what's going on. If the mixer surprisingly
turns out to be non-sticky, they can submit a patch for a new quirk
table entry.
The Sennheiser MOMENTUM 3 and Edifier MF200 need the quirk flag. Though
their UAC mixers respond to SET_CUR by tuning the volume, the
corresponding GET_CUR methods are somehow stubbed and return constant
values, resulting in them being disabled by the sticky check.
Signed-off-by: Rong Zhang <i@rong.moe>
---
Changes in v4:
- Rebase since a patch improving the error path of the sticky check has
been applied earlier
- https://patch.msgid.link/20260531-uac-sticky-error-path-v1-1-12c2329d17ef@rong.moe
- Integrate a follow-up series into this one
- https://patch.msgid.link/20260531-uac-edifier-mf200-v1-0-be69657c3f87@rong.moe
- Link to v3: https://patch.msgid.link/20260529-uac-quirk-get-cur-vol-v3-0-bde363188ca4@rong.moe
Changes in v3:
- Make the log less noisy (thanks Takashi Iwai)
- Do not propagate mixer values written by sanity checks when GET_CUR is
broken, nor restore the garbage backed-up value. Instead, rely on
init_cur_mix_raw() to initialize the mixer properly
- Gate cache invalidation as well, so that the current volume is always
available to userspace
- Update the comment of check_sticky_volume_control()
- Link to v2: https://patch.msgid.link/20260528-uac-quirk-get-cur-vol-v2-0-84d3c8f48150@rong.moe
Changes in v2:
- Turn the approach into a less radical one
- Rename the quirk flag to QUIRK_FLAG_MIXER_GET_CUR_BROKEN
- Add a flag `get_cur_broken' to `struct usb_mixer_elem_info'
- When the sticky check fails, check quirk flags. Gate further GET_CUR
by setting `cval->get_cur_broken' if QUIRK_FLAG_MIXER_GET_CUR_BROKEN
is set, otherwise disable the mixer as usual
- The quirk flag still applies to all mixers, but as long as a mixer
makes the sticky check happy, it won't be affected at all. Only
those mixers with constant GET_CUR values will have their GET_CUR
gated. I assume the impact is minimal, since it's very unlikely a
device would have sticky mixers (broken SET_CUR) along with mixers
with working SET_CUR but broken GET_CUR at the same time
- Link to v1: https://patch.msgid.link/20260527-uac-quirk-get-cur-vol-v1-0-e9362b712e5e@rong.moe
---
Rong Zhang (3):
ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3
ALSA: usb-audio: Add quirk flag for Edifier MF200
Documentation/sound/alsa-configuration.rst | 12 ++++++
sound/usb/mixer.c | 60 +++++++++++++++++++++++++-----
sound/usb/mixer.h | 1 +
sound/usb/quirks.c | 5 +++
sound/usb/usbaudio.h | 13 +++++++
5 files changed, 81 insertions(+), 10 deletions(-)
---
base-commit: f52b1b0506c6a209c10a741d031944d1ed19548c
change-id: 20260527-uac-quirk-get-cur-vol-d0b292c3e796
Thanks,
Rong
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
2026-05-31 15:45 [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Rong Zhang
@ 2026-05-31 15:45 ` Rong Zhang
2026-05-31 15:45 ` [PATCH v4 2/3] ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3 Rong Zhang
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Rong Zhang @ 2026-05-31 15:45 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan
Cc: Takashi Iwai, Steve Smith, linux-sound, linux-doc, linux-kernel,
Rong Zhang
Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
identify devices with sticky mixers. Unfortunately, even though most
devices with sticky GET_CUR also have corresponding sticky SET_CUR,
which I actually met more since the commit had been merged, there is
also a rare case that some devices may have volume mixers that responds
to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
check to consider the mixer to be sticky and unnecessarily disable it.
As the sticky check can't distinguish between sticky mixers and working
SET_CUR but broken GET_CUR, add QUIRK_FLAG_MIXER_GET_CUR_BROKEN to tell
that the device should fall into the second category when GET_CUR
returns a constant value. In this case, the sticky check becomes
non-fatal and only disables GET_CUR instead of the whole mixer. The
current volume will then be provided by the internal cache that stores
the last set volume.
An info message prompting users to check MIXER_GET_CUR_BROKEN for
potential sticky mixers is also added, so that users can learn how to do
some experiments to determine what's going on. If the mixer surprisingly
turns out to be non-sticky, they can submit a patch for a new quirk
table entry.
Signed-off-by: Rong Zhang <i@rong.moe>
---
Documentation/sound/alsa-configuration.rst | 12 ++++++
sound/usb/mixer.c | 60 +++++++++++++++++++++++++-----
sound/usb/mixer.h | 1 +
sound/usb/quirks.c | 1 +
sound/usb/usbaudio.h | 13 +++++++
5 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst
index 4b30cd63c5a5..78fb484e8b04 100644
--- a/Documentation/sound/alsa-configuration.rst
+++ b/Documentation/sound/alsa-configuration.rst
@@ -2389,6 +2389,18 @@ quirk_flags
from snd_usb_handle_sync_urb. Instead fall through and enqueue a
packet_info containing only size-0 packets, so the OUT ring keeps
moving (emits silence). Needed by Behringer Flow 8 (1397:050c).
+ * bit 30: ``mixer_get_cur_broken``
+ Some mixers are sticky, which means that setting their current volume
+ is a no-op, and reading the current volume returns a constant value.
+ The sticky check disables these mixers to prevent confusing userspace.
+ However, some devices do have a tunable volume despite the reported
+ current volume being constant. As the sticky check can't distinguish
+ between the two categories, setting this flag tells that the device
+ should fall into the second category when GET_CUR returns a constant
+ value, resulting in the sticky check being non-fatal and only
+ disabling GET_CUR instead of the whole mixer. The current volume will
+ then be provided by the internal cache that stores the last set
+ volume
This module supports multiple devices, autoprobe and hotplugging.
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index b30af79f716c..b4c855c25eef 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -434,6 +434,11 @@ int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval,
*value = cval->cache_val[index];
return 0;
}
+
+ /* The current value is always provided by the cache after initialization. */
+ if (cval->get_cur_broken)
+ return -ENXIO;
+
err = get_cur_mix_raw(cval, channel, value);
if (err < 0) {
if (!cval->head.mixer->ignore_ctl_error)
@@ -1223,7 +1228,7 @@ static void init_cur_mix_raw(struct usb_mixer_elem_info *cval, int ch, int idx)
err = snd_usb_get_cur_mix_value(cval, ch, idx, &val);
if (!err)
return;
- if (!cval->head.mixer->ignore_ctl_error)
+ if (!cval->head.mixer->ignore_ctl_error && !cval->get_cur_broken)
usb_audio_warn(cval->head.mixer->chip,
"%d:%d: failed to get current value for ch %d (%d)\n",
cval->head.id, mixer_ctrl_intf(cval->head.mixer),
@@ -1237,8 +1242,16 @@ static void init_cur_mix_raw(struct usb_mixer_elem_info *cval, int ch, int idx)
* Some devices' volume control mixers are sticky, which accept SET_CUR but
* do absolutely nothing.
*
- * Prevent sticky mixers from being registered, otherwise they confuses
- * userspace and results in ineffective volume control.
+ * Check the return values of GET_CUR with different SET_CUR values. Consider
+ * the mixer as sticky if GET_CUR always returns a constant value.
+ *
+ * Some devices have effective SET_CUR despite GET_CUR being constant. Do not
+ * consider the mixer as sticky if a quirk flag indicates that.
+ *
+ * Gate the registration of sticky mixers to prevent confusing userspace, so
+ * that they won't cause ineffective volume control. However, for mixers with
+ * effective SET_CUR but broken GET_CUR, the registration can continue normally
+ * but further GET_CUR requests will be gated.
*/
static int check_sticky_volume_control(struct usb_mixer_elem_info *cval,
int channel, int saved)
@@ -1258,10 +1271,22 @@ static int check_sticky_volume_control(struct usb_mixer_elem_info *cval,
return 0;
}
+ if (cval->head.mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_GET_CUR_BROKEN) {
+ usb_audio_info(cval->head.mixer->chip,
+ "%d:%d: broken mixer GET_CUR (%d/%d/%d => %d)\n",
+ cval->head.id, mixer_ctrl_intf(cval->head.mixer),
+ cval->min, cval->max, cval->res, saved);
+
+ cval->get_cur_broken = 1;
+ return -ENXIO;
+ }
+
usb_audio_err(cval->head.mixer->chip,
"%d:%d: sticky mixer values (%d/%d/%d => %d), disabling\n",
cval->head.id, mixer_ctrl_intf(cval->head.mixer),
cval->min, cval->max, cval->res, saved);
+ usb_audio_info(cval->head.mixer->chip,
+ "check MIXER_GET_CUR_BROKEN if you believe the mixer is non-sticky");
return -ENODEV;
}
@@ -1304,7 +1329,7 @@ static void check_volume_control_res(struct usb_mixer_elem_info *cval,
static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
int default_min, struct snd_kcontrol *kctl)
{
- int i, idx, ret;
+ int i, idx, ret = 0;
/* for failsafe */
cval->min = default_min;
@@ -1360,8 +1385,10 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
goto no_checks;
ret = check_sticky_volume_control(cval, minchn, saved);
- if (ret < 0)
+ if (ret == -ENODEV)
goto sticky;
+ if (ret)
+ goto no_checks;
if (cval->min + cval->res < cval->max)
check_volume_control_res(cval, minchn, saved);
@@ -1370,6 +1397,16 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
}
no_checks:
+ /*
+ * Got a non-fatal failure during sanity checks.
+ *
+ * Do not propagate mixer values written by sanity checks.
+ * Instead, rely on init_cur_mix_raw() to initialize the mixer
+ * properly.
+ */
+ if (ret)
+ cval->cached = 0;
+
cval->initialized = 1;
}
@@ -3538,7 +3575,8 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
continue;
info = mixer_elem_list_to_info(list);
/* invalidate cache, so the value is read from the device */
- info->cached = 0;
+ if (!info->get_cur_broken)
+ info->cached = 0;
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&list->kctl->id);
}
@@ -3635,10 +3673,12 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
switch (attribute) {
case UAC2_CS_CUR:
/* invalidate cache, so the value is read from the device */
- if (channel)
- info->cached &= ~BIT(channel);
- else /* master channel */
- info->cached = 0;
+ if (!info->get_cur_broken) {
+ if (channel)
+ info->cached &= ~BIT(channel);
+ else /* master channel */
+ info->cached = 0;
+ }
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&info->head.kctl->id);
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index afbb3dd9f177..3fa1bd96f858 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -94,6 +94,7 @@ struct usb_mixer_elem_info {
int cache_val[MAX_CHANNELS];
u8 initialized;
u8 min_mute;
+ u8 get_cur_broken;
void *private_data;
};
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 410f5a92c0cf..10c32e633786 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2607,6 +2607,7 @@ static const char *const snd_usb_audio_quirk_flag_names[] = {
QUIRK_STRING_ENTRY(MIXER_PLAYBACK_LINEAR_VOL),
QUIRK_STRING_ENTRY(MIXER_CAPTURE_LINEAR_VOL),
QUIRK_STRING_ENTRY(IFB_SILENCE_ON_EMPTY),
+ QUIRK_STRING_ENTRY(MIXER_GET_CUR_BROKEN),
NULL
};
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 9afcad8f143a..e472aef6eb87 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -242,6 +242,17 @@ extern bool snd_usb_skip_validation;
* from snd_usb_handle_sync_urb. Instead fall through and enqueue a
* packet_info containing only size-0 packets, so the OUT ring keeps
* moving (emits silence). Needed by Behringer Flow 8 (1397:050c).
+ * QUIRK_FLAG_MIXER_GET_CUR_BROKEN
+ * Some mixers are sticky, which means that setting their current volume is a
+ * no-op, and reading the current volume returns a constant value. The sticky
+ * check disables these mixers to prevent confusing userspace. However, some
+ * devices do have a tunable volume despite the reported current volume being
+ * constant. As the sticky check can't distinguish between the two categories,
+ * setting this flag tells that the device should fall into the second
+ * category when GET_CUR returns a constant value, resulting in the sticky
+ * check being non-fatal and only disabling GET_CUR instead of the whole mixer.
+ * The current volume will then be provided by the internal cache that stores
+ * the last set volume
*/
enum {
@@ -275,6 +286,7 @@ enum {
QUIRK_TYPE_MIXER_PLAYBACK_LINEAR_VOL = 27,
QUIRK_TYPE_MIXER_CAPTURE_LINEAR_VOL = 28,
QUIRK_TYPE_IFB_SILENCE_ON_EMPTY = 29,
+ QUIRK_TYPE_MIXER_GET_CUR_BROKEN = 30,
/* Please also edit snd_usb_audio_quirk_flag_names */
};
@@ -310,5 +322,6 @@ enum {
#define QUIRK_FLAG_MIXER_PLAYBACK_LINEAR_VOL QUIRK_FLAG(MIXER_PLAYBACK_LINEAR_VOL)
#define QUIRK_FLAG_MIXER_CAPTURE_LINEAR_VOL QUIRK_FLAG(MIXER_CAPTURE_LINEAR_VOL)
#define QUIRK_FLAG_IFB_SILENCE_ON_EMPTY QUIRK_FLAG(IFB_SILENCE_ON_EMPTY)
+#define QUIRK_FLAG_MIXER_GET_CUR_BROKEN QUIRK_FLAG(MIXER_GET_CUR_BROKEN)
#endif /* __USBAUDIO_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/3] ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3
2026-05-31 15:45 [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Rong Zhang
2026-05-31 15:45 ` [PATCH v4 1/3] " Rong Zhang
@ 2026-05-31 15:45 ` Rong Zhang
2026-05-31 15:45 ` [PATCH v4 3/3] ALSA: usb-audio: Add quirk flag for Edifier MF200 Rong Zhang
2026-05-31 15:50 ` [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Takashi Iwai
3 siblings, 0 replies; 8+ messages in thread
From: Rong Zhang @ 2026-05-31 15:45 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan
Cc: Takashi Iwai, Steve Smith, linux-sound, linux-doc, linux-kernel,
Rong Zhang
The Sennheiser MOMENTUM 3 is a wireless around-ear headphones featuring
ANC, which can be connected via Bluetooth or USB-C.
When connecting via USB-C, its UAC mixer works fine and precisely
corresponds to the reported dB range. However, the mixer's volume
GET_CUR method is somehow stubbed and returns a constant value (15dB).
Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
mixers"), the sticky check considers the mixer to be sticky and
unnecessarily disables the mixer.
Add a quirk table entry matching VID/PID=0x1377/0x6004 and applying
the MIXER_GET_CUR_BROKEN quirk flag, so that the mixer is usable again.
Quirky device sample:
usb 7-1.4.4.1.1.1: new full-speed USB device number 30 using xhci_hcd
usb 7-1.4.4.1.1.1: New USB device found, idVendor=1377, idProduct=6004, bcdDevice=38.85
usb 7-1.4.4.1.1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 7-1.4.4.1.1.1: Product: MOMENTUM 3
usb 7-1.4.4.1.1.1: Manufacturer: Sennheiser electronic GmbH & Co. KG
usb 7-1.4.4.1.1.1: SerialNumber: <REDACTED>
usb 7-1.4.4.1.1.1: Found last interface = 0
usb 7-1.4.4.1.1.1: 1:1: add audio endpoint 0x3
usb 7-1.4.4.1.1.1: Creating new data endpoint #3
usb 7-1.4.4.1.1.1: 1:1 Set sample rate 48000, clock 0
usb 7-1.4.4.1.1.1: 6:0: sticky mixer values (0/11520/768 => 3840), disabling
usb 7-1.4.4.1.1.1: [6] FU [PCM Playback Volume] skipped due to invalid volume
input: Sennheiser electronic GmbH & Co. KG MOMENTUM 3 as /devices/pci0000:00/0000:00:08.3/0000:67:00.4/usb7/7-1/7-1.4/7-1.4.4/7-1.4.4.1/7-1.4.4.1.1/7-1.4.4.1.1.1/7-1.4.4.1.1.1:1.2/0003:1377:6004.002B/input/input208
input: Sennheiser electronic GmbH & Co. KG MOMENTUM 3 Consumer Control as /devices/pci0000:00/0000:00:08.3/0000:67:00.4/usb7/7-1/7-1.4/7-1.4.4/7-1.4.4.1/7-1.4.4.1.1/7-1.4.4.1.1.1/7-1.4.4.1.1.1:1.2/0003:1377:6004.002B/input/input209
hid-generic 0003:1377:6004.002B: input,hiddev99,hidraw12: USB HID v1.11 Device [Sennheiser electronic GmbH & Co. KG MOMENTUM 3] on usb-0000:67:00.4-1.4.4.1.1.1/input2
Signed-off-by: Rong Zhang <i@rong.moe>
---
sound/usb/quirks.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 10c32e633786..3adfda40d7cb 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2357,6 +2357,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
+ DEVICE_FLG(0x1377, 0x6004, /* Sennheiser MOMENTUM 3 */
+ QUIRK_FLAG_MIXER_GET_CUR_BROKEN),
DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 3/3] ALSA: usb-audio: Add quirk flag for Edifier MF200
2026-05-31 15:45 [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Rong Zhang
2026-05-31 15:45 ` [PATCH v4 1/3] " Rong Zhang
2026-05-31 15:45 ` [PATCH v4 2/3] ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3 Rong Zhang
@ 2026-05-31 15:45 ` Rong Zhang
2026-05-31 15:50 ` [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Takashi Iwai
3 siblings, 0 replies; 8+ messages in thread
From: Rong Zhang @ 2026-05-31 15:45 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan
Cc: Takashi Iwai, Steve Smith, linux-sound, linux-doc, linux-kernel,
Rong Zhang
The UAC mixer of Edifier MF200 works fine except that its volume GET_CUR
method is somehow stubbed and returns a constant value. Since commit
86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky mixers"), the
sticky check considers the mixer to be sticky and unnecessarily disables
the mixer.
Add a quirk table entry matching VID/PID=0x2d99/0xa024 and applying
the MIXER_SKIP_GET_CUR_VOL quirk flag, so that the mixer is usable
again.
Quirky device sample:
usb 1-3.2: new full-speed USB device number 7 using xhci_hcd
usb 1-3.2: New USB device found, idVendor=2d99, idProduct=a024, bcdDevice= 0.00
usb 1-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-3.2: Product: EDIFIER MF200
usb 1-3.2: Manufacturer: EDIFIER
usb 1-3.2: SerialNumber: EDI00000X06
input: EDIFIER EDIFIER MF200 Consumer Control as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:0e:00.0/usb1/1-3/1-3.2/1-3.2:1.0/0003:2D99:A024.0003/input/input8
input: EDIFIER EDIFIER MF200 Mouse as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:0e:00.0/usb1/1-3/1-3.2/1-3.2:1.0/0003:2D99:A024.0003/input/input9
input: EDIFIER EDIFIER MF200 Keyboard as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:0e:00.0/usb1/1-3/1-3.2/1-3.2:1.0/0003:2D99:A024.0003/input/input10
input: EDIFIER EDIFIER MF200 as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:0e:00.0/usb1/1-3/1-3.2/1-3.2:1.0/0003:2D99:A024.0003/input/input11
input: EDIFIER EDIFIER MF200 as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:0e:00.0/usb1/1-3/1-3.2/1-3.2:1.0/0003:2D99:A024.0003/input/input12
hid-generic 0003:2D99:A024.0003: input,hiddev1,hidraw2: USB HID v1.10 Mouse [EDIFIER EDIFIER MF200] on usb-0000:0e:00.0-3.2/input0
usb 1-3.2: 9:1: sticky mixer values (-32768/-32513/1 => -32702), disabling
Reported-by: Steve Smith <tarkasteve@gmail.com>
Closes: https://lore.kernel.org/r/CAHLWS5FJCx66GQ-O10pu+nEudEo_QgQAM9vt76T7vT0zGPPC1g@mail.gmail.com
Tested-by: Steve Smith <tarkasteve@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
---
sound/usb/quirks.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 3adfda40d7cb..27fd8621e8f5 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2477,6 +2477,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x2d99, 0x0026, /* HECATE G2 GAMING HEADSET */
QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
+ DEVICE_FLG(0x2d99, 0xa024, /* Edifier MF200 */
+ QUIRK_FLAG_MIXER_GET_CUR_BROKEN),
DEVICE_FLG(0x2fc6, 0xf06b, /* MOONDROP Moonriver2 Ti */
QUIRK_FLAG_CTL_MSG_DELAY),
DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
2026-05-31 15:45 [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Rong Zhang
` (2 preceding siblings ...)
2026-05-31 15:45 ` [PATCH v4 3/3] ALSA: usb-audio: Add quirk flag for Edifier MF200 Rong Zhang
@ 2026-05-31 15:50 ` Takashi Iwai
2026-05-31 15:52 ` Rong Zhang
2026-06-05 12:00 ` Thorsten Leemhuis
3 siblings, 2 replies; 8+ messages in thread
From: Takashi Iwai @ 2026-05-31 15:50 UTC (permalink / raw)
To: Rong Zhang
Cc: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan,
Takashi Iwai, Steve Smith, linux-sound, linux-doc, linux-kernel
On Sun, 31 May 2026 17:45:19 +0200,
Rong Zhang wrote:
>
> Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
> mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
> identify devices with sticky mixers. Unfortunately, even though most
> devices with sticky GET_CUR also have corresponding sticky SET_CUR,
> which I actually met more since the commit had been merged, there is
> also a rare case that some devices may have volume mixers that responds
> to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
> check to consider the mixer to be sticky and unnecessarily disable it.
>
> As the sticky check can't distinguish between sticky mixers and working
> SET_CUR but broken GET_CUR, add QUIRK_FLAG_MIXER_GET_CUR_BROKEN to tell
> that the device should fall into the second category when GET_CUR
> returns a constant value. In this case, the sticky check becomes
> non-fatal and only disables GET_CUR instead of the whole mixer. The
> current volume will then be provided by the internal cache that stores
> the last set volume.
>
> An info message prompting users to check MIXER_GET_CUR_BROKEN for
> potential sticky mixers is also added, so that users can learn how to do
> some experiments to determine what's going on. If the mixer surprisingly
> turns out to be non-sticky, they can submit a patch for a new quirk
> table entry.
>
> The Sennheiser MOMENTUM 3 and Edifier MF200 need the quirk flag. Though
> their UAC mixers respond to SET_CUR by tuning the volume, the
> corresponding GET_CUR methods are somehow stubbed and return constant
> values, resulting in them being disabled by the sticky check.
>
> Signed-off-by: Rong Zhang <i@rong.moe>
> ---
> Changes in v4:
> - Rebase since a patch improving the error path of the sticky check has
> been applied earlier
> - https://patch.msgid.link/20260531-uac-sticky-error-path-v1-1-12c2329d17ef@rong.moe
> - Integrate a follow-up series into this one
> - https://patch.msgid.link/20260531-uac-edifier-mf200-v1-0-be69657c3f87@rong.moe
> - Link to v3: https://patch.msgid.link/20260529-uac-quirk-get-cur-vol-v3-0-bde363188ca4@rong.moe
>
> Changes in v3:
> - Make the log less noisy (thanks Takashi Iwai)
> - Do not propagate mixer values written by sanity checks when GET_CUR is
> broken, nor restore the garbage backed-up value. Instead, rely on
> init_cur_mix_raw() to initialize the mixer properly
> - Gate cache invalidation as well, so that the current volume is always
> available to userspace
> - Update the comment of check_sticky_volume_control()
> - Link to v2: https://patch.msgid.link/20260528-uac-quirk-get-cur-vol-v2-0-84d3c8f48150@rong.moe
>
> Changes in v2:
> - Turn the approach into a less radical one
> - Rename the quirk flag to QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> - Add a flag `get_cur_broken' to `struct usb_mixer_elem_info'
> - When the sticky check fails, check quirk flags. Gate further GET_CUR
> by setting `cval->get_cur_broken' if QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> is set, otherwise disable the mixer as usual
> - The quirk flag still applies to all mixers, but as long as a mixer
> makes the sticky check happy, it won't be affected at all. Only
> those mixers with constant GET_CUR values will have their GET_CUR
> gated. I assume the impact is minimal, since it's very unlikely a
> device would have sticky mixers (broken SET_CUR) along with mixers
> with working SET_CUR but broken GET_CUR at the same time
> - Link to v1: https://patch.msgid.link/20260527-uac-quirk-get-cur-vol-v1-0-e9362b712e5e@rong.moe
>
> ---
> Rong Zhang (3):
> ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3
> ALSA: usb-audio: Add quirk flag for Edifier MF200
Now took all three patches onto for-next branch. Thanks.
Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
2026-05-31 15:50 ` [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Takashi Iwai
@ 2026-05-31 15:52 ` Rong Zhang
2026-06-05 12:00 ` Thorsten Leemhuis
1 sibling, 0 replies; 8+ messages in thread
From: Rong Zhang @ 2026-05-31 15:52 UTC (permalink / raw)
To: Takashi Iwai
Cc: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan,
Steve Smith, linux-sound, linux-doc, linux-kernel
Hi Takashi,
On Sun, 2026-05-31 at 17:50 +0200, Takashi Iwai wrote:
> On Sun, 31 May 2026 17:45:19 +0200,
> Rong Zhang wrote:
> >
> > Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
> > mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
> > identify devices with sticky mixers. Unfortunately, even though most
> > devices with sticky GET_CUR also have corresponding sticky SET_CUR,
> > which I actually met more since the commit had been merged, there is
> > also a rare case that some devices may have volume mixers that responds
> > to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
> > check to consider the mixer to be sticky and unnecessarily disable it.
> >
> > As the sticky check can't distinguish between sticky mixers and working
> > SET_CUR but broken GET_CUR, add QUIRK_FLAG_MIXER_GET_CUR_BROKEN to tell
> > that the device should fall into the second category when GET_CUR
> > returns a constant value. In this case, the sticky check becomes
> > non-fatal and only disables GET_CUR instead of the whole mixer. The
> > current volume will then be provided by the internal cache that stores
> > the last set volume.
> >
> > An info message prompting users to check MIXER_GET_CUR_BROKEN for
> > potential sticky mixers is also added, so that users can learn how to do
> > some experiments to determine what's going on. If the mixer surprisingly
> > turns out to be non-sticky, they can submit a patch for a new quirk
> > table entry.
> >
> > The Sennheiser MOMENTUM 3 and Edifier MF200 need the quirk flag. Though
> > their UAC mixers respond to SET_CUR by tuning the volume, the
> > corresponding GET_CUR methods are somehow stubbed and return constant
> > values, resulting in them being disabled by the sticky check.
> >
> > Signed-off-by: Rong Zhang <i@rong.moe>
> > ---
> > Changes in v4:
> > - Rebase since a patch improving the error path of the sticky check has
> > been applied earlier
> > - https://patch.msgid.link/20260531-uac-sticky-error-path-v1-1-12c2329d17ef@rong.moe
> > - Integrate a follow-up series into this one
> > - https://patch.msgid.link/20260531-uac-edifier-mf200-v1-0-be69657c3f87@rong.moe
> > - Link to v3: https://patch.msgid.link/20260529-uac-quirk-get-cur-vol-v3-0-bde363188ca4@rong.moe
> >
> > Changes in v3:
> > - Make the log less noisy (thanks Takashi Iwai)
> > - Do not propagate mixer values written by sanity checks when GET_CUR is
> > broken, nor restore the garbage backed-up value. Instead, rely on
> > init_cur_mix_raw() to initialize the mixer properly
> > - Gate cache invalidation as well, so that the current volume is always
> > available to userspace
> > - Update the comment of check_sticky_volume_control()
> > - Link to v2: https://patch.msgid.link/20260528-uac-quirk-get-cur-vol-v2-0-84d3c8f48150@rong.moe
> >
> > Changes in v2:
> > - Turn the approach into a less radical one
> > - Rename the quirk flag to QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> > - Add a flag `get_cur_broken' to `struct usb_mixer_elem_info'
> > - When the sticky check fails, check quirk flags. Gate further GET_CUR
> > by setting `cval->get_cur_broken' if QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> > is set, otherwise disable the mixer as usual
> > - The quirk flag still applies to all mixers, but as long as a mixer
> > makes the sticky check happy, it won't be affected at all. Only
> > those mixers with constant GET_CUR values will have their GET_CUR
> > gated. I assume the impact is minimal, since it's very unlikely a
> > device would have sticky mixers (broken SET_CUR) along with mixers
> > with working SET_CUR but broken GET_CUR at the same time
> > - Link to v1: https://patch.msgid.link/20260527-uac-quirk-get-cur-vol-v1-0-e9362b712e5e@rong.moe
> >
> > ---
> > Rong Zhang (3):
> > ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
> > ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3
> > ALSA: usb-audio: Add quirk flag for Edifier MF200
>
> Now took all three patches onto for-next branch. Thanks.
Thanks a lot! :)
Thanks,
Rong
>
>
> Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
2026-05-31 15:50 ` [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Takashi Iwai
2026-05-31 15:52 ` Rong Zhang
@ 2026-06-05 12:00 ` Thorsten Leemhuis
2026-06-05 12:05 ` Takashi Iwai
1 sibling, 1 reply; 8+ messages in thread
From: Thorsten Leemhuis @ 2026-06-05 12:00 UTC (permalink / raw)
To: Takashi Iwai, Rong Zhang
Cc: Jaroslav Kysela, Takashi Iwai, Jonathan Corbet, Shuah Khan,
Steve Smith, linux-sound, linux-doc, linux-kernel,
Linux kernel regressions list
On 5/31/26 17:50, Takashi Iwai wrote:
> On Sun, 31 May 2026 17:45:19 +0200,
> Rong Zhang wrote:
>>
>> Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
>> mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
>> identify devices with sticky mixers. Unfortunately, even though most
>> devices with sticky GET_CUR also have corresponding sticky SET_CUR,
>> which I actually met more since the commit had been merged, there is
>> also a rare case that some devices may have volume mixers that responds
>> to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
>> check to consider the mixer to be sticky and unnecessarily disable it.
> [...]
>
> Now took all three patches onto for-next branch. Thanks.
I noticed that patch 1 is somewhat on the larger side, nevertheless
allow me to ask: wouldn't it be better to mainline this for -rc7, as
this fixes a regression from the 7.1 cycle? Or did I misjudge this? Then
don't hesitate to tell me!
Ciao, Thorsten
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN
2026-06-05 12:00 ` Thorsten Leemhuis
@ 2026-06-05 12:05 ` Takashi Iwai
0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2026-06-05 12:05 UTC (permalink / raw)
To: Thorsten Leemhuis
Cc: Takashi Iwai, Rong Zhang, Jaroslav Kysela, Takashi Iwai,
Jonathan Corbet, Shuah Khan, Steve Smith, linux-sound, linux-doc,
linux-kernel, Linux kernel regressions list
On Fri, 05 Jun 2026 14:00:02 +0200,
Thorsten Leemhuis wrote:
>
> On 5/31/26 17:50, Takashi Iwai wrote:
> > On Sun, 31 May 2026 17:45:19 +0200,
> > Rong Zhang wrote:
> >>
> >> Since commit 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky
> >> mixers"), the UAC mixer core utilizes volume SET_CUR and GET_CUR to
> >> identify devices with sticky mixers. Unfortunately, even though most
> >> devices with sticky GET_CUR also have corresponding sticky SET_CUR,
> >> which I actually met more since the commit had been merged, there is
> >> also a rare case that some devices may have volume mixers that responds
> >> to SET_CUR properly but with its GET_CUR stubbed. This cause the sticky
> >> check to consider the mixer to be sticky and unnecessarily disable it.
> > [...]
> >
> > Now took all three patches onto for-next branch. Thanks.
>
> I noticed that patch 1 is somewhat on the larger side, nevertheless
> allow me to ask: wouldn't it be better to mainline this for -rc7, as
> this fixes a regression from the 7.1 cycle? Or did I misjudge this? Then
> don't hesitate to tell me!
A regression fix will be included in the upcoming PR by another commit
aa2f4addab44407c7aa742321de5dc1914ab5762.
Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-05 12:06 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-31 15:45 [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Rong Zhang
2026-05-31 15:45 ` [PATCH v4 1/3] " Rong Zhang
2026-05-31 15:45 ` [PATCH v4 2/3] ALSA: usb-audio: Add quirk flag for Sennheiser MOMENTUM 3 Rong Zhang
2026-05-31 15:45 ` [PATCH v4 3/3] ALSA: usb-audio: Add quirk flag for Edifier MF200 Rong Zhang
2026-05-31 15:50 ` [PATCH v4 0/3] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN Takashi Iwai
2026-05-31 15:52 ` Rong Zhang
2026-06-05 12:00 ` Thorsten Leemhuis
2026-06-05 12:05 ` Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox