Skip to contentSkip to conversation

ALSA: usb-audio: apply quirk for MOONDROP JU Jiu

PATCH Applied Cryolitia PukNgae 2 participants 4 messages Apr 2 – Apr 10

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ALSA: usb-audio: apply quirk for MOONDROP JU Jiu

It(ID 31b2:0111 JU Jiu) reports a MIN value -12800 for volume control, but will mute when setting it less than -10880.

Thanks to my girlfriend Kagura for reporting this issue.

---
Btw, is it a good idea for turn the volume_control_quirks from switch-case to a table and sort it accroding to USB VID&PID?

---
 sound/usb/mixer.c | 7 +++++++
 1 file changed, 7 insertions(+)
sound/usb/mixer.c +7 -0
index 69026cf54979..a25e8145af67 100644
@@ -1204,6 +1204,13 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 			cval->min = -11264; /* Mute under it */
 		}
 		break;
+	case USB_ID(0x31b2, 0x0111): /* MOONDROP JU Jiu */
+		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
+			usb_audio_info(chip,
+				       "set volume quirk for MOONDROP JU Jiu\n");
+			cval->min = -10880; /* Mute under it */
+		}
+		break;
 	}
 }
 

---
base-commit: 872c7433582a3570dd0c827967ba291450096bf0
change-id: 20260402-syy-f04074ca6782

Best regards,

Signature · 1 line
Cryolitia PukNgae <[email protected]>
Applied
#1 lore raw
Quoted 9 lines · Cryolitia PukNgae

It(ID 31b2:0111 JU Jiu) reports a MIN value -12800 for volume control, but will mute when setting it less than -10880.

Thanks to my girlfriend Kagura for reporting this issue.

Applied to for-next branch now.

Quoted 3 lines

---
Btw, is it a good idea for turn the volume_control_quirks from switch-case to a table and sort it accroding to USB VID&PID?

Yeah, this might be better, indeed.

But the quirk isn't really straightforward for those, maybe we need a matching of USB id plus kctl id name string, then update the cval fields conditionally with flags. Let me cook later...

thanks,

Takashi

#2 lore raw
Quoted 19 lines · Takashi Iwai
Quoted 9 lines · Cryolitia PukNgae

It(ID 31b2:0111 JU Jiu) reports a MIN value -12800 for volume control, but will mute when setting it less than -10880.

Thanks to my girlfriend Kagura for reporting this issue.

Applied to for-next branch now.

Quoted 3 lines

---
Btw, is it a good idea for turn the volume_control_quirks from switch-case to a table and sort it accroding to USB VID&PID?

Quoted 5 lines

Yeah, this might be better, indeed.

But the quirk isn't really straightforward for those, maybe we need a matching of USB id plus kctl id name string, then update the cval fields conditionally with flags. Let me cook later...

This doesn't look easy. A quick hack is like below, but it doesn't reduce the code, ended up with more lines.

So, unless any other clever implementation is given, still not much worth for it, as it seems.

Takashi

-- 8< --

sound/usb/mixer.c +108 -93
@@ -1070,11 +1070,107 @@ void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl)
  * interface to ALSA control for feature/mixer units
  */
 
