summaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-06-19 12:42:03 +0200
committerTakashi Iwai <tiwai@suse.de>2018-06-21 13:54:36 +0200
commitc647f806b8c227de05f7f91b0ba8450b58cb3dfe (patch)
treee035d52d7714cf1de76051b6a9ae41d2a813b461 /sound/pci
parent184e302b46c94bfb1d53fe3d4c925a45a6990430 (diff)
ALSA: hda - Allow multiple ADCs for mic mute LED controls
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@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_generic.c32
1 files 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);