[ALSA] hda - Fix ALC262 fujitsu model
authorTakashi Iwai <tiwai@suse.de>
Tue, 20 May 2008 07:23:05 +0000 (09:23 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 May 2008 09:56:33 +0000 (11:56 +0200)
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>
sound/pci/hda/patch_realtek.c

index 6d4df45e81e033372354d1275a1681bea4e46b73..ad2763c86bf5824170a47451dfe3f70f336d627e 100644 (file)
@@ -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 },