]> err.no Git - linux-2.6/blobdiff - sound/pci/hda/patch_realtek.c
[ALSA] hda-codec - Fix Toshiba A135 model selection
[linux-2.6] / sound / pci / hda / patch_realtek.c
index 778853c0de8caa470fecbc62fd87e39ae3e97cb2..e4064f997e8c0f13780ebbed0cf0e685c91efd95 100644 (file)
@@ -103,6 +103,7 @@ enum {
 enum {
        ALC268_3ST,
        ALC268_TOSHIBA,
+       ALC268_ACER,
        ALC268_AUTO,
        ALC268_MODEL_LAST /* last tag */
 };
@@ -5275,6 +5276,20 @@ static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
                            AC_VERB_SET_GPIO_DATA, gpiostate);
 }
 
+/* set up GPIO at initialization */
+static void alc885_macpro_init_hook(struct hda_codec *codec)
+{
+       alc882_gpio_mute(codec, 0, 0);
+       alc882_gpio_mute(codec, 1, 0);
+}
+
+/* set up GPIO and update auto-muting at initialization */
+static void alc885_imac24_init_hook(struct hda_codec *codec)
+{
+       alc885_macpro_init_hook(codec);
+       alc885_imac24_automute(codec);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -5479,6 +5494,7 @@ static struct alc_config_preset alc882_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
                .channel_mode = alc882_ch_modes,
                .input_mux = &alc882_capture_source,
+               .init_hook = alc885_macpro_init_hook,
        },
        [ALC885_IMAC24] = {
                .mixers = { alc885_imac24_mixer },
@@ -5491,7 +5507,7 @@ static struct alc_config_preset alc882_presets[] = {
                .channel_mode = alc882_ch_modes,
                .input_mux = &alc882_capture_source,
                .unsol_event = alc885_imac24_unsol_event,
-               .init_hook = alc885_imac24_automute,
+               .init_hook = alc885_imac24_init_hook,
        },
        [ALC882_TARGA] = {
                .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
@@ -5694,11 +5710,6 @@ static int patch_alc882(struct hda_codec *codec)
        if (board_config != ALC882_AUTO)
                setup_preset(spec, &alc882_presets[board_config]);
 
-       if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
-               alc882_gpio_mute(codec, 0, 0);
-               alc882_gpio_mute(codec, 1, 0);
-       }
-
        spec->stream_name_analog = "ALC882 Analog";
        spec->stream_analog_playback = &alc882_pcm_analog_playback;
        spec->stream_analog_capture = &alc882_pcm_analog_capture;
@@ -6564,18 +6575,41 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
                alc883_lenovo_101e_ispeaker_automute(codec);
 }
 
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_acer_aspire_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+       snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+}
+
+static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc883_acer_aspire_automute(codec);
+}
+
 static struct hda_verb alc883_acer_eapd_verbs[] = {
        /* HP Pin: output 0 (0x0c) */
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
        /* Front Pin: output 0 (0x0c) */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
         /* eanable EAPD on medion laptop */
        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
        {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
+       /* enable unsolicited event */
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
        { }
 };
 
@@ -6717,6 +6751,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
+       SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
@@ -6821,8 +6856,7 @@ static struct alc_config_preset alc883_presets[] = {
                .init_hook = alc883_tagra_automute,
        },
        [ALC883_ACER] = {
-               .mixers = { alc883_base_mixer,
-                           alc883_chmode_mixer },
+               .mixers = { alc883_base_mixer },
                /* On TravelMate laptops, GPIO 0 enables the internal speaker
                 * and the headphone jack.  Turn this on and rely on the
                 * standard mute methods whenever the user wants to turn
@@ -6838,12 +6872,7 @@ static struct alc_config_preset alc883_presets[] = {
                .input_mux = &alc883_capture_source,
        },
        [ALC883_ACER_ASPIRE] = {
-               .mixers = { alc883_acer_aspire_mixer, alc883_chmode_mixer },
-               /* On TravelMate laptops, GPIO 0 enables the internal speaker
-                * and the headphone jack.  Turn this on and rely on the
-                * standard mute methods whenever the user wants to turn
-                * these outputs off.
-                */
+               .mixers = { alc883_acer_aspire_mixer },
                .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
@@ -6853,6 +6882,8 @@ static struct alc_config_preset alc883_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
                .channel_mode = alc883_3ST_2ch_modes,
                .input_mux = &alc883_capture_source,
+               .unsol_event = alc883_acer_aspire_unsol_event,
+               .init_hook = alc883_acer_aspire_automute,
        },
        [ALC883_MEDION] = {
                .mixers = { alc883_fivestack_mixer,
@@ -6882,8 +6913,7 @@ static struct alc_config_preset alc883_presets[] = {
                .init_hook = alc883_medion_md2_automute,
        },      
        [ALC883_LAPTOP_EAPD] = {
-               .mixers = { alc883_base_mixer,
-                           alc883_chmode_mixer },
+               .mixers = { alc883_base_mixer },
                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
@@ -8234,6 +8264,58 @@ static struct hda_verb alc268_eapd_verbs[] = {
        { }
 };
 
+/* Toshiba specific */
+#define alc268_toshiba_automute        alc262_hippo_automute
+
+static struct hda_verb alc268_toshiba_verbs[] = {
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       { } /* end */
+};
+
+/* Acer specific */
+#define alc268_acer_bind_master_vol    alc262_fujitsu_bind_master_vol
+#define alc268_acer_master_sw_put      alc262_fujitsu_master_sw_put
+#define alc268_acer_automute   alc262_fujitsu_automute
+
+static struct snd_kcontrol_new alc268_acer_mixer[] = {
+       /* output mixer control */
+       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Master Playback Switch",
+               .info = snd_hda_mixer_amp_switch_info,
+               .get = snd_hda_mixer_amp_switch_get,
+               .put = alc268_acer_master_sw_put,
+               .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+       },
+       { }
+};
+
+static struct hda_verb alc268_acer_verbs[] = {
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+       { }
+};
+
+/* unsolicited event for HP jack sensing */
+static void alc268_toshiba_unsol_event(struct hda_codec *codec,
+                                      unsigned int res)
+{
+       if ((res >> 28) != ALC880_HP_EVENT)
+               return;
+       alc268_toshiba_automute(codec);
+}
+
+static void alc268_acer_unsol_event(struct hda_codec *codec,
+                                      unsigned int res)
+{
+       if ((res >> 28) != ALC880_HP_EVENT)
+               return;
+       alc268_acer_automute(codec, 1);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8609,21 +8691,21 @@ static void alc268_auto_init(struct hda_codec *codec)
        alc268_auto_init_analog_input(codec);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc883_loopbacks       alc880_loopbacks
-#endif
-
 /*
  * configuration and preset
  */
 static const char *alc268_models[ALC268_MODEL_LAST] = {
        [ALC268_3ST]            = "3stack",
+       [ALC268_TOSHIBA]        = "toshiba",
+       [ALC268_ACER]           = "acer",
        [ALC268_AUTO]           = "auto",
 };
 
 static struct snd_pci_quirk alc268_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
        SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
+       SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
+       SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
        {}
 };
 
@@ -8643,7 +8725,8 @@ static struct alc_config_preset alc268_presets[] = {
        },
        [ALC268_TOSHIBA] = {
                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs },
+               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+                               alc268_toshiba_verbs },
                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
                .dac_nids = alc268_dac_nids,
                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
@@ -8652,6 +8735,23 @@ static struct alc_config_preset alc268_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc268_modes),
                .channel_mode = alc268_modes,
                .input_mux = &alc268_capture_source,
+               .input_mux = &alc268_capture_source,
+               .unsol_event = alc268_toshiba_unsol_event,
+               .init_hook = alc268_toshiba_automute,
+       },
+       [ALC268_ACER] = {
+               .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
+               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+                               alc268_acer_verbs },
+               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
+               .dac_nids = alc268_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+               .adc_nids = alc268_adc_nids_alt,
+               .hp_nid = 0x02,
+               .num_channel_mode = ARRAY_SIZE(alc268_modes),
+               .channel_mode = alc268_modes,
+               .input_mux = &alc268_capture_source,
+               .unsol_event = alc268_acer_unsol_event,
        },
 };
 
@@ -10427,12 +10527,13 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
  */
 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
        [ALC660VD_3ST]          = "3stack-660",
-       [ALC660VD_3ST_DIG]= "3stack-660-digout",
+       [ALC660VD_3ST_DIG]      = "3stack-660-digout",
        [ALC861VD_3ST]          = "3stack",
        [ALC861VD_3ST_DIG]      = "3stack-digout",
        [ALC861VD_6ST_DIG]      = "6stack-digout",
        [ALC861VD_LENOVO]       = "lenovo",
        [ALC861VD_DALLAS]       = "dallas",
+       [ALC861VD_HP]           = "hp",
        [ALC861VD_AUTO]         = "auto",
 };
 
@@ -10443,11 +10544,12 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
-       SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
+       /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
        SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
        SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
        SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
+       SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
        SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
        {}