[PATCH 3/4] ALSA: usb-audio: Reverse MIXER_GET_CUR_BROKEN as MIXER_GET_CUR_OK

Rong Zhang <[email protected]>
Newsgroups org.kernel.vger.linux-sound,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The default behavior of sticky check now becomes what
QUIRK_FLAG_MIXER_GET_CUR_BROKEN originally does, so the quirk flag is no
longer needed.

On some devices, whether their GET_CUR being sticky depends on whether
hotpluggable components are present. When the hotpluggable components
are missing on probe, their GET_CUR behavior is classified as broken.
Therefore, reverse QUIRK_FLAG_MIXER_GET_CUR_BROKEN as
QUIRK_FLAG_MIXER_GET_CUR_OK, so that it can be set to prevent the
heuristics from gating GET_CUR.

Note that even if the quirk flag is set, init_cur_mix_raw() should still
initialize the mixer value to cval->min, otherwise restoring the bogus
saved value on the first channel could lead to unbalanced channels.

Signed-off-by: Rong Zhang <[email protected]>
---
 Documentation/sound/alsa-configuration.rst | 20 ++++++++------------
 sound/usb/mixer.c                          |  8 ++++++++
 sound/usb/quirks.c                         | 16 +++-------------
 sound/usb/usbaudio.h                       | 20 +++++++-------------
 4 files changed, 26 insertions(+), 38 deletions(-)

diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst
index 71733e807a7c..e500ec84e3ef 100644
--- a/Documentation/sound/alsa-configuration.rst
+++ b/Documentation/sound/alsa-configuration.rst
@@ -2316,6 +2316,9 @@ quirk_flags
     applies the ``mixer_playback_min_mute`` flag and clears the
     ``ignore_ctl_error`` flag for the device 1234:abcd, and applies the
     ``skip_sample_rate`` flag for all devices.
+    New quirk flags may replace old ones by reusing the latter's bits, so the
+    new usage is preferred. Despite that, depending on the order of probing is
+    fragile, so it'd better migrate to the new usage anyway.
 
         * bit 0: ``get_sample_rate``
           Skip reading sample rate for devices
@@ -2389,18 +2392,11 @@ 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
+        * bit 30: ``mixer_get_cur_ok``
+          On some devices, whether their GET_CUR being sticky depends on whether
+          hotpluggable components are present. When the hotpluggable components
+          are missing on probe, their GET_CUR behavior is classified as broken.
+          Set the flag to prevent the heuristics from gating GET_CUR.
         * bit 31: ``playback_urb_fixup``
           Some devices show the stuttering at playback, and this quirk
           works around it by enforcing the fixed max URBs (12) instead of
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 3aa9a9c12557..ecaa8bc08d7c 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1447,6 +1447,14 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
 		}
 	}
 
+	/*
+	 * When GET_CUR is sticky, the saved value is bogus, so mixer values set
+	 * by the sanity checks must be discarded through init_cur_mix_raw().
+	 * After that, we can clear the flag as per QUIRK_FLAG_MIXER_GET_CUR_OK.
+	 */
+	if (cval->head.mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_GET_CUR_OK)
+		cval->get_cur_broken = 0;
+
 	return 0;
 }
 
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index eb1750def067..b62168a11e32 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2215,8 +2215,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 		   QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
 	DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */
 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
-	DEVICE_FLG(0x040b, 0x0897, /* Weltrend Semiconductor, sold as Redragon H510-PRO Wireless headset */
-		   QUIRK_FLAG_MIXER_GET_CUR_BROKEN),
 	DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */
 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
 	DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */
@@ -2256,8 +2254,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 	DEVICE_FLG(0x046d, 0x0a8f, /* Logitech H390 headset */
 		   QUIRK_FLAG_CTL_MSG_DELAY_1M |
 		   QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
-	DEVICE_FLG(0x046d, 0x0af7, /* Logitech PRO X 2 LIGHTSPEED */
-		   QUIRK_FLAG_MIXER_GET_CUR_BROKEN),
 	DEVICE_FLG(0x0499, 0x1506, /* Yamaha THR5 */
 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */
@@ -2329,9 +2325,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 	DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */
 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x0763, 0x2080, /* M-Audio Fast Track Ultra */
-		   QUIRK_FLAG_MIXER_GET_CUR_BROKEN | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x0763, 0x2081, /* M-Audio Fast Track Ultra */
-		   QUIRK_FLAG_MIXER_GET_CUR_BROKEN | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x07fd, 0x000b, /* MOTU M Series 2nd hardware revision */
 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
 	DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */
@@ -2370,8 +2366,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
 	DEVICE_FLG(0x1038, 0x1294, /* SteelSeries Arctis Pro Wireless */
 		   QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
-	DEVICE_FLG(0x1038, 0x2232, /* SteelSeries Arctis Nova 5 */
-		   QUIRK_FLAG_MIXER_GET_CUR_BROKEN),
 	DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */
 		   QUIRK_FLAG_GET_SAMPLE_RATE),
 	DEVICE_FLG(0x12d1, 0x3a07, /* HUAWEI USB-C HEADSET */
@@ -2379,8 +2373,6 @@ 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 */
@@ -2505,8 +2497,6 @@ 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, 0xf0b5, /* iBasso DC-Elite */
@@ -2647,7 +2637,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),
+	QUIRK_STRING_ENTRY(MIXER_GET_CUR_OK),
 	QUIRK_STRING_ENTRY(PLAYBACK_URB_FIXUP),
 	QUIRK_STRING_ENTRY(ALWAYS_SET_RATE),
 	NULL
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index abc2d7e579de..24436473931d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -243,17 +243,11 @@ 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
+ * QUIRK_FLAG_MIXER_GET_CUR_OK
+ *  On some devices, whether their GET_CUR being sticky depends on whether
+ *  hotpluggable components are present. When the hotpluggable components are
+ *  missing on probe, their GET_CUR behavior is classified as broken. Set the
+ *  flag to prevent the heuristics from gating GET_CUR.
  * QUIRK_FLAG_PLAYBACK_URB_FIXUP
  *  Set URB_ISO_ASAP flag for isochronous URBs and force nurbs to MAX_URBS.
  *  This is needed for devices that exhibit boot-time audio stuttering due
@@ -297,7 +291,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,
+	QUIRK_TYPE_MIXER_GET_CUR_OK		= 30,
 	QUIRK_TYPE_PLAYBACK_URB_FIXUP		= 31,
 	QUIRK_TYPE_ALWAYS_SET_RATE		= 32,
 /* Please also edit snd_usb_audio_quirk_flag_names and alsa-configuration.rst */
@@ -335,7 +329,7 @@ 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)
+#define QUIRK_FLAG_MIXER_GET_CUR_OK		QUIRK_FLAG(MIXER_GET_CUR_OK)
 #define QUIRK_FLAG_PLAYBACK_URB_FIXUP		QUIRK_FLAG(PLAYBACK_URB_FIXUP)
 #define QUIRK_FLAG_ALWAYS_SET_RATE		QUIRK_FLAG(ALWAYS_SET_RATE)
 

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.