Home Home > GIT Browse > stable-xen
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-08-22 19:55:58 +0200
committerTakashi Iwai <tiwai@suse.de>2017-08-22 19:55:58 +0200
commita3c362f9ead01492504c051c0db1316a1ff81e51 (patch)
tree752a4e4e539c3788523e6a929772073bda9e8476
parentee50b897ce5bb0d39a03f788f6386f5f9dce854a (diff)
ALSA: hda - Implement mic-mute LED mode enum (bsc#1055013).
-rw-r--r--patches.drivers/ALSA-hda-Implement-mic-mute-LED-mode-enum149
-rw-r--r--series.conf1
2 files changed, 150 insertions, 0 deletions
diff --git a/patches.drivers/ALSA-hda-Implement-mic-mute-LED-mode-enum b/patches.drivers/ALSA-hda-Implement-mic-mute-LED-mode-enum
new file mode 100644
index 0000000000..e2b999e454
--- /dev/null
+++ b/patches.drivers/ALSA-hda-Implement-mic-mute-LED-mode-enum
@@ -0,0 +1,149 @@
+From 62a939477173fabfe9f52114fab878a00b87f9a3 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 22 Aug 2017 16:52:10 +0200
+Subject: [PATCH] ALSA: hda - Implement mic-mute LED mode enum
+References: bsc#1055013
+Git-commit: 62a939477173fabfe9f52114fab878a00b87f9a3
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+Dell laptops have another LED for mic-mute in addition to the master
+mute. The former is tied with the capture switch (in a reverse way)
+while the latter is tied with the master playback switch. We already
+have an enum control to change the behavior for the master mute LED in
+different ways, e.g. keeping always off or turning off at mute. But,
+the mic-mute LED has no such management but its behavior is
+hard-coded.
+
+This patch implements an enum control to change the mic-mute LED
+behavior like what we have for the master mute LED. The ctl provides
+four modes: keep-on, keep-off, follow-capture and follow-mute. The
+default mode is the last one, follow-mute, which follows the capture
+mute, i.e. LED turning on when the capture is off, and turning off
+when the capture is active.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/dell_wmi_helper.c | 87 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 81 insertions(+), 6 deletions(-)
+
+--- a/sound/pci/hda/dell_wmi_helper.c
++++ b/sound/pci/hda/dell_wmi_helper.c
+@@ -5,12 +5,47 @@
+ #if IS_ENABLED(CONFIG_DELL_LAPTOP)
+ #include <linux/dell-led.h>
+
++enum {
++ MICMUTE_LED_ON,
++ MICMUTE_LED_OFF,
++ MICMUTE_LED_FOLLOW_CAPTURE,
++ MICMUTE_LED_FOLLOW_MUTE,
++};
++
++static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE;
++static int dell_capture;
+ static int dell_led_value;
+ static int (*dell_micmute_led_set_func)(int);
+ static void (*dell_old_cap_hook)(struct hda_codec *,
+ struct snd_kcontrol *,
+ struct snd_ctl_elem_value *);
+
++static void call_micmute_led_update(void)
++{
++ int val;
++
++ switch (dell_led_mode) {
++ case MICMUTE_LED_ON:
++ val = 1;
++ break;
++ case MICMUTE_LED_OFF:
++ val = 0;
++ break;
++ case MICMUTE_LED_FOLLOW_CAPTURE:
++ val = dell_capture;
++ break;
++ case MICMUTE_LED_FOLLOW_MUTE:
++ default:
++ val = !dell_capture;
++ break;
++ }
++
++ if (val == dell_led_value)
++ return;
++ dell_led_value = val;
++ dell_micmute_led_set_func(dell_led_value);
++}
++
+ static void update_dell_wmi_micmute_led(struct hda_codec *codec,
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+@@ -22,15 +57,54 @@ static void update_dell_wmi_micmute_led(
+ return;
+ if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
+ /* TODO: How do I verify if it's a mono or stereo here? */
+- int val = (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) ? 0 : 1;
+- if (val == dell_led_value)
+- return;
+- dell_led_value = val;
+- if (dell_micmute_led_set_func)
+- dell_micmute_led_set_func(dell_led_value);
++ dell_capture = (ucontrol->value.integer.value[0] ||
++ ucontrol->value.integer.value[1]);
++ call_micmute_led_update();
+ }
+ }
+
++static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_info *uinfo)
++{
++ static const char * const texts[] = {
++ "On", "Off", "Follow Capture", "Follow Mute",
++ };
++
++ return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
++}
++
++static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ ucontrol->value.enumerated.item[0] = dell_led_mode;
++ return 0;
++}
++
++static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ unsigned int mode;
++
++ mode = ucontrol->value.enumerated.item[0];
++ if (mode > MICMUTE_LED_FOLLOW_MUTE)
++ mode = MICMUTE_LED_FOLLOW_MUTE;
++ if (mode == dell_led_mode)
++ return 0;
++ dell_led_mode = mode;
++ call_micmute_led_update();
++ return 1;
++}
++
++static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = {
++ {
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .name = "Mic Mute-LED Mode",
++ .info = dell_mic_mute_led_mode_info,
++ .get = dell_mic_mute_led_mode_get,
++ .put = dell_mic_mute_led_mode_put,
++ },
++ {}
++};
+
+ static void alc_fixup_dell_wmi(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+@@ -55,6 +129,7 @@ static void alc_fixup_dell_wmi(struct hd
+ dell_old_cap_hook = spec->gen.cap_sync_hook;
+ spec->gen.cap_sync_hook = update_dell_wmi_micmute_led;
+ removefunc = false;
++ add_mixer(spec, dell_mic_mute_mode_ctls);
+ }
+ }
+
diff --git a/series.conf b/series.conf
index 97bc7b073d..41e7ba63fa 100644
--- a/series.conf
+++ b/series.conf
@@ -361,6 +361,7 @@
##########################################################
# Sound
##########################################################
+ patches.drivers/ALSA-hda-Implement-mic-mute-LED-mode-enum
########################################################
# Char / serial