]> Pileus Git - ~andy/linux/blobdiff - sound/pci/hda/patch_sigmatel.c
ALSA: hda: Add STAC_DELL_M4_3 quirk
[~andy/linux] / sound / pci / hda / patch_sigmatel.c
index 1633ef2c654a269682ef89c92541ab5f09e7ff2a..9047dc76b007df797545c393db03c019ed846dc5 100644 (file)
 #include "hda_beep.h"
 
 #define NUM_CONTROL_ALLOC      32
+
+#define STAC_VREF_EVENT                0x00
+#define STAC_INSERT_EVENT      0x10
 #define STAC_PWR_EVENT         0x20
 #define STAC_HP_EVENT          0x30
-#define STAC_VREF_EVENT                0x40
 
 enum {
        STAC_REF,
@@ -82,6 +84,7 @@ enum {
        STAC_92HD71BXX_REF,
        STAC_DELL_M4_1,
        STAC_DELL_M4_2,
+       STAC_DELL_M4_3,
        STAC_HP_M4,
        STAC_92HD71BXX_MODELS
 };
@@ -135,6 +138,7 @@ struct sigmatel_spec {
        unsigned int num_mixers;
 
        int board_config;
+       unsigned int eapd_switch: 1;
        unsigned int surr_switch: 1;
        unsigned int line_switch: 1;
        unsigned int mic_switch: 1;
@@ -1668,10 +1672,17 @@ static unsigned int dell_m4_2_pin_configs[11] = {
        0x40f000f0, 0x044413b0, 0x044413b0,
 };
 
+static unsigned int dell_m4_3_pin_configs[11] = {
+       0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
+       0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
+       0x40f000f0, 0x044413b0, 0x044413b0,
+};
+
 static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
        [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
        [STAC_DELL_M4_1]        = dell_m4_1_pin_configs,
        [STAC_DELL_M4_2]        = dell_m4_2_pin_configs,
+       [STAC_DELL_M4_3]        = dell_m4_3_pin_configs,
        [STAC_HP_M4]            = NULL,
 };
 
@@ -1679,6 +1690,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
        [STAC_92HD71BXX_REF] = "ref",
        [STAC_DELL_M4_1] = "dell-m4-1",
        [STAC_DELL_M4_2] = "dell-m4-2",
+       [STAC_DELL_M4_3] = "dell-m4-3",
        [STAC_HP_M4] = "hp-m4",
 };
 
@@ -1686,6 +1698,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                      "DFI LanParty", STAC_92HD71BXX_REF),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
+                     "HP dv5", STAC_HP_M4),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
+                     "HP dv7", STAC_HP_M4),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
                                "unknown HP", STAC_HP_M4),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -1710,6 +1726,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                                "unknown Dell", STAC_DELL_M4_2),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
                                "unknown Dell", STAC_DELL_M4_2),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
+                               "unknown Dell", STAC_DELL_M4_3),
        {} /* terminator */
 };
 
@@ -3895,7 +3913,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
                for (i = 0; i < cfg->speaker_outs; i++)
                        stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
                                                AC_PINCTL_OUT_EN);
-               if (spec->eapd_mask)
+               if (spec->eapd_mask && spec->eapd_switch)
                        stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data &
                                ~spec->eapd_mask);
@@ -3910,7 +3928,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
                for (i = 0; i < cfg->speaker_outs; i++)
                        stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
                                                AC_PINCTL_OUT_EN);
-               if (spec->eapd_mask)
+               if (spec->eapd_mask && spec->eapd_switch)
                        stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data |
                                spec->eapd_mask);
@@ -4237,6 +4255,7 @@ again:
                spec->num_smuxes = 0;
                spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
                spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
+               spec->eapd_switch = 0;
                spec->num_amps = 1;
 
                if (!spec->init)
@@ -4268,6 +4287,7 @@ again:
        default:
                spec->num_dmics = STAC92HD73XX_NUM_DMICS;
                spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
