>From e5ce94c6156d1c588f29745ade06d1d76c87a0a1 Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Thu, 11 Sep 2014 11:04:42 +0200
Subject: [PATCH] ALSA: hda - Do not enable unsol events on phantom jacks

To make sure we don't enable unsol events on phantom jacks,
we move the logic for determining what a phantom jack is to
snd_hda_jack_tbl_new.

Reported-by: Adam Richter <adam_richter2004@yahoo.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 sound/pci/hda/hda_jack.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9746d73..376ce8f 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -105,6 +105,12 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
 		return NULL;
 	jack->nid = nid;
 	jack->jack_dirty = 1;
+	if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN) {
+		unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+		unsigned int conn = get_defcfg_connect(def_conf);
+		if ((conn != AC_JACK_PORT_COMPLEX) || !is_jack_detectable(codec, nid))
+			jack->phantom_jack = 1;
+	}
 	jack->tag = codec->jacktbl.used;
 	return jack;
 }
@@ -230,6 +236,8 @@ int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
 		jack->action = action;
 	if (cb)
 		jack->callback = cb;
+	if (jack->phantom_jack)
+		return 0;
 	if (codec->jackpoll_interval > 0)
 		return 0; /* No unsol if we're polling instead */
 	return snd_hda_codec_write_cache(codec, nid, 0,
@@ -334,8 +342,8 @@ static void hda_free_jack_priv(struct snd_jack *jack)
  * This assigns a jack-detection kctl to the given pin.  The kcontrol
  * will have the given name and index.
  */
-static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
-			  const char *name, int idx, bool phantom_jack)
+int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
+			  const char *name, int idx)
 {
 	struct hda_jack_tbl *jack;
 	struct snd_kcontrol *kctl;
@@ -353,12 +361,11 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 	if (err < 0)
 		return err;
 	jack->kctl = kctl;
-	jack->phantom_jack = !!phantom_jack;
 
 	state = snd_hda_jack_detect(codec, nid);
 	snd_kctl_jack_report(codec->bus->card, kctl, state);
 #ifdef CONFIG_SND_HDA_INPUT_JACK
-	if (!phantom_jack) {
+	if (!jack->phantom_jack) {
 		jack->type = get_input_jack_type(codec, nid);
 		err = snd_jack_new(codec->bus->card, name, jack->type,
 				   &jack->jack);
@@ -371,12 +378,6 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 #endif
 	return 0;
 }
-
-int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
-			  const char *name, int idx)
-{
-	return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
-}
 EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
 
 /* get the unique index number for the given kctl name */
@@ -406,7 +407,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
 	unsigned int def_conf, conn;
 	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 	int idx, err;
-	bool phantom_jack;
+	struct hda_jack_tbl *jack;
 
 	if (!nid)
 		return 0;
@@ -414,23 +415,25 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
 	conn = get_defcfg_connect(def_conf);
 	if (conn == AC_JACK_PORT_NONE)
 		return 0;
-	phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
-		       !is_jack_detectable(codec, nid);
 
 	if (base_name) {
 		strlcpy(name, base_name, sizeof(name));
 		idx = 0;
 	} else
 		snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
-	if (phantom_jack)
+
+	jack = snd_hda_jack_tbl_new(codec, nid);
+	if (!jack)
+		return -ENOMEM;
+	if (jack->phantom_jack)
 		/* Example final name: "Internal Mic Phantom Jack" */
 		strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
 	idx = get_unique_index(codec, name, idx);
-	err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
+	err = snd_hda_jack_add_kctl(codec, nid, name, idx);
 	if (err < 0)
 		return err;
 
-	if (!phantom_jack)
+	if (!jack->phantom_jack)
 		return snd_hda_jack_detect_enable(codec, nid, 0);
 	return 0;
 }
-- 
1.9.1

