1
0
Fork 0

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>
hifive-unleashed-5.1
Takashi Iwai 2018-06-19 12:42:03 +02:00
parent 184e302b46
commit c647f806b8
1 changed files with 14 additions and 18 deletions

View File

@ -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);