+#define VOL_QUIRK_MIN	BIT(0)
+#define VOL_QUIRK_MAX	BIT(1)
+#define VOL_QUIRK_RES	BIT(2)
+
+struct mixer_volume_quirk {
+	unsigned int id;
+	const char *ctl_name;
+	unsigned int to_update;
+	int min, max, res;
+};
+
+#define QUIRK_ENTRY(vid, pid, name) \
+	.id = USB_ID(vid, pid), .ctl_name = (name)
+#define QUIRK_MIN(v) \
+	.to_update = VOL_QUIRK_MIN, .min = (v)
+#define QUIRK_RES(v) \
+	.to_update = VOL_QUIRK_RES, .res = (v)
+#define QUIRK_MINMAX(vmin, vmax) \
+	.to_update = VOL_QUIRK_MIN | VOL_QUIRK_MAX, .min = (vmin), .max = (vmax)
+#define QUIRK_MINMAXRES(vmin, vmax, vres) \
+	.to_update = VOL_QUIRK_MIN | VOL_QUIRK_MAX | VOL_QUIRK_RES, \
+	.min = (vmin), .max = (vmax), .res = (vres)
+
+static const struct mixer_volume_quirk mixer_volume_quirk_entries[] = {
+	/* M-Audio Fast Track C400 */
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Effect Duration"),
+	  QUIRK_MINMAXRES(0x0000, 0xffff, 0x00e6) },
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Effect Volume"),
+	  QUIRK_MINMAX(0x00, 0xff) },
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Effect Feedback Volume"),
+	  QUIRK_MINMAX(0x00, 0xff) },
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Effect Return"),
+	  QUIRK_MINMAXRES(0xb706, 0xff7b, 0x0073) },
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Playback Volume"),
+	  QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+	{ QUIRK_ENTRY(0x0763, 0x2030, "Effect Send"),
+	  QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+
+	/* M-Audio Fast Track C600 */
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Effect Duration"),
+	  QUIRK_MINMAXRES(0x0000, 0xffff, 0x00e6) },
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Effect Volume"),
+	  QUIRK_MINMAX(0x00, 0xff) },
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Effect Feedback Volume"),
+	  QUIRK_MINMAX(0x00, 0xff) },
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Effect Return"),
+	  QUIRK_MINMAXRES(0xb706, 0xff7b, 0x0073) },
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Playback Volume"),
+	  QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+	{ QUIRK_ENTRY(0x0763, 0x2031, "Effect Send"),
+	  QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+
+	/* M-Audio Fast Track Ultra 8R */
+	{ QUIRK_ENTRY(0x0763, 0x2081, "Effect Duration"),
+	  QUIRK_MINMAXRES(0x0000, 0x7f00, 0x0100) },
+	{ QUIRK_ENTRY(0x0763, 0x2081, "Effect Volume"),
+	  QUIRK_MINMAX(0x00, 0x7f) },
+	{ QUIRK_ENTRY(0x0763, 0x2081, "Effect Feedback Volume"),
+	  QUIRK_MINMAX(0x00, 0x7f) },
+
+	/* M-Audio Fast Track Ultra */
+	{ QUIRK_ENTRY(0x0763, 0x2080, "Effect Duration"),
+	  QUIRK_MINMAXRES(0x0000, 0x7f00, 0x0100) },
+	{ QUIRK_ENTRY(0x0763, 0x2080, "Effect Volume"),
+	  QUIRK_MINMAX(0x00, 0x7f) },
+	{ QUIRK_ENTRY(0x0763, 0x2080, "Effect Feedback Volume"),
+	  QUIRK_MINMAX(0x00, 0x7f) },
+
+	/* CM102-A+/102S+ */
+	{ QUIRK_ENTRY(0x0d8c, 0x0103, "PCM Playback Volume"),
+	  QUIRK_MIN(-256) },
+
+	/* MS LifeChat LX-3000 Headset */
+	{ QUIRK_ENTRY(0x045e, 0x070f, "Speaker Playback Volume"),
+	  QUIRK_RES(192) },
+
+	/* QuickCam E3500 */
+	{ QUIRK_ENTRY(0x046d, 0x09a4, "Mic Capture Volume"),
+	  QUIRK_MINMAXRES(6080, 8768, 192) },
+
+	/* MOONDROP Quark2 */
+	{ QUIRK_ENTRY(0x3302, 0x12db, "PCM Playback Volume"),
+	  QUIRK_MIN(-14208) }, /* Mute under it */
+
+	/* Huawei Technologies Co., Ltd. CM-Q3 */
+	{ QUIRK_ENTRY(0x12d1, 0x3a07, "PCM Playback Volume"),
+	  QUIRK_MIN(-11264) }, /* Mute under it */
+
+	/* MOONDROP JU Jiu */
+	{ QUIRK_ENTRY(0x31b2, 0x0111, "PCM Playback Volume"),
+	  QUIRK_MIN(-10880) }, /* Mute under it */
+
+	{} /* terminator */
+};
+
 /* volume control quirks */
 static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 				  struct snd_kcontrol *kctl)
 {
 	struct snd_usb_audio *chip = cval->head.mixer->chip;
+	const struct mixer_volume_quirk *q;
 
 	if (chip->quirk_flags & QUIRK_FLAG_MIC_RES_384) {
 		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
@@ -1090,71 +1186,21 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 		}
 	}
 
