ALSA: hda - Avoid automatic pin-ctl update for hp/mic when jack ctl exists

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>
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index c879122..fb232c1 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -1890,6 +1890,17 @@
  * 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 @@
 		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 @@
 						  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 @@
 			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 @@
 	if (!knew)
 		return -ENOMEM;
 	knew->private_value = pin;
+	spec->hp_mic_jack_modes = 1;
 	return 0;
 }
 
@@ -3800,10 +3806,7 @@
 {
 	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