aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-08-30 14:33:26 -0400
committerSteve French <sfrench@us.ibm.com>2005-08-30 14:33:26 -0400
commit2016ef789a9ded2e169ad1c028ae3deb5302571f (patch)
tree601359f15b42d4d9868b4eadfe909a7bef6435c5 /sound/pci/ac97
parent7f57356b70dda014ef269135942426e4a852023e (diff)
parent6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (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/Makefile2
-rw-r--r--sound/pci/ac97/ac97_bus.c79
-rw-r--r--sound/pci/ac97/ac97_codec.c85
-rw-r--r--sound/pci/ac97/ac97_patch.c449
-rw-r--r--sound/pci/ac97/ac97_patch.h1
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
10endif 10endif
11 11
12snd-ak4531-codec-objs := ak4531_codec.o 12snd-ak4531-codec-objs := ak4531_codec.o
13snd-ac97-bus-objs := ac97_bus.o
13 14
14# Toplevel Module Dependency 15# Toplevel Module Dependency
15obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o 16obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
16obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o 17obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o
18obj-$(CONFIG_SND_AC97_BUS) += snd-ac97-bus.o
17 19
18obj-m := $(sort $(obj-m)) 20obj-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 */
23static int ac97_bus_match(struct device *dev, struct device_driver *drv)
24{
25 return (strstr(dev->bus_id, drv->name) != NULL);
26}
27
28static 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
42static 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
56struct 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
63static int __init ac97_bus_init(void)
64{
65 return bus_register(&ac97_bus_type);
66}
67
68subsys_initcall(ac97_bus_init);
69
70static void __exit ac97_bus_exit(void)
71{
72 bus_unregister(&ac97_bus_type);
73}
74
75module_exit(ac97_bus_exit);
76
77EXPORT_SYMBOL(ac97_bus_type);
78
79MODULE_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 */
1818static void ac97_device_release(struct device * dev)
1819{
1820}
1821
1822/* register ac97 codec to bus */
1823static 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 */
1842static 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 */
1811static struct snd_ac97_build_ops null_build_ops; 1851static 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
373int patch_wolfson03(ac97_t * ac97) 373static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = {
374AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
375AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
376};
377
378static 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
394static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
395 .build_specific = patch_wolfson_wm9703_specific,
396};
377 397
378 // WM9703/9707/9708/9717 398int 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
384int patch_wolfson04(ac97_t * ac97) 404static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = {
405AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
406AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
407AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1),
408AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1),
409AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1),
410AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
411};
412
413static 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
425static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
426 .build_specific = patch_wolfson_wm9704_specific,
427};
428
429int patch_wolfson04(ac97_t * ac97)
430{
431 /* WM9704M/9704Q */
432 ac97->build_ops = &patch_wolfson_wm9704_ops;
433 return 0;
434}
435
436static 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
447static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
448 .build_specific = patch_wolfson_wm9705_specific,
449};
450
402int patch_wolfson05(ac97_t * ac97) 451int 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
458static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"};
459static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"};
460static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"};
461static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"};
462static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
463static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"};
464static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
465static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
466static const char* wm9711_rec_sel[] =
467 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
468static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"};
469
470static const struct ac97_enum wm9711_enum[] = {
471AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select),
472AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix),
473AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src),
474AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc),
475AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc),
476AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base),
477AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain),
478AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic),
479AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel),
480AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type),
481};
482
483static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = {
484AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
485AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
486AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
487AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
488AC97_ENUM("ALC Function", wm9711_enum[0]),
489AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1),
490AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
491AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
492AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
493AC97_ENUM("ALC NG Type", wm9711_enum[9]),
494AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
495
496AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1),
497AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1),
498AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]),
499AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
500
501AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
502AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1),
503AC97_ENUM("Out3 Mux", wm9711_enum[2]),
504AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
505AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
506
507AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
508AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
509AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1),
510AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1),
511AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1),
512AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1),
513
514AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1),
515AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1),
516AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1),
517AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1),
518AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1),
519AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1),
520
521AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1),
522AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1),
523
524AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1),
525AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1),
526AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1),
527
528AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1),
529AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1),
530AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1),
531
532AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
533AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]),
534AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
535AC97_ENUM("Capture Select", wm9711_enum[8]),
536
537AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
538AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
539
540AC97_ENUM("Bass Control", wm9711_enum[5]),
541AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
542AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
543AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
544
545AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
546AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
547AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1),
548AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
549
550AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
551AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
552AC97_ENUM("Mic Select Source", wm9711_enum[7]),
553AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1),
554AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
555
556AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
557AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
558AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
559};
560
561static 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
578static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
579 .build_specific = patch_wolfson_wm9711_specific,
580};
581
410int patch_wolfson11(ac97_t * ac97) 582int 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
418static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; 593static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
419static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; 594static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
420static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; 595static const char* wm9713_rec_src[] =
421static 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"};
598static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
599static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
600static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
601static const char* wm9713_spk_pga[] =
602 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
603static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
604static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"};
605static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"};
606static const char* wm9713_dac_inv[] =
607 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
608 "Headphone Mix Mono", "NC", "Vmid"};
609static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"};
610static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"};
422 611
423static const struct ac97_enum wm9713_enum[] = { 612static const struct ac97_enum wm9713_enum[] = {
424AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), 613AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
425AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), 614AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
426AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), 615AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
427AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), 616AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src),
428AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), 617AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain),
618AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select),
619AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga),
620AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga),
621AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga),
622AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga),
623AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga),
624AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv),
625AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base),
626AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
429}; 627};
430 628
431static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { 629static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = {
432AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 630AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
433AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), 631AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
434AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), 632AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1),
435AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), 633AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1),
634
635AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1),
636AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1),
637AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1),
638AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1),
639
640AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
641AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
642AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1),
643AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1),
644AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
645AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]),
646AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
647
648AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
649AC97_ENUM("Capture Volume Steps", wm9713_enum[4]),
650AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0),
651AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
652
653AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]),
654AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1),
655AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]),
656AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
657AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
658AC97_ENUM("Capture Select", wm9713_enum[3]),
659
660AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
661AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
662AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
663AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
664AC97_ENUM("ALC Function", wm9713_enum[5]),
665AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
666AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
667AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
668AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
669AC97_ENUM("ALC NG Type", wm9713_enum[13]),
670AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
671
672AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0),
673AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
674AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0),
675AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1),
676AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1),
677AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1),
678
679AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1),
680AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1),
681AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1),
682AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
683AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
684AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
685
686AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
687AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
688AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1),
689AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1),
690AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1),
691AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1),
692
693AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
694AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
695AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1),
696AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1),
697AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1),
698AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1),
699
700AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1),
701AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1),
702AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1),
703AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1),
704AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1),
705AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1),
706
707AC97_ENUM("Mono Input Mux", wm9713_enum[6]),
708AC97_ENUM("Master Input Mux", wm9713_enum[7]),
709AC97_ENUM("Headphone Input Mux", wm9713_enum[8]),
710AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]),
711AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]),
712
713AC97_ENUM("Bass Control", wm9713_enum[12]),
714AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
715AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
716AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
717AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
718AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
436}; 719};
437 720
438static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { 721static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = {
439AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), 722AC97_ENUM("Inv Input Mux", wm9713_enum[11]),
440AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), 723AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
441AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), 724AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
442AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), 725AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
443}; 726};
444 727
445static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { 728static int patch_wolfson_wm9713_3d (ac97_t * ac97)
446AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), 729{
447AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), 730 int err, i;
448AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), 731
449AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), 732 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) {
450AC97_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)
451AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), 734 return err;
452AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) 735 }
453}; 736 return 0;
454 737}
455static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = {
456AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1),
457AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1),
458AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0),
459AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1),
460};
461
462static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = {
463AC97_ENUM("Record to Headphone Path", wm9713_enum[1]),
464AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0),
465AC97_ENUM("Record to Mono Path", wm9713_enum[2]),
466AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0),
467AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0),
468AC97_ENUM("Record Select Left", wm9713_enum[3]),
469AC97_ENUM("Record Select Right", wm9713_enum[4]),
470};
471 738
472static int patch_wolfson_wm9713_specific(ac97_t * ac97) 739static 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
526static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { 772static 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
534int patch_wolfson13(ac97_t * ac97) 781int 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
1708static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { 1959static 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
1851static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { 2102static 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 */
2672int 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 */
2420static void it2646_update_jacks(ac97_t *ac97) 2681static 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
2435static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { 2696static 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);
56int patch_cm9761(ac97_t * ac97); 56int patch_cm9761(ac97_t * ac97);
57int patch_cm9780(ac97_t * ac97); 57int patch_cm9780(ac97_t * ac97);
58int patch_vt1616(ac97_t * ac97); 58int patch_vt1616(ac97_t * ac97);
59int patch_vt1617a(ac97_t * ac97);
59int patch_it2646(ac97_t * ac97); 60int patch_it2646(ac97_t * ac97);
60int mpatch_si3036(ac97_t * ac97); 61int mpatch_si3036(ac97_t * ac97);