ALSA: hda - Avoid automatic pin-ctl update for hp/mic when jack ctl exists
authorTakashi Iwai <tiwai@suse.de>
Thu, 7 Mar 2013 17:40:58 +0000 (18:40 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 7 Mar 2013 17:43:27 +0000 (18:43 +0100)
When the headphone mic jack enum control is created (via explicitly
specification by user), it doesn't make much sense to change the I/O
direction dynamically per capture source change, since the I/O
direction is rather controlled over the enum ctl.

This also reduces the implicit dependency between the capture source
and the hp mic jack enum ctls, which might confuse a program accessing
the whole control elements at once like alsactl.

In addition, this patch introduces update_hp_automute_hook() function
to call the proper hook function.  It's just to remove the open codes
in multiple places in hda_generic.c.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h

index c8791225b2ba2ba12e8d7472e018984f215d5fdd..fb232c118e91e3e142ebf61d384f5cd0ef40810e 100644 (file)
@@ -1890,6 +1890,17 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
  * independent HP controls
  */
 
+/* update HP auto-mute state too */
+static void update_hp_automute_hook(struct hda_codec *codec)
+{
+       struct hda_gen_spec *spec = codec->spec;
+
+       if (spec->hp_automute_hook)
+               spec->hp_automute_hook(codec, NULL);
+       else
+               snd_hda_gen_hp_automute(codec, NULL);
+}
+
 static int indep_hp_info(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_info *uinfo)
 {
@@ -1950,12 +1961,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol,
                else
                        *dacp = spec->alt_dac_nid;
 
-               /* update HP auto-mute state too */
-               if (spec->hp_automute_hook)
-                       spec->hp_automute_hook(codec, NULL);
-               else
-                       snd_hda_gen_hp_automute(codec, NULL);
-
+               update_hp_automute_hook(codec);
                ret = 1;
        }
  unlock:
@@ -2237,17 +2243,14 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force)
                                                  PIN_IN | (as_mic ? vref_val : 0));
        }
 
-       if (as_mic)
-               val |= PIN_IN;
-       else
-               val = PIN_HP;
-       set_pin_target(codec, pin, val, true);
-
-       /* update HP auto-mute state too */
-       if (spec->hp_automute_hook)
-               spec->hp_automute_hook(codec, NULL);
-       else
-               snd_hda_gen_hp_automute(codec, NULL);
+       if (!spec->hp_mic_jack_modes) {
+               if (as_mic)
+                       val |= PIN_IN;
+               else
+                       val = PIN_HP;
+               set_pin_target(codec, pin, val, true);
+               update_hp_automute_hook(codec);
+       }
 }
 
 /* create a shared input with the headphone out */
@@ -2654,6 +2657,8 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol,
                        val = snd_hda_get_default_vref(codec, nid);
        }
        snd_hda_set_pin_ctl_cache(codec, nid, val);
+       update_hp_automute_hook(codec);
+
        return 1;
 }
 
@@ -2677,6 +2682,7 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin)
        if (!knew)
                return -ENOMEM;
        knew->private_value = pin;
+       spec->hp_mic_jack_modes = 1;
        return 0;
 }
 
@@ -3800,10 +3806,7 @@ static void update_automute_all(struct hda_codec *codec)
 {
        struct hda_gen_spec *spec = codec->spec;
 
-       if (spec->hp_automute_hook)
-               spec->hp_automute_hook(codec, NULL);
-       else
-               snd_hda_gen_hp_automute(codec, NULL);
+       update_hp_automute_hook(codec);
        if (spec->line_automute_hook)
                spec->line_automute_hook(codec, NULL);
        else
index 984bf301ebbb13ff7fff12d6513488921745f3c7..094e6af7a10719b295bdd3e81a7bfbfd072b15c4 100644 (file)
@@ -221,6 +221,7 @@ struct hda_gen_spec {
        unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
        unsigned int indep_hp_enabled:1; /* independent HP enabled */
        unsigned int have_aamix_ctl:1;
+       unsigned int hp_mic_jack_modes:1;
 
        /* loopback mixing mode */
        bool aamix_mode;