diff options
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 91 |
1 files changed, 67 insertions, 24 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6983eea226da..41fc290149ed 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -112,6 +112,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { | |||
112 | { 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */ | 112 | { 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */ |
113 | { 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL }, | 113 | { 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL }, |
114 | { 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, | 114 | { 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, |
115 | { 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ | ||
115 | { 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, | 116 | { 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, |
116 | { 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, | 117 | { 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, |
117 | { 0x414c4730, 0xffffffff, "ALC101", NULL, NULL }, | 118 | { 0x414c4730, 0xffffffff, "ALC101", NULL, NULL }, |
@@ -157,6 +158,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)] | 158 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] |
158 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, | 159 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, |
159 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF | 160 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF |
161 | { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF | ||
160 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, | 162 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, |
161 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, | 163 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, |
162 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, | 164 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, |
@@ -1307,16 +1309,18 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1307 | } | 1309 | } |
1308 | 1310 | ||
1309 | /* build master tone controls */ | 1311 | /* build master tone controls */ |
1310 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { | 1312 | if (!(ac97->flags & AC97_HAS_NO_TONE)) { |
1311 | for (idx = 0; idx < 2; idx++) { | 1313 | 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) | 1314 | for (idx = 0; idx < 2; idx++) { |
1313 | return err; | 1315 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) |
1314 | if (ac97->id == AC97_ID_YMF753) { | 1316 | return err; |
1315 | kctl->private_value &= ~(0xff << 16); | 1317 | if (ac97->id == AC97_ID_YMF753) { |
1316 | kctl->private_value |= 7 << 16; | 1318 | kctl->private_value &= ~(0xff << 16); |
1319 | kctl->private_value |= 7 << 16; | ||
1320 | } | ||
1317 | } | 1321 | } |
1322 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1318 | } | 1323 | } |
1319 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
1320 | } | 1324 | } |
1321 | 1325 | ||
1322 | /* build PC Speaker controls */ | 1326 | /* build PC Speaker controls */ |
@@ -1339,11 +1343,13 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1339 | } | 1343 | } |
1340 | 1344 | ||
1341 | /* build MIC controls */ | 1345 | /* build MIC controls */ |
1342 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { | 1346 | if (!(ac97->flags & AC97_HAS_NO_MIC)) { |
1343 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) | 1347 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { |
1344 | return err; | 1348 | 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) | 1349 | return err; |
1346 | return err; | 1350 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) |
1351 | return err; | ||
1352 | } | ||
1347 | } | 1353 | } |
1348 | 1354 | ||
1349 | /* build Line controls */ | 1355 | /* build Line controls */ |
@@ -1402,12 +1408,14 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
1402 | } | 1408 | } |
1403 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); | 1409 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); |
1404 | } else { | 1410 | } else { |
1405 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) | 1411 | if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { |
1406 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); | 1412 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) |
1407 | else | 1413 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); |
1408 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); | 1414 | else |
1409 | if (err < 0) | 1415 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); |
1410 | return err; | 1416 | if (err < 0) |
1417 | return err; | ||
1418 | } | ||
1411 | } | 1419 | } |
1412 | 1420 | ||
1413 | /* build Capture controls */ | 1421 | /* build Capture controls */ |
@@ -1549,7 +1557,7 @@ static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97) | |||
1549 | 1557 | ||
1550 | /* build modem switches */ | 1558 | /* build modem switches */ |
1551 | for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++) | 1559 | for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++) |
1552 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_modem_switches[idx], ac97))) < 0) | 1560 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97))) < 0) |
1553 | return err; | 1561 | return err; |
1554 | 1562 | ||
1555 | /* build chip specific controls */ | 1563 | /* build chip specific controls */ |
@@ -1789,7 +1797,7 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, | |||
1789 | 1797 | ||
1790 | snd_assert(card != NULL, return -EINVAL); | 1798 | snd_assert(card != NULL, return -EINVAL); |
1791 | snd_assert(rbus != NULL, return -EINVAL); | 1799 | snd_assert(rbus != NULL, return -EINVAL); |
1792 | bus = kcalloc(1, sizeof(*bus), GFP_KERNEL); | 1800 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); |
1793 | if (bus == NULL) | 1801 | if (bus == NULL) |
1794 | return -ENOMEM; | 1802 | return -ENOMEM; |
1795 | bus->card = card; | 1803 | bus->card = card; |
@@ -1807,6 +1815,38 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, | |||
1807 | return 0; | 1815 | return 0; |
1808 | } | 1816 | } |
1809 | 1817 | ||
1818 | /* stop no dev release warning */ | ||
1819 | static void ac97_device_release(struct device * dev) | ||
1820 | { | ||
1821 | } | ||
1822 | |||
1823 | /* register ac97 codec to bus */ | ||
1824 | static int snd_ac97_dev_register(snd_device_t *device) | ||
1825 | { | ||
1826 | ac97_t *ac97 = device->device_data; | ||
1827 | int err; | ||
1828 | |||
1829 | ac97->dev.bus = &ac97_bus_type; | ||
1830 | ac97->dev.parent = ac97->bus->card->dev; | ||
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); |
@@ -1863,7 +1905,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
1863 | } | 1905 | } |
1864 | 1906 | ||
1865 | card = bus->card; | 1907 | card = bus->card; |
1866 | ac97 = kcalloc(1, sizeof(*ac97), GFP_KERNEL); | 1908 | ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); |
1867 | if (ac97 == NULL) | 1909 | if (ac97 == NULL) |
1868 | return -ENOMEM; | 1910 | return -ENOMEM; |
1869 | ac97->private_data = template->private_data; | 1911 | ac97->private_data = template->private_data; |
@@ -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; |