+               spec->eapd_switch = 1;
        }
        if (spec->board_config > STAC_92HD73XX_REF) {
                /* GPIO0 High = Enable EAPD */
@@ -4413,7 +4433,13 @@ static int stac92hd71xx_resume(struct hda_codec *codec)
 
 static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
 {
+       struct sigmatel_spec *spec = codec->spec;
+
        stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
+       if (spec->eapd_mask)
+               stac_gpio_set(codec, spec->gpio_mask,
+                               spec->gpio_dir, spec->gpio_data &
+                               ~spec->eapd_mask);
        return 0;
 };
 
@@ -4476,6 +4502,13 @@ again:
                stac92xx_set_config_regs(codec);
        }
 
+       if (spec->board_config > STAC_92HD71BXX_REF) {
+               /* GPIO0 = EAPD */
+               spec->gpio_mask = 0x01;
+               spec->gpio_dir = 0x01;
+               spec->gpio_data = 0x01;
+       }
+
        switch (codec->vendor_id) {
        case 0x111d76b6: /* 4 Port without Analog Mixer */
        case 0x111d76b7:
@@ -4486,10 +4519,10 @@ again:
                codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
                break;
        case 0x111d7608: /* 5 Port with Analog Mixer */
-               switch (codec->subsystem_id) {
-               case 0x103c361a:
+               switch (spec->board_config) {
+               case STAC_HP_M4:
                        /* Enable VREF power saving on GPIO1 detect */
-                       snd_hda_codec_write(codec, codec->afg, 0,
+                       snd_hda_codec_write_cache(codec, codec->afg, 0,
                                AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
                        snd_hda_codec_write_cache(codec, codec->afg, 0,
                                        AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -4535,13 +4568,6 @@ again:
        spec->aloopback_mask = 0x50;
        spec->aloopback_shift = 0;
 
-       if (spec->board_config > STAC_92HD71BXX_REF) {
-               /* GPIO0 = EAPD */
-               spec->gpio_mask = 0x01;
-               spec->gpio_dir = 0x01;
-               spec->gpio_data = 0x01;
-       }
-
        spec->powerdown_adcs = 1;
        spec->digbeep_nid = 0x26;
        spec->mux_nids = stac92hd71bxx_mux_nids;
@@ -4556,14 +4582,21 @@ again:
 
        switch (spec->board_config) {
        case STAC_HP_M4:
-               spec->num_dmics = 0;
-               spec->num_smuxes = 0;
-               spec->num_dmuxes = 0;
-
                /* enable internal microphone */
                stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
                stac92xx_auto_set_pinctl(codec, 0x0e,
                        AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
+               /* fallthru */
+       case STAC_DELL_M4_2:
+               spec->num_dmics = 0;
+               spec->num_smuxes = 0;
+               spec->num_dmuxes = 0;
+               break;
+       case STAC_DELL_M4_1:
+       case STAC_DELL_M4_3:
+               spec->num_dmics = 1;
+               spec->num_smuxes = 0;
+               spec->num_dmuxes = 0;
                break;
        default:
                spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
@@ -4800,6 +4833,7 @@ static int patch_stac927x(struct hda_codec *codec)
        spec->num_pwrs = 0;
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
+       spec->eapd_switch = 1;
 
        err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
        if (!err) {
@@ -4880,6 +4914,7 @@ static int patch_stac9205(struct hda_codec *codec)
 
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
+       spec->eapd_switch = 1;
        spec->multiout.dac_nids = spec->dac_nids;
        
        switch (spec->board_config){
@@ -4889,7 +4924,7 @@ static int patch_stac9205(struct hda_codec *codec)
                stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
 
                /* Enable unsol response for GPIO4/Dock HP connection */
-               snd_hda_codec_write(codec, codec->afg, 0,
+               snd_hda_codec_write_cache(codec, codec->afg, 0,
                        AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
                snd_hda_codec_write_cache(codec, codec->afg, 0,
                                          AC_VERB_SET_UNSOLICITED_ENABLE,