-	switch (chip->usb_id) {
-	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
-	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
-		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
-			cval->min = 0x0000;
-			cval->max = 0xffff;
-			cval->res = 0x00e6;
-			break;
-		}
-		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
-		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
-			cval->min = 0x00;
-			cval->max = 0xff;
-			break;
-		}
-		if (strstr(kctl->id.name, "Effect Return") != NULL) {
-			cval->min = 0xb706;
-			cval->max = 0xff7b;
-			cval->res = 0x0073;
-			break;
-		}
-		if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
-			(strstr(kctl->id.name, "Effect Send") != NULL)) {
-			cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
-			cval->max = 0xfcfe;
-			cval->res = 0x0073;
-		}
-		break;
-
-	case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
-	case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
-		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
-			usb_audio_info(chip,
-				       "set quirk for FTU Effect Duration\n");
-			cval->min = 0x0000;
-			cval->max = 0x7f00;
-			cval->res = 0x0100;
+	for (q = mixer_volume_quirk_entries; q->id; q++) {
+		if (q->id == chip->usb_id &&
+		    !strcmp(q->ctl_name, kctl->id.name)) {
+			if (q->to_update & VOL_QUIRK_MIN)
+				cval->min = q->min;
+			if (q->to_update & VOL_QUIRK_MAX)
+				cval->max = q->max;
+			if (q->to_update & VOL_QUIRK_RES)
+				cval->res = q->res;
 			break;
 		}
-		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
-		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
-			usb_audio_info(chip,
-				       "set quirks for FTU Effect Feedback/Volume\n");
-			cval->min = 0x00;
-			cval->max = 0x7f;
-			break;
-		}
-		break;
-
-	case USB_ID(0x0d8c, 0x0103):
-		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-			usb_audio_info(chip,
-				 "set volume quirk for CM102-A+/102S+\n");
-			cval->min = -256;
-		}
-		break;
-
-	case USB_ID(0x045e, 0x070f): /* MS LifeChat LX-3000 Headset */
-		if (!strcmp(kctl->id.name, "Speaker Playback Volume")) {
-			usb_audio_info(chip,
-				"set volume quirk for MS LifeChat LX-3000\n");
-			cval->res = 192;
-		}
-		break;
+	}
 
+	/* other exceptional cases */
+	switch (chip->usb_id) {
 	case USB_ID(0x0471, 0x0101):
 	case USB_ID(0x0471, 0x0104):
 	case USB_ID(0x0471, 0x0105):
@@ -1172,16 +1218,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 		}
 		break;
 
-	case USB_ID(0x046d, 0x09a4):
-		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
-			usb_audio_info(chip,
-				"set volume quirk for QuickCam E3500\n");
-			cval->min = 6080;
-			cval->max = 8768;
-			cval->res = 192;
-		}
-		break;
-
 	case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */
 		if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
 			strstr(kctl->id.name, "Capture Volume") != NULL) {
@@ -1190,27 +1226,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 			cval->res = 1;
 		}
 		break;
-	case USB_ID(0x3302, 0x12db): /* MOONDROP Quark2 */
-		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-			usb_audio_info(chip,
-				"set volume quirk for MOONDROP Quark2\n");
-			cval->min = -14208; /* Mute under it */
-		}
-		break;
-	case USB_ID(0x12d1, 0x3a07): /* Huawei Technologies Co., Ltd. CM-Q3 */
-		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-			usb_audio_info(chip,
-				       "set volume quirk for Huawei Technologies Co., Ltd. CM-Q3\n");
-			cval->min = -11264; /* Mute under it */
-		}
-		break;
-	case USB_ID(0x31b2, 0x0111): /* MOONDROP JU Jiu */
-		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-			usb_audio_info(chip,
-				       "set volume quirk for MOONDROP JU Jiu\n");
-			cval->min = -10880; /* Mute under it */
-		}
-		break;
 	}
 }
 
