ALSA: hda - Add expose_enum_ctl flag to snd_hda_add_vmaster_hook()

Since it's not always safe to assume that the vmaster hook is purely the
mute-LED control, add the flag indicating whether to expose the mute-LED
enum control or not.  Currently, conexant codec sets this off for non-HP
laptops where EAPD may be used really as EAPD.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index b981ea9..7a8fcc4 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2508,7 +2508,8 @@
  * the given hook.
  */
 int snd_hda_add_vmaster_hook(struct hda_codec *codec,
-			     struct hda_vmaster_mute_hook *hook)
+			     struct hda_vmaster_mute_hook *hook,
+			     bool expose_enum_ctl)
 {
 	struct snd_kcontrol *kctl;
 
@@ -2517,6 +2518,8 @@
 	snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
 	hook->codec = codec;
 	hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
+	if (!expose_enum_ctl)
+		return 0;
 	kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
 	if (!kctl)
 		return -ENOMEM;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 3f82ab6..0ec9248 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -165,7 +165,8 @@
 };
 
 int snd_hda_add_vmaster_hook(struct hda_codec *codec,
-			     struct hda_vmaster_mute_hook *hook);
+			     struct hda_vmaster_mute_hook *hook,
+			     bool expose_enum_ctl);
 void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
 
 /* amp value bits */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a21a485..e6eafb1 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -71,6 +71,7 @@
 	int num_mixers;
 	hda_nid_t vmaster_nid;
 	struct hda_vmaster_mute_hook vmaster_mute;
+	bool vmaster_mute_led;
 
 	const struct hda_verb *init_verbs[5];	/* initialization verbs
 						 * don't forget NULL
@@ -4346,8 +4347,10 @@
 	err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
 	if (err < 0)
 		return err;
-	if (spec->vmaster_mute.hook && spec->vmaster_mute.sw_kctl) {
-		err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
+	if (spec->vmaster_mute.sw_kctl) {
+		spec->vmaster_mute.hook = cx_auto_vmaster_hook;
+		err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
+					       spec->vmaster_mute_led);
 		if (err < 0)
 			return err;
 	}
@@ -4476,11 +4479,17 @@
 
 	apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
 
-	/* add EAPD vmaster hook to all HP machines */
-	/* NOTE: this should be applied via fixup once when the generic
-	 *       fixup code is merged to hda_codec.c
+	/* Show mute-led control only on HP laptops
+	 * This is a sort of white-list: on HP laptops, EAPD corresponds
+	 * only to the mute-LED without actualy amp function.  Meanwhile,
+	 * others may use EAPD really as an amp switch, so it might be
+	 * not good to expose it blindly.
 	 */
-	spec->vmaster_mute.hook = cx_auto_vmaster_hook;
+	switch (codec->subsystem_id >> 16) {
+	case 0x103c:
+		spec->vmaster_mute_led = 1;
+		break;
+	}
 
 	err = cx_auto_search_adcs(codec);
 	if (err < 0)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b69d2fe..8ea2fd6 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5895,7 +5895,7 @@
 	switch (action) {
 	case ALC_FIXUP_ACT_BUILD:
 		spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
-		snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
+		snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
 		/* fallthru */
 	case ALC_FIXUP_ACT_INIT:
 		snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index cd04e29..153b9ae 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1166,7 +1166,7 @@
 
 	if (spec->gpio_led) {
 		spec->vmaster_mute.hook = stac92xx_vmaster_hook;
-		err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
+		err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
 		if (err < 0)
 			return err;
 	}