diff options
author | Tobin Davis <tdavis@dsl-only.net> | 2007-01-08 05:04:17 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:02:56 -0500 |
commit | 8e21c34cd4742c508dcc307fdbac9b3ba6899002 (patch) | |
tree | 1a400a6312148ec5a9b81c3f82799c9045285505 /sound/pci | |
parent | c68487151a0dceea07db8632327e3a0ab9e25e1f (diff) |
[ALSA] hda-codec - Add support for Sigmatel STAC9202/9250/9251 codecs
This patch adds support for Gateway laptops based on the
Sigmatel STAC9250 codecs, as well as basic support for
STAC9202/9250/9251 codecs. Some Gateway systems require
probe_mask=1 to work. More work to be done prior to alsa 1.0.14
final.
Signed-off-by: Tobin Davis <tdavis@dsl-only.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e3fc95b7b4f..0556b7e7bb8b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -48,6 +48,13 @@ enum { | |||
48 | }; | 48 | }; |
49 | 49 | ||
50 | enum { | 50 | enum { |
51 | STAC_925x_REF, | ||
52 | STAC_M2_2, | ||
53 | STAC_MA6, | ||
54 | STAC_925x_MODELS | ||
55 | }; | ||
56 | |||
57 | enum { | ||
51 | STAC_D945_REF, | 58 | STAC_D945_REF, |
52 | STAC_D945GTP3, | 59 | STAC_D945GTP3, |
53 | STAC_D945GTP5, | 60 | STAC_D945GTP5, |
@@ -129,6 +136,18 @@ static hda_nid_t stac9200_dac_nids[1] = { | |||
129 | 0x02, | 136 | 0x02, |
130 | }; | 137 | }; |
131 | 138 | ||
139 | static hda_nid_t stac925x_adc_nids[1] = { | ||
140 | 0x03, | ||
141 | }; | ||
142 | |||
143 | static hda_nid_t stac925x_mux_nids[1] = { | ||
144 | 0x0f, | ||
145 | }; | ||
146 | |||
147 | static hda_nid_t stac925x_dac_nids[1] = { | ||
148 | 0x02, | ||
149 | }; | ||
150 | |||
132 | static hda_nid_t stac922x_adc_nids[2] = { | 151 | static hda_nid_t stac922x_adc_nids[2] = { |
133 | 0x06, 0x07, | 152 | 0x06, 0x07, |
134 | }; | 153 | }; |
@@ -162,6 +181,11 @@ static hda_nid_t stac9200_pin_nids[8] = { | |||
162 | 0x0f, 0x10, 0x11, 0x12, | 181 | 0x0f, 0x10, 0x11, 0x12, |
163 | }; | 182 | }; |
164 | 183 | ||
184 | static hda_nid_t stac925x_pin_nids[8] = { | ||
185 | 0x07, 0x08, 0x0a, 0x0b, | ||
186 | 0x0c, 0x0d, 0x10, 0x11, | ||
187 | }; | ||
188 | |||
165 | static hda_nid_t stac922x_pin_nids[10] = { | 189 | static hda_nid_t stac922x_pin_nids[10] = { |
166 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 190 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
167 | 0x0f, 0x10, 0x11, 0x15, 0x1b, | 191 | 0x0f, 0x10, 0x11, 0x15, 0x1b, |
@@ -241,6 +265,12 @@ static struct hda_verb stac9200_core_init[] = { | |||
241 | {} | 265 | {} |
242 | }; | 266 | }; |
243 | 267 | ||
268 | static struct hda_verb stac925x_core_init[] = { | ||
269 | /* set dac0mux for dac converter */ | ||
270 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
271 | {} | ||
272 | }; | ||
273 | |||
244 | static struct hda_verb stac922x_core_init[] = { | 274 | static struct hda_verb stac922x_core_init[] = { |
245 | /* set master volume and direct control */ | 275 | /* set master volume and direct control */ |
246 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 276 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
@@ -286,6 +316,23 @@ static struct snd_kcontrol_new stac9200_mixer[] = { | |||
286 | { } /* end */ | 316 | { } /* end */ |
287 | }; | 317 | }; |
288 | 318 | ||
319 | static struct snd_kcontrol_new stac925x_mixer[] = { | ||
320 | HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), | ||
321 | HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), | ||
322 | { | ||
323 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
324 | .name = "Input Source", | ||
325 | .count = 1, | ||
326 | .info = stac92xx_mux_enum_info, | ||
327 | .get = stac92xx_mux_enum_get, | ||
328 | .put = stac92xx_mux_enum_put, | ||
329 | }, | ||
330 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | ||
331 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), | ||
332 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), | ||
333 | { } /* end */ | ||
334 | }; | ||
335 | |||
289 | /* This needs to be generated dynamically based on sequence */ | 336 | /* This needs to be generated dynamically based on sequence */ |
290 | static struct snd_kcontrol_new stac922x_mixer[] = { | 337 | static struct snd_kcontrol_new stac922x_mixer[] = { |
291 | { | 338 | { |
@@ -411,6 +458,43 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
411 | {} /* terminator */ | 458 | {} /* terminator */ |
412 | }; | 459 | }; |
413 | 460 | ||
461 | static unsigned int ref925x_pin_configs[8] = { | ||
462 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | ||
463 | 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e, | ||
464 | }; | ||
465 | |||
466 | static unsigned int stac925x_MA6_pin_configs[8] = { | ||
467 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | ||
468 | 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, | ||
469 | }; | ||
470 | |||
471 | static unsigned int stac925xM2_2_pin_configs[8] = { | ||
472 | 0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020, | ||
473 | 0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e, | ||
474 | }; | ||
475 | |||
476 | static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | ||
477 | [STAC_REF] = ref925x_pin_configs, | ||
478 | [STAC_M2_2] = stac925xM2_2_pin_configs, | ||
479 | [STAC_MA6] = stac925x_MA6_pin_configs, | ||
480 | }; | ||
481 | |||
482 | static const char *stac925x_models[STAC_925x_MODELS] = { | ||
483 | [STAC_REF] = "ref", | ||
484 | [STAC_M2_2] = "m2-2", | ||
485 | [STAC_MA6] = "m6", | ||
486 | }; | ||
487 | |||
488 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { | ||
489 | /* SigmaTel reference board */ | ||
490 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | ||
491 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), | ||
492 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), | ||
493 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), | ||
494 | SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2), | ||
495 | {} /* terminator */ | ||
496 | }; | ||
497 | |||
414 | static unsigned int ref922x_pin_configs[10] = { | 498 | static unsigned int ref922x_pin_configs[10] = { |
415 | 0x01014010, 0x01016011, 0x01012012, 0x0221401f, | 499 | 0x01014010, 0x01016011, 0x01012012, 0x0221401f, |
416 | 0x01813122, 0x01011014, 0x01441030, 0x01c41030, | 500 | 0x01813122, 0x01011014, 0x01441030, 0x01c41030, |
@@ -1699,6 +1783,56 @@ static int patch_stac9200(struct hda_codec *codec) | |||
1699 | return 0; | 1783 | return 0; |
1700 | } | 1784 | } |
1701 | 1785 | ||
1786 | static int patch_stac925x(struct hda_codec *codec) | ||
1787 | { | ||
1788 | struct sigmatel_spec *spec; | ||
1789 | int err; | ||
1790 | |||
1791 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1792 | if (spec == NULL) | ||
1793 | return -ENOMEM; | ||
1794 | |||
1795 | codec->spec = spec; | ||
1796 | spec->num_pins = 8; | ||
1797 | spec->pin_nids = stac925x_pin_nids; | ||
1798 | spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, | ||
1799 | stac925x_models, | ||
1800 | stac925x_cfg_tbl); | ||
1801 | if (spec->board_config < 0) { | ||
1802 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n"); | ||
1803 | err = stac92xx_save_bios_config_regs(codec); | ||
1804 | if (err < 0) { | ||
1805 | stac92xx_free(codec); | ||
1806 | return err; | ||
1807 | } | ||
1808 | spec->pin_configs = spec->bios_pin_configs; | ||
1809 | } else if (stac925x_brd_tbl[spec->board_config] != NULL){ | ||
1810 | spec->pin_configs = stac925x_brd_tbl[spec->board_config]; | ||
1811 | stac92xx_set_config_regs(codec); | ||
1812 | } | ||
1813 | |||
1814 | spec->multiout.max_channels = 2; | ||
1815 | spec->multiout.num_dacs = 1; | ||
1816 | spec->multiout.dac_nids = stac925x_dac_nids; | ||
1817 | spec->adc_nids = stac925x_adc_nids; | ||
1818 | spec->mux_nids = stac925x_mux_nids; | ||
1819 | spec->num_muxes = 1; | ||
1820 | spec->num_dmics = 0; | ||
1821 | |||
1822 | spec->init = stac925x_core_init; | ||
1823 | spec->mixer = stac925x_mixer; | ||
1824 | |||
1825 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); | ||
1826 | if (err < 0) { | ||
1827 | stac92xx_free(codec); | ||
1828 | return err; | ||
1829 | } | ||
1830 | |||
1831 | codec->patch_ops = stac92xx_patch_ops; | ||
1832 | |||
1833 | return 0; | ||
1834 | } | ||
1835 | |||
1702 | static int patch_stac922x(struct hda_codec *codec) | 1836 | static int patch_stac922x(struct hda_codec *codec) |
1703 | { | 1837 | { |
1704 | struct sigmatel_spec *spec; | 1838 | struct sigmatel_spec *spec; |
@@ -2149,6 +2283,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
2149 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, | 2283 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, |
2150 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, | 2284 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, |
2151 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, | 2285 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, |
2286 | { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x }, | ||
2287 | { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x }, | ||
2288 | { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x }, | ||
2289 | { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, | ||
2290 | { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, | ||
2291 | { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, | ||
2152 | /* The following does not take into account .id=0x83847661 when subsys = | 2292 | /* The following does not take into account .id=0x83847661 when subsys = |
2153 | * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are | 2293 | * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are |
2154 | * currently not fully supported. | 2294 | * currently not fully supported. |