diff options
author | Steve French <sfrench@us.ibm.com> | 2005-08-30 14:33:26 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-08-30 14:33:26 -0400 |
commit | 2016ef789a9ded2e169ad1c028ae3deb5302571f (patch) | |
tree | 601359f15b42d4d9868b4eadfe909a7bef6435c5 /sound/pci/ac97 | |
parent | 7f57356b70dda014ef269135942426e4a852023e (diff) | |
parent | 6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r-- | sound/pci/ac97/Makefile | 2 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_bus.c | 79 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 85 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 449 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.h | 1 |
5 files changed, 501 insertions, 115 deletions
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c3222122d8b..77b3482cb133 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile | |||
@@ -10,9 +10,11 @@ snd-ac97-codec-objs += ac97_proc.o | |||
10 | endif | 10 | endif |
11 | 11 | ||
12 | snd-ak4531-codec-objs := ak4531_codec.o | 12 | snd-ak4531-codec-objs := ak4531_codec.o |
13 | snd-ac97-bus-objs := ac97_bus.o | ||
13 | 14 | ||
14 | # Toplevel Module Dependency | 15 | # Toplevel Module Dependency |
15 | obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o | 16 | obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o |
16 | obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o | 17 | obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o |
18 | obj-$(CONFIG_SND_AC97_BUS) += snd-ac97-bus.o | ||
17 | 19 | ||
18 | obj-m := $(sort $(obj-m)) | 20 | obj-m := $(sort $(obj-m)) |
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c new file mode 100644 index 000000000000..227f8b9f67ce --- /dev/null +++ b/sound/pci/ac97/ac97_bus.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Linux driver model AC97 bus interface | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Jan 14, 2005 | ||
6 | * Copyright: (C) MontaVista Software Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/string.h> | ||
18 | |||
19 | /* | ||
20 | * Codec families have names seperated by commas, so we search for an | ||
21 | * individual codec name within the family string. | ||
22 | */ | ||
23 | static int ac97_bus_match(struct device *dev, struct device_driver *drv) | ||
24 | { | ||
25 | return (strstr(dev->bus_id, drv->name) != NULL); | ||
26 | } | ||
27 | |||
28 | static int ac97_bus_suspend(struct device *dev, pm_message_t state) | ||
29 | { | ||
30 | int ret = 0; | ||
31 | |||
32 | if (dev->driver && dev->driver->suspend) { | ||
33 | ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE); | ||
34 | if (ret == 0) | ||
35 | ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE); | ||
36 | if (ret == 0) | ||
37 | ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN); | ||
38 | } | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static int ac97_bus_resume(struct device *dev) | ||
43 | { | ||
44 | int ret = 0; | ||
45 | |||
46 | if (dev->driver && dev->driver->resume) { | ||
47 | ret = dev->driver->resume(dev, RESUME_POWER_ON); | ||
48 | if (ret == 0) | ||
49 | ret = dev->driver->resume(dev, RESUME_RESTORE_STATE); | ||
50 | if (ret == 0) | ||
51 | ret = dev->driver->resume(dev, RESUME_ENABLE); | ||
52 | } | ||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | struct bus_type ac97_bus_type = { | ||
57 | .name = "ac97", | ||
58 | .match = ac97_bus_match, | ||
59 | .suspend = ac97_bus_suspend, | ||
60 | .resume = ac97_bus_resume, | ||
61 | }; | ||
62 | |||
63 | static int __init ac97_bus_init(void) | ||
64 | { | ||
65 | return bus_register(&ac97_bus_type); | ||
66 | } | ||
67 | |||
68 | subsys_initcall(ac97_bus_init); | ||
69 | |||
70 | static void __exit ac97_bus_exit(void) | ||
71 | { | ||
72 | bus_unregister(&ac97_bus_type); | ||
73 | } | ||
74 | |||
75 | module_exit(ac97_bus_exit); | ||
76 | |||
77 | EXPORT_SYMBOL(ac97_bus_type); | ||
78 | |||
79 | MODULE_LICENSE("GPL"); | ||
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; |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 66edc857d3e6..b584172c1104 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -370,141 +370,387 @@ int patch_yamaha_ymf753(ac97_t * ac97) | |||
370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. | 370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. |
371 | */ | 371 | */ |
372 | 372 | ||
373 | int patch_wolfson03(ac97_t * ac97) | 373 | static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = { |
374 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
375 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
376 | }; | ||
377 | |||
378 | static int patch_wolfson_wm9703_specific(ac97_t * ac97) | ||
374 | { | 379 | { |
375 | /* This is known to work for the ViewSonic ViewPad 1000 | 380 | /* This is known to work for the ViewSonic ViewPad 1000 |
376 | Randolph Bentson <bentson@holmsjoen.com> */ | 381 | * Randolph Bentson <bentson@holmsjoen.com> |
382 | * WM9703/9707/9708/9717 | ||
383 | */ | ||
384 | int err, i; | ||
385 | |||
386 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
387 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
388 | return err; | ||
389 | } | ||
390 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { | ||
395 | .build_specific = patch_wolfson_wm9703_specific, | ||
396 | }; | ||
377 | 397 | ||
378 | // WM9703/9707/9708/9717 | 398 | int patch_wolfson03(ac97_t * ac97) |
379 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 399 | { |
380 | snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000); | 400 | ac97->build_ops = &patch_wolfson_wm9703_ops; |
381 | return 0; | 401 | return 0; |
382 | } | 402 | } |
383 | 403 | ||
384 | int patch_wolfson04(ac97_t * ac97) | 404 | static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = { |
405 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
406 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
407 | AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1), | ||
408 | AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1), | ||
409 | AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1), | ||
410 | AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), | ||
411 | }; | ||
412 | |||
413 | static int patch_wolfson_wm9704_specific(ac97_t * ac97) | ||
385 | { | 414 | { |
386 | // WM9704M/9704Q | 415 | int err, i; |
387 | // set front and rear mixer volume | 416 | for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) { |
388 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 417 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0) |
389 | snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808); | 418 | return err; |
390 | 419 | } | |
391 | // patch for DVD noise | 420 | /* patch for DVD noise */ |
392 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); | 421 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); |
393 | |||
394 | // init vol | ||
395 | snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808); | ||
396 | |||
397 | // set rear surround volume | ||
398 | snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); | ||
399 | return 0; | 422 | return 0; |
400 | } | 423 | } |
401 | 424 | ||
425 | static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { | ||
426 | .build_specific = patch_wolfson_wm9704_specific, | ||
427 | }; | ||
428 | |||
429 | int patch_wolfson04(ac97_t * ac97) | ||
430 | { | ||
431 | /* WM9704M/9704Q */ | ||
432 | ac97->build_ops = &patch_wolfson_wm9704_ops; | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int patch_wolfson_wm9705_specific(ac97_t * ac97) | ||
437 | { | ||
438 | int err, i; | ||
439 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
440 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
441 | return err; | ||
442 | } | ||
443 | snd_ac97_write_cache(ac97, 0x72, 0x0808); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { | ||
448 | .build_specific = patch_wolfson_wm9705_specific, | ||
449 | }; | ||
450 | |||
402 | int patch_wolfson05(ac97_t * ac97) | 451 | int patch_wolfson05(ac97_t * ac97) |
403 | { | 452 | { |
404 | // WM9705, WM9710 | 453 | /* WM9705, WM9710 */ |
405 | // set front mixer volume | 454 | ac97->build_ops = &patch_wolfson_wm9705_ops; |
406 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 455 | return 0; |
456 | } | ||
457 | |||
458 | static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
459 | static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"}; | ||
460 | static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; | ||
461 | static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"}; | ||
462 | static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; | ||
463 | static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"}; | ||
464 | static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
465 | static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; | ||
466 | static const char* wm9711_rec_sel[] = | ||
467 | {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"}; | ||
468 | static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"}; | ||
469 | |||
470 | static const struct ac97_enum wm9711_enum[] = { | ||
471 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select), | ||
472 | AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix), | ||
473 | AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src), | ||
474 | AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc), | ||
475 | AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc), | ||
476 | AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base), | ||
477 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain), | ||
478 | AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic), | ||
479 | AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel), | ||
480 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type), | ||
481 | }; | ||
482 | |||
483 | static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = { | ||
484 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
485 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
486 | AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
487 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
488 | AC97_ENUM("ALC Function", wm9711_enum[0]), | ||
489 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1), | ||
490 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), | ||
491 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
492 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
493 | AC97_ENUM("ALC NG Type", wm9711_enum[9]), | ||
494 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), | ||
495 | |||
496 | AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1), | ||
497 | AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1), | ||
498 | AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), | ||
499 | AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), | ||
500 | |||
501 | AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), | ||
502 | AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), | ||
503 | AC97_ENUM("Out3 Mux", wm9711_enum[2]), | ||
504 | AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), | ||
505 | AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), | ||
506 | |||
507 | AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), | ||
508 | AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1), | ||
509 | AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1), | ||
510 | AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1), | ||
511 | AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1), | ||
512 | AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1), | ||
513 | |||
514 | AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1), | ||
515 | AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1), | ||
516 | AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1), | ||
517 | AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1), | ||
518 | AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1), | ||
519 | AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1), | ||
520 | |||
521 | AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1), | ||
522 | AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1), | ||
523 | |||
524 | AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1), | ||
525 | AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1), | ||
526 | AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1), | ||
527 | |||
528 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
529 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1), | ||
530 | AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1), | ||
531 | |||
532 | AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), | ||
533 | AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]), | ||
534 | AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), | ||
535 | AC97_ENUM("Capture Select", wm9711_enum[8]), | ||
536 | |||
537 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), | ||
538 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), | ||
539 | |||
540 | AC97_ENUM("Bass Control", wm9711_enum[5]), | ||
541 | AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), | ||
542 | AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), | ||
543 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
544 | |||
545 | AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), | ||
546 | AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), | ||
547 | AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), | ||
548 | AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | ||
549 | |||
550 | AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), | ||
551 | AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), | ||
552 | AC97_ENUM("Mic Select Source", wm9711_enum[7]), | ||
553 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), | ||
554 | AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | ||
555 | |||
556 | AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), | ||
557 | AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), | ||
558 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), | ||
559 | }; | ||
560 | |||
561 | static int patch_wolfson_wm9711_specific(ac97_t * ac97) | ||
562 | { | ||
563 | int err, i; | ||
564 | |||
565 | for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) { | ||
566 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0) | ||
567 | return err; | ||
568 | } | ||
569 | snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808); | ||
570 | snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808); | ||
571 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808); | ||
572 | snd_ac97_write_cache(ac97, AC97_AUX, 0x0808); | ||
573 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | ||
574 | snd_ac97_write_cache(ac97, AC97_CD, 0x0000); | ||
407 | return 0; | 575 | return 0; |
408 | } | 576 | } |
409 | 577 | ||
578 | static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { | ||
579 | .build_specific = patch_wolfson_wm9711_specific, | ||
580 | }; | ||
581 | |||
410 | int patch_wolfson11(ac97_t * ac97) | 582 | int patch_wolfson11(ac97_t * ac97) |
411 | { | 583 | { |
412 | // WM9711, WM9712 | 584 | /* WM9711, WM9712 */ |
413 | // set out3 volume | 585 | ac97->build_ops = &patch_wolfson_wm9711_ops; |
414 | snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808); | 586 | |
587 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC | | ||
588 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | ||
589 | |||
415 | return 0; | 590 | return 0; |
416 | } | 591 | } |
417 | 592 | ||
418 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; | 593 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; |
419 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; | 594 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; |
420 | static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; | 595 | static const char* wm9713_rec_src[] = |
421 | static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"}; | 596 | {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix", |
597 | "Mono Mix", "Zh"}; | ||
598 | static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
599 | static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
600 | static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"}; | ||
601 | static const char* wm9713_spk_pga[] = | ||
602 | {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"}; | ||
603 | static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"}; | ||
604 | static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"}; | ||
605 | static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"}; | ||
606 | static const char* wm9713_dac_inv[] = | ||
607 | {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R", | ||
608 | "Headphone Mix Mono", "NC", "Vmid"}; | ||
609 | static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"}; | ||
610 | static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"}; | ||
422 | 611 | ||
423 | static const struct ac97_enum wm9713_enum[] = { | 612 | static const struct ac97_enum wm9713_enum[] = { |
424 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), | 613 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), |
425 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), | 614 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), |
426 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), | 615 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), |
427 | AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), | 616 | AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src), |
428 | AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), | 617 | AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), |
618 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), | ||
619 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), | ||
620 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga), | ||
621 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga), | ||
622 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), | ||
623 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), | ||
624 | AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv), | ||
625 | AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base), | ||
626 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), | ||
429 | }; | 627 | }; |
430 | 628 | ||
431 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { | 629 | static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = { |
432 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), | 630 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), |
433 | AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), | 631 | AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), |
434 | AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), | 632 | AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1), |
435 | AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), | 633 | AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1), |
634 | |||
635 | AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), | ||
636 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1), | ||
637 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1), | ||
638 | AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1), | ||
639 | |||
640 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), | ||
641 | AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), | ||
642 | AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1), | ||
643 | AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1), | ||
644 | AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), | ||
645 | AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]), | ||
646 | AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), | ||
647 | |||
648 | AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1), | ||
649 | AC97_ENUM("Capture Volume Steps", wm9713_enum[4]), | ||
650 | AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0), | ||
651 | AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), | ||
652 | |||
653 | AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]), | ||
654 | AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), | ||
655 | AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]), | ||
656 | AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), | ||
657 | AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), | ||
658 | AC97_ENUM("Capture Select", wm9713_enum[3]), | ||
659 | |||
660 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
661 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
662 | AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
663 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
664 | AC97_ENUM("ALC Function", wm9713_enum[5]), | ||
665 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), | ||
666 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0), | ||
667 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
668 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
669 | AC97_ENUM("ALC NG Type", wm9713_enum[13]), | ||
670 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0), | ||
671 | |||
672 | AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0), | ||
673 | AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0), | ||
674 | AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0), | ||
675 | AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1), | ||
676 | AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1), | ||
677 | AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1), | ||
678 | |||
679 | AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1), | ||
680 | AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1), | ||
681 | AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1), | ||
682 | AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1), | ||
683 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
684 | AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), | ||
685 | |||
686 | AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), | ||
687 | AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), | ||
688 | AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), | ||
689 | AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), | ||
690 | AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), | ||
691 | AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), | ||
692 | |||
693 | AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
694 | AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), | ||
695 | AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1), | ||
696 | AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1), | ||
697 | AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1), | ||
698 | AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1), | ||
699 | |||
700 | AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1), | ||
701 | AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1), | ||
702 | AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1), | ||
703 | AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1), | ||
704 | AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1), | ||
705 | AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1), | ||
706 | |||
707 | AC97_ENUM("Mono Input Mux", wm9713_enum[6]), | ||
708 | AC97_ENUM("Master Input Mux", wm9713_enum[7]), | ||
709 | AC97_ENUM("Headphone Input Mux", wm9713_enum[8]), | ||
710 | AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]), | ||
711 | AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]), | ||
712 | |||
713 | AC97_ENUM("Bass Control", wm9713_enum[12]), | ||
714 | AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), | ||
715 | AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1), | ||
716 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0), | ||
717 | AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1), | ||
718 | AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1), | ||
436 | }; | 719 | }; |
437 | 720 | ||
438 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { | 721 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = { |
439 | AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), | 722 | AC97_ENUM("Inv Input Mux", wm9713_enum[11]), |
440 | AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), | 723 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0), |
441 | AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), | 724 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), |
442 | AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), | 725 | AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), |
443 | }; | 726 | }; |
444 | 727 | ||
445 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { | 728 | static int patch_wolfson_wm9713_3d (ac97_t * ac97) |
446 | AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), | 729 | { |
447 | AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), | 730 | int err, i; |
448 | AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), | 731 | |
449 | AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), | 732 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) { |
450 | AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1), | 733 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0) |
451 | AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), | 734 | return err; |
452 | AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) | 735 | } |
453 | }; | 736 | return 0; |
454 | 737 | } | |
455 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = { | ||
456 | AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1), | ||
457 | AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1), | ||
458 | AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0), | ||
459 | AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1), | ||
460 | }; | ||
461 | |||
462 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = { | ||
463 | AC97_ENUM("Record to Headphone Path", wm9713_enum[1]), | ||
464 | AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0), | ||
465 | AC97_ENUM("Record to Mono Path", wm9713_enum[2]), | ||
466 | AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0), | ||
467 | AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0), | ||
468 | AC97_ENUM("Record Select Left", wm9713_enum[3]), | ||
469 | AC97_ENUM("Record Select Right", wm9713_enum[4]), | ||
470 | }; | ||
471 | 738 | ||
472 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) | 739 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) |
473 | { | 740 | { |
474 | int err, i; | 741 | int err, i; |
475 | 742 | ||
476 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) { | 743 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) { |
477 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0) | 744 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0) |
478 | return err; | 745 | return err; |
479 | } | 746 | } |
480 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | 747 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); |
481 | |||
482 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) { | ||
483 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0) | ||
484 | return err; | ||
485 | } | ||
486 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); | 748 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); |
487 | |||
488 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) { | ||
489 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0) | ||
490 | return err; | ||
491 | } | ||
492 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); | 749 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); |
493 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); | 750 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); |
494 | |||
495 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) { | ||
496 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0) | ||
497 | return err; | ||
498 | } | ||
499 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); | 751 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); |
500 | |||
501 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) { | ||
502 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0) | ||
503 | return err; | ||
504 | } | ||
505 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); | 752 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); |
506 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); | 753 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); |
507 | |||
508 | return 0; | 754 | return 0; |
509 | } | 755 | } |
510 | 756 | ||
@@ -525,6 +771,7 @@ static void patch_wolfson_wm9713_resume (ac97_t * ac97) | |||
525 | 771 | ||
526 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | 772 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { |
527 | .build_specific = patch_wolfson_wm9713_specific, | 773 | .build_specific = patch_wolfson_wm9713_specific, |
774 | .build_3d = patch_wolfson_wm9713_3d, | ||
528 | #ifdef CONFIG_PM | 775 | #ifdef CONFIG_PM |
529 | .suspend = patch_wolfson_wm9713_suspend, | 776 | .suspend = patch_wolfson_wm9713_suspend, |
530 | .resume = patch_wolfson_wm9713_resume | 777 | .resume = patch_wolfson_wm9713_resume |
@@ -533,10 +780,13 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | |||
533 | 780 | ||
534 | int patch_wolfson13(ac97_t * ac97) | 781 | int patch_wolfson13(ac97_t * ac97) |
535 | { | 782 | { |
783 | /* WM9713, WM9714 */ | ||
536 | ac97->build_ops = &patch_wolfson_wm9713_ops; | 784 | ac97->build_ops = &patch_wolfson_wm9713_ops; |
537 | 785 | ||
538 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | | 786 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | |
539 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | 787 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE | |
788 | AC97_HAS_NO_STD_PCM; | ||
789 | ac97->scaps &= ~AC97_SCAP_MODEM; | ||
540 | 790 | ||
541 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); | 791 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); |
542 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); | 792 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); |
@@ -1379,6 +1629,7 @@ static void check_ad1981_hp_jack_sense(ac97_t *ac97) | |||
1379 | u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; | 1629 | u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; |
1380 | switch (subid) { | 1630 | switch (subid) { |
1381 | case 0x103c0890: /* HP nc6000 */ | 1631 | case 0x103c0890: /* HP nc6000 */ |
1632 | case 0x103c099c: /* HP nx6110 */ | ||
1382 | case 0x103c006d: /* HP nx9105 */ | 1633 | case 0x103c006d: /* HP nx9105 */ |
1383 | case 0x17340088: /* FSC Scenic-W */ | 1634 | case 0x17340088: /* FSC Scenic-W */ |
1384 | /* enable headphone jack sense */ | 1635 | /* enable headphone jack sense */ |
@@ -1706,7 +1957,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { | |||
1706 | }; | 1957 | }; |
1707 | 1958 | ||
1708 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { | 1959 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { |
1709 | AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), | 1960 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0), |
1710 | AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), | 1961 | AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), |
1711 | /* disable this controls since it doesn't work as expected */ | 1962 | /* disable this controls since it doesn't work as expected */ |
1712 | /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ | 1963 | /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ |
@@ -1849,12 +2100,12 @@ static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ | |||
1849 | } | 2100 | } |
1850 | 2101 | ||
1851 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { | 2102 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { |
1852 | AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0), | 2103 | AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0), |
1853 | /* disable this controls since it doesn't work as expected */ | 2104 | /* disable this controls since it doesn't work as expected */ |
1854 | /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ | 2105 | /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ |
1855 | { | 2106 | { |
1856 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2107 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1857 | .name = "IEC958 Playback Route", | 2108 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
1858 | .info = alc655_iec958_route_info, | 2109 | .info = alc655_iec958_route_info, |
1859 | .get = alc655_iec958_route_get, | 2110 | .get = alc655_iec958_route_get, |
1860 | .put = alc655_iec958_route_put, | 2111 | .put = alc655_iec958_route_put, |
@@ -2416,6 +2667,16 @@ int patch_vt1616(ac97_t * ac97) | |||
2416 | } | 2667 | } |
2417 | 2668 | ||
2418 | /* | 2669 | /* |
2670 | * VT1617A codec | ||
2671 | */ | ||
2672 | int patch_vt1617a(ac97_t * ac97) | ||
2673 | { | ||
2674 | ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ | ||
2675 | ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; | ||
2676 | return 0; | ||
2677 | } | ||
2678 | |||
2679 | /* | ||
2419 | */ | 2680 | */ |
2420 | static void it2646_update_jacks(ac97_t *ac97) | 2681 | static void it2646_update_jacks(ac97_t *ac97) |
2421 | { | 2682 | { |
@@ -2433,7 +2694,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = { | |||
2433 | }; | 2694 | }; |
2434 | 2695 | ||
2435 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { | 2696 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { |
2436 | AC97_SINGLE("IEC958 Capture Switch", 0x76, 11, 1, 0), | 2697 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0), |
2437 | AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), | 2698 | AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), |
2438 | AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), | 2699 | AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), |
2439 | }; | 2700 | }; |
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 7b7377d0f2ae..ec1811320106 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
@@ -56,5 +56,6 @@ int patch_cm9739(ac97_t * ac97); | |||
56 | int patch_cm9761(ac97_t * ac97); | 56 | int patch_cm9761(ac97_t * ac97); |
57 | int patch_cm9780(ac97_t * ac97); | 57 | int patch_cm9780(ac97_t * ac97); |
58 | int patch_vt1616(ac97_t * ac97); | 58 | int patch_vt1616(ac97_t * ac97); |
59 | int patch_vt1617a(ac97_t * ac97); | ||
59 | int patch_it2646(ac97_t * ac97); | 60 | int patch_it2646(ac97_t * ac97); |
60 | int mpatch_si3036(ac97_t * ac97); | 61 | int mpatch_si3036(ac97_t * ac97); |