diff options
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6983eea226da..5501f4440c92 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -157,6 +157,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { | |||
157 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] | 157 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] |
158 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, | 158 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, |
159 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF | 159 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF |
160 | { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF | ||
160 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, | 161 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, |
161 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, | 162 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, |
162 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, | 163 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, |
@@ -1307,16 +1308,18 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1307 | } | 1308 | } |
1308 | 1309 | ||
1309 | /* build master tone controls */ | 1310 | /* build master tone controls */ |
1310 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { | 1311 | if (!(ac97->flags & AC97_HAS_NO_TONE)) { |
1311 | for (idx = 0; idx < 2; idx++) { | 1312 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { |
1312 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) | 1313 | for (idx = 0; idx < 2; idx++) { |
1313 | return err; | 1314 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) |
1314 | if (ac97->id == AC97_ID_YMF753) { | 1315 | return err; |
1315 | kctl->private_value &= ~(0xff << 16); | 1316 | if (ac97->id == AC97_ID_YMF753) { |
1316 | kctl->private_value |= 7 << 16; | 1317 | kctl->private_value &= ~(0xff << 16); |
1318 | kctl->private_value |= 7 << 16; | ||
1319 | } | ||
1317 | } | 1320 | } |
1321 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1318 | } | 1322 | } |
1319 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1320 | } | 1323 | } |
1321 | 1324 | ||
1322 | /* build PC Speaker controls */ | 1325 | /* build PC Speaker controls */ |
@@ -1339,11 +1342,13 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1339 | } | 1342 | } |
1340 | 1343 | ||
1341 | /* build MIC controls */ | 1344 | /* build MIC controls */ |
1342 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { | 1345 | if (!(ac97->flags & AC97_HAS_NO_MIC)) { |
1343 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) | 1346 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { |
1344 | return err; | 1347 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) |
1345 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) | 1348 | return err; |
1346 | return err; | 1349 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) |
1350 | return err; | ||
1351 | } | ||
1347 | } | 1352 | } |
1348 | 1353 | ||
1349 | /* build Line controls */ | 1354 | /* build Line controls */ |
@@ -1402,12 +1407,14 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1402 | } | 1407 | } |
1403 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); | 1408 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); |
1404 | } else { | 1409 | } else { |
1405 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) | 1410 | if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { |
1406 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); | 1411 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) |
1407 | else | 1412 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); |
1408 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); | 1413 | else |
1409 | if (err < 0) | 1414 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); |
1410 | return err; | 1415 | if (err < 0) |
1416 | return err; | ||
1417 | } | ||
1411 | } | 1418 | } |
1412 | 1419 | ||
1413 | /* build Capture controls */ | 1420 | /* build Capture controls */ |
@@ -1807,6 +1814,39 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, | |||
1807 | return 0; | 1814 | return 0; |
1808 | } | 1815 | } |
1809 | 1816 | ||
1817 | /* stop no dev release warning */ | ||
1818 | static void ac97_device_release(struct device * dev) | ||
1819 | { | ||
1820 | } | ||
1821 | |||
1822 | /* register ac97 codec to bus */ | ||
1823 | static int snd_ac97_dev_register(snd_device_t *device) | ||
1824 | { | ||
1825 | ac97_t *ac97 = device->device_data; | ||
1826 | int err; | ||
1827 | |||
1828 | ac97->dev.bus = &ac97_bus_type; | ||
1829 | ac97->dev.parent = ac97->bus->card->dev; | ||
1830 | ac97->dev.platform_data = ac97; | ||
1831 | ac97->dev.release = ac97_device_release; | ||
1832 | snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "card%d-%d", ac97->bus->card->number, ac97->num); | ||
1833 | if ((err = device_register(&ac97->dev)) < 0) { | ||
1834 | snd_printk(KERN_ERR "Can't register ac97 bus\n"); | ||
1835 | ac97->dev.bus = NULL; | ||
1836 | return err; | ||
1837 | } | ||
1838 | return 0; | ||
1839 | } | ||
1840 | |||
1841 | /* unregister ac97 codec */ | ||
1842 | static int snd_ac97_dev_unregister(snd_device_t *device) | ||
1843 | { | ||
1844 | ac97_t *ac97 = device->device_data; | ||
1845 | if (ac97->dev.bus) | ||
1846 | device_unregister(&ac97->dev); | ||
1847 | return snd_ac97_free(ac97); | ||
1848 | } | ||
1849 | |||
1810 | /* build_ops to do nothing */ | 1850 | /* build_ops to do nothing */ |
1811 | static struct snd_ac97_build_ops null_build_ops; | 1851 | static struct snd_ac97_build_ops null_build_ops; |
1812 | 1852 | ||
@@ -1840,6 +1880,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
1840 | const ac97_codec_id_t *pid; | 1880 | const ac97_codec_id_t *pid; |
1841 | static snd_device_ops_t ops = { | 1881 | static snd_device_ops_t ops = { |
1842 | .dev_free = snd_ac97_dev_free, | 1882 | .dev_free = snd_ac97_dev_free, |
1883 | .dev_register = snd_ac97_dev_register, | ||
1884 | .dev_unregister = snd_ac97_dev_unregister, | ||
1843 | }; | 1885 | }; |
1844 | 1886 | ||
1845 | snd_assert(rac97 != NULL, return -EINVAL); | 1887 | snd_assert(rac97 != NULL, return -EINVAL); |
@@ -2539,8 +2581,6 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o | |||
2539 | { | 2581 | { |
2540 | int result; | 2582 | int result; |
2541 | 2583 | ||
2542 | snd_assert(quirk, return -EINVAL); | ||
2543 | |||
2544 | /* quirk overriden? */ | 2584 | /* quirk overriden? */ |
2545 | if (override && strcmp(override, "-1") && strcmp(override, "default")) { | 2585 | if (override && strcmp(override, "-1") && strcmp(override, "default")) { |
2546 | result = apply_quirk_str(ac97, override); | 2586 | result = apply_quirk_str(ac97, override); |
@@ -2549,6 +2589,9 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o | |||
2549 | return result; | 2589 | return result; |
2550 | } | 2590 | } |
2551 | 2591 | ||
2592 | if (! quirk) | ||
2593 | return -EINVAL; | ||
2594 | |||
2552 | for (; quirk->subvendor; quirk++) { | 2595 | for (; quirk->subvendor; quirk++) { |
2553 | if (quirk->subvendor != ac97->subsystem_vendor) | 2596 | if (quirk->subvendor != ac97->subsystem_vendor) |
2554 | continue; | 2597 | continue; |