ALSA: hda - Add expose_enum_ctl flag to snd_hda_add_vmaster_hook()
Takashi Iwai [Tue, 13 Mar 2012 06:55:10 +0000 (07:55 +0100)]
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>

sound/pci/hda/hda_codec.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c

index b981ea9..7a8fcc4 100644 (file)
@@ -2508,7 +2508,8 @@ static struct snd_kcontrol_new vmaster_mute_mode = {
  * 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 @@ int snd_hda_add_vmaster_hook(struct hda_codec *codec,
        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;
index 3f82ab6..0ec9248 100644 (file)
@@ -165,7 +165,8 @@ struct hda_vmaster_mute_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);
 void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
 
 /* amp value bits */
index a21a485..e6eafb1 100644 (file)
@@ -71,6 +71,7 @@ struct conexant_spec {
        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 @@ static int cx_auto_build_controls(struct hda_codec *codec)
        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 @@ static int patch_conexant_auto(struct hda_codec *codec)
 
        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)
index b69d2fe..8ea2fd6 100644 (file)
@@ -5895,7 +5895,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
        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);
index cd04e29..153b9ae 100644 (file)
@@ -1166,7 +1166,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
 
        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;
        }