#3 lore raw
Quoted 28 lines · Takashi Iwai <[email protected]> 于2026年4月2日周四 21:00写道:
Quoted 19 lines · Takashi Iwai
Quoted 9 lines · Cryolitia PukNgae

It(ID 31b2:0111 JU Jiu) reports a MIN value -12800 for volume control, but will mute when setting it less than -10880.

Thanks to my girlfriend Kagura for reporting this issue.

Applied to for-next branch now.

Quoted 3 lines

---
Btw, is it a good idea for turn the volume_control_quirks from switch-case to a table and sort it accroding to USB VID&PID?

Quoted 5 lines

Yeah, this might be better, indeed.

But the quirk isn't really straightforward for those, maybe we need a matching of USB id plus kctl id name string, then update the cval fields conditionally with flags. Let me cook later...

Quoted 6 lines

This doesn't look easy. A quick hack is like below, but it doesn't reduce the code, ended up with more lines.

So, unless any other clever implementation is given, still not much worth for it, as it seems.

Hi Takashi,

Thanks for trying this out.

I think the current quirk list is probably still too small to justify a refactoring like this. For now, it may be better to keep the existing code and revisit it later if more devices with similar quirks show up.

Best regards,
Cryolitia PukNgae

Quoted 243 lines

Takashi

-- 8< --

sound/usb/mixer.c +108 -93
@@ -1070,11 +1070,107 @@ void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl)
  * interface to ALSA control for feature/mixer units
  */
 
