diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 95 |
1 files changed, 61 insertions, 34 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index be53e9685bc0..9b1d433178bf 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -44,6 +44,7 @@ enum { | |||
44 | 44 | ||
45 | enum { | 45 | enum { |
46 | STAC_9205_REF, | 46 | STAC_9205_REF, |
47 | STAC_M43xx, | ||
47 | STAC_9205_MODELS | 48 | STAC_9205_MODELS |
48 | }; | 49 | }; |
49 | 50 | ||
@@ -218,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = { | |||
218 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 219 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
219 | 0x0f, 0x14, 0x16, 0x17, 0x18, | 220 | 0x0f, 0x14, 0x16, 0x17, 0x18, |
220 | 0x21, 0x22, | 221 | 0x21, 0x22, |
221 | |||
222 | }; | 222 | }; |
223 | 223 | ||
224 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, | 224 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, |
@@ -773,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = { | |||
773 | }; | 773 | }; |
774 | 774 | ||
775 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | 775 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { |
776 | ref9205_pin_configs, | 776 | [STAC_REF] = ref9205_pin_configs, |
777 | [STAC_M43xx] = NULL, | ||
777 | }; | 778 | }; |
778 | 779 | ||
779 | static const char *stac9205_models[STAC_9205_MODELS] = { | 780 | static const char *stac9205_models[STAC_9205_MODELS] = { |
@@ -784,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
784 | /* SigmaTel reference board */ | 785 | /* SigmaTel reference board */ |
785 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 786 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
786 | "DFI LanParty", STAC_9205_REF), | 787 | "DFI LanParty", STAC_9205_REF), |
788 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8, | ||
789 | "Dell Precision", STAC_M43xx), | ||
790 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff, | ||
791 | "Dell Precision", STAC_M43xx), | ||
787 | {} /* terminator */ | 792 | {} /* terminator */ |
788 | }; | 793 | }; |
789 | 794 | ||
@@ -813,48 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | |||
813 | return 0; | 818 | return 0; |
814 | } | 819 | } |
815 | 820 | ||
821 | static void stac92xx_set_config_reg(struct hda_codec *codec, | ||
822 | hda_nid_t pin_nid, unsigned int pin_config) | ||
823 | { | ||
824 | int i; | ||
825 | snd_hda_codec_write(codec, pin_nid, 0, | ||
826 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
827 | pin_config & 0x000000ff); | ||
828 | snd_hda_codec_write(codec, pin_nid, 0, | ||
829 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
830 | (pin_config & 0x0000ff00) >> 8); | ||
831 | snd_hda_codec_write(codec, pin_nid, 0, | ||
832 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
833 | (pin_config & 0x00ff0000) >> 16); | ||
834 | snd_hda_codec_write(codec, pin_nid, 0, | ||
835 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
836 | pin_config >> 24); | ||
837 | i = snd_hda_codec_read(codec, pin_nid, 0, | ||
838 | AC_VERB_GET_CONFIG_DEFAULT, | ||
839 | 0x00); | ||
840 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", | ||
841 | pin_nid, i); | ||
842 | } | ||
843 | |||
816 | static void stac92xx_set_config_regs(struct hda_codec *codec) | 844 | static void stac92xx_set_config_regs(struct hda_codec *codec) |
817 | { | 845 | { |
818 | int i; | 846 | int i; |
819 | struct sigmatel_spec *spec = codec->spec; | 847 | struct sigmatel_spec *spec = codec->spec; |
820 | unsigned int pin_cfg; | ||
821 | 848 | ||
822 | if (! spec->pin_nids || ! spec->pin_configs) | 849 | if (!spec->pin_configs) |
823 | return; | 850 | return; |
824 | 851 | ||
825 | for (i = 0; i < spec->num_pins; i++) { | 852 | for (i = 0; i < spec->num_pins; i++) |
826 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 853 | stac92xx_set_config_reg(codec, spec->pin_nids[i], |
827 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | 854 | spec->pin_configs[i]); |
828 | spec->pin_configs[i] & 0x000000ff); | ||
829 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | ||
830 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
831 | (spec->pin_configs[i] & 0x0000ff00) >> 8); | ||
832 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | ||
833 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
834 | (spec->pin_configs[i] & 0x00ff0000) >> 16); | ||
835 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | ||
836 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
837 | spec->pin_configs[i] >> 24); | ||
838 | pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, | ||
839 | AC_VERB_GET_CONFIG_DEFAULT, | ||
840 | 0x00); | ||
841 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); | ||
842 | } | ||
843 | } | 855 | } |
844 | 856 | ||
845 | static void stac92xx_enable_eapd(struct hda_codec *codec) | 857 | static void stac92xx_enable_gpio_mask(struct hda_codec *codec, |
858 | int gpio_mask, int gpio_data) | ||
846 | { | 859 | { |
847 | /* Configure GPIO0 as output */ | 860 | /* Configure GPIOx as output */ |
848 | snd_hda_codec_write(codec, codec->afg, 0, | 861 | snd_hda_codec_write(codec, codec->afg, 0, |
849 | AC_VERB_SET_GPIO_DIRECTION, 0x00000001); | 862 | AC_VERB_SET_GPIO_DIRECTION, gpio_mask); |
850 | /* Configure GPIO0 as CMOS */ | 863 | /* Configure GPIOx as CMOS */ |
851 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); | 864 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); |
852 | /* Assert GPIO0 high */ | 865 | /* Assert GPIOx */ |
853 | snd_hda_codec_write(codec, codec->afg, 0, | 866 | snd_hda_codec_write(codec, codec->afg, 0, |
854 | AC_VERB_SET_GPIO_DATA, 0x00000001); | 867 | AC_VERB_SET_GPIO_DATA, gpio_data); |
855 | /* Enable GPIO0 */ | 868 | /* Enable GPIOx */ |
856 | snd_hda_codec_write(codec, codec->afg, 0, | 869 | snd_hda_codec_write(codec, codec->afg, 0, |
857 | AC_VERB_SET_GPIO_MASK, 0x00000001); | 870 | AC_VERB_SET_GPIO_MASK, gpio_mask); |
858 | } | 871 | } |
859 | 872 | ||
860 | /* | 873 | /* |
@@ -2233,7 +2246,8 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2233 | } | 2246 | } |
2234 | 2247 | ||
2235 | spec->multiout.dac_nids = spec->dac_nids; | 2248 | spec->multiout.dac_nids = spec->dac_nids; |
2236 | stac92xx_enable_eapd(codec); | 2249 | /* GPIO0 High = Enable EAPD */ |
2250 | stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001); | ||
2237 | 2251 | ||
2238 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); | 2252 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); |
2239 | if (!err) { | 2253 | if (!err) { |
@@ -2265,7 +2279,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2265 | static int patch_stac9205(struct hda_codec *codec) | 2279 | static int patch_stac9205(struct hda_codec *codec) |
2266 | { | 2280 | { |
2267 | struct sigmatel_spec *spec; | 2281 | struct sigmatel_spec *spec; |
2268 | int err; | 2282 | int err, gpio_mask, gpio_data; |
2269 | 2283 | ||
2270 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2284 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
2271 | if (spec == NULL) | 2285 | if (spec == NULL) |
@@ -2302,8 +2316,21 @@ static int patch_stac9205(struct hda_codec *codec) | |||
2302 | spec->mixer = stac9205_mixer; | 2316 | spec->mixer = stac9205_mixer; |
2303 | 2317 | ||
2304 | spec->multiout.dac_nids = spec->dac_nids; | 2318 | spec->multiout.dac_nids = spec->dac_nids; |
2305 | stac92xx_enable_eapd(codec); | 2319 | |
2320 | if (spec->board_config == STAC_M43xx) { | ||
2321 | /* Enable SPDIF in/out */ | ||
2322 | stac92xx_set_config_reg(codec, 0x1f, 0x01441030); | ||
2323 | stac92xx_set_config_reg(codec, 0x20, 0x1c410030); | ||
2324 | |||
2325 | gpio_mask = 0x00000007; /* GPIO0-2 */ | ||
2326 | /* GPIO0 High = EAPD, GPIO1 Low = DRM, | ||
2327 | * GPIO2 High = Headphone Mute | ||
2328 | */ | ||
2329 | gpio_data = 0x00000005; | ||
2330 | } else | ||
2331 | gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */ | ||
2306 | 2332 | ||
2333 | stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data); | ||
2307 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); | 2334 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); |
2308 | if (!err) { | 2335 | if (!err) { |
2309 | if (spec->board_config < 0) { | 2336 | if (spec->board_config < 0) { |