lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <s5hljvphr9r.wl%tiwai@suse.de>
Date:	Wed, 12 Nov 2008 16:56:32 +0100
From:	Takashi Iwai <tiwai@...e.de>
To:	Linus Torvalds <torvalds@...ux-foundation.org>
Cc:	Andrew Morton <akpm@...ux-foundation.org>,
	linux-kernel@...r.kernel.org
Subject: [GIT PULL] ALSA fixes

Linus,

please pull ALSA updates for 2.6.28-rc5 from:

  git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git for-linus

This contains fixes for bugs with STAC/IDT HD-audio codecs, typically
hitting Dell laptops.


Thanks!

Takashi

===

Takashi Iwai (3):
      ALSA: hda - Add missing analog-mux mixer creation for STAC9200
      ALSA: hda - Fix input pin initialization for STAC/IDT codecs
      ALSA: hda - Fix IDT/STAC multiple HP detection

---
 sound/pci/hda/patch_sigmatel.c |   85 +++++++++++++++++++++++++++++----------
 1 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e608591..4300a67 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -212,7 +212,7 @@ struct sigmatel_spec {
 	/* i/o switches */
 	unsigned int io_switch[2];
 	unsigned int clfe_swap;
-	unsigned int hp_switch;
+	unsigned int hp_switch; /* NID of HP as line-out */
 	unsigned int aloopback;
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
@@ -2443,7 +2443,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
 
-	ucontrol->value.integer.value[0] = spec->hp_switch;
+	ucontrol->value.integer.value[0] = !!spec->hp_switch;
 	return 0;
 }
 
@@ -2452,8 +2452,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
-
-	spec->hp_switch = ucontrol->value.integer.value[0];
+	int nid = kcontrol->private_value;
+ 
+	spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
 
 	/* check to be sure that the ports are upto date with
 	 * switch changes
@@ -2862,7 +2863,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
 	if (cfg->hp_outs > 1) {
 		err = stac92xx_add_control(spec,
 			STAC_CTL_WIDGET_HP_SWITCH,
-			"Headphone as Line Out Switch", 0);
+			"Headphone as Line Out Switch",
+			cfg->hp_pins[cfg->hp_outs - 1]);
 		if (err < 0)
 			return err;
 	}
@@ -3530,6 +3532,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
 	if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
 		return err;
 
+	if (spec->num_muxes > 0) {
+		err = stac92xx_auto_create_mux_input_ctls(codec);
+		if (err < 0)
+			return err;
+	}
+
 	if (spec->autocfg.dig_out_pin)
 		spec->multiout.dig_out_nid = 0x05;
 	if (spec->autocfg.dig_in_pin)
@@ -3647,14 +3655,18 @@ static int stac92xx_init(struct hda_codec *codec)
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = cfg->input_pins[i];
 		if (nid) {
-			unsigned int pinctl = snd_hda_codec_read(codec, nid,
-				0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-			/* if PINCTL already set then skip */
-			if (pinctl & AC_PINCAP_IN)
-				continue;
-			pinctl = AC_PINCTL_IN_EN;
-			if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
-				pinctl |= stac92xx_get_vref(codec, nid);
+			unsigned int pinctl;
+			if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
+				/* for mic pins, force to initialize */
+				pinctl = stac92xx_get_vref(codec, nid);
+			} else {
+				pinctl = snd_hda_codec_read(codec, nid, 0,
+					AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+				/* if PINCTL already set then skip */
+				if (pinctl & AC_PINCTL_IN_EN)
+					continue;
+			}
+			pinctl |= AC_PINCTL_IN_EN;
 			stac92xx_auto_set_pinctl(codec, nid, pinctl);
 		}
 	}
@@ -3776,11 +3788,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
 	return 0;
 }
 
+/* return non-zero if the hp-pin of the given array index isn't
+ * a jack-detection target
+ */
+static int no_hp_sensing(struct sigmatel_spec *spec, int i)
+{
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+
+	/* ignore sensing of shared line and mic jacks */
+	if (spec->line_switch &&
+	    cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
+		return 1;
+	if (spec->mic_switch &&
+	    cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
+		return 1;
+	/* ignore if the pin is set as line-out */
+	if (cfg->hp_pins[i] == spec->hp_switch)
+		return 1;
+	return 0;
+}
+
 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
-	int nid = cfg->hp_pins[cfg->hp_outs - 1];
 	int i, presence;
 
 	presence = 0;
@@ -3791,15 +3822,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 	for (i = 0; i < cfg->hp_outs; i++) {
 		if (presence)
 			break;
-		if (spec->hp_switch && cfg->hp_pins[i] == nid)
-			break;
+		if (no_hp_sensing(spec, i))
+			continue;
 		presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
 	}
 
 	if (presence) {
-		/* disable lineouts, enable hp */
+		/* disable lineouts */
 		if (spec->hp_switch)
-			stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+			stac92xx_reset_pinctl(codec, spec->hp_switch,
+					      AC_PINCTL_OUT_EN);
 		for (i = 0; i < cfg->line_outs; i++)
 			stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
 						AC_PINCTL_OUT_EN);
@@ -3811,9 +3843,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 				spec->gpio_dir, spec->gpio_data &
 				~spec->eapd_mask);
 	} else {
-		/* enable lineouts, disable hp */
+		/* enable lineouts */
 		if (spec->hp_switch)
-			stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+			stac92xx_set_pinctl(codec, spec->hp_switch,
+					    AC_PINCTL_OUT_EN);
 		for (i = 0; i < cfg->line_outs; i++)
 			stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
 						AC_PINCTL_OUT_EN);
@@ -3825,8 +3858,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 				spec->gpio_dir, spec->gpio_data |
 				spec->eapd_mask);
 	}
-	if (!spec->hp_switch && cfg->hp_outs > 1 && presence)
-		stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+	/* toggle hp outs */
+	for (i = 0; i < cfg->hp_outs; i++) {
+		unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
+		if (no_hp_sensing(spec, i))
+			continue;
+		if (presence)
+			stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
+		else
+			stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
+	}
 } 
 
 static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