+#define VOL_QUIRK_MIN  BIT(0)
+#define VOL_QUIRK_MAX  BIT(1)
+#define VOL_QUIRK_RES  BIT(2)
+
+struct mixer_volume_quirk {
+       unsigned int id;
+       const char *ctl_name;
+       unsigned int to_update;
+       int min, max, res;
+};
+
+#define QUIRK_ENTRY(vid, pid, name) \
+       .id = USB_ID(vid, pid), .ctl_name = (name)
+#define QUIRK_MIN(v) \
+       .to_update = VOL_QUIRK_MIN, .min = (v)
+#define QUIRK_RES(v) \
+       .to_update = VOL_QUIRK_RES, .res = (v)
+#define QUIRK_MINMAX(vmin, vmax) \
+       .to_update = VOL_QUIRK_MIN | VOL_QUIRK_MAX, .min = (vmin), .max = (vmax)
+#define QUIRK_MINMAXRES(vmin, vmax, vres) \
+       .to_update = VOL_QUIRK_MIN | VOL_QUIRK_MAX | VOL_QUIRK_RES, \
+       .min = (vmin), .max = (vmax), .res = (vres)
+
+static const struct mixer_volume_quirk mixer_volume_quirk_entries[] = {
+       /* M-Audio Fast Track C400 */
+       { QUIRK_ENTRY(0x0763, 0x2030, "Effect Duration"),
+         QUIRK_MINMAXRES(0x0000, 0xffff, 0x00e6) },
+       { QUIRK_ENTRY(0x0763, 0x2030, "Effect Volume"),
+         QUIRK_MINMAX(0x00, 0xff) },
+       { QUIRK_ENTRY(0x0763, 0x2030, "Effect Feedback Volume"),
+         QUIRK_MINMAX(0x00, 0xff) },
+       { QUIRK_ENTRY(0x0763, 0x2030, "Effect Return"),
+         QUIRK_MINMAXRES(0xb706, 0xff7b, 0x0073) },
+       { QUIRK_ENTRY(0x0763, 0x2030, "Playback Volume"),
+         QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+       { QUIRK_ENTRY(0x0763, 0x2030, "Effect Send"),
+         QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+
+       /* M-Audio Fast Track C600 */
+       { QUIRK_ENTRY(0x0763, 0x2031, "Effect Duration"),
+         QUIRK_MINMAXRES(0x0000, 0xffff, 0x00e6) },
+       { QUIRK_ENTRY(0x0763, 0x2031, "Effect Volume"),
+         QUIRK_MINMAX(0x00, 0xff) },
+       { QUIRK_ENTRY(0x0763, 0x2031, "Effect Feedback Volume"),
+         QUIRK_MINMAX(0x00, 0xff) },
+       { QUIRK_ENTRY(0x0763, 0x2031, "Effect Return"),
+         QUIRK_MINMAXRES(0xb706, 0xff7b, 0x0073) },
+       { QUIRK_ENTRY(0x0763, 0x2031, "Playback Volume"),
+         QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+       { QUIRK_ENTRY(0x0763, 0x2031, "Effect Send"),
+         QUIRK_MINMAXRES(0xb5fb, 0xfcfe, 0x0073) }, /* -73 dB = 0xb6ff */
+
+       /* M-Audio Fast Track Ultra 8R */
+       { QUIRK_ENTRY(0x0763, 0x2081, "Effect Duration"),
+         QUIRK_MINMAXRES(0x0000, 0x7f00, 0x0100) },
+       { QUIRK_ENTRY(0x0763, 0x2081, "Effect Volume"),
+         QUIRK_MINMAX(0x00, 0x7f) },
+       { QUIRK_ENTRY(0x0763, 0x2081, "Effect Feedback Volume"),
+         QUIRK_MINMAX(0x00, 0x7f) },
+
+       /* M-Audio Fast Track Ultra */
+       { QUIRK_ENTRY(0x0763, 0x2080, "Effect Duration"),
+         QUIRK_MINMAXRES(0x0000, 0x7f00, 0x0100) },
+       { QUIRK_ENTRY(0x0763, 0x2080, "Effect Volume"),
+         QUIRK_MINMAX(0x00, 0x7f) },
+       { QUIRK_ENTRY(0x0763, 0x2080, "Effect Feedback Volume"),
+         QUIRK_MINMAX(0x00, 0x7f) },
+
+       /* CM102-A+/102S+ */
+       { QUIRK_ENTRY(0x0d8c, 0x0103, "PCM Playback Volume"),
+         QUIRK_MIN(-256) },
+
+       /* MS LifeChat LX-3000 Headset */
+       { QUIRK_ENTRY(0x045e, 0x070f, "Speaker Playback Volume"),
+         QUIRK_RES(192) },
+
+       /* QuickCam E3500 */
+       { QUIRK_ENTRY(0x046d, 0x09a4, "Mic Capture Volume"),
+         QUIRK_MINMAXRES(6080, 8768, 192) },
+
+       /* MOONDROP Quark2 */
+       { QUIRK_ENTRY(0x3302, 0x12db, "PCM Playback Volume"),
+         QUIRK_MIN(-14208) }, /* Mute under it */
+
+       /* Huawei Technologies Co., Ltd. CM-Q3 */
+       { QUIRK_ENTRY(0x12d1, 0x3a07, "PCM Playback Volume"),
+         QUIRK_MIN(-11264) }, /* Mute under it */
+
+       /* MOONDROP JU Jiu */
+       { QUIRK_ENTRY(0x31b2, 0x0111, "PCM Playback Volume"),
+         QUIRK_MIN(-10880) }, /* Mute under it */
+
+       {} /* terminator */
+};
+
 /* volume control quirks */
 static void volume_control_quirks(struct usb_mixer_elem_info *cval,
                                  struct snd_kcontrol *kctl)
 {
        struct snd_usb_audio *chip = cval->head.mixer->chip;
+       const struct mixer_volume_quirk *q;
 
        if (chip->quirk_flags & QUIRK_FLAG_MIC_RES_384) {
                if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
@@ -1090,71 +1186,21 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
                }
        }
 
-       switch (chip->usb_id) {
-       case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
-       case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
-               if (strcmp(kctl->id.name, "Effect Duration") == 0) {
-                       cval->min = 0x0000;
-                       cval->max = 0xffff;
-                       cval->res = 0x00e6;
-                       break;
-               }
-               if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
-                   strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
-                       cval->min = 0x00;
-                       cval->max = 0xff;
-                       break;
-               }
-               if (strstr(kctl->id.name, "Effect Return") != NULL) {
-                       cval->min = 0xb706;
-                       cval->max = 0xff7b;
-                       cval->res = 0x0073;
-                       break;
-               }
-               if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
-                       (strstr(kctl->id.name, "Effect Send") != NULL)) {
-                       cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
-                       cval->max = 0xfcfe;
-                       cval->res = 0x0073;
-               }
-               break;
-
-       case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
-       case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
-               if (strcmp(kctl->id.name, "Effect Duration") == 0) {
-                       usb_audio_info(chip,
-                                      "set quirk for FTU Effect Duration\n");
-                       cval->min = 0x0000;
-                       cval->max = 0x7f00;
-                       cval->res = 0x0100;
+       for (q = mixer_volume_quirk_entries; q->id; q++) {
+               if (q->id == chip->usb_id &&
+                   !strcmp(q->ctl_name, kctl->id.name)) {
+                       if (q->to_update & VOL_QUIRK_MIN)
+                               cval->min = q->min;
+                       if (q->to_update & VOL_QUIRK_MAX)
+                               cval->max = q->max;
+                       if (q->to_update & VOL_QUIRK_RES)
+                               cval->res = q->res;
                        break;
                }
-               if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
-                   strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
-                       usb_audio_info(chip,
-                                      "set quirks for FTU Effect Feedback/Volume\n");
-                       cval->min = 0x00;
-                       cval->max = 0x7f;
-                       break;
-               }
-               break;
-
-       case USB_ID(0x0d8c, 0x0103):
-               if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-                       usb_audio_info(chip,
-                                "set volume quirk for CM102-A+/102S+\n");
-                       cval->min = -256;
-               }
-               break;
-
-       case USB_ID(0x045e, 0x070f): /* MS LifeChat LX-3000 Headset */
-               if (!strcmp(kctl->id.name, "Speaker Playback Volume")) {
-                       usb_audio_info(chip,
-                               "set volume quirk for MS LifeChat LX-3000\n");
-                       cval->res = 192;
-               }
-               break;
+       }
 
+       /* other exceptional cases */
+       switch (chip->usb_id) {
        case USB_ID(0x0471, 0x0101):
        case USB_ID(0x0471, 0x0104):
        case USB_ID(0x0471, 0x0105):
@@ -1172,16 +1218,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
                }
                break;
 
-       case USB_ID(0x046d, 0x09a4):
-               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
-                       usb_audio_info(chip,
-                               "set volume quirk for QuickCam E3500\n");
-                       cval->min = 6080;
-                       cval->max = 8768;
-                       cval->res = 192;
-               }
-               break;
-
        case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */
                if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
                        strstr(kctl->id.name, "Capture Volume") != NULL) {
@@ -1190,27 +1226,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
                        cval->res = 1;
                }
                break;
-       case USB_ID(0x3302, 0x12db): /* MOONDROP Quark2 */
-               if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-                       usb_audio_info(chip,
-                               "set volume quirk for MOONDROP Quark2\n");
-                       cval->min = -14208; /* Mute under it */
-               }
-               break;
-       case USB_ID(0x12d1, 0x3a07): /* Huawei Technologies Co., Ltd. CM-Q3 */
-               if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-                       usb_audio_info(chip,
-                                      "set volume quirk for Huawei Technologies Co., Ltd. CM-Q3\n");
-                       cval->min = -11264; /* Mute under it */
-               }
-               break;
-       case USB_ID(0x31b2, 0x0111): /* MOONDROP JU Jiu */
-               if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
-                       usb_audio_info(chip,
-                                      "set volume quirk for MOONDROP JU Jiu\n");
-                       cval->min = -10880; /* Mute under it */
-               }
-               break;
        }
 }