aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_sigmatel.c95
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
45enum { 45enum {
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
224static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, 224static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
@@ -773,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = {
773}; 773};
774 774
775static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { 775static 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
779static const char *stac9205_models[STAC_9205_MODELS] = { 780static 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
821static 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
816static void stac92xx_set_config_regs(struct hda_codec *codec) 844static 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
845static void stac92xx_enable_eapd(struct hda_codec *codec) 857static 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)
2265static int patch_stac9205(struct hda_codec *codec) 2279static 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) {