[alsa-devel] [PATCH 3/5] ALSA: hda - Allow multiple ADCs for mic mute LED controls

Takashi Iwai tiwai at suse.de
Thu Jun 21 14:24:59 CEST 2018


Instead of refusing, allow the configuration with the multiple ADCs
(thus multiple capture switches) for enabling the mic mute LED.
This has been done for Sigmatel/IDT codecs, and we treat the OR-ed
values from all capture switches as the boolean condition.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/pci/hda/hda_generic.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index cdce9ce6b901..942f96e184b6 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3922,7 +3922,7 @@ static void call_micmute_led_update(struct hda_codec *codec)
 		val = 0;
 		break;
 	case MICMUTE_LED_FOLLOW_CAPTURE:
-		val = spec->micmute_led.capture;
+		val = !!spec->micmute_led.capture;
 		break;
 	case MICMUTE_LED_FOLLOW_MUTE:
 	default:
@@ -3942,17 +3942,21 @@ static void update_micmute_led(struct hda_codec *codec,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_gen_spec *spec = codec->spec;
+	unsigned int mask;
 
 	if (spec->micmute_led.old_hook)
 		spec->micmute_led.old_hook(codec, kcontrol, ucontrol);
 
 	if (!ucontrol)
 		return;
-	if (!strcmp("Capture Switch", ucontrol->id.name) &&
-	    !ucontrol->id.index) {
+	mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	if (!strcmp("Capture Switch", ucontrol->id.name)) {
 		/* TODO: How do I verify if it's a mono or stereo here? */
-		spec->micmute_led.capture = (ucontrol->value.integer.value[0] ||
-					     ucontrol->value.integer.value[1]);
+		if (ucontrol->value.integer.value[0] ||
+		    ucontrol->value.integer.value[1])
+			spec->micmute_led.capture |= mask;
+		else
+			spec->micmute_led.capture &= ~mask;
 		call_micmute_led_update(codec);
 	}
 }
@@ -4008,25 +4012,17 @@ static const struct snd_kcontrol_new micmute_led_mode_ctl = {
  * @hook: the callback for updating LED
  *
  * Called from the codec drivers for offering the mic mute LED controls.
- * Only valid for a single ADC (or a single input).  When established, it
- * sets up cap_sync_hook and triggers the callback at each time when the
- * capture mixer switch changes.  The callback is supposed to update the LED
- * accordingly.
+ * When established, it sets up cap_sync_hook and triggers the callback at
+ * each time when the capture mixer switch changes.  The callback is supposed
+ * to update the LED accordingly.
  *
- * Returns 1 if the hook is established, 0 if skipped (no valid config), or
- * a negative error code.
+ * Returns 0 if the hook is established or a negative error code.
  */
 int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
 				void (*hook)(struct hda_codec *))
 {
 	struct hda_gen_spec *spec = codec->spec;
 
-	if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch) {
-		codec_dbg(codec,
-			  "Skipping micmute LED control due to several ADCs");
-		return 0;
-	}
-
 	spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
 	spec->micmute_led.capture = 0;
 	spec->micmute_led.led_value = 0;
@@ -4035,7 +4031,7 @@ int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
 	spec->cap_sync_hook = update_micmute_led;
 	if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
 		return -ENOMEM;
-	return 1;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led);
 
-- 
2.17.1



More information about the Alsa-devel mailing list