Skip to content

Commit

Permalink
ALSA: hda - Allow multiple ADCs for mic mute LED controls
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Takashi Iwai committed Jun 21, 2018
1 parent 184e302 commit c647f80
Showing 1 changed file with 14 additions and 18 deletions.
32 changes: 14 additions & 18 deletions sound/pci/hda/hda_generic.c
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit c647f80

Please sign in to comment.