summary refs log tree commit diff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-05-20 09:23:05 +0200
committerTakashi Iwai <tiwai@suse.de>2008-05-20 11:56:33 +0200
commitebc7a406633acefc6d12c1ccc9441bfef69e0f33 (patch)
treec9d51a0c3f5f6c8aa0405b242df787dac33a427a /sound
parent4b7afb0d0d23b298a7e6d30eaba0679449542d2e (diff)
downloadlinux-ebc7a406633acefc6d12c1ccc9441bfef69e0f33.tar.gz
[ALSA] hda - Fix ALC262 fujitsu model
Fixed the speaker auto-mute with two laptop and docking headphones.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Acked-by: Tony Vroon <tony@linx.net>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6d4df45e81e0..ad2763c86bf5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -8757,35 +8757,39 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {
 	},
 };
 
-/* mute/unmute internal speaker according to the hp jack and mute state */
+/* mute/unmute internal speaker according to the hp jacks and mute state */
 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
 {
 	struct alc_spec *spec = codec->spec;
 	unsigned int mute;
 
 	if (force || !spec->sense_updated) {
-		unsigned int present_int_hp, present_dock_hp;
+		unsigned int present;
 		/* need to execute and sync at first */
 		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
-		present_int_hp = snd_hda_codec_read(codec, 0x14, 0,
-					AC_VERB_GET_PIN_SENSE, 0);
-		snd_hda_codec_read(codec, 0x1B, 0, AC_VERB_SET_PIN_SENSE, 0);
-		present_dock_hp = snd_hda_codec_read(codec, 0x1b, 0,
-					AC_VERB_GET_PIN_SENSE, 0);
-		spec->jack_present = (present_int_hp & 0x80000000) != 0;
-		spec->jack_present |= (present_dock_hp & 0x80000000) != 0;
+		/* check laptop HP jack */
+		present = snd_hda_codec_read(codec, 0x14, 0,
+					     AC_VERB_GET_PIN_SENSE, 0);
+		/* need to execute and sync at first */
+		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
+		/* check docking HP jack */
+		present |= snd_hda_codec_read(codec, 0x1b, 0,
+					      AC_VERB_GET_PIN_SENSE, 0);
+		if (present & AC_PINSENSE_PRESENCE)
+			spec->jack_present = 1;
+		else
+			spec->jack_present = 0;
 		spec->sense_updated = 1;
 	}
-	if (spec->jack_present) {
-		/* mute internal speaker */
-		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
-					 HDA_AMP_MUTE, HDA_AMP_MUTE);
-	} else {
-		/* unmute internal speaker if necessary */
+	/* unmute internal speaker only if both HPs are unplugged and
+	 * master switch is on
+	 */
+	if (spec->jack_present)
+		mute = HDA_AMP_MUTE;
+	else
 		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
-		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
-					 HDA_AMP_MUTE, mute);
-	}
+	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+				 HDA_AMP_MUTE, mute);
 }
 
 /* unsolicited event for HP jack sensing */
@@ -8797,6 +8801,11 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
 	alc262_fujitsu_automute(codec, 1);
 }
 
+static void alc262_fujitsu_init_hook(struct hda_codec *codec)
+{
+	alc262_fujitsu_automute(codec, 1);
+}
+
 /* bind volumes of both NID 0x0c and 0x0d */
 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
 	.ops = &snd_hda_bind_vol,
@@ -9570,6 +9579,7 @@ static struct alc_config_preset alc262_presets[] = {
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_fujitsu_capture_source,
 		.unsol_event = alc262_fujitsu_unsol_event,
+		.init_hook = alc262_fujitsu_init_hook,
 	},
 	[ALC262_HP_BPC] = {
 		.mixers = { alc262_HP_BPC_mixer },