aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c13
-rw-r--r--sound/aoa/codecs/tas.c13
-rw-r--r--sound/arm/aaci.c13
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/init.c170
-rw-r--r--sound/core/jack.c4
-rw-r--r--sound/core/misc.c2
-rw-r--r--sound/core/pcm.c100
-rw-r--r--sound/core/pcm_lib.c3
-rw-r--r--sound/core/pcm_native.c15
-rw-r--r--sound/core/seq/seq.c1
-rw-r--r--sound/core/timer.c1
-rw-r--r--sound/core/vmaster.c46
-rw-r--r--sound/firewire/isight.c4
-rw-r--r--sound/firewire/speakers.c4
-rw-r--r--sound/i2c/other/tea575x-tuner.c169
-rw-r--r--sound/pci/au88x0/au88x0.h13
-rw-r--r--sound/pci/au88x0/au88x0_core.c20
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c127
-rw-r--r--sound/pci/ctxfi/ctvmem.c2
-rw-r--r--sound/pci/es1968.c15
-rw-r--r--sound/pci/fm801.c20
-rw-r--r--sound/pci/hda/alc260_quirks.c968
-rw-r--r--sound/pci/hda/alc880_quirks.c1707
-rw-r--r--sound/pci/hda/alc882_quirks.c866
-rw-r--r--sound/pci/hda/alc_quirks.c480
-rw-r--r--sound/pci/hda/hda_codec.c192
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_eld.c4
-rw-r--r--sound/pci/hda/hda_intel.c52
-rw-r--r--sound/pci/hda/hda_jack.c16
-rw-r--r--sound/pci/hda/hda_jack.h13
-rw-r--r--sound/pci/hda/hda_local.h30
-rw-r--r--sound/pci/hda/patch_analog.c72
-rw-r--r--sound/pci/hda/patch_conexant.c124
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c1840
-rw-r--r--sound/pci/hda/patch_sigmatel.c203
-rw-r--r--sound/pci/hda/patch_via.c48
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c9
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/atmel/atmel-pcm.c4
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c37
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c17
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c17
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c29
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c20
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c13
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1701.c16
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c13
-rw-r--r--sound/soc/codecs/Kconfig8
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/ad1836.c6
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/adau1373.c7
-rw-r--r--sound/soc/codecs/adau1701.c2
-rw-r--r--sound/soc/codecs/ak4104.c174
-rw-r--r--sound/soc/codecs/ak4535.c98
-rw-r--r--sound/soc/codecs/ak4535.h2
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c2
-rw-r--r--sound/soc/codecs/alc5623.c12
-rw-r--r--sound/soc/codecs/alc5632.c197
-rw-r--r--sound/soc/codecs/alc5632.h1
-rw-r--r--sound/soc/codecs/cq93vc.c4
-rw-r--r--sound/soc/codecs/cs4270.c4
-rw-r--r--sound/soc/codecs/cs4271.c2
-rw-r--r--sound/soc/codecs/da7210.c146
-rw-r--r--sound/soc/codecs/lm4857.c2
-rw-r--r--sound/soc/codecs/max9768.c247
-rw-r--r--sound/soc/codecs/max98088.c4
-rw-r--r--sound/soc/codecs/max98095.c6
-rw-r--r--sound/soc/codecs/max9877.c2
-rw-r--r--sound/soc/codecs/sgtl5000.c19
-rw-r--r--sound/soc/codecs/sn95031.c5
-rw-r--r--sound/soc/codecs/ssm2602.c2
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/tlv320aic26.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c66
-rw-r--r--sound/soc/codecs/tlv320aic3x.h9
-rw-r--r--sound/soc/codecs/tlv320dac33.c10
-rw-r--r--sound/soc/codecs/tpa6130a2.c4
-rw-r--r--sound/soc/codecs/twl4030.c42
-rw-r--r--sound/soc/codecs/twl6040.c31
-rw-r--r--sound/soc/codecs/twl6040.h1
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/wl1273.c2
-rw-r--r--sound/soc/codecs/wm2200.c2286
-rw-r--r--sound/soc/codecs/wm2200.h3674
-rw-r--r--sound/soc/codecs/wm5100.c643
-rw-r--r--sound/soc/codecs/wm8731.c109
-rw-r--r--sound/soc/codecs/wm8737.c2
-rw-r--r--sound/soc/codecs/wm8753.c195
-rw-r--r--sound/soc/codecs/wm8770.c5
-rw-r--r--sound/soc/codecs/wm8776.c8
-rw-r--r--sound/soc/codecs/wm8804.c154
-rw-r--r--sound/soc/codecs/wm8904.c856
-rw-r--r--sound/soc/codecs/wm8904.h11
-rw-r--r--sound/soc/codecs/wm8940.c16
-rw-r--r--sound/soc/codecs/wm8955.c247
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c14
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c2141
-rw-r--r--sound/soc/codecs/wm8971.c37
-rw-r--r--sound/soc/codecs/wm8974.c45
-rw-r--r--sound/soc/codecs/wm8978.c185
-rw-r--r--sound/soc/codecs/wm8978.h2
-rw-r--r--sound/soc/codecs/wm8983.c5
-rw-r--r--sound/soc/codecs/wm8985.c315
-rw-r--r--sound/soc/codecs/wm8988.c171
-rw-r--r--sound/soc/codecs/wm8990.c2
-rw-r--r--sound/soc/codecs/wm8991.c2
-rw-r--r--sound/soc/codecs/wm8993.c649
-rw-r--r--sound/soc/codecs/wm8993.h9
-rw-r--r--sound/soc/codecs/wm8994.c548
-rw-r--r--sound/soc/codecs/wm8994.h14
-rw-r--r--sound/soc/codecs/wm8995.c4
-rw-r--r--sound/soc/codecs/wm8996.c253
-rw-r--r--sound/soc/codecs/wm9081.c80
-rw-r--r--sound/soc/codecs/wm9090.c272
-rw-r--r--sound/soc/codecs/wm9705.c2
-rw-r--r--sound/soc/codecs/wm9712.c16
-rw-r--r--sound/soc/codecs/wm9713.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c152
-rw-r--r--sound/soc/codecs/wm_hubs.h12
-rw-r--r--sound/soc/davinci/davinci-pcm.c4
-rw-r--r--sound/soc/ep93xx/Kconfig1
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c152
-rw-r--r--sound/soc/fsl/fsl_dma.c10
-rw-r--r--sound/soc/fsl/fsl_ssi.c6
-rw-r--r--sound/soc/fsl/mpc5200_dma.c17
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c18
-rw-r--r--sound/soc/fsl/p1022_ds.c60
-rw-r--r--sound/soc/imx/Kconfig25
-rw-r--r--sound/soc/imx/Makefile15
-rw-r--r--sound/soc/imx/eukrea-tlv320.c40
-rw-r--r--sound/soc/imx/imx-audmux.c314
-rw-r--r--sound/soc/imx/imx-audmux.h60
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c223
-rw-r--r--sound/soc/imx/imx-pcm.c105
-rw-r--r--sound/soc/imx/imx-pcm.h32
-rw-r--r--sound/soc/imx/imx-ssi.c118
-rw-r--r--sound/soc/imx/imx-ssi.h16
-rw-r--r--sound/soc/imx/mx27vis-aic32x4.c159
-rw-r--r--sound/soc/imx/phycore-ac97.c27
-rw-r--r--sound/soc/imx/wm1133-ev1.c25
-rw-r--r--sound/soc/jz4740/qi_lb60.c56
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c4
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c46
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c47
-rw-r--r--sound/soc/mid-x86/mfld_machine.c2
-rw-r--r--sound/soc/mxs/Kconfig2
-rw-r--r--sound/soc/mxs/mxs-pcm.c157
-rw-r--r--sound/soc/mxs/mxs-pcm.h16
-rw-r--r--sound/soc/mxs/mxs-saif.c51
-rw-r--r--sound/soc/omap/Kconfig15
-rw-r--r--sound/soc/omap/Makefile6
-rw-r--r--sound/soc/omap/am3517evm.c2
-rw-r--r--sound/soc/omap/ams-delta.c4
-rw-r--r--sound/soc/omap/igep0020.c2
-rw-r--r--sound/soc/omap/mcbsp.c1040
-rw-r--r--sound/soc/omap/mcbsp.h346
-rw-r--r--sound/soc/omap/n810.c19
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c349
-rw-r--r--sound/soc/omap/omap-dmic.c7
-rw-r--r--sound/soc/omap/omap-mcbsp.c321
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-mcpdm.c2
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/omap3beagle.c2
-rw-r--r--sound/soc/omap/omap3evm.c2
-rw-r--r--sound/soc/omap/omap3pandora.c4
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/overo.c2
-rw-r--r--sound/soc/omap/rx51.c27
-rw-r--r--sound/soc/omap/sdp3430.c4
-rw-r--r--sound/soc/omap/sdp4430.c279
-rw-r--r--sound/soc/omap/zoom2.c4
-rw-r--r--sound/soc/pxa/corgi.c14
-rw-r--r--sound/soc/pxa/magician.c2
-rw-r--r--sound/soc/pxa/poodle.c14
-rw-r--r--sound/soc/pxa/pxa-ssp.c64
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c10
-rw-r--r--sound/soc/pxa/raumfeld.c2
-rw-r--r--sound/soc/pxa/spitz.c14
-rw-r--r--sound/soc/pxa/tosa.c2
-rw-r--r--sound/soc/s6000/s6000-pcm.c5
-rw-r--r--sound/soc/samsung/ac97.c4
-rw-r--r--sound/soc/samsung/dma.c2
-rw-r--r--sound/soc/samsung/i2s.c27
-rw-r--r--sound/soc/samsung/i2s.h2
-rw-r--r--sound/soc/samsung/littlemill.c3
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c4
-rw-r--r--sound/soc/samsung/pcm.c4
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c6
-rw-r--r--sound/soc/samsung/smdk_wm8580.c4
-rw-r--r--sound/soc/samsung/smdk_wm9713.c4
-rw-r--r--sound/soc/sh/fsi.c912
-rw-r--r--sound/soc/soc-core.c399
-rw-r--r--sound/soc/soc-dapm.c400
-rw-r--r--sound/soc/soc-dmaengine-pcm.c288
-rw-r--r--sound/soc/soc-io.c7
-rw-r--r--sound/soc/soc-pcm.c104
-rw-r--r--sound/soc/soc-utils.c20
-rw-r--r--sound/soc/tegra/tegra_alc5632.c129
-rw-r--r--sound/soc/tegra/tegra_pcm.c2
-rw-r--r--sound/spi/at73c213.c12
-rw-r--r--sound/usb/6fire/chip.c3
-rw-r--r--sound/usb/6fire/chip.h1
-rw-r--r--sound/usb/6fire/comm.c1
-rw-r--r--sound/usb/6fire/comm.h1
-rw-r--r--sound/usb/6fire/common.h1
-rw-r--r--sound/usb/6fire/control.c341
-rw-r--r--sound/usb/6fire/control.h7
-rw-r--r--sound/usb/6fire/firmware.c1
-rw-r--r--sound/usb/6fire/midi.c1
-rw-r--r--sound/usb/6fire/midi.h1
-rw-r--r--sound/usb/6fire/pcm.c1
-rw-r--r--sound/usb/6fire/pcm.h1
-rw-r--r--sound/usb/Kconfig1
-rw-r--r--sound/usb/pcm.c6
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c4
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
228 files changed, 17649 insertions, 11295 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 762af68c8996..270790d384e2 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1132,15 +1132,4 @@ static struct i2c_driver onyx_driver = {
1132 .id_table = onyx_i2c_id, 1132 .id_table = onyx_i2c_id,
1133}; 1133};
1134 1134
1135static int __init onyx_init(void) 1135module_i2c_driver(onyx_driver);
1136{
1137 return i2c_add_driver(&onyx_driver);
1138}
1139
1140static void __exit onyx_exit(void)
1141{
1142 i2c_del_driver(&onyx_driver);
1143}
1144
1145module_init(onyx_init);
1146module_exit(onyx_exit);
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index fd2188c3df2b..8e63d1f35ce1 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -1026,15 +1026,4 @@ static struct i2c_driver tas_driver = {
1026 .id_table = tas_i2c_id, 1026 .id_table = tas_i2c_id,
1027}; 1027};
1028 1028
1029static int __init tas_init(void) 1029module_i2c_driver(tas_driver);
1030{
1031 return i2c_add_driver(&tas_driver);
1032}
1033
1034static void __exit tas_exit(void)
1035{
1036 i2c_del_driver(&tas_driver);
1037}
1038
1039module_init(tas_init);
1040module_exit(tas_exit);
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index b37b702a3a6a..5119fdabcb98 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -1110,18 +1110,7 @@ static struct amba_driver aaci_driver = {
1110 .id_table = aaci_ids, 1110 .id_table = aaci_ids,
1111}; 1111};
1112 1112
1113static int __init aaci_init(void) 1113module_amba_driver(aaci_driver);
1114{
1115 return amba_driver_register(&aaci_driver);
1116}
1117
1118static void __exit aaci_exit(void)
1119{
1120 amba_driver_unregister(&aaci_driver);
1121}
1122
1123module_init(aaci_init);
1124module_exit(aaci_exit);
1125 1114
1126MODULE_LICENSE("GPL"); 1115MODULE_LICENSE("GPL");
1127MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver"); 1116MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver");
diff --git a/sound/core/control.c b/sound/core/control.c
index 819a5c579a39..2487a6bb1c54 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1313,7 +1313,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1313 err = -EPERM; 1313 err = -EPERM;
1314 goto __kctl_end; 1314 goto __kctl_end;
1315 } 1315 }
1316 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); 1316 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
1317 if (err > 0) { 1317 if (err > 0) {
1318 up_read(&card->controls_rwsem); 1318 up_read(&card->controls_rwsem);
1319 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); 1319 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
diff --git a/sound/core/init.c b/sound/core/init.c
index 3ac49b1b7cb8..d8ec849af128 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/device.h>
25#include <linux/file.h> 26#include <linux/file.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <linux/time.h> 28#include <linux/time.h>
@@ -480,74 +481,104 @@ int snd_card_free(struct snd_card *card)
480 481
481EXPORT_SYMBOL(snd_card_free); 482EXPORT_SYMBOL(snd_card_free);
482 483
483static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) 484/* retrieve the last word of shortname or longname */
485static const char *retrieve_id_from_card_name(const char *name)
484{ 486{
485 int i, len, idx_flag = 0, loops = SNDRV_CARDS; 487 const char *spos = name;
486 const char *spos, *src; 488
487 char *id; 489 while (*name) {
488 490 if (isspace(*name) && isalnum(name[1]))
489 if (nid == NULL) { 491 spos = name + 1;
490 id = card->shortname; 492 name++;
491 spos = src = id;
492 while (*id != '\0') {
493 if (*id == ' ')
494 spos = id + 1;
495 id++;
496 }
497 } else {
498 spos = src = nid;
499 } 493 }
500 id = card->id; 494 return spos;
501 while (*spos != '\0' && !isalnum(*spos)) 495}
502 spos++; 496
503 if (isdigit(*spos)) 497/* return true if the given id string doesn't conflict any other card ids */
504 *id++ = isalpha(src[0]) ? src[0] : 'D'; 498static bool card_id_ok(struct snd_card *card, const char *id)
505 while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { 499{
506 if (isalnum(*spos)) 500 int i;
507 *id++ = *spos; 501 if (!snd_info_check_reserved_words(id))
508 spos++; 502 return false;
503 for (i = 0; i < snd_ecards_limit; i++) {
504 if (snd_cards[i] && snd_cards[i] != card &&
505 !strcmp(snd_cards[i]->id, id))
506 return false;
509 } 507 }
510 *id = '\0'; 508 return true;
509}
511 510
512 id = card->id; 511/* copy to card->id only with valid letters from nid */
512static void copy_valid_id_string(struct snd_card *card, const char *src,
513 const char *nid)
514{
515 char *id = card->id;
516
517 while (*nid && !isalnum(*nid))
518 nid++;
519 if (isdigit(*nid))
520 *id++ = isalpha(*src) ? *src : 'D';
521 while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) {
522 if (isalnum(*nid))
523 *id++ = *nid;
524 nid++;
525 }
526 *id = 0;
527}
528
529/* Set card->id from the given string
530 * If the string conflicts with other ids, add a suffix to make it unique.
531 */
532static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
533 const char *nid)
534{
535 int len, loops;
536 bool with_suffix;
537 bool is_default = false;
538 char *id;
513 539
514 if (*id == '\0') 540 copy_valid_id_string(card, src, nid);
541 id = card->id;
542
543 again:
544 /* use "Default" for obviously invalid strings
545 * ("card" conflicts with proc directories)
546 */
547 if (!*id || !strncmp(id, "card", 4)) {
515 strcpy(id, "Default"); 548 strcpy(id, "Default");
549 is_default = true;
550 }
516 551
517 while (1) { 552 with_suffix = false;
518 if (loops-- == 0) { 553 for (loops = 0; loops < SNDRV_CARDS; loops++) {
519 snd_printk(KERN_ERR "unable to set card id (%s)\n", id); 554 if (card_id_ok(card, id))
520 strcpy(card->id, card->proc_root->name); 555 return; /* OK */
521 return;
522 }
523 if (!snd_info_check_reserved_words(id))
524 goto __change;
525 for (i = 0; i < snd_ecards_limit; i++) {
526 if (snd_cards[i] && !strcmp(snd_cards[i]->id, id))
527 goto __change;
528 }
529 break;
530 556
531 __change:
532 len = strlen(id); 557 len = strlen(id);
533 if (idx_flag) { 558 if (!with_suffix) {
534 if (id[len-1] != '9') 559 /* add the "_X" suffix */
535 id[len-1]++; 560 char *spos = id + len;
536 else 561 if (len > sizeof(card->id) - 3)
537 id[len-1] = 'A'; 562 spos = id + sizeof(card->id) - 3;
538 } else if ((size_t)len <= sizeof(card->id) - 3) { 563 strcpy(spos, "_1");
539 strcat(id, "_1"); 564 with_suffix = true;
540 idx_flag++;
541 } else { 565 } else {
542 spos = id + len - 2; 566 /* modify the existing suffix */
543 if ((size_t)len <= sizeof(card->id) - 2) 567 if (id[len - 1] != '9')
544 spos++; 568 id[len - 1]++;
545 *(char *)spos++ = '_'; 569 else
546 *(char *)spos++ = '1'; 570 id[len - 1] = 'A';
547 *(char *)spos++ = '\0';
548 idx_flag++;
549 } 571 }
550 } 572 }
573 /* fallback to the default id */
574 if (!is_default) {
575 *id = 0;
576 goto again;
577 }
578 /* last resort... */
579 snd_printk(KERN_ERR "unable to set card id (%s)\n", id);
580 if (card->proc_root->name)
581 strcpy(card->id, card->proc_root->name);
551} 582}
552 583
553/** 584/**
@@ -564,7 +595,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
564 if (card->id[0] != '\0') 595 if (card->id[0] != '\0')
565 return; 596 return;
566 mutex_lock(&snd_card_mutex); 597 mutex_lock(&snd_card_mutex);
567 snd_card_set_id_no_lock(card, nid); 598 snd_card_set_id_no_lock(card, nid, nid);
568 mutex_unlock(&snd_card_mutex); 599 mutex_unlock(&snd_card_mutex);
569} 600}
570EXPORT_SYMBOL(snd_card_set_id); 601EXPORT_SYMBOL(snd_card_set_id);
@@ -596,22 +627,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
596 memcpy(buf1, buf, copy); 627 memcpy(buf1, buf, copy);
597 buf1[copy] = '\0'; 628 buf1[copy] = '\0';
598 mutex_lock(&snd_card_mutex); 629 mutex_lock(&snd_card_mutex);
599 if (!snd_info_check_reserved_words(buf1)) { 630 if (!card_id_ok(NULL, buf1)) {
600 __exist:
601 mutex_unlock(&snd_card_mutex); 631 mutex_unlock(&snd_card_mutex);
602 return -EEXIST; 632 return -EEXIST;
603 } 633 }
604 for (idx = 0; idx < snd_ecards_limit; idx++) {
605 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) {
606 if (card == snd_cards[idx])
607 goto __ok;
608 else
609 goto __exist;
610 }
611 }
612 strcpy(card->id, buf1); 634 strcpy(card->id, buf1);
613 snd_info_card_id_change(card); 635 snd_info_card_id_change(card);
614__ok:
615 mutex_unlock(&snd_card_mutex); 636 mutex_unlock(&snd_card_mutex);
616 637
617 return count; 638 return count;
@@ -665,7 +686,18 @@ int snd_card_register(struct snd_card *card)
665 mutex_unlock(&snd_card_mutex); 686 mutex_unlock(&snd_card_mutex);
666 return 0; 687 return 0;
667 } 688 }
668 snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); 689 if (*card->id) {
690 /* make a unique id name from the given string */
691 char tmpid[sizeof(card->id)];
692 memcpy(tmpid, card->id, sizeof(card->id));
693 snd_card_set_id_no_lock(card, tmpid, tmpid);
694 } else {
695 /* create an id from either shortname or longname */
696 const char *src;
697 src = *card->shortname ? card->shortname : card->longname;
698 snd_card_set_id_no_lock(card, src,
699 retrieve_id_from_card_name(src));
700 }
669 snd_cards[card->number] = card; 701 snd_cards[card->number] = card;
670 mutex_unlock(&snd_card_mutex); 702 mutex_unlock(&snd_card_mutex);
671 init_info_for_card(card); 703 init_info_for_card(card);
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 26edf63b265f..471e1e3b0a99 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -25,7 +25,7 @@
25#include <sound/jack.h> 25#include <sound/jack.h>
26#include <sound/core.h> 26#include <sound/core.h>
27 27
28static int jack_switch_types[] = { 28static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
29 SW_HEADPHONE_INSERT, 29 SW_HEADPHONE_INSERT,
30 SW_MICROPHONE_INSERT, 30 SW_MICROPHONE_INSERT,
31 SW_LINEOUT_INSERT, 31 SW_LINEOUT_INSERT,
@@ -128,7 +128,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
128 128
129 jack->type = type; 129 jack->type = type;
130 130
131 for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) 131 for (i = 0; i < SND_JACK_SWITCH_TYPES; i++)
132 if (type & (1 << i)) 132 if (type & (1 << i))
133 input_set_capability(jack->input_dev, EV_SW, 133 input_set_capability(jack->input_dev, EV_SW,
134 jack_switch_types[i]); 134 jack_switch_types[i]);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 465f0ce772cb..768167925409 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line,
72 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; 72 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
73#endif 73#endif
74 74
75#ifdef CONFIG_SND_DEBUG 75#ifdef CONFIG_SND_DEBUG
76 if (debug < level) 76 if (debug < level)
77 return; 77 return;
78#endif 78#endif
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 8928ca871c22..1a3070b4e5b5 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/time.h> 25#include <linux/time.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/device.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/minors.h> 29#include <sound/minors.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
@@ -650,7 +651,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
650 pstr->stream = stream; 651 pstr->stream = stream;
651 pstr->pcm = pcm; 652 pstr->pcm = pcm;
652 pstr->substream_count = substream_count; 653 pstr->substream_count = substream_count;
653 if (substream_count > 0) { 654 if (substream_count > 0 && !pcm->internal) {
654 err = snd_pcm_stream_proc_init(pstr); 655 err = snd_pcm_stream_proc_init(pstr);
655 if (err < 0) { 656 if (err < 0) {
656 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 657 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
@@ -674,15 +675,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
674 pstr->substream = substream; 675 pstr->substream = substream;
675 else 676 else
676 prev->next = substream; 677 prev->next = substream;
677 err = snd_pcm_substream_proc_init(substream); 678
678 if (err < 0) { 679 if (!pcm->internal) {
679 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 680 err = snd_pcm_substream_proc_init(substream);
680 if (prev == NULL) 681 if (err < 0) {
681 pstr->substream = NULL; 682 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
682 else 683 if (prev == NULL)
683 prev->next = NULL; 684 pstr->substream = NULL;
684 kfree(substream); 685 else
685 return err; 686 prev->next = NULL;
687 kfree(substream);
688 return err;
689 }
686 } 690 }
687 substream->group = &substream->self_group; 691 substream->group = &substream->self_group;
688 spin_lock_init(&substream->self_group.lock); 692 spin_lock_init(&substream->self_group.lock);
@@ -696,25 +700,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
696 700
697EXPORT_SYMBOL(snd_pcm_new_stream); 701EXPORT_SYMBOL(snd_pcm_new_stream);
698 702
699/** 703static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
700 * snd_pcm_new - create a new PCM instance 704 int playback_count, int capture_count, bool internal,
701 * @card: the card instance 705 struct snd_pcm **rpcm)
702 * @id: the id string
703 * @device: the device index (zero based)
704 * @playback_count: the number of substreams for playback
705 * @capture_count: the number of substreams for capture
706 * @rpcm: the pointer to store the new pcm instance
707 *
708 * Creates a new PCM instance.
709 *
710 * The pcm operators have to be set afterwards to the new instance
711 * via snd_pcm_set_ops().
712 *
713 * Returns zero if successful, or a negative error code on failure.
714 */
715int snd_pcm_new(struct snd_card *card, const char *id, int device,
716 int playback_count, int capture_count,
717 struct snd_pcm ** rpcm)
718{ 706{
719 struct snd_pcm *pcm; 707 struct snd_pcm *pcm;
720 int err; 708 int err;
@@ -735,6 +723,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
735 } 723 }
736 pcm->card = card; 724 pcm->card = card;
737 pcm->device = device; 725 pcm->device = device;
726 pcm->internal = internal;
738 if (id) 727 if (id)
739 strlcpy(pcm->id, id, sizeof(pcm->id)); 728 strlcpy(pcm->id, id, sizeof(pcm->id));
740 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { 729 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@@ -756,8 +745,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
756 return 0; 745 return 0;
757} 746}
758 747
748/**
749 * snd_pcm_new - create a new PCM instance
750 * @card: the card instance
751 * @id: the id string
752 * @device: the device index (zero based)
753 * @playback_count: the number of substreams for playback
754 * @capture_count: the number of substreams for capture
755 * @rpcm: the pointer to store the new pcm instance
756 *
757 * Creates a new PCM instance.
758 *
759 * The pcm operators have to be set afterwards to the new instance
760 * via snd_pcm_set_ops().
761 *
762 * Returns zero if successful, or a negative error code on failure.
763 */
764int snd_pcm_new(struct snd_card *card, const char *id, int device,
765 int playback_count, int capture_count, struct snd_pcm **rpcm)
766{
767 return _snd_pcm_new(card, id, device, playback_count, capture_count,
768 false, rpcm);
769}
759EXPORT_SYMBOL(snd_pcm_new); 770EXPORT_SYMBOL(snd_pcm_new);
760 771
772/**
773 * snd_pcm_new_internal - create a new internal PCM instance
774 * @card: the card instance
775 * @id: the id string
776 * @device: the device index (zero based - shared with normal PCMs)
777 * @playback_count: the number of substreams for playback
778 * @capture_count: the number of substreams for capture
779 * @rpcm: the pointer to store the new pcm instance
780 *
781 * Creates a new internal PCM instance with no userspace device or procfs
782 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
783 * will only be used internally by kernel drivers. i.e. it cannot be opened
784 * by userspace. It provides existing ASoC components drivers with a substream
785 * and access to any private data.
786 *
787 * The pcm operators have to be set afterwards to the new instance
788 * via snd_pcm_set_ops().
789 *
790 * Returns zero if successful, or a negative error code on failure.
791 */
792int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
793 int playback_count, int capture_count,
794 struct snd_pcm **rpcm)
795{
796 return _snd_pcm_new(card, id, device, playback_count, capture_count,
797 true, rpcm);
798}
799EXPORT_SYMBOL(snd_pcm_new_internal);
800
761static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 801static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
762{ 802{
763 struct snd_pcm_substream *substream, *substream_next; 803 struct snd_pcm_substream *substream, *substream_next;
@@ -994,7 +1034,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
994 } 1034 }
995 for (cidx = 0; cidx < 2; cidx++) { 1035 for (cidx = 0; cidx < 2; cidx++) {
996 int devtype = -1; 1036 int devtype = -1;
997 if (pcm->streams[cidx].substream == NULL) 1037 if (pcm->streams[cidx].substream == NULL || pcm->internal)
998 continue; 1038 continue;
999 switch (cidx) { 1039 switch (cidx) {
1000 case SNDRV_PCM_STREAM_PLAYBACK: 1040 case SNDRV_PCM_STREAM_PLAYBACK:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 3420bd3da5d7..4d18941178e6 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1029,7 +1029,8 @@ static int snd_interval_ratden(struct snd_interval *i,
1029 * 1029 *
1030 * Returns non-zero if the value is changed, zero if not changed. 1030 * Returns non-zero if the value is changed, zero if not changed.
1031 */ 1031 */
1032int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) 1032int snd_interval_list(struct snd_interval *i, unsigned int count,
1033 const unsigned int *list, unsigned int mask)
1033{ 1034{
1034 unsigned int k; 1035 unsigned int k;
1035 struct snd_interval list_range; 1036 struct snd_interval list_range;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 25ed9fe41b89..3fe99e644eb8 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1586 struct file *file; 1586 struct file *file;
1587 struct snd_pcm_file *pcm_file; 1587 struct snd_pcm_file *pcm_file;
1588 struct snd_pcm_substream *substream1; 1588 struct snd_pcm_substream *substream1;
1589 struct snd_pcm_group *group;
1589 1590
1590 file = snd_pcm_file_fd(fd); 1591 file = snd_pcm_file_fd(fd);
1591 if (!file) 1592 if (!file)
1592 return -EBADFD; 1593 return -EBADFD;
1593 pcm_file = file->private_data; 1594 pcm_file = file->private_data;
1594 substream1 = pcm_file->substream; 1595 substream1 = pcm_file->substream;
1596 group = kmalloc(sizeof(*group), GFP_KERNEL);
1597 if (!group) {
1598 res = -ENOMEM;
1599 goto _nolock;
1600 }
1595 down_write(&snd_pcm_link_rwsem); 1601 down_write(&snd_pcm_link_rwsem);
1596 write_lock_irq(&snd_pcm_link_rwlock); 1602 write_lock_irq(&snd_pcm_link_rwlock);
1597 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || 1603 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
@@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1604 goto _end; 1610 goto _end;
1605 } 1611 }
1606 if (!snd_pcm_stream_linked(substream)) { 1612 if (!snd_pcm_stream_linked(substream)) {
1607 substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); 1613 substream->group = group;
1608 if (substream->group == NULL) {
1609 res = -ENOMEM;
1610 goto _end;
1611 }
1612 spin_lock_init(&substream->group->lock); 1614 spin_lock_init(&substream->group->lock);
1613 INIT_LIST_HEAD(&substream->group->substreams); 1615 INIT_LIST_HEAD(&substream->group->substreams);
1614 list_add_tail(&substream->link_list, &substream->group->substreams); 1616 list_add_tail(&substream->link_list, &substream->group->substreams);
@@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1620 _end: 1622 _end:
1621 write_unlock_irq(&snd_pcm_link_rwlock); 1623 write_unlock_irq(&snd_pcm_link_rwlock);
1622 up_write(&snd_pcm_link_rwsem); 1624 up_write(&snd_pcm_link_rwsem);
1625 _nolock:
1623 fput(file); 1626 fput(file);
1627 if (res < 0)
1628 kfree(group);
1624 return res; 1629 return res;
1625} 1630}
1626 1631
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 9d8379aedf40..712110561082 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/initval.h> 26#include <sound/initval.h>
26 27
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8e7561dfc5fc..6ddcf06f52f9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/time.h> 25#include <linux/time.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/device.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/string.h> 29#include <linux/string.h>
29#include <sound/core.h> 30#include <sound/core.h>
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 130cfe677d60..14a286a7bf2b 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -37,6 +37,8 @@ struct link_master {
37 struct link_ctl_info info; 37 struct link_ctl_info info;
38 int val; /* the master value */ 38 int val; /* the master value */
39 unsigned int tlv[4]; 39 unsigned int tlv[4];
40 void (*hook)(void *private_data, int);
41 void *hook_private_data;
40}; 42};
41 43
42/* 44/*
@@ -126,7 +128,9 @@ static int master_init(struct link_master *master)
126 master->info.count = 1; /* always mono */ 128 master->info.count = 1; /* always mono */
127 /* set full volume as default (= no attenuation) */ 129 /* set full volume as default (= no attenuation) */
128 master->val = master->info.max_val; 130 master->val = master->info.max_val;
129 return 0; 131 if (master->hook)
132 master->hook(master->hook_private_data, master->val);
133 return 1;
130 } 134 }
131 return -ENOENT; 135 return -ENOENT;
132} 136}
@@ -329,6 +333,8 @@ static int master_put(struct snd_kcontrol *kcontrol,
329 slave_put_val(slave, uval); 333 slave_put_val(slave, uval);
330 } 334 }
331 kfree(uval); 335 kfree(uval);
336 if (master->hook && !err)
337 master->hook(master->hook_private_data, master->val);
332 return 1; 338 return 1;
333} 339}
334 340
@@ -408,3 +414,41 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
408 return kctl; 414 return kctl;
409} 415}
410EXPORT_SYMBOL(snd_ctl_make_virtual_master); 416EXPORT_SYMBOL(snd_ctl_make_virtual_master);
417
418/**
419 * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
420 * @kcontrol: vmaster kctl element
421 * @hook: the hook function
422 *
423 * Adds the given hook to the vmaster control element so that it's called
424 * at each time when the value is changed.
425 */
426int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
427 void (*hook)(void *private_data, int),
428 void *private_data)
429{
430 struct link_master *master = snd_kcontrol_chip(kcontrol);
431 master->hook = hook;
432 master->hook_private_data = private_data;
433 return 0;
434}
435EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
436
437/**
438 * snd_ctl_sync_vmaster_hook - Sync the vmaster hook
439 * @kcontrol: vmaster kctl element
440 *
441 * Call the hook function to synchronize with the current value of the given
442 * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't
443 * exist.
444 */
445void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol)
446{
447 struct link_master *master;
448 if (!kcontrol)
449 return;
450 master = snd_kcontrol_chip(kcontrol);
451 if (master->hook)
452 master->hook(master->hook_private_data, master->val);
453}
454EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook);
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index cd094ecaca3b..d428ffede4f3 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -611,7 +611,6 @@ static void isight_card_free(struct snd_card *card)
611 611
612 fw_iso_resources_destroy(&isight->resources); 612 fw_iso_resources_destroy(&isight->resources);
613 fw_unit_put(isight->unit); 613 fw_unit_put(isight->unit);
614 fw_device_put(isight->device);
615 mutex_destroy(&isight->mutex); 614 mutex_destroy(&isight->mutex);
616} 615}
617 616
@@ -644,7 +643,7 @@ static int isight_probe(struct device *unit_dev)
644 isight->card = card; 643 isight->card = card;
645 mutex_init(&isight->mutex); 644 mutex_init(&isight->mutex);
646 isight->unit = fw_unit_get(unit); 645 isight->unit = fw_unit_get(unit);
647 isight->device = fw_device_get(fw_dev); 646 isight->device = fw_dev;
648 isight->audio_base = get_unit_base(unit); 647 isight->audio_base = get_unit_base(unit);
649 if (!isight->audio_base) { 648 if (!isight->audio_base) {
650 dev_err(&unit->device, "audio unit base not found\n"); 649 dev_err(&unit->device, "audio unit base not found\n");
@@ -681,7 +680,6 @@ static int isight_probe(struct device *unit_dev)
681 680
682err_unit: 681err_unit:
683 fw_unit_put(isight->unit); 682 fw_unit_put(isight->unit);
684 fw_device_put(isight->device);
685 mutex_destroy(&isight->mutex); 683 mutex_destroy(&isight->mutex);
686error: 684error:
687 snd_card_free(card); 685 snd_card_free(card);
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index cbe6bb9e53b6..297244e658d9 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit)
656static void fwspk_card_free(struct snd_card *card) 656static void fwspk_card_free(struct snd_card *card)
657{ 657{
658 struct fwspk *fwspk = card->private_data; 658 struct fwspk *fwspk = card->private_data;
659 struct fw_device *dev = fw_parent_device(fwspk->unit);
660 659
661 amdtp_out_stream_destroy(&fwspk->stream); 660 amdtp_out_stream_destroy(&fwspk->stream);
662 cmp_connection_destroy(&fwspk->connection); 661 cmp_connection_destroy(&fwspk->connection);
663 fw_unit_put(fwspk->unit); 662 fw_unit_put(fwspk->unit);
664 fw_device_put(dev);
665 mutex_destroy(&fwspk->mutex); 663 mutex_destroy(&fwspk->mutex);
666} 664}
667 665
@@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev)
718 fwspk = card->private_data; 716 fwspk = card->private_data;
719 fwspk->card = card; 717 fwspk->card = card;
720 mutex_init(&fwspk->mutex); 718 mutex_init(&fwspk->mutex);
721 fw_device_get(fw_dev);
722 fwspk->unit = fw_unit_get(unit); 719 fwspk->unit = fw_unit_get(unit);
723 fwspk->device_info = fwspk_detect(fw_dev); 720 fwspk->device_info = fwspk_detect(fw_dev);
724 if (!fwspk->device_info) { 721 if (!fwspk->device_info) {
@@ -767,7 +764,6 @@ err_connection:
767 cmp_connection_destroy(&fwspk->connection); 764 cmp_connection_destroy(&fwspk->connection);
768err_unit: 765err_unit:
769 fw_unit_put(fwspk->unit); 766 fw_unit_put(fwspk->unit);
770 fw_device_put(fw_dev);
771 mutex_destroy(&fwspk->mutex); 767 mutex_destroy(&fwspk->mutex);
772error: 768error:
773 snd_card_free(card); 769 snd_card_free(card);
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 6b68c8206805..a63faec5e7fd 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -25,21 +25,20 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/version.h> 28#include <linux/sched.h>
29#include <media/v4l2-device.h>
29#include <media/v4l2-dev.h> 30#include <media/v4l2-dev.h>
31#include <media/v4l2-fh.h>
30#include <media/v4l2-ioctl.h> 32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-event.h>
31#include <sound/tea575x-tuner.h> 34#include <sound/tea575x-tuner.h>
32 35
33MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
34MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); 37MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
35MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
36 39
37static int radio_nr = -1; 40#define FREQ_LO (76U * 16000)
38module_param(radio_nr, int, 0); 41#define FREQ_HI (108U * 16000)
39
40#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
41#define FREQ_LO (50UL * 16000)
42#define FREQ_HI (150UL * 16000)
43 42
44/* 43/*
45 * definitions 44 * definitions
@@ -90,7 +89,7 @@ static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
90 tea->ops->set_pins(tea, 0); 89 tea->ops->set_pins(tea, 0);
91} 90}
92 91
93static unsigned int snd_tea575x_read(struct snd_tea575x *tea) 92static u32 snd_tea575x_read(struct snd_tea575x *tea)
94{ 93{
95 u16 l, rdata; 94 u16 l, rdata;
96 u32 data = 0; 95 u32 data = 0;
@@ -121,11 +120,13 @@ static unsigned int snd_tea575x_read(struct snd_tea575x *tea)
121 return data; 120 return data;
122} 121}
123 122
124static void snd_tea575x_get_freq(struct snd_tea575x *tea) 123static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
125{ 124{
126 unsigned long freq; 125 u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
126
127 if (freq == 0)
128 return freq;
127 129
128 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
129 /* freq *= 12.5 */ 130 /* freq *= 12.5 */
130 freq *= 125; 131 freq *= 125;
131 freq /= 10; 132 freq /= 10;
@@ -135,14 +136,13 @@ static void snd_tea575x_get_freq(struct snd_tea575x *tea)
135 else 136 else
136 freq -= TEA575X_FMIF; 137 freq -= TEA575X_FMIF;
137 138
138 tea->freq = freq * 16; /* from kHz */ 139 return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */
139} 140}
140 141
141static void snd_tea575x_set_freq(struct snd_tea575x *tea) 142static void snd_tea575x_set_freq(struct snd_tea575x *tea)
142{ 143{
143 unsigned long freq; 144 u32 freq = tea->freq;
144 145
145 freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
146 freq /= 16; /* to kHz */ 146 freq /= 16; /* to kHz */
147 /* crystal fixup */ 147 /* crystal fixup */
148 if (tea->tea5759) 148 if (tea->tea5759)
@@ -167,12 +167,14 @@ static int vidioc_querycap(struct file *file, void *priv,
167{ 167{
168 struct snd_tea575x *tea = video_drvdata(file); 168 struct snd_tea575x *tea = video_drvdata(file);
169 169
170 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 170 strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
171 strlcpy(v->card, tea->card, sizeof(v->card)); 171 strlcpy(v->card, tea->card, sizeof(v->card));
172 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); 172 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
173 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); 173 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
174 v->version = RADIO_VERSION; 174 v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
175 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 175 if (!tea->cannot_read_data)
176 v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
177 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
176 return 0; 178 return 0;
177} 179}
178 180
@@ -191,18 +193,24 @@ static int vidioc_g_tuner(struct file *file, void *priv,
191 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 193 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
192 v->rangelow = FREQ_LO; 194 v->rangelow = FREQ_LO;
193 v->rangehigh = FREQ_HI; 195 v->rangehigh = FREQ_HI;
194 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 196 v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
195 v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; 197 v->audmode = (tea->val & TEA575X_BIT_MONO) ?
198 V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
196 v->signal = tea->tuned ? 0xffff : 0; 199 v->signal = tea->tuned ? 0xffff : 0;
197
198 return 0; 200 return 0;
199} 201}
200 202
201static int vidioc_s_tuner(struct file *file, void *priv, 203static int vidioc_s_tuner(struct file *file, void *priv,
202 struct v4l2_tuner *v) 204 struct v4l2_tuner *v)
203{ 205{
204 if (v->index > 0) 206 struct snd_tea575x *tea = video_drvdata(file);
207
208 if (v->index)
205 return -EINVAL; 209 return -EINVAL;
210 tea->val &= ~TEA575X_BIT_MONO;
211 if (v->audmode == V4L2_TUNER_MODE_MONO)
212 tea->val |= TEA575X_BIT_MONO;
213 snd_tea575x_write(tea, tea->val);
206 return 0; 214 return 0;
207} 215}
208 216
@@ -214,7 +222,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
214 if (f->tuner != 0) 222 if (f->tuner != 0)
215 return -EINVAL; 223 return -EINVAL;
216 f->type = V4L2_TUNER_RADIO; 224 f->type = V4L2_TUNER_RADIO;
217 snd_tea575x_get_freq(tea);
218 f->frequency = tea->freq; 225 f->frequency = tea->freq;
219 return 0; 226 return 0;
220} 227}
@@ -227,33 +234,72 @@ static int vidioc_s_frequency(struct file *file, void *priv,
227 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 234 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
228 return -EINVAL; 235 return -EINVAL;
229 236
230 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 237 tea->val &= ~TEA575X_BIT_SEARCH;
231 return -EINVAL; 238 tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI);
232
233 tea->freq = f->frequency;
234
235 snd_tea575x_set_freq(tea); 239 snd_tea575x_set_freq(tea);
236
237 return 0; 240 return 0;
238} 241}
239 242
240static int vidioc_g_audio(struct file *file, void *priv, 243static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
241 struct v4l2_audio *a) 244 struct v4l2_hw_freq_seek *a)
242{ 245{
243 if (a->index > 1) 246 struct snd_tea575x *tea = video_drvdata(file);
244 return -EINVAL; 247 unsigned long timeout;
245 248 int i;
246 strcpy(a->name, "Radio");
247 a->capability = V4L2_AUDCAP_STEREO;
248 return 0;
249}
250 249
251static int vidioc_s_audio(struct file *file, void *priv, 250 if (tea->cannot_read_data)
252 struct v4l2_audio *a) 251 return -ENOTTY;
253{ 252 if (a->tuner || a->wrap_around)
254 if (a->index != 0)
255 return -EINVAL; 253 return -EINVAL;
256 return 0; 254
255 /* clear the frequency, HW will fill it in */
256 tea->val &= ~TEA575X_BIT_FREQ_MASK;
257 tea->val |= TEA575X_BIT_SEARCH;
258 if (a->seek_upward)
259 tea->val |= TEA575X_BIT_UPDOWN;
260 else
261 tea->val &= ~TEA575X_BIT_UPDOWN;
262 snd_tea575x_write(tea, tea->val);
263 timeout = jiffies + msecs_to_jiffies(10000);
264 for (;;) {
265 if (time_after(jiffies, timeout))
266 break;
267 if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
268 /* some signal arrived, stop search */
269 tea->val &= ~TEA575X_BIT_SEARCH;
270 snd_tea575x_set_freq(tea);
271 return -ERESTARTSYS;
272 }
273 if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
274 u32 freq;
275
276 /* Found a frequency, wait until it can be read */
277 for (i = 0; i < 100; i++) {
278 msleep(10);
279 freq = snd_tea575x_get_freq(tea);
280 if (freq) /* available */
281 break;
282 }
283 if (freq == 0) /* shouldn't happen */
284 break;
285 /*
286 * if we moved by less than 50 kHz, or in the wrong
287 * direction, continue seeking
288 */
289 if (abs(tea->freq - freq) < 16 * 50 ||
290 (a->seek_upward && freq < tea->freq) ||
291 (!a->seek_upward && freq > tea->freq)) {
292 snd_tea575x_write(tea, tea->val);
293 continue;
294 }
295 tea->freq = freq;
296 tea->val &= ~TEA575X_BIT_SEARCH;
297 return 0;
298 }
299 }
300 tea->val &= ~TEA575X_BIT_SEARCH;
301 snd_tea575x_set_freq(tea);
302 return -EAGAIN;
257} 303}
258 304
259static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) 305static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -273,23 +319,27 @@ static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
273static const struct v4l2_file_operations tea575x_fops = { 319static const struct v4l2_file_operations tea575x_fops = {
274 .owner = THIS_MODULE, 320 .owner = THIS_MODULE,
275 .unlocked_ioctl = video_ioctl2, 321 .unlocked_ioctl = video_ioctl2,
322 .open = v4l2_fh_open,
323 .release = v4l2_fh_release,
324 .poll = v4l2_ctrl_poll,
276}; 325};
277 326
278static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { 327static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
279 .vidioc_querycap = vidioc_querycap, 328 .vidioc_querycap = vidioc_querycap,
280 .vidioc_g_tuner = vidioc_g_tuner, 329 .vidioc_g_tuner = vidioc_g_tuner,
281 .vidioc_s_tuner = vidioc_s_tuner, 330 .vidioc_s_tuner = vidioc_s_tuner,
282 .vidioc_g_audio = vidioc_g_audio,
283 .vidioc_s_audio = vidioc_s_audio,
284 .vidioc_g_frequency = vidioc_g_frequency, 331 .vidioc_g_frequency = vidioc_g_frequency,
285 .vidioc_s_frequency = vidioc_s_frequency, 332 .vidioc_s_frequency = vidioc_s_frequency,
333 .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
334 .vidioc_log_status = v4l2_ctrl_log_status,
335 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
336 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
286}; 337};
287 338
288static struct video_device tea575x_radio = { 339static const struct video_device tea575x_radio = {
289 .name = "tea575x-tuner",
290 .fops = &tea575x_fops, 340 .fops = &tea575x_fops,
291 .ioctl_ops = &tea575x_ioctl_ops, 341 .ioctl_ops = &tea575x_ioctl_ops,
292 .release = video_device_release_empty, 342 .release = video_device_release_empty,
293}; 343};
294 344
295static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { 345static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
@@ -303,27 +353,34 @@ int snd_tea575x_init(struct snd_tea575x *tea)
303{ 353{
304 int retval; 354 int retval;
305 355
306 tea->mute = 1; 356 tea->mute = true;
307 357
308 snd_tea575x_write(tea, 0x55AA); 358 /* Not all devices can or know how to read the data back.
309 if (snd_tea575x_read(tea) != 0x55AA) 359 Such devices can set cannot_read_data to true. */
310 return -ENODEV; 360 if (!tea->cannot_read_data) {
361 snd_tea575x_write(tea, 0x55AA);
362 if (snd_tea575x_read(tea) != 0x55AA)
363 return -ENODEV;
364 }
311 365
312 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 366 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
313 tea->freq = 90500 * 16; /* 90.5Mhz default */ 367 tea->freq = 90500 * 16; /* 90.5Mhz default */
314 snd_tea575x_set_freq(tea); 368 snd_tea575x_set_freq(tea);
315 369
316 tea->vd = tea575x_radio; 370 tea->vd = tea575x_radio;
317 video_set_drvdata(&tea->vd, tea); 371 video_set_drvdata(&tea->vd, tea);
318 mutex_init(&tea->mutex); 372 mutex_init(&tea->mutex);
373 strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
319 tea->vd.lock = &tea->mutex; 374 tea->vd.lock = &tea->mutex;
375 tea->vd.v4l2_dev = tea->v4l2_dev;
376 tea->vd.ctrl_handler = &tea->ctrl_handler;
377 set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
320 378
321 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); 379 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
322 tea->vd.ctrl_handler = &tea->ctrl_handler;
323 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 380 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
324 retval = tea->ctrl_handler.error; 381 retval = tea->ctrl_handler.error;
325 if (retval) { 382 if (retval) {
326 printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); 383 v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
327 v4l2_ctrl_handler_free(&tea->ctrl_handler); 384 v4l2_ctrl_handler_free(&tea->ctrl_handler);
328 return retval; 385 return retval;
329 } 386 }
@@ -338,9 +395,9 @@ int snd_tea575x_init(struct snd_tea575x *tea)
338 395
339 v4l2_ctrl_handler_setup(&tea->ctrl_handler); 396 v4l2_ctrl_handler_setup(&tea->ctrl_handler);
340 397
341 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); 398 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
342 if (retval) { 399 if (retval) {
343 printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 400 v4l2_err(tea->v4l2_dev, "can't register video device!\n");
344 v4l2_ctrl_handler_free(&tea->ctrl_handler); 401 v4l2_ctrl_handler_free(&tea->ctrl_handler);
345 return retval; 402 return retval;
346 } 403 }
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index bb938153a964..466a5c8e8354 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
26#include <sound/mpu401.h> 26#include <sound/mpu401.h>
27#include <sound/hwdep.h> 27#include <sound/hwdep.h>
28#include <sound/ac97_codec.h> 28#include <sound/ac97_codec.h>
29 29#include <sound/tlv.h>
30#endif 30#endif
31 31
32#ifndef CHIP_AU8820 32#ifndef CHIP_AU8820
@@ -107,6 +107,14 @@
107#define NR_WTPB 0x20 /* WT channels per each bank. */ 107#define NR_WTPB 0x20 /* WT channels per each bank. */
108#define NR_PCM 0x10 108#define NR_PCM 0x10
109 109
110struct pcm_vol {
111 struct snd_kcontrol *kctl;
112 int active;
113 int dma;
114 int mixin[4];
115 int vol[4];
116};
117
110/* Structs */ 118/* Structs */
111typedef struct { 119typedef struct {
112 //int this_08; /* Still unknown */ 120 //int this_08; /* Still unknown */
@@ -168,6 +176,7 @@ struct snd_vortex {
168 /* Xtalk canceler */ 176 /* Xtalk canceler */
169 int xt_mode; /* 1: speakers, 0:headphones. */ 177 int xt_mode; /* 1: speakers, 0:headphones. */
170#endif 178#endif
179 struct pcm_vol pcm_vol[NR_PCM];
171 180
172 int isquad; /* cache of extended ID codec flag. */ 181 int isquad; /* cache of extended ID codec flag. */
173 182
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
239/* Connection stuff. */ 248/* Connection stuff. */
240static void vortex_connect_default(vortex_t * vortex, int en); 249static void vortex_connect_default(vortex_t * vortex, int en);
241static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, 250static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
242 int dir, int type); 251 int dir, int type, int subdev);
243static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, 252static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
244 int restype); 253 int restype);
245#ifndef CHIP_AU8810 254#ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27a5d76..525f881f0409 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2050} 2050}
2051 2051
2052/* Default Connections */ 2052/* Default Connections */
2053static int
2054vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2055 2053
2056static void vortex_connect_default(vortex_t * vortex, int en) 2054static void vortex_connect_default(vortex_t * vortex, int en)
2057{ 2055{
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en)
2111 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. 2109 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2112*/ 2110*/
2113static int 2111static int
2114vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) 2112vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2113 int type, int subdev)
2115{ 2114{
2116 stream_t *stream; 2115 stream_t *stream;
2117 int i, en; 2116 int i, en;
2117 struct pcm_vol *p;
2118 2118
2119 if ((nr_ch == 3)
2120 || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2121 return -EBUSY;
2122
2123 if (dma >= 0) { 2119 if (dma >= 0) {
2124 en = 0; 2120 en = 0;
2125 vortex_adb_checkinout(vortex, 2121 vortex_adb_checkinout(vortex,
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2250 MIX_DEFIGAIN); 2246 MIX_DEFIGAIN);
2251#endif 2247#endif
2252 } 2248 }
2249 if (stream->type == VORTEX_PCM_ADB && en) {
2250 p = &vortex->pcm_vol[subdev];
2251 p->dma = dma;
2252 for (i = 0; i < nr_ch; i++)
2253 p->mixin[i] = mix[i];
2254 for (i = 0; i < ch_top; i++)
2255 p->vol[i] = 0;
2256 }
2253 } 2257 }
2254#ifndef CHIP_AU8820 2258#ifndef CHIP_AU8820
2255 else { 2259 else {
@@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2473 hwread(vortex->mmio, VORTEX_IRQ_STAT); 2477 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2474 handled = 1; 2478 handled = 1;
2475 } 2479 }
2476 if (source & IRQ_MIDI) { 2480 if ((source & IRQ_MIDI) && vortex->rmidi) {
2477 snd_mpu401_uart_interrupt(vortex->irq, 2481 snd_mpu401_uart_interrupt(vortex->irq,
2478 vortex->rmidi->private_data); 2482 vortex->rmidi->private_data);
2479 handled = 1; 2483 handled = 1;
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0ef2f9712208..e59f120742a4 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
122 .mask = 0, 122 .mask = 0,
123}; 123};
124#endif 124#endif
125
126static void vortex_notify_pcm_vol_change(struct snd_card *card,
127 struct snd_kcontrol *kctl, int activate)
128{
129 if (activate)
130 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
131 else
132 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
133 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
134 SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
135}
136
125/* open callback */ 137/* open callback */
126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 138static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127{ 139{
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
230 if (stream != NULL) 242 if (stream != NULL)
231 vortex_adb_allocroute(chip, stream->dma, 243 vortex_adb_allocroute(chip, stream->dma,
232 stream->nr_ch, stream->dir, 244 stream->nr_ch, stream->dir,
233 stream->type); 245 stream->type,
246 substream->number);
234 /* Alloc routes. */ 247 /* Alloc routes. */
235 dma = 248 dma =
236 vortex_adb_allocroute(chip, -1, 249 vortex_adb_allocroute(chip, -1,
237 params_channels(hw_params), 250 params_channels(hw_params),
238 substream->stream, type); 251 substream->stream, type,
252 substream->number);
239 if (dma < 0) { 253 if (dma < 0) {
240 spin_unlock_irq(&chip->lock); 254 spin_unlock_irq(&chip->lock);
241 return dma; 255 return dma;
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
246 vortex_adbdma_setbuffers(chip, dma, 260 vortex_adbdma_setbuffers(chip, dma,
247 params_period_bytes(hw_params), 261 params_period_bytes(hw_params),
248 params_periods(hw_params)); 262 params_periods(hw_params));
263 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
264 chip->pcm_vol[substream->number].active = 1;
265 vortex_notify_pcm_vol_change(chip->card,
266 chip->pcm_vol[substream->number].kctl, 1);
267 }
249 } 268 }
250#ifndef CHIP_AU8810 269#ifndef CHIP_AU8810
251 else { 270 else {
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
275 spin_lock_irq(&chip->lock); 294 spin_lock_irq(&chip->lock);
276 // Delete audio routes. 295 // Delete audio routes.
277 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { 296 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
278 if (stream != NULL) 297 if (stream != NULL) {
298 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
299 chip->pcm_vol[substream->number].active = 0;
300 vortex_notify_pcm_vol_change(chip->card,
301 chip->pcm_vol[substream->number].kctl,
302 0);
303 }
279 vortex_adb_allocroute(chip, stream->dma, 304 vortex_adb_allocroute(chip, stream->dma,
280 stream->nr_ch, stream->dir, 305 stream->nr_ch, stream->dir,
281 stream->type); 306 stream->type,
307 substream->number);
308 }
282 } 309 }
283#ifndef CHIP_AU8810 310#ifndef CHIP_AU8810
284 else { 311 else {
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
506 }, 533 },
507}; 534};
508 535
536/* subdevice PCM Volume control */
537
538static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_info *uinfo)
540{
541 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
543 uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
544 uinfo->value.integer.min = -128;
545 uinfo->value.integer.max = 32;
546 return 0;
547}
548
549static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
551{
552 int i;
553 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
554 int subdev = kcontrol->id.subdevice;
555 struct pcm_vol *p = &vortex->pcm_vol[subdev];
556 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
557 for (i = 0; i < max_chn; i++)
558 ucontrol->value.integer.value[i] = p->vol[i];
559 return 0;
560}
561
562static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 int i;
566 int changed = 0;
567 int mixin;
568 unsigned char vol;
569 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
570 int subdev = kcontrol->id.subdevice;
571 struct pcm_vol *p = &vortex->pcm_vol[subdev];
572 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
573 for (i = 0; i < max_chn; i++) {
574 if (p->vol[i] != ucontrol->value.integer.value[i]) {
575 p->vol[i] = ucontrol->value.integer.value[i];
576 if (p->active) {
577 switch (vortex->dma_adb[p->dma].nr_ch) {
578 case 1:
579 mixin = p->mixin[0];
580 break;
581 case 2:
582 default:
583 mixin = p->mixin[(i < 2) ? i : (i - 2)];
584 break;
585 case 4:
586 mixin = p->mixin[i];
587 break;
588 };
589 vol = p->vol[i];
590 vortex_mix_setinputvolumebyte(vortex,
591 vortex->mixplayb[i], mixin, vol);
592 }
593 changed = 1;
594 }
595 }
596 return changed;
597}
598
599static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
600
601static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
602 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
603 .name = "PCM Playback Volume",
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
605 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
606 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
607 .info = snd_vortex_pcm_vol_info,
608 .get = snd_vortex_pcm_vol_get,
609 .put = snd_vortex_pcm_vol_put,
610 .tlv = { .p = vortex_pcm_vol_db_scale },
611};
612
509/* create a pcm device */ 613/* create a pcm device */
510static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) 614static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
511{ 615{
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
555 return err; 659 return err;
556 } 660 }
557 } 661 }
662 if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
663 for (i = 0; i < NR_PCM; i++) {
664 chip->pcm_vol[i].active = 0;
665 chip->pcm_vol[i].dma = -1;
666 kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
667 if (!kctl)
668 return -ENOMEM;
669 chip->pcm_vol[i].kctl = kctl;
670 kctl->id.device = 0;
671 kctl->id.subdevice = i;
672 err = snd_ctl_add(chip->card, kctl);
673 if (err < 0)
674 return err;
675 }
676 }
558 return 0; 677 return 0;
559} 678}
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index b78f3fc3c33c..6109490b83e8 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
36 36
37 size = CT_PAGE_ALIGN(size); 37 size = CT_PAGE_ALIGN(size);
38 if (size > vm->size) { 38 if (size > vm->size) {
39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " 39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual "
40 "memory space available!\n"); 40 "memory space available!\n");
41 return NULL; 41 return NULL;
42 } 42 }
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index cb557c603a80..a8faae1c85e4 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -142,6 +142,7 @@ static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
142#ifdef SUPPORT_JOYSTICK 142#ifdef SUPPORT_JOYSTICK
143static bool joystick[SNDRV_CARDS]; 143static bool joystick[SNDRV_CARDS];
144#endif 144#endif
145static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
145 146
146module_param_array(index, int, NULL, 0444); 147module_param_array(index, int, NULL, 0444);
147MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 148MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -165,6 +166,9 @@ MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
165module_param_array(joystick, bool, NULL, 0444); 166module_param_array(joystick, bool, NULL, 0444);
166MODULE_PARM_DESC(joystick, "Enable joystick."); 167MODULE_PARM_DESC(joystick, "Enable joystick.");
167#endif 168#endif
169module_param_array(radio_nr, int, NULL, 0444);
170MODULE_PARM_DESC(radio_nr, "Radio device numbers");
171
168 172
169 173
170#define NR_APUS 64 174#define NR_APUS 64
@@ -558,6 +562,7 @@ struct es1968 {
558 struct work_struct hwvol_work; 562 struct work_struct hwvol_work;
559 563
560#ifdef CONFIG_SND_ES1968_RADIO 564#ifdef CONFIG_SND_ES1968_RADIO
565 struct v4l2_device v4l2_dev;
561 struct snd_tea575x tea; 566 struct snd_tea575x tea;
562#endif 567#endif
563}; 568};
@@ -2613,6 +2618,7 @@ static int snd_es1968_free(struct es1968 *chip)
2613 2618
2614#ifdef CONFIG_SND_ES1968_RADIO 2619#ifdef CONFIG_SND_ES1968_RADIO
2615 snd_tea575x_exit(&chip->tea); 2620 snd_tea575x_exit(&chip->tea);
2621 v4l2_device_unregister(&chip->v4l2_dev);
2616#endif 2622#endif
2617 2623
2618 if (chip->irq >= 0) 2624 if (chip->irq >= 0)
@@ -2655,6 +2661,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2655 int capt_streams, 2661 int capt_streams,
2656 int chip_type, 2662 int chip_type,
2657 int do_pm, 2663 int do_pm,
2664 int radio_nr,
2658 struct es1968 **chip_ret) 2665 struct es1968 **chip_ret)
2659{ 2666{
2660 static struct snd_device_ops ops = { 2667 static struct snd_device_ops ops = {
@@ -2751,7 +2758,14 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2751 snd_card_set_dev(card, &pci->dev); 2758 snd_card_set_dev(card, &pci->dev);
2752 2759
2753#ifdef CONFIG_SND_ES1968_RADIO 2760#ifdef CONFIG_SND_ES1968_RADIO
2761 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
2762 if (err < 0) {
2763 snd_es1968_free(chip);
2764 return err;
2765 }
2766 chip->tea.v4l2_dev = &chip->v4l2_dev;
2754 chip->tea.private_data = chip; 2767 chip->tea.private_data = chip;
2768 chip->tea.radio_nr = radio_nr;
2755 chip->tea.ops = &snd_es1968_tea_ops; 2769 chip->tea.ops = &snd_es1968_tea_ops;
2756 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); 2770 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2757 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 2771 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
@@ -2797,6 +2811,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2797 pcm_substreams_c[dev], 2811 pcm_substreams_c[dev],
2798 pci_id->driver_data, 2812 pci_id->driver_data,
2799 use_pm[dev], 2813 use_pm[dev],
2814 radio_nr[dev],
2800 &chip)) < 0) { 2815 &chip)) < 0) {
2801 snd_card_free(card); 2816 snd_card_free(card);
2802 return err; 2817 return err;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 9597ef1eccca..a416ea8af3e9 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -58,6 +58,7 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card
58 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
59 */ 59 */
60static int tea575x_tuner[SNDRV_CARDS]; 60static int tea575x_tuner[SNDRV_CARDS];
61static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
61 62
62module_param_array(index, int, NULL, 0444); 63module_param_array(index, int, NULL, 0444);
63MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); 64MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
@@ -67,6 +68,9 @@ module_param_array(enable, bool, NULL, 0444);
67MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 68MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
68module_param_array(tea575x_tuner, int, NULL, 0444); 69module_param_array(tea575x_tuner, int, NULL, 0444);
69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); 70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71module_param_array(radio_nr, int, NULL, 0444);
72MODULE_PARM_DESC(radio_nr, "Radio device numbers");
73
70 74
71#define TUNER_DISABLED (1<<3) 75#define TUNER_DISABLED (1<<3)
72#define TUNER_ONLY (1<<4) 76#define TUNER_ONLY (1<<4)
@@ -197,6 +201,7 @@ struct fm801 {
197 struct snd_info_entry *proc_entry; 201 struct snd_info_entry *proc_entry;
198 202
199#ifdef CONFIG_SND_FM801_TEA575X_BOOL 203#ifdef CONFIG_SND_FM801_TEA575X_BOOL
204 struct v4l2_device v4l2_dev;
200 struct snd_tea575x tea; 205 struct snd_tea575x tea;
201#endif 206#endif
202 207
@@ -1154,8 +1159,10 @@ static int snd_fm801_free(struct fm801 *chip)
1154 1159
1155 __end_hw: 1160 __end_hw:
1156#ifdef CONFIG_SND_FM801_TEA575X_BOOL 1161#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1157 if (!(chip->tea575x_tuner & TUNER_DISABLED)) 1162 if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
1158 snd_tea575x_exit(&chip->tea); 1163 snd_tea575x_exit(&chip->tea);
1164 v4l2_device_unregister(&chip->v4l2_dev);
1165 }
1159#endif 1166#endif
1160 if (chip->irq >= 0) 1167 if (chip->irq >= 0)
1161 free_irq(chip->irq, chip); 1168 free_irq(chip->irq, chip);
@@ -1175,6 +1182,7 @@ static int snd_fm801_dev_free(struct snd_device *device)
1175static int __devinit snd_fm801_create(struct snd_card *card, 1182static int __devinit snd_fm801_create(struct snd_card *card,
1176 struct pci_dev * pci, 1183 struct pci_dev * pci,
1177 int tea575x_tuner, 1184 int tea575x_tuner,
1185 int radio_nr,
1178 struct fm801 ** rchip) 1186 struct fm801 ** rchip)
1179{ 1187{
1180 struct fm801 *chip; 1188 struct fm801 *chip;
@@ -1234,6 +1242,13 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1234 snd_card_set_dev(card, &pci->dev); 1242 snd_card_set_dev(card, &pci->dev);
1235 1243
1236#ifdef CONFIG_SND_FM801_TEA575X_BOOL 1244#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1245 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
1246 if (err < 0) {
1247 snd_fm801_free(chip);
1248 return err;
1249 }
1250 chip->tea.v4l2_dev = &chip->v4l2_dev;
1251 chip->tea.radio_nr = radio_nr;
1237 chip->tea.private_data = chip; 1252 chip->tea.private_data = chip;
1238 chip->tea.ops = &snd_fm801_tea_ops; 1253 chip->tea.ops = &snd_fm801_tea_ops;
1239 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 1254 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
@@ -1241,6 +1256,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1241 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1256 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1242 if (snd_tea575x_init(&chip->tea)) { 1257 if (snd_tea575x_init(&chip->tea)) {
1243 snd_printk(KERN_ERR "TEA575x radio not found\n"); 1258 snd_printk(KERN_ERR "TEA575x radio not found\n");
1259 snd_fm801_free(chip);
1244 return -ENODEV; 1260 return -ENODEV;
1245 } 1261 }
1246 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { 1262 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
@@ -1287,7 +1303,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1287 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 1303 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
1288 if (err < 0) 1304 if (err < 0)
1289 return err; 1305 return err;
1290 if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { 1306 if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
1291 snd_card_free(card); 1307 snd_card_free(card);
1292 return err; 1308 return err;
1293 } 1309 }
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
deleted file mode 100644
index 3b5170b9700f..000000000000
--- a/sound/pci/hda/alc260_quirks.c
+++ /dev/null
@@ -1,968 +0,0 @@
1/*
2 * ALC260 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC260 models */
7enum {
8 ALC260_AUTO,
9 ALC260_BASIC,
10 ALC260_FUJITSU_S702X,
11 ALC260_ACER,
12 ALC260_WILL,
13 ALC260_REPLACER_672V,
14 ALC260_FAVORIT100,
15#ifdef CONFIG_SND_DEBUG
16 ALC260_TEST,
17#endif
18 ALC260_MODEL_LAST /* last tag */
19};
20
21static const hda_nid_t alc260_dac_nids[1] = {
22 /* front */
23 0x02,
24};
25
26static const hda_nid_t alc260_adc_nids[1] = {
27 /* ADC0 */
28 0x04,
29};
30
31static const hda_nid_t alc260_adc_nids_alt[1] = {
32 /* ADC1 */
33 0x05,
34};
35
36/* NIDs used when simultaneous access to both ADCs makes sense. Note that
37 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
38 */
39static const hda_nid_t alc260_dual_adc_nids[2] = {
40 /* ADC0, ADC1 */
41 0x04, 0x05
42};
43
44#define ALC260_DIGOUT_NID 0x03
45#define ALC260_DIGIN_NID 0x06
46
47static const struct hda_input_mux alc260_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
58 * headphone jack and the internal CD lines since these are the only pins at
59 * which audio can appear. For flexibility, also allow the option of
60 * recording the mixer output on the second ADC (ADC0 doesn't have a
61 * connection to the mixer output).
62 */
63static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
64 {
65 .num_items = 3,
66 .items = {
67 { "Mic/Line", 0x0 },
68 { "CD", 0x4 },
69 { "Headphone", 0x2 },
70 },
71 },
72 {
73 .num_items = 4,
74 .items = {
75 { "Mic/Line", 0x0 },
76 { "CD", 0x4 },
77 { "Headphone", 0x2 },
78 { "Mixer", 0x5 },
79 },
80 },
81
82};
83
84/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
85 * the Fujitsu S702x, but jacks are marked differently.
86 */
87static const struct hda_input_mux alc260_acer_capture_sources[2] = {
88 {
89 .num_items = 4,
90 .items = {
91 { "Mic", 0x0 },
92 { "Line", 0x2 },
93 { "CD", 0x4 },
94 { "Headphone", 0x5 },
95 },
96 },
97 {
98 .num_items = 5,
99 .items = {
100 { "Mic", 0x0 },
101 { "Line", 0x2 },
102 { "CD", 0x4 },
103 { "Headphone", 0x6 },
104 { "Mixer", 0x5 },
105 },
106 },
107};
108
109/* Maxdata Favorit 100XS */
110static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
111 {
112 .num_items = 2,
113 .items = {
114 { "Line/Mic", 0x0 },
115 { "CD", 0x4 },
116 },
117 },
118 {
119 .num_items = 3,
120 .items = {
121 { "Line/Mic", 0x0 },
122 { "CD", 0x4 },
123 { "Mixer", 0x5 },
124 },
125 },
126};
127
128/*
129 * This is just place-holder, so there's something for alc_build_pcms to look
130 * at when it calculates the maximum number of channels. ALC260 has no mixer
131 * element which allows changing the channel mode, so the verb list is
132 * never used.
133 */
134static const struct hda_channel_mode alc260_modes[1] = {
135 { 2, NULL },
136};
137
138
139/* Mixer combinations
140 *
141 * basic: base_output + input + pc_beep + capture
142 * fujitsu: fujitsu + capture
143 * acer: acer + capture
144 */
145
146static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
147 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
148 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
149 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
150 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
151 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
152 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc260_input_mixer[] = {
157 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
158 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
162 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
163 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
165 { } /* end */
166};
167
168/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
169 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
170 */
171static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
173 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
174 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
175 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
176 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
177 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
179 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
180 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
181 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
182 { } /* end */
183};
184
185/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
186 * versions of the ALC260 don't act on requests to enable mic bias from NID
187 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
188 * datasheet doesn't mention this restriction. At this stage it's not clear
189 * whether this behaviour is intentional or is a hardware bug in chip
190 * revisions available in early 2006. Therefore for now allow the
191 * "Headphone Jack Mode" control to span all choices, but if it turns out
192 * that the lack of mic bias for this NID is intentional we could change the
193 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
194 *
195 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
196 * don't appear to make the mic bias available from the "line" jack, even
197 * though the NID used for this jack (0x14) can supply it. The theory is
198 * that perhaps Acer have included blocking capacitors between the ALC260
199 * and the output jack. If this turns out to be the case for all such
200 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
201 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
202 *
203 * The C20x Tablet series have a mono internal speaker which is controlled
204 * via the chip's Mono sum widget and pin complex, so include the necessary
205 * controls for such models. On models without a "mono speaker" the control
206 * won't do anything.
207 */
208static const struct snd_kcontrol_new alc260_acer_mixer[] = {
209 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
211 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
212 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
213 HDA_OUTPUT),
214 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
215 HDA_INPUT),
216 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
217 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
219 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
220 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
221 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
222 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
223 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
224 { } /* end */
225};
226
227/* Maxdata Favorit 100XS: one output and one input (0x12) jack
228 */
229static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
230 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
231 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
232 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
233 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
235 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
236 { } /* end */
237};
238
239/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
240 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
241 */
242static const struct snd_kcontrol_new alc260_will_mixer[] = {
243 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
244 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
246 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
247 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
248 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
249 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
250 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
251 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
252 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
253 { } /* end */
254};
255
256/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
257 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
258 */
259static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
261 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
263 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
264 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
265 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
266 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
267 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
268 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
269 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
270 { } /* end */
271};
272
273/*
274 * initialization verbs
275 */
276static const struct hda_verb alc260_init_verbs[] = {
277 /* Line In pin widget for input */
278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
279 /* CD pin widget for input */
280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
281 /* Mic1 (rear panel) pin widget for input and vref at 80% */
282 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 /* Mic2 (front panel) pin widget for input and vref at 80% */
284 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
285 /* LINE-2 is used for line-out in rear */
286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
287 /* select line-out */
288 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
289 /* LINE-OUT pin */
290 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
291 /* enable HP */
292 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
293 /* enable Mono */
294 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 /* mute capture amp left and right */
296 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
297 /* set connection select to line in (default select for this ADC) */
298 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
299 /* mute capture amp left and right */
300 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
301 /* set connection select to line in (default select for this ADC) */
302 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
303 /* set vol=0 Line-Out mixer amp left and right */
304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
305 /* unmute pin widget amp left and right (no gain on this amp) */
306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 /* set vol=0 HP mixer amp left and right */
308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309 /* unmute pin widget amp left and right (no gain on this amp) */
310 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
311 /* set vol=0 Mono mixer amp left and right */
312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
313 /* unmute pin widget amp left and right (no gain on this amp) */
314 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
315 /* unmute LINE-2 out pin */
316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
318 * Line In 2 = 0x03
319 */
320 /* mute analog inputs */
321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
326 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
327 /* mute Front out path */
328 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
330 /* mute Headphone out path */
331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
332 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
333 /* mute Mono out path */
334 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
335 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
336 { }
337};
338
339/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
340 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
341 * audio = 0x16, internal speaker = 0x10.
342 */
343static const struct hda_verb alc260_fujitsu_init_verbs[] = {
344 /* Disable all GPIOs */
345 {0x01, AC_VERB_SET_GPIO_MASK, 0},
346 /* Internal speaker is connected to headphone pin */
347 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
348 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
350 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
352 /* Ensure all other unused pins are disabled and muted. */
353 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
355 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
356 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
357 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
358 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
361
362 /* Disable digital (SPDIF) pins */
363 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
364 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
365
366 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
367 * when acting as an output.
368 */
369 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
370
371 /* Start with output sum widgets muted and their output gains at min */
372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
381
382 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
384 /* Unmute Line1 pin widget output buffer since it starts as an output.
385 * If the pin mode is changed by the user the pin mode control will
386 * take care of enabling the pin's input/output buffers as needed.
387 * Therefore there's no need to enable the input buffer at this
388 * stage.
389 */
390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 /* Unmute input buffer of pin widget used for Line-in (no equiv
392 * mixer ctrl)
393 */
394 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
395
396 /* Mute capture amp left and right */
397 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
398 /* Set ADC connection select to match default mixer setting - line
399 * in (on mic1 pin)
400 */
401 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
402
403 /* Do the same for the second ADC: mute capture input amp and
404 * set ADC connection to line in (on mic1 pin)
405 */
406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
407 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
408
409 /* Mute all inputs to mixer widget (even unconnected ones) */
410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
418
419 { }
420};
421
422/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
423 * similar laptops (adapted from Fujitsu init verbs).
424 */
425static const struct hda_verb alc260_acer_init_verbs[] = {
426 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
427 * the headphone jack. Turn this on and rely on the standard mute
428 * methods whenever the user wants to turn these outputs off.
429 */
430 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
431 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
432 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
433 /* Internal speaker/Headphone jack is connected to Line-out pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
435 /* Internal microphone/Mic jack is connected to Mic1 pin */
436 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
437 /* Line In jack is connected to Line1 pin */
438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
439 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
440 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
441 /* Ensure all other unused pins are disabled and muted. */
442 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
443 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
445 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
448 /* Disable digital (SPDIF) pins */
449 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
450 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
451
452 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
453 * bus when acting as outputs.
454 */
455 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
456 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
457
458 /* Start with output sum widgets muted and their output gains at min */
459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
461 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
468
469 /* Unmute Line-out pin widget amp left and right
470 * (no equiv mixer ctrl)
471 */
472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
474 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
475 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
476 * inputs. If the pin mode is changed by the user the pin mode control
477 * will take care of enabling the pin's input/output buffers as needed.
478 * Therefore there's no need to enable the input buffer at this
479 * stage.
480 */
481 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
483
484 /* Mute capture amp left and right */
485 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 /* Set ADC connection select to match default mixer setting - mic
487 * (on mic1 pin)
488 */
489 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
490
491 /* Do similar with the second ADC: mute capture input amp and
492 * set ADC connection to mic to match ALSA's default state.
493 */
494 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
495 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
496
497 /* Mute all inputs to mixer widget (even unconnected ones) */
498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
506
507 { }
508};
509
510/* Initialisation sequence for Maxdata Favorit 100XS
511 * (adapted from Acer init verbs).
512 */
513static const struct hda_verb alc260_favorit100_init_verbs[] = {
514 /* GPIO 0 enables the output jack.
515 * Turn this on and rely on the standard mute
516 * methods whenever the user wants to turn these outputs off.
517 */
518 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
519 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
520 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
521 /* Line/Mic input jack is connected to Mic1 pin */
522 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
523 /* Ensure all other unused pins are disabled and muted. */
524 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
525 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
526 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
527 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
528 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
529 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
533 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
534 /* Disable digital (SPDIF) pins */
535 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
536 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
537
538 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
539 * bus when acting as outputs.
540 */
541 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
542 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
543
544 /* Start with output sum widgets muted and their output gains at min */
545 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
549 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
551 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
554
555 /* Unmute Line-out pin widget amp left and right
556 * (no equiv mixer ctrl)
557 */
558 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
559 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
560 * inputs. If the pin mode is changed by the user the pin mode control
561 * will take care of enabling the pin's input/output buffers as needed.
562 * Therefore there's no need to enable the input buffer at this
563 * stage.
564 */
565 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
566
567 /* Mute capture amp left and right */
568 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
569 /* Set ADC connection select to match default mixer setting - mic
570 * (on mic1 pin)
571 */
572 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
573
574 /* Do similar with the second ADC: mute capture input amp and
575 * set ADC connection to mic to match ALSA's default state.
576 */
577 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
578 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
579
580 /* Mute all inputs to mixer widget (even unconnected ones) */
581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
589
590 { }
591};
592
593static const struct hda_verb alc260_will_verbs[] = {
594 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
596 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
597 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
598 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
599 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
600 {}
601};
602
603static const struct hda_verb alc260_replacer_672v_verbs[] = {
604 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
605 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
606 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
607
608 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
609 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
610 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
611
612 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
613 {}
614};
615
616/* toggle speaker-output according to the hp-jack state */
617static void alc260_replacer_672v_automute(struct hda_codec *codec)
618{
619 unsigned int present;
620
621 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
622 present = snd_hda_jack_detect(codec, 0x0f);
623 if (present) {
624 snd_hda_codec_write_cache(codec, 0x01, 0,
625 AC_VERB_SET_GPIO_DATA, 1);
626 snd_hda_codec_write_cache(codec, 0x0f, 0,
627 AC_VERB_SET_PIN_WIDGET_CONTROL,
628 PIN_HP);
629 } else {
630 snd_hda_codec_write_cache(codec, 0x01, 0,
631 AC_VERB_SET_GPIO_DATA, 0);
632 snd_hda_codec_write_cache(codec, 0x0f, 0,
633 AC_VERB_SET_PIN_WIDGET_CONTROL,
634 PIN_OUT);
635 }
636}
637
638static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
639 unsigned int res)
640{
641 if ((res >> 26) == ALC_HP_EVENT)
642 alc260_replacer_672v_automute(codec);
643}
644
645static const struct hda_verb alc260_hp_dc7600_verbs[] = {
646 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
647 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
648 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
650 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
652 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
653 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
654 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
655 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
656 {}
657};
658
659/* Test configuration for debugging, modelled after the ALC880 test
660 * configuration.
661 */
662#ifdef CONFIG_SND_DEBUG
663static const hda_nid_t alc260_test_dac_nids[1] = {
664 0x02,
665};
666static const hda_nid_t alc260_test_adc_nids[2] = {
667 0x04, 0x05,
668};
669/* For testing the ALC260, each input MUX needs its own definition since
670 * the signal assignments are different. This assumes that the first ADC
671 * is NID 0x04.
672 */
673static const struct hda_input_mux alc260_test_capture_sources[2] = {
674 {
675 .num_items = 7,
676 .items = {
677 { "MIC1 pin", 0x0 },
678 { "MIC2 pin", 0x1 },
679 { "LINE1 pin", 0x2 },
680 { "LINE2 pin", 0x3 },
681 { "CD pin", 0x4 },
682 { "LINE-OUT pin", 0x5 },
683 { "HP-OUT pin", 0x6 },
684 },
685 },
686 {
687 .num_items = 8,
688 .items = {
689 { "MIC1 pin", 0x0 },
690 { "MIC2 pin", 0x1 },
691 { "LINE1 pin", 0x2 },
692 { "LINE2 pin", 0x3 },
693 { "CD pin", 0x4 },
694 { "Mixer", 0x5 },
695 { "LINE-OUT pin", 0x6 },
696 { "HP-OUT pin", 0x7 },
697 },
698 },
699};
700static const struct snd_kcontrol_new alc260_test_mixer[] = {
701 /* Output driver widgets */
702 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
703 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
704 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
707 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
708
709 /* Modes for retasking pin widgets
710 * Note: the ALC260 doesn't seem to act on requests to enable mic
711 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
712 * mention this restriction. At this stage it's not clear whether
713 * this behaviour is intentional or is a hardware bug in chip
714 * revisions available at least up until early 2006. Therefore for
715 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
716 * choices, but if it turns out that the lack of mic bias for these
717 * NIDs is intentional we could change their modes from
718 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
719 */
720 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
721 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
722 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
723 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
724 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
725 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
726
727 /* Loopback mixer controls */
728 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
729 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
730 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
731 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
732 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
733 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
734 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
735 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
736 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
737 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
738 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
739 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
740 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
741 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
742
743 /* Controls for GPIO pins, assuming they are configured as outputs */
744 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
745 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
746 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
747 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
748
749 /* Switches to allow the digital IO pins to be enabled. The datasheet
750 * is ambigious as to which NID is which; testing on laptops which
751 * make this output available should provide clarification.
752 */
753 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
754 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
755
756 /* A switch allowing EAPD to be enabled. Some laptops seem to use
757 * this output to turn on an external amplifier.
758 */
759 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
760 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
761
762 { } /* end */
763};
764static const struct hda_verb alc260_test_init_verbs[] = {
765 /* Enable all GPIOs as outputs with an initial value of 0 */
766 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
767 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
768 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
769
770 /* Enable retasking pins as output, initially without power amp */
771 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
772 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
775 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
776 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
777
778 /* Disable digital (SPDIF) pins initially, but users can enable
779 * them via a mixer switch. In the case of SPDIF-out, this initverb
780 * payload also sets the generation to 0, output to be in "consumer"
781 * PCM format, copyright asserted, no pre-emphasis and no validity
782 * control.
783 */
784 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
785 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
786
787 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
788 * OUT1 sum bus when acting as an output.
789 */
790 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
791 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
792 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
793 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
794
795 /* Start with output sum widgets muted and their output gains at min */
796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
802 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
803 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
804 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
805
806 /* Unmute retasking pin widget output buffers since the default
807 * state appears to be output. As the pin mode is changed by the
808 * user the pin mode control will take care of enabling the pin's
809 * input/output buffers as needed.
810 */
811 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
815 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
816 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
817 /* Also unmute the mono-out pin widget */
818 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
819
820 /* Mute capture amp left and right */
821 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 /* Set ADC connection select to match default mixer setting (mic1
823 * pin)
824 */
825 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 /* Do the same for the second ADC: mute capture input amp and
828 * set ADC connection to mic1 pin
829 */
830 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
831 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
832
833 /* Mute all inputs to mixer widget (even unconnected ones) */
834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
835 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
836 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
842
843 { }
844};
845#endif
846
847/*
848 * ALC260 configurations
849 */
850static const char * const alc260_models[ALC260_MODEL_LAST] = {
851 [ALC260_BASIC] = "basic",
852 [ALC260_FUJITSU_S702X] = "fujitsu",
853 [ALC260_ACER] = "acer",
854 [ALC260_WILL] = "will",
855 [ALC260_REPLACER_672V] = "replacer",
856 [ALC260_FAVORIT100] = "favorit100",
857#ifdef CONFIG_SND_DEBUG
858 [ALC260_TEST] = "test",
859#endif
860 [ALC260_AUTO] = "auto",
861};
862
863static const struct snd_pci_quirk alc260_cfg_tbl[] = {
864 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
865 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
866 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
867 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
868 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
869 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
870 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
871 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
872 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
873 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
874 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
875 {}
876};
877
878static const struct alc_config_preset alc260_presets[] = {
879 [ALC260_BASIC] = {
880 .mixers = { alc260_base_output_mixer,
881 alc260_input_mixer },
882 .init_verbs = { alc260_init_verbs },
883 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
884 .dac_nids = alc260_dac_nids,
885 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
886 .adc_nids = alc260_dual_adc_nids,
887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
888 .channel_mode = alc260_modes,
889 .input_mux = &alc260_capture_source,
890 },
891 [ALC260_FUJITSU_S702X] = {
892 .mixers = { alc260_fujitsu_mixer },
893 .init_verbs = { alc260_fujitsu_init_verbs },
894 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
895 .dac_nids = alc260_dac_nids,
896 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
897 .adc_nids = alc260_dual_adc_nids,
898 .num_channel_mode = ARRAY_SIZE(alc260_modes),
899 .channel_mode = alc260_modes,
900 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
901 .input_mux = alc260_fujitsu_capture_sources,
902 },
903 [ALC260_ACER] = {
904 .mixers = { alc260_acer_mixer },
905 .init_verbs = { alc260_acer_init_verbs },
906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
907 .dac_nids = alc260_dac_nids,
908 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
909 .adc_nids = alc260_dual_adc_nids,
910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
911 .channel_mode = alc260_modes,
912 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
913 .input_mux = alc260_acer_capture_sources,
914 },
915 [ALC260_FAVORIT100] = {
916 .mixers = { alc260_favorit100_mixer },
917 .init_verbs = { alc260_favorit100_init_verbs },
918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
919 .dac_nids = alc260_dac_nids,
920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
921 .adc_nids = alc260_dual_adc_nids,
922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
923 .channel_mode = alc260_modes,
924 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
925 .input_mux = alc260_favorit100_capture_sources,
926 },
927 [ALC260_WILL] = {
928 .mixers = { alc260_will_mixer },
929 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
930 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
931 .dac_nids = alc260_dac_nids,
932 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
933 .adc_nids = alc260_adc_nids,
934 .dig_out_nid = ALC260_DIGOUT_NID,
935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
936 .channel_mode = alc260_modes,
937 .input_mux = &alc260_capture_source,
938 },
939 [ALC260_REPLACER_672V] = {
940 .mixers = { alc260_replacer_672v_mixer },
941 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
942 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
943 .dac_nids = alc260_dac_nids,
944 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
945 .adc_nids = alc260_adc_nids,
946 .dig_out_nid = ALC260_DIGOUT_NID,
947 .num_channel_mode = ARRAY_SIZE(alc260_modes),
948 .channel_mode = alc260_modes,
949 .input_mux = &alc260_capture_source,
950 .unsol_event = alc260_replacer_672v_unsol_event,
951 .init_hook = alc260_replacer_672v_automute,
952 },
953#ifdef CONFIG_SND_DEBUG
954 [ALC260_TEST] = {
955 .mixers = { alc260_test_mixer },
956 .init_verbs = { alc260_test_init_verbs },
957 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
958 .dac_nids = alc260_test_dac_nids,
959 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
960 .adc_nids = alc260_test_adc_nids,
961 .num_channel_mode = ARRAY_SIZE(alc260_modes),
962 .channel_mode = alc260_modes,
963 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
964 .input_mux = alc260_test_capture_sources,
965 },
966#endif
967};
968
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
deleted file mode 100644
index 501501ef36a9..000000000000
--- a/sound/pci/hda/alc880_quirks.c
+++ /dev/null
@@ -1,1707 +0,0 @@
1/*
2 * ALC880 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC880 board config type */
7enum {
8 ALC880_AUTO,
9 ALC880_3ST,
10 ALC880_3ST_DIG,
11 ALC880_5ST,
12 ALC880_5ST_DIG,
13 ALC880_W810,
14 ALC880_Z71V,
15 ALC880_6ST,
16 ALC880_6ST_DIG,
17 ALC880_F1734,
18 ALC880_ASUS,
19 ALC880_ASUS_DIG,
20 ALC880_ASUS_W1V,
21 ALC880_ASUS_DIG2,
22 ALC880_FUJITSU,
23 ALC880_UNIWILL_DIG,
24 ALC880_UNIWILL,
25 ALC880_UNIWILL_P53,
26 ALC880_CLEVO,
27 ALC880_TCL_S700,
28 ALC880_LG,
29#ifdef CONFIG_SND_DEBUG
30 ALC880_TEST,
31#endif
32 ALC880_MODEL_LAST /* last tag */
33};
34
35/*
36 * ALC880 3-stack model
37 *
38 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
39 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
40 * F-Mic = 0x1b, HP = 0x19
41 */
42
43static const hda_nid_t alc880_dac_nids[4] = {
44 /* front, rear, clfe, rear_surr */
45 0x02, 0x05, 0x04, 0x03
46};
47
48static const hda_nid_t alc880_adc_nids[3] = {
49 /* ADC0-2 */
50 0x07, 0x08, 0x09,
51};
52
53/* The datasheet says the node 0x07 is connected from inputs,
54 * but it shows zero connection in the real implementation on some devices.
55 * Note: this is a 915GAV bug, fixed on 915GLV
56 */
57static const hda_nid_t alc880_adc_nids_alt[2] = {
58 /* ADC1-2 */
59 0x08, 0x09,
60};
61
62#define ALC880_DIGOUT_NID 0x06
63#define ALC880_DIGIN_NID 0x0a
64#define ALC880_PIN_CD_NID 0x1c
65
66static const struct hda_input_mux alc880_capture_source = {
67 .num_items = 4,
68 .items = {
69 { "Mic", 0x0 },
70 { "Front Mic", 0x3 },
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76/* channel source setting (2/6 channel selection for 3-stack) */
77/* 2ch mode */
78static const struct hda_verb alc880_threestack_ch2_init[] = {
79 /* set line-in to input, mute it */
80 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
81 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
82 /* set mic-in to input vref 80%, mute it */
83 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
84 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
85 { } /* end */
86};
87
88/* 6ch mode */
89static const struct hda_verb alc880_threestack_ch6_init[] = {
90 /* set line-in to output, unmute it */
91 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
92 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
93 /* set mic-in to output, unmute it */
94 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
95 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
96 { } /* end */
97};
98
99static const struct hda_channel_mode alc880_threestack_modes[2] = {
100 { 2, alc880_threestack_ch2_init },
101 { 6, alc880_threestack_ch6_init },
102};
103
104static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
105 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
106 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
107 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
110 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
111 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
112 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
122 {
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
124 .name = "Channel Mode",
125 .info = alc_ch_mode_info,
126 .get = alc_ch_mode_get,
127 .put = alc_ch_mode_put,
128 },
129 { } /* end */
130};
131
132/*
133 * ALC880 5-stack model
134 *
135 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
136 * Side = 0x02 (0xd)
137 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
138 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
139 */
140
141/* additional mixers to alc880_three_stack_mixer */
142static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
143 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
144 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
145 { } /* end */
146};
147
148/* channel source setting (6/8 channel selection for 5-stack) */
149/* 6ch mode */
150static const struct hda_verb alc880_fivestack_ch6_init[] = {
151 /* set line-in to input, mute it */
152 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
153 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
154 { } /* end */
155};
156
157/* 8ch mode */
158static const struct hda_verb alc880_fivestack_ch8_init[] = {
159 /* set line-in to output, unmute it */
160 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
161 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
162 { } /* end */
163};
164
165static const struct hda_channel_mode alc880_fivestack_modes[2] = {
166 { 6, alc880_fivestack_ch6_init },
167 { 8, alc880_fivestack_ch8_init },
168};
169
170
171/*
172 * ALC880 6-stack model
173 *
174 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
175 * Side = 0x05 (0x0f)
176 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
177 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
178 */
179
180static const hda_nid_t alc880_6st_dac_nids[4] = {
181 /* front, rear, clfe, rear_surr */
182 0x02, 0x03, 0x04, 0x05
183};
184
185static const struct hda_input_mux alc880_6stack_capture_source = {
186 .num_items = 4,
187 .items = {
188 { "Mic", 0x0 },
189 { "Front Mic", 0x1 },
190 { "Line", 0x2 },
191 { "CD", 0x4 },
192 },
193};
194
195/* fixed 8-channels */
196static const struct hda_channel_mode alc880_sixstack_modes[1] = {
197 { 8, NULL },
198};
199
200static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
218 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
219 {
220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
221 .name = "Channel Mode",
222 .info = alc_ch_mode_info,
223 .get = alc_ch_mode_get,
224 .put = alc_ch_mode_put,
225 },
226 { } /* end */
227};
228
229
230/*
231 * ALC880 W810 model
232 *
233 * W810 has rear IO for:
234 * Front (DAC 02)
235 * Surround (DAC 03)
236 * Center/LFE (DAC 04)
237 * Digital out (06)
238 *
239 * The system also has a pair of internal speakers, and a headphone jack.
240 * These are both connected to Line2 on the codec, hence to DAC 02.
241 *
242 * There is a variable resistor to control the speaker or headphone
243 * volume. This is a hardware-only device without a software API.
244 *
245 * Plugging headphones in will disable the internal speakers. This is
246 * implemented in hardware, not via the driver using jack sense. In
247 * a similar fashion, plugging into the rear socket marked "front" will
248 * disable both the speakers and headphones.
249 *
250 * For input, there's a microphone jack, and an "audio in" jack.
251 * These may not do anything useful with this driver yet, because I
252 * haven't setup any initialization verbs for these yet...
253 */
254
255static const hda_nid_t alc880_w810_dac_nids[3] = {
256 /* front, rear/surround, clfe */
257 0x02, 0x03, 0x04
258};
259
260/* fixed 6 channels */
261static const struct hda_channel_mode alc880_w810_modes[1] = {
262 { 6, NULL }
263};
264
265/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
266static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
276 { } /* end */
277};
278
279
280/*
281 * Z710V model
282 *
283 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
284 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
285 * Line = 0x1a
286 */
287
288static const hda_nid_t alc880_z71v_dac_nids[1] = {
289 0x02
290};
291#define ALC880_Z71V_HP_DAC 0x03
292
293/* fixed 2 channels */
294static const struct hda_channel_mode alc880_2_jack_modes[1] = {
295 { 2, NULL }
296};
297
298static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
301 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
304 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
307 { } /* end */
308};
309
310
311/*
312 * ALC880 F1734 model
313 *
314 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
315 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
316 */
317
318static const hda_nid_t alc880_f1734_dac_nids[1] = {
319 0x03
320};
321#define ALC880_F1734_HP_DAC 0x02
322
323static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
332 { } /* end */
333};
334
335static const struct hda_input_mux alc880_f1734_capture_source = {
336 .num_items = 2,
337 .items = {
338 { "Mic", 0x1 },
339 { "CD", 0x4 },
340 },
341};
342
343
344/*
345 * ALC880 ASUS model
346 *
347 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
348 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
349 * Mic = 0x18, Line = 0x1a
350 */
351
352#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
353#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
354
355static const struct snd_kcontrol_new alc880_asus_mixer[] = {
356 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
357 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
358 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
361 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
362 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
363 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
364 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
365 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
370 {
371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
372 .name = "Channel Mode",
373 .info = alc_ch_mode_info,
374 .get = alc_ch_mode_get,
375 .put = alc_ch_mode_put,
376 },
377 { } /* end */
378};
379
380/*
381 * ALC880 ASUS W1V model
382 *
383 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
384 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
385 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
386 */
387
388/* additional mixers to alc880_asus_mixer */
389static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
390 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
391 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
392 { } /* end */
393};
394
395/* TCL S700 */
396static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
398 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
401 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
404 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
406 { } /* end */
407};
408
409/* Uniwill */
410static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
411 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
412 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
427 {
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "Channel Mode",
430 .info = alc_ch_mode_info,
431 .get = alc_ch_mode_get,
432 .put = alc_ch_mode_put,
433 },
434 { } /* end */
435};
436
437static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
440 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
447 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
452 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
458 { } /* end */
459};
460
461/*
462 * initialize the codec volumes, etc
463 */
464
465/*
466 * generic initialization of ADC, input mixers and output mixers
467 */
468static const struct hda_verb alc880_volume_init_verbs[] = {
469 /*
470 * Unmute ADC0-2 and set the default input to mic-in
471 */
472 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478
479 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
480 * mixer widget
481 * Note: PASD motherboards uses the Line In 2 as the input for front
482 * panel mic (mic 2)
483 */
484 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
492
493 /*
494 * Set up output mixers (0x0c - 0x0f)
495 */
496 /* set vol=0 to output mixers */
497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 /* set up input amps for analog loopback */
502 /* Amp Indices: DAC = 0, mixer = 1 */
503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511
512 { }
513};
514
515/*
516 * 3-stack pin configuration:
517 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
518 */
519static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
520 /*
521 * preset connection lists of input pins
522 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
523 */
524 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
525 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
526 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
527
528 /*
529 * Set pin mode and muting
530 */
531 /* set front pin widgets 0x14 for output */
532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
534 /* Mic1 (rear panel) pin widget for input and vref at 80% */
535 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
536 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
537 /* Mic2 (as headphone out) for HP output */
538 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
540 /* Line In pin widget for input */
541 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
542 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
543 /* Line2 (as front mic) pin widget for input and vref at 80% */
544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
545 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
546 /* CD pin widget for input */
547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
548
549 { }
550};
551
552/*
553 * 5-stack pin configuration:
554 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
555 * line-in/side = 0x1a, f-mic = 0x1b
556 */
557static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
558 /*
559 * preset connection lists of input pins
560 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
561 */
562 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
563 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
564
565 /*
566 * Set pin mode and muting
567 */
568 /* set pin widgets 0x14-0x17 for output */
569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
571 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 /* unmute pins for output (no gain on this amp) */
574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578
579 /* Mic1 (rear panel) pin widget for input and vref at 80% */
580 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
582 /* Mic2 (as headphone out) for HP output */
583 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 /* Line In pin widget for input */
586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
587 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
588 /* Line2 (as front mic) pin widget for input and vref at 80% */
589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
591 /* CD pin widget for input */
592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
593
594 { }
595};
596
597/*
598 * W810 pin configuration:
599 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
600 */
601static const struct hda_verb alc880_pin_w810_init_verbs[] = {
602 /* hphone/speaker input selector: front DAC */
603 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
604
605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611
612 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
613 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
614
615 { }
616};
617
618/*
619 * Z71V pin configuration:
620 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
621 */
622static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627
628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632
633 { }
634};
635
636/*
637 * 6-stack pin configuration:
638 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
639 * f-mic = 0x19, line = 0x1a, HP = 0x1b
640 */
641static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
642 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
643
644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652
653 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
662
663 { }
664};
665
666/*
667 * Uniwill pin configuration:
668 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
669 * line = 0x1a
670 */
671static const struct hda_verb alc880_uniwill_init_verbs[] = {
672 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
673
674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688
689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
691 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
696 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
697 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
698
699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
700 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
701
702 { }
703};
704
705/*
706* Uniwill P53
707* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
708 */
709static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
710 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
711
712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724
725 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
726 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731
732 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
734
735 { }
736};
737
738static const struct hda_verb alc880_beep_init_verbs[] = {
739 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
740 { }
741};
742
743static void alc880_uniwill_setup(struct hda_codec *codec)
744{
745 struct alc_spec *spec = codec->spec;
746
747 spec->autocfg.hp_pins[0] = 0x14;
748 spec->autocfg.speaker_pins[0] = 0x15;
749 spec->autocfg.speaker_pins[0] = 0x16;
750 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
751}
752
753static void alc880_uniwill_init_hook(struct hda_codec *codec)
754{
755 alc_hp_automute(codec);
756 alc88x_simple_mic_automute(codec);
757}
758
759static void alc880_uniwill_unsol_event(struct hda_codec *codec,
760 unsigned int res)
761{
762 /* Looks like the unsol event is incompatible with the standard
763 * definition. 4bit tag is placed at 28 bit!
764 */
765 res >>= 28;
766 switch (res) {
767 case ALC_MIC_EVENT:
768 alc88x_simple_mic_automute(codec);
769 break;
770 default:
771 alc_exec_unsol_event(codec, res);
772 break;
773 }
774}
775
776static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
777{
778 alc_exec_unsol_event(codec, res >> 28);
779}
780
781static void alc880_uniwill_p53_setup(struct hda_codec *codec)
782{
783 struct alc_spec *spec = codec->spec;
784
785 spec->autocfg.hp_pins[0] = 0x14;
786 spec->autocfg.speaker_pins[0] = 0x15;
787 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
788}
789
790static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
791{
792 unsigned int present;
793
794 present = snd_hda_codec_read(codec, 0x21, 0,
795 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
796 present &= HDA_AMP_VOLMASK;
797 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
800 HDA_AMP_VOLMASK, present);
801}
802
803static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
804 unsigned int res)
805{
806 /* Looks like the unsol event is incompatible with the standard
807 * definition. 4bit tag is placed at 28 bit!
808 */
809 res >>= 28;
810 if (res == ALC_DCVOL_EVENT)
811 alc880_uniwill_p53_dcvol_automute(codec);
812 else
813 alc_exec_unsol_event(codec, res);
814}
815
816/*
817 * F1734 pin configuration:
818 * HP = 0x14, speaker-out = 0x15, mic = 0x18
819 */
820static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
821 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
823 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
824 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
825 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
828 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
831
832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
836 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
838 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
840 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
841
842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
843 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
844
845 { }
846};
847
848/*
849 * ASUS pin configuration:
850 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
851 */
852static const struct hda_verb alc880_pin_asus_init_verbs[] = {
853 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
854 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
855 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
856 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
857
858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
860 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
862 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
866
867 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
871 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
873 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
874 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
875 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
876
877 { }
878};
879
880/* Enable GPIO mask and set output */
881#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
882#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
883#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
884
885/* Clevo m520g init */
886static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
887 /* headphone output */
888 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
889 /* line-out */
890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* Line-in */
893 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* CD */
896 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
897 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic1 (rear panel) */
899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* Mic2 (front panel) */
902 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
903 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* headphone */
905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
907 /* change to EAPD mode */
908 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
909 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
910
911 { }
912};
913
914static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
915 /* change to EAPD mode */
916 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
917 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
918
919 /* Headphone output */
920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
921 /* Front output*/
922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
923 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
924
925 /* Line In pin widget for input */
926 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
927 /* CD pin widget for input */
928 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
929 /* Mic1 (rear panel) pin widget for input and vref at 80% */
930 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
931
932 /* change to EAPD mode */
933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
935
936 { }
937};
938
939/*
940 * LG m1 express dual
941 *
942 * Pin assignment:
943 * Rear Line-In/Out (blue): 0x14
944 * Build-in Mic-In: 0x15
945 * Speaker-out: 0x17
946 * HP-Out (green): 0x1b
947 * Mic-In/Out (red): 0x19
948 * SPDIF-Out: 0x1e
949 */
950
951/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
952static const hda_nid_t alc880_lg_dac_nids[3] = {
953 0x05, 0x02, 0x03
954};
955
956/* seems analog CD is not working */
957static const struct hda_input_mux alc880_lg_capture_source = {
958 .num_items = 3,
959 .items = {
960 { "Mic", 0x1 },
961 { "Line", 0x5 },
962 { "Internal Mic", 0x6 },
963 },
964};
965
966/* 2,4,6 channel modes */
967static const struct hda_verb alc880_lg_ch2_init[] = {
968 /* set line-in and mic-in to input */
969 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
970 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
971 { }
972};
973
974static const struct hda_verb alc880_lg_ch4_init[] = {
975 /* set line-in to out and mic-in to input */
976 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
977 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
978 { }
979};
980
981static const struct hda_verb alc880_lg_ch6_init[] = {
982 /* set line-in and mic-in to output */
983 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
984 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
985 { }
986};
987
988static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
989 { 2, alc880_lg_ch2_init },
990 { 4, alc880_lg_ch4_init },
991 { 6, alc880_lg_ch6_init },
992};
993
994static const struct snd_kcontrol_new alc880_lg_mixer[] = {
995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
996 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
999 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1000 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1001 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1002 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1004 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1007 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1008 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1009 {
1010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1011 .name = "Channel Mode",
1012 .info = alc_ch_mode_info,
1013 .get = alc_ch_mode_get,
1014 .put = alc_ch_mode_put,
1015 },
1016 { } /* end */
1017};
1018
1019static const struct hda_verb alc880_lg_init_verbs[] = {
1020 /* set capture source to mic-in */
1021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1024 /* mute all amp mixer inputs */
1025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1028 /* line-in to input */
1029 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* built-in mic */
1032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* speaker-out */
1035 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1036 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1037 /* mic-in to input */
1038 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1040 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1041 /* HP-out */
1042 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1043 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1044 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1045 /* jack sense */
1046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1047 { }
1048};
1049
1050/* toggle speaker-output according to the hp-jack state */
1051static void alc880_lg_setup(struct hda_codec *codec)
1052{
1053 struct alc_spec *spec = codec->spec;
1054
1055 spec->autocfg.hp_pins[0] = 0x1b;
1056 spec->autocfg.speaker_pins[0] = 0x17;
1057 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1058}
1059
1060#ifdef CONFIG_SND_HDA_POWER_SAVE
1061static const struct hda_amp_list alc880_lg_loopbacks[] = {
1062 { 0x0b, HDA_INPUT, 1 },
1063 { 0x0b, HDA_INPUT, 6 },
1064 { 0x0b, HDA_INPUT, 7 },
1065 { } /* end */
1066};
1067#endif
1068
1069/*
1070 * Test configuration for debugging
1071 *
1072 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1073 * enum controls.
1074 */
1075#ifdef CONFIG_SND_DEBUG
1076static const hda_nid_t alc880_test_dac_nids[4] = {
1077 0x02, 0x03, 0x04, 0x05
1078};
1079
1080static const struct hda_input_mux alc880_test_capture_source = {
1081 .num_items = 7,
1082 .items = {
1083 { "In-1", 0x0 },
1084 { "In-2", 0x1 },
1085 { "In-3", 0x2 },
1086 { "In-4", 0x3 },
1087 { "CD", 0x4 },
1088 { "Front", 0x5 },
1089 { "Surround", 0x6 },
1090 },
1091};
1092
1093static const struct hda_channel_mode alc880_test_modes[4] = {
1094 { 2, NULL },
1095 { 4, NULL },
1096 { 6, NULL },
1097 { 8, NULL },
1098};
1099
1100static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1101 struct snd_ctl_elem_info *uinfo)
1102{
1103 static const char * const texts[] = {
1104 "N/A", "Line Out", "HP Out",
1105 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1106 };
1107 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1108 uinfo->count = 1;
1109 uinfo->value.enumerated.items = 8;
1110 if (uinfo->value.enumerated.item >= 8)
1111 uinfo->value.enumerated.item = 7;
1112 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1113 return 0;
1114}
1115
1116static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1117 struct snd_ctl_elem_value *ucontrol)
1118{
1119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1120 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1121 unsigned int pin_ctl, item = 0;
1122
1123 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1124 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1125 if (pin_ctl & AC_PINCTL_OUT_EN) {
1126 if (pin_ctl & AC_PINCTL_HP_EN)
1127 item = 2;
1128 else
1129 item = 1;
1130 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1131 switch (pin_ctl & AC_PINCTL_VREFEN) {
1132 case AC_PINCTL_VREF_HIZ: item = 3; break;
1133 case AC_PINCTL_VREF_50: item = 4; break;
1134 case AC_PINCTL_VREF_GRD: item = 5; break;
1135 case AC_PINCTL_VREF_80: item = 6; break;
1136 case AC_PINCTL_VREF_100: item = 7; break;
1137 }
1138 }
1139 ucontrol->value.enumerated.item[0] = item;
1140 return 0;
1141}
1142
1143static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1144 struct snd_ctl_elem_value *ucontrol)
1145{
1146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1147 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1148 static const unsigned int ctls[] = {
1149 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1150 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1151 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1152 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1153 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1154 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1155 };
1156 unsigned int old_ctl, new_ctl;
1157
1158 old_ctl = snd_hda_codec_read(codec, nid, 0,
1159 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1160 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1161 if (old_ctl != new_ctl) {
1162 int val;
1163 snd_hda_codec_write_cache(codec, nid, 0,
1164 AC_VERB_SET_PIN_WIDGET_CONTROL,
1165 new_ctl);
1166 val = ucontrol->value.enumerated.item[0] >= 3 ?
1167 HDA_AMP_MUTE : 0;
1168 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1169 HDA_AMP_MUTE, val);
1170 return 1;
1171 }
1172 return 0;
1173}
1174
1175static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1176 struct snd_ctl_elem_info *uinfo)
1177{
1178 static const char * const texts[] = {
1179 "Front", "Surround", "CLFE", "Side"
1180 };
1181 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1182 uinfo->count = 1;
1183 uinfo->value.enumerated.items = 4;
1184 if (uinfo->value.enumerated.item >= 4)
1185 uinfo->value.enumerated.item = 3;
1186 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1187 return 0;
1188}
1189
1190static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1191 struct snd_ctl_elem_value *ucontrol)
1192{
1193 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1194 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1195 unsigned int sel;
1196
1197 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1198 ucontrol->value.enumerated.item[0] = sel & 3;
1199 return 0;
1200}
1201
1202static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1203 struct snd_ctl_elem_value *ucontrol)
1204{
1205 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1206 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1207 unsigned int sel;
1208
1209 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1210 if (ucontrol->value.enumerated.item[0] != sel) {
1211 sel = ucontrol->value.enumerated.item[0] & 3;
1212 snd_hda_codec_write_cache(codec, nid, 0,
1213 AC_VERB_SET_CONNECT_SEL, sel);
1214 return 1;
1215 }
1216 return 0;
1217}
1218
1219#define PIN_CTL_TEST(xname,nid) { \
1220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1221 .name = xname, \
1222 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1223 .info = alc_test_pin_ctl_info, \
1224 .get = alc_test_pin_ctl_get, \
1225 .put = alc_test_pin_ctl_put, \
1226 .private_value = nid \
1227 }
1228
1229#define PIN_SRC_TEST(xname,nid) { \
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1231 .name = xname, \
1232 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1233 .info = alc_test_pin_src_info, \
1234 .get = alc_test_pin_src_get, \
1235 .put = alc_test_pin_src_put, \
1236 .private_value = nid \
1237 }
1238
1239static const struct snd_kcontrol_new alc880_test_mixer[] = {
1240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1241 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1242 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1243 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1246 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1247 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1248 PIN_CTL_TEST("Front Pin Mode", 0x14),
1249 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1250 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1251 PIN_CTL_TEST("Side Pin Mode", 0x17),
1252 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1253 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1254 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1255 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1256 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1257 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1258 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1259 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1260 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1261 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1262 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1263 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1264 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1265 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1266 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1267 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1268 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1269 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1270 {
1271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1272 .name = "Channel Mode",
1273 .info = alc_ch_mode_info,
1274 .get = alc_ch_mode_get,
1275 .put = alc_ch_mode_put,
1276 },
1277 { } /* end */
1278};
1279
1280static const struct hda_verb alc880_test_init_verbs[] = {
1281 /* Unmute inputs of 0x0c - 0x0f */
1282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1288 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1289 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1290 /* Vol output for 0x0c-0x0f */
1291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1294 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1295 /* Set output pins 0x14-0x17 */
1296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1300 /* Unmute output pins 0x14-0x17 */
1301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1305 /* Set input pins 0x18-0x1c */
1306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1307 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1308 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1311 /* Mute input pins 0x18-0x1b */
1312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1316 /* ADC set up */
1317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1318 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1322 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1323 /* Analog input/passthru */
1324 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1327 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1329 { }
1330};
1331#endif
1332
1333/*
1334 */
1335
1336static const char * const alc880_models[ALC880_MODEL_LAST] = {
1337 [ALC880_3ST] = "3stack",
1338 [ALC880_TCL_S700] = "tcl",
1339 [ALC880_3ST_DIG] = "3stack-digout",
1340 [ALC880_CLEVO] = "clevo",
1341 [ALC880_5ST] = "5stack",
1342 [ALC880_5ST_DIG] = "5stack-digout",
1343 [ALC880_W810] = "w810",
1344 [ALC880_Z71V] = "z71v",
1345 [ALC880_6ST] = "6stack",
1346 [ALC880_6ST_DIG] = "6stack-digout",
1347 [ALC880_ASUS] = "asus",
1348 [ALC880_ASUS_W1V] = "asus-w1v",
1349 [ALC880_ASUS_DIG] = "asus-dig",
1350 [ALC880_ASUS_DIG2] = "asus-dig2",
1351 [ALC880_UNIWILL_DIG] = "uniwill",
1352 [ALC880_UNIWILL_P53] = "uniwill-p53",
1353 [ALC880_FUJITSU] = "fujitsu",
1354 [ALC880_F1734] = "F1734",
1355 [ALC880_LG] = "lg",
1356#ifdef CONFIG_SND_DEBUG
1357 [ALC880_TEST] = "test",
1358#endif
1359 [ALC880_AUTO] = "auto",
1360};
1361
1362static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1363 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1364 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1365 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1366 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1367 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1368 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1369 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1370 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1371 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1372 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1373 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1374 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1375 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1376 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1377 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1378 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1379 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1380 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1381 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1382 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1383 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1384 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1385 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1386 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1387 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1388 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1389 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1390 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1391 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1392 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1393 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1394 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1395 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1396 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1397 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1398 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1399 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1400 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1401 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1402 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1403 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1404 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1405 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1406 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1407 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1408 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1409 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1410 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1411 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1412 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1413 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1414 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1415 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1416 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1417 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1418 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1419 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1420 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1421 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1422 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1423 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1424 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1425 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1426 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1427 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1428 /* default Intel */
1429 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1430 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1431 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1432 {}
1433};
1434
1435/*
1436 * ALC880 codec presets
1437 */
1438static const struct alc_config_preset alc880_presets[] = {
1439 [ALC880_3ST] = {
1440 .mixers = { alc880_three_stack_mixer },
1441 .init_verbs = { alc880_volume_init_verbs,
1442 alc880_pin_3stack_init_verbs },
1443 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1444 .dac_nids = alc880_dac_nids,
1445 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1446 .channel_mode = alc880_threestack_modes,
1447 .need_dac_fix = 1,
1448 .input_mux = &alc880_capture_source,
1449 },
1450 [ALC880_3ST_DIG] = {
1451 .mixers = { alc880_three_stack_mixer },
1452 .init_verbs = { alc880_volume_init_verbs,
1453 alc880_pin_3stack_init_verbs },
1454 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1455 .dac_nids = alc880_dac_nids,
1456 .dig_out_nid = ALC880_DIGOUT_NID,
1457 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1458 .channel_mode = alc880_threestack_modes,
1459 .need_dac_fix = 1,
1460 .input_mux = &alc880_capture_source,
1461 },
1462 [ALC880_TCL_S700] = {
1463 .mixers = { alc880_tcl_s700_mixer },
1464 .init_verbs = { alc880_volume_init_verbs,
1465 alc880_pin_tcl_S700_init_verbs,
1466 alc880_gpio2_init_verbs },
1467 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1468 .dac_nids = alc880_dac_nids,
1469 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1470 .num_adc_nids = 1, /* single ADC */
1471 .hp_nid = 0x03,
1472 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1473 .channel_mode = alc880_2_jack_modes,
1474 .input_mux = &alc880_capture_source,
1475 },
1476 [ALC880_5ST] = {
1477 .mixers = { alc880_three_stack_mixer,
1478 alc880_five_stack_mixer},
1479 .init_verbs = { alc880_volume_init_verbs,
1480 alc880_pin_5stack_init_verbs },
1481 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1482 .dac_nids = alc880_dac_nids,
1483 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1484 .channel_mode = alc880_fivestack_modes,
1485 .input_mux = &alc880_capture_source,
1486 },
1487 [ALC880_5ST_DIG] = {
1488 .mixers = { alc880_three_stack_mixer,
1489 alc880_five_stack_mixer },
1490 .init_verbs = { alc880_volume_init_verbs,
1491 alc880_pin_5stack_init_verbs },
1492 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1493 .dac_nids = alc880_dac_nids,
1494 .dig_out_nid = ALC880_DIGOUT_NID,
1495 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1496 .channel_mode = alc880_fivestack_modes,
1497 .input_mux = &alc880_capture_source,
1498 },
1499 [ALC880_6ST] = {
1500 .mixers = { alc880_six_stack_mixer },
1501 .init_verbs = { alc880_volume_init_verbs,
1502 alc880_pin_6stack_init_verbs },
1503 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1504 .dac_nids = alc880_6st_dac_nids,
1505 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1506 .channel_mode = alc880_sixstack_modes,
1507 .input_mux = &alc880_6stack_capture_source,
1508 },
1509 [ALC880_6ST_DIG] = {
1510 .mixers = { alc880_six_stack_mixer },
1511 .init_verbs = { alc880_volume_init_verbs,
1512 alc880_pin_6stack_init_verbs },
1513 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1514 .dac_nids = alc880_6st_dac_nids,
1515 .dig_out_nid = ALC880_DIGOUT_NID,
1516 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1517 .channel_mode = alc880_sixstack_modes,
1518 .input_mux = &alc880_6stack_capture_source,
1519 },
1520 [ALC880_W810] = {
1521 .mixers = { alc880_w810_base_mixer },
1522 .init_verbs = { alc880_volume_init_verbs,
1523 alc880_pin_w810_init_verbs,
1524 alc880_gpio2_init_verbs },
1525 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1526 .dac_nids = alc880_w810_dac_nids,
1527 .dig_out_nid = ALC880_DIGOUT_NID,
1528 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1529 .channel_mode = alc880_w810_modes,
1530 .input_mux = &alc880_capture_source,
1531 },
1532 [ALC880_Z71V] = {
1533 .mixers = { alc880_z71v_mixer },
1534 .init_verbs = { alc880_volume_init_verbs,
1535 alc880_pin_z71v_init_verbs },
1536 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1537 .dac_nids = alc880_z71v_dac_nids,
1538 .dig_out_nid = ALC880_DIGOUT_NID,
1539 .hp_nid = 0x03,
1540 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1541 .channel_mode = alc880_2_jack_modes,
1542 .input_mux = &alc880_capture_source,
1543 },
1544 [ALC880_F1734] = {
1545 .mixers = { alc880_f1734_mixer },
1546 .init_verbs = { alc880_volume_init_verbs,
1547 alc880_pin_f1734_init_verbs },
1548 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1549 .dac_nids = alc880_f1734_dac_nids,
1550 .hp_nid = 0x02,
1551 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1552 .channel_mode = alc880_2_jack_modes,
1553 .input_mux = &alc880_f1734_capture_source,
1554 .unsol_event = alc880_uniwill_p53_unsol_event,
1555 .setup = alc880_uniwill_p53_setup,
1556 .init_hook = alc_hp_automute,
1557 },
1558 [ALC880_ASUS] = {
1559 .mixers = { alc880_asus_mixer },
1560 .init_verbs = { alc880_volume_init_verbs,
1561 alc880_pin_asus_init_verbs,
1562 alc880_gpio1_init_verbs },
1563 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1564 .dac_nids = alc880_asus_dac_nids,
1565 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1566 .channel_mode = alc880_asus_modes,
1567 .need_dac_fix = 1,
1568 .input_mux = &alc880_capture_source,
1569 },
1570 [ALC880_ASUS_DIG] = {
1571 .mixers = { alc880_asus_mixer },
1572 .init_verbs = { alc880_volume_init_verbs,
1573 alc880_pin_asus_init_verbs,
1574 alc880_gpio1_init_verbs },
1575 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1576 .dac_nids = alc880_asus_dac_nids,
1577 .dig_out_nid = ALC880_DIGOUT_NID,
1578 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1579 .channel_mode = alc880_asus_modes,
1580 .need_dac_fix = 1,
1581 .input_mux = &alc880_capture_source,
1582 },
1583 [ALC880_ASUS_DIG2] = {
1584 .mixers = { alc880_asus_mixer },
1585 .init_verbs = { alc880_volume_init_verbs,
1586 alc880_pin_asus_init_verbs,
1587 alc880_gpio2_init_verbs }, /* use GPIO2 */
1588 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1589 .dac_nids = alc880_asus_dac_nids,
1590 .dig_out_nid = ALC880_DIGOUT_NID,
1591 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1592 .channel_mode = alc880_asus_modes,
1593 .need_dac_fix = 1,
1594 .input_mux = &alc880_capture_source,
1595 },
1596 [ALC880_ASUS_W1V] = {
1597 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1598 .init_verbs = { alc880_volume_init_verbs,
1599 alc880_pin_asus_init_verbs,
1600 alc880_gpio1_init_verbs },
1601 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1602 .dac_nids = alc880_asus_dac_nids,
1603 .dig_out_nid = ALC880_DIGOUT_NID,
1604 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1605 .channel_mode = alc880_asus_modes,
1606 .need_dac_fix = 1,
1607 .input_mux = &alc880_capture_source,
1608 },
1609 [ALC880_UNIWILL_DIG] = {
1610 .mixers = { alc880_asus_mixer },
1611 .init_verbs = { alc880_volume_init_verbs,
1612 alc880_pin_asus_init_verbs },
1613 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1614 .dac_nids = alc880_asus_dac_nids,
1615 .dig_out_nid = ALC880_DIGOUT_NID,
1616 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1617 .channel_mode = alc880_asus_modes,
1618 .need_dac_fix = 1,
1619 .input_mux = &alc880_capture_source,
1620 },
1621 [ALC880_UNIWILL] = {
1622 .mixers = { alc880_uniwill_mixer },
1623 .init_verbs = { alc880_volume_init_verbs,
1624 alc880_uniwill_init_verbs },
1625 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1626 .dac_nids = alc880_asus_dac_nids,
1627 .dig_out_nid = ALC880_DIGOUT_NID,
1628 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1629 .channel_mode = alc880_threestack_modes,
1630 .need_dac_fix = 1,
1631 .input_mux = &alc880_capture_source,
1632 .unsol_event = alc880_uniwill_unsol_event,
1633 .setup = alc880_uniwill_setup,
1634 .init_hook = alc880_uniwill_init_hook,
1635 },
1636 [ALC880_UNIWILL_P53] = {
1637 .mixers = { alc880_uniwill_p53_mixer },
1638 .init_verbs = { alc880_volume_init_verbs,
1639 alc880_uniwill_p53_init_verbs },
1640 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1641 .dac_nids = alc880_asus_dac_nids,
1642 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1643 .channel_mode = alc880_threestack_modes,
1644 .input_mux = &alc880_capture_source,
1645 .unsol_event = alc880_uniwill_p53_unsol_event,
1646 .setup = alc880_uniwill_p53_setup,
1647 .init_hook = alc_hp_automute,
1648 },
1649 [ALC880_FUJITSU] = {
1650 .mixers = { alc880_fujitsu_mixer },
1651 .init_verbs = { alc880_volume_init_verbs,
1652 alc880_uniwill_p53_init_verbs,
1653 alc880_beep_init_verbs },
1654 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1655 .dac_nids = alc880_dac_nids,
1656 .dig_out_nid = ALC880_DIGOUT_NID,
1657 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1658 .channel_mode = alc880_2_jack_modes,
1659 .input_mux = &alc880_capture_source,
1660 .unsol_event = alc880_uniwill_p53_unsol_event,
1661 .setup = alc880_uniwill_p53_setup,
1662 .init_hook = alc_hp_automute,
1663 },
1664 [ALC880_CLEVO] = {
1665 .mixers = { alc880_three_stack_mixer },
1666 .init_verbs = { alc880_volume_init_verbs,
1667 alc880_pin_clevo_init_verbs },
1668 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1669 .dac_nids = alc880_dac_nids,
1670 .hp_nid = 0x03,
1671 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1672 .channel_mode = alc880_threestack_modes,
1673 .need_dac_fix = 1,
1674 .input_mux = &alc880_capture_source,
1675 },
1676 [ALC880_LG] = {
1677 .mixers = { alc880_lg_mixer },
1678 .init_verbs = { alc880_volume_init_verbs,
1679 alc880_lg_init_verbs },
1680 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1681 .dac_nids = alc880_lg_dac_nids,
1682 .dig_out_nid = ALC880_DIGOUT_NID,
1683 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1684 .channel_mode = alc880_lg_ch_modes,
1685 .need_dac_fix = 1,
1686 .input_mux = &alc880_lg_capture_source,
1687 .unsol_event = alc880_unsol_event,
1688 .setup = alc880_lg_setup,
1689 .init_hook = alc_hp_automute,
1690#ifdef CONFIG_SND_HDA_POWER_SAVE
1691 .loopbacks = alc880_lg_loopbacks,
1692#endif
1693 },
1694#ifdef CONFIG_SND_DEBUG
1695 [ALC880_TEST] = {
1696 .mixers = { alc880_test_mixer },
1697 .init_verbs = { alc880_test_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1699 .dac_nids = alc880_test_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1702 .channel_mode = alc880_test_modes,
1703 .input_mux = &alc880_test_capture_source,
1704 },
1705#endif
1706};
1707
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
deleted file mode 100644
index bb364a53f546..000000000000
--- a/sound/pci/hda/alc882_quirks.c
+++ /dev/null
@@ -1,866 +0,0 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC885_MBA21,
10 ALC885_MBP3,
11 ALC885_MB5,
12 ALC885_MACMINI3,
13 ALC885_IMAC91,
14 ALC889A_MB31,
15 ALC882_MODEL_LAST,
16};
17
18#define ALC882_DIGOUT_NID 0x06
19#define ALC882_DIGIN_NID 0x0a
20#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
21#define ALC883_DIGIN_NID ALC882_DIGIN_NID
22#define ALC1200_DIGOUT_NID 0x10
23
24
25static const struct hda_channel_mode alc882_ch_modes[1] = {
26 { 8, NULL }
27};
28
29/* DACs */
30static const hda_nid_t alc882_dac_nids[4] = {
31 /* front, rear, clfe, rear_surr */
32 0x02, 0x03, 0x04, 0x05
33};
34#define alc883_dac_nids alc882_dac_nids
35
36/* ADCs */
37#define alc882_adc_nids alc880_adc_nids
38#define alc882_adc_nids_alt alc880_adc_nids_alt
39#define alc883_adc_nids alc882_adc_nids_alt
40
41static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
42#define alc883_capsrc_nids alc882_capsrc_nids_alt
43
44/* input MUX */
45/* FIXME: should be a matrix-type input source selection */
46
47static const struct hda_input_mux alc882_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57#define alc883_capture_source alc882_capture_source
58
59static const struct hda_input_mux mb5_capture_source = {
60 .num_items = 3,
61 .items = {
62 { "Mic", 0x1 },
63 { "Line", 0x7 },
64 { "CD", 0x4 },
65 },
66};
67
68static const struct hda_input_mux macmini3_capture_source = {
69 .num_items = 2,
70 .items = {
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76static const struct hda_input_mux alc883_3stack_6ch_intel = {
77 .num_items = 4,
78 .items = {
79 { "Mic", 0x1 },
80 { "Front Mic", 0x0 },
81 { "Line", 0x2 },
82 { "CD", 0x4 },
83 },
84};
85
86static const struct hda_input_mux alc889A_mb31_capture_source = {
87 .num_items = 2,
88 .items = {
89 { "Mic", 0x0 },
90 /* Front Mic (0x01) unused */
91 { "Line", 0x2 },
92 /* Line 2 (0x03) unused */
93 /* CD (0x04) unused? */
94 },
95};
96
97static const struct hda_input_mux alc889A_imac91_capture_source = {
98 .num_items = 2,
99 .items = {
100 { "Mic", 0x01 },
101 { "Line", 0x2 }, /* Not sure! */
102 },
103};
104
105/* Macbook Air 2,1 */
106
107static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
108 { 2, NULL },
109};
110
111/*
112 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
113 */
114
115/*
116 * 2ch mode
117 */
118static const struct hda_verb alc885_mbp_ch2_init[] = {
119 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
120 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
121 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
122 { } /* end */
123};
124
125/*
126 * 4ch mode
127 */
128static const struct hda_verb alc885_mbp_ch4_init[] = {
129 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
130 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
131 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
132 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
133 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
134 { } /* end */
135};
136
137static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
138 { 2, alc885_mbp_ch2_init },
139 { 4, alc885_mbp_ch4_init },
140};
141
142/*
143 * 2ch
144 * Speakers/Woofer/HP = Front
145 * LineIn = Input
146 */
147static const struct hda_verb alc885_mb5_ch2_init[] = {
148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
149 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 { } /* end */
151};
152
153/*
154 * 6ch mode
155 * Speakers/HP = Front
156 * Woofer = LFE
157 * LineIn = Surround
158 */
159static const struct hda_verb alc885_mb5_ch6_init[] = {
160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
162 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
163 { } /* end */
164};
165
166static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
167 { 2, alc885_mb5_ch2_init },
168 { 6, alc885_mb5_ch6_init },
169};
170
171#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
172
173/* Macbook Air 2,1 same control for HP and internal Speaker */
174
175static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
176 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
177 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
178 { }
179};
180
181
182static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
184 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
186 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
187 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
188 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
189 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
191 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
192 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
194 { } /* end */
195};
196
197static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
199 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
201 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
202 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
203 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
205 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
207 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
208 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
209 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
210 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
212 { } /* end */
213};
214
215static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
217 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
218 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
219 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
220 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
221 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
223 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
225 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
226 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
227 { } /* end */
228};
229
230static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
233 { } /* end */
234};
235
236
237static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Channel Mode",
241 .info = alc_ch_mode_info,
242 .get = alc_ch_mode_get,
243 .put = alc_ch_mode_put,
244 },
245 { } /* end */
246};
247
248static const struct hda_verb alc882_base_init_verbs[] = {
249 /* Front mixer: unmute input/output amp left and right (volume = 0) */
250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 /* Rear mixer */
253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
255 /* CLFE mixer */
256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
258 /* Side mixer */
259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
261
262 /* Front Pin: output 0 (0x0c) */
263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
264 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
265 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
266 /* Rear Pin: output 1 (0x0d) */
267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
270 /* CLFE Pin: output 2 (0x0e) */
271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
273 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
274 /* Side Pin: output 3 (0x0f) */
275 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
276 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
277 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
278 /* Mic (rear) pin: input vref at 80% */
279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 /* Front Mic pin: input vref at 80% */
282 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284 /* Line In pin: input */
285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
287 /* Line-2 In: Headphone output (output 0 - 0x0c) */
288 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
289 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
290 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
291 /* CD pin widget for input */
292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293
294 /* FIXME: use matrix-type input source selection */
295 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
296 /* Input mixer2 */
297 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
298 /* Input mixer3 */
299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
300 /* ADC2: mute amp left and right */
301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
303 /* ADC3: mute amp left and right */
304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
305 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
306
307 { }
308};
309
310#define alc883_init_verbs alc882_base_init_verbs
311
312/* Macbook 5,1 */
313static const struct hda_verb alc885_mb5_init_verbs[] = {
314 /* DACs */
315 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
316 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
318 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
319 /* Front mixer */
320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 /* Surround mixer */
324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
327 /* LFE mixer */
328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
331 /* HP mixer */
332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
335 /* Front Pin (0x0c) */
336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
338 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
339 /* LFE Pin (0x0e) */
340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
342 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
343 /* HP Pin (0x0f) */
344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
346 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
347 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
348 /* Front Mic pin: input vref at 80% */
349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
350 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line In pin */
352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
354
355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
358 { }
359};
360
361/* Macmini 3,1 */
362static const struct hda_verb alc885_macmini3_init_verbs[] = {
363 /* DACs */
364 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
365 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
366 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
367 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
368 /* Front mixer */
369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
372 /* Surround mixer */
373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
376 /* LFE mixer */
377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 /* HP mixer */
381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
384 /* Front Pin (0x0c) */
385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
386 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
387 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
388 /* LFE Pin (0x0e) */
389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
392 /* HP Pin (0x0f) */
393 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
394 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
396 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
397 /* Line In pin */
398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
400
401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
405 { }
406};
407
408
409static const struct hda_verb alc885_mba21_init_verbs[] = {
410 /*Internal and HP Speaker Mixer*/
411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
414 /*Internal Speaker Pin (0x0c)*/
415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
417 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
418 /* HP Pin: output 0 (0x0e) */
419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
423 /* Line in (is hp when jack connected)*/
424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
426
427 { }
428 };
429
430
431/* Macbook Pro rev3 */
432static const struct hda_verb alc885_mbp3_init_verbs[] = {
433 /* Front mixer: unmute input/output amp left and right (volume = 0) */
434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
437 /* Rear mixer */
438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
441 /* HP mixer */
442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
445 /* Front Pin: output 0 (0x0c) */
446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
448 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
449 /* HP Pin: output 0 (0x0e) */
450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
453 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
454 /* Mic (rear) pin: input vref at 80% */
455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
457 /* Front Mic pin: input vref at 80% */
458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
460 /* Line In pin: use output 1 when in LineOut mode */
461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
463 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
464
465 /* FIXME: use matrix-type input source selection */
466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
467 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
472 /* Input mixer2 */
473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
477 /* Input mixer3 */
478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
482 /* ADC1: mute amp left and right */
483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
484 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
485 /* ADC2: mute amp left and right */
486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
487 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
488 /* ADC3: mute amp left and right */
489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
490 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
491
492 { }
493};
494
495/* iMac 9,1 */
496static const struct hda_verb alc885_imac91_init_verbs[] = {
497 /* Internal Speaker Pin (0x0c) */
498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
500 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
503 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
504 /* HP Pin: Rear */
505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
507 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
508 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
509 /* Line in Rear */
510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Front Mic pin: input vref at 80% */
513 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Rear mixer */
516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
519 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
523 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
528 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
533 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
538 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
540 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
541 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
544 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
545 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
547 { }
548};
549
550/* Toggle speaker-output according to the hp-jack state */
551static void alc885_imac24_setup(struct hda_codec *codec)
552{
553 struct alc_spec *spec = codec->spec;
554
555 spec->autocfg.hp_pins[0] = 0x14;
556 spec->autocfg.speaker_pins[0] = 0x18;
557 spec->autocfg.speaker_pins[1] = 0x1a;
558 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
559}
560
561#define alc885_mb5_setup alc885_imac24_setup
562#define alc885_macmini3_setup alc885_imac24_setup
563
564/* Macbook Air 2,1 */
565static void alc885_mba21_setup(struct hda_codec *codec)
566{
567 struct alc_spec *spec = codec->spec;
568
569 spec->autocfg.hp_pins[0] = 0x14;
570 spec->autocfg.speaker_pins[0] = 0x18;
571 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
572}
573
574
575
576static void alc885_mbp3_setup(struct hda_codec *codec)
577{
578 struct alc_spec *spec = codec->spec;
579
580 spec->autocfg.hp_pins[0] = 0x15;
581 spec->autocfg.speaker_pins[0] = 0x14;
582 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
583}
584
585static void alc885_imac91_setup(struct hda_codec *codec)
586{
587 struct alc_spec *spec = codec->spec;
588
589 spec->autocfg.hp_pins[0] = 0x14;
590 spec->autocfg.speaker_pins[0] = 0x18;
591 spec->autocfg.speaker_pins[1] = 0x1a;
592 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
593}
594
595/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
596static const struct hda_verb alc889A_mb31_ch2_init[] = {
597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
601 { } /* end */
602};
603
604/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
605static const struct hda_verb alc889A_mb31_ch4_init[] = {
606 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
607 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
608 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
609 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
610 { } /* end */
611};
612
613/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
614static const struct hda_verb alc889A_mb31_ch5_init[] = {
615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
619 { } /* end */
620};
621
622/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
623static const struct hda_verb alc889A_mb31_ch6_init[] = {
624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
626 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
627 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
628 { } /* end */
629};
630
631static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
632 { 2, alc889A_mb31_ch2_init },
633 { 4, alc889A_mb31_ch4_init },
634 { 5, alc889A_mb31_ch5_init },
635 { 6, alc889A_mb31_ch6_init },
636};
637
638static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
650 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
651 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
653 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
655 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
656 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
657 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
658 { } /* end */
659};
660
661static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
662 /* Output mixers */
663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
666 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
668 HDA_OUTPUT),
669 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
672 /* Output switches */
673 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
674 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
675 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
676 /* Boost mixers */
677 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
678 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
679 /* Input mixers */
680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
682 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
683 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
684 { } /* end */
685};
686
687static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
688 {
689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
690 .name = "Channel Mode",
691 .info = alc_ch_mode_info,
692 .get = alc_ch_mode_get,
693 .put = alc_ch_mode_put,
694 },
695 { } /* end */
696};
697
698static const struct hda_verb alc889A_mb31_verbs[] = {
699 /* Init rear pin (used as headphone output) */
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
703 /* Init line pin (used as output in 4ch and 6ch mode) */
704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
705 /* Init line 2 pin (used as headphone out by default) */
706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
708 { } /* end */
709};
710
711/* Mute speakers according to the headphone jack state */
712static void alc889A_mb31_automute(struct hda_codec *codec)
713{
714 unsigned int present;
715
716 /* Mute only in 2ch or 4ch mode */
717 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
718 == 0x00) {
719 present = snd_hda_jack_detect(codec, 0x15);
720 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
721 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
722 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
723 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
724 }
725}
726
727static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
728{
729 if ((res >> 26) == ALC_HP_EVENT)
730 alc889A_mb31_automute(codec);
731}
732
733static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
734{
735 alc_exec_unsol_event(codec, res >> 26);
736}
737
738/*
739 * configuration and preset
740 */
741static const char * const alc882_models[ALC882_MODEL_LAST] = {
742 [ALC885_MB5] = "mb5",
743 [ALC885_MACMINI3] = "macmini3",
744 [ALC885_MBA21] = "mba21",
745 [ALC885_MBP3] = "mbp3",
746 [ALC885_IMAC91] = "imac91",
747 [ALC889A_MB31] = "mb31",
748 [ALC882_AUTO] = "auto",
749};
750
751/* codec SSID table for Intel Mac */
752static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
753 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
754 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
755 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
756 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
757 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
758 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
759 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
760 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
761 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
762 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
763 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
764 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
765 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
766 * so apparently no perfect solution yet
767 */
768 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
769 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
770 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
771 {} /* terminator */
772};
773
774static const struct alc_config_preset alc882_presets[] = {
775 [ALC885_MBA21] = {
776 .mixers = { alc885_mba21_mixer },
777 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
778 .num_dacs = 2,
779 .dac_nids = alc882_dac_nids,
780 .channel_mode = alc885_mba21_ch_modes,
781 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
782 .input_mux = &alc882_capture_source,
783 .unsol_event = alc882_unsol_event,
784 .setup = alc885_mba21_setup,
785 .init_hook = alc_hp_automute,
786 },
787 [ALC885_MBP3] = {
788 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
789 .init_verbs = { alc885_mbp3_init_verbs,
790 alc880_gpio1_init_verbs },
791 .num_dacs = 2,
792 .dac_nids = alc882_dac_nids,
793 .hp_nid = 0x04,
794 .channel_mode = alc885_mbp_4ch_modes,
795 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
796 .input_mux = &alc882_capture_source,
797 .dig_out_nid = ALC882_DIGOUT_NID,
798 .dig_in_nid = ALC882_DIGIN_NID,
799 .unsol_event = alc882_unsol_event,
800 .setup = alc885_mbp3_setup,
801 .init_hook = alc_hp_automute,
802 },
803 [ALC885_MB5] = {
804 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
805 .init_verbs = { alc885_mb5_init_verbs,
806 alc880_gpio1_init_verbs },
807 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
808 .dac_nids = alc882_dac_nids,
809 .channel_mode = alc885_mb5_6ch_modes,
810 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
811 .input_mux = &mb5_capture_source,
812 .dig_out_nid = ALC882_DIGOUT_NID,
813 .dig_in_nid = ALC882_DIGIN_NID,
814 .unsol_event = alc882_unsol_event,
815 .setup = alc885_mb5_setup,
816 .init_hook = alc_hp_automute,
817 },
818 [ALC885_MACMINI3] = {
819 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
820 .init_verbs = { alc885_macmini3_init_verbs,
821 alc880_gpio1_init_verbs },
822 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
823 .dac_nids = alc882_dac_nids,
824 .channel_mode = alc885_macmini3_6ch_modes,
825 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
826 .input_mux = &macmini3_capture_source,
827 .dig_out_nid = ALC882_DIGOUT_NID,
828 .dig_in_nid = ALC882_DIGIN_NID,
829 .unsol_event = alc882_unsol_event,
830 .setup = alc885_macmini3_setup,
831 .init_hook = alc_hp_automute,
832 },
833 [ALC885_IMAC91] = {
834 .mixers = {alc885_imac91_mixer},
835 .init_verbs = { alc885_imac91_init_verbs,
836 alc880_gpio1_init_verbs },
837 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
838 .dac_nids = alc882_dac_nids,
839 .channel_mode = alc885_mba21_ch_modes,
840 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
841 .input_mux = &alc889A_imac91_capture_source,
842 .dig_out_nid = ALC882_DIGOUT_NID,
843 .dig_in_nid = ALC882_DIGIN_NID,
844 .unsol_event = alc882_unsol_event,
845 .setup = alc885_imac91_setup,
846 .init_hook = alc_hp_automute,
847 },
848 [ALC889A_MB31] = {
849 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
850 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
851 alc880_gpio1_init_verbs },
852 .adc_nids = alc883_adc_nids,
853 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
854 .capsrc_nids = alc883_capsrc_nids,
855 .dac_nids = alc883_dac_nids,
856 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
857 .channel_mode = alc889A_mb31_6ch_modes,
858 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
859 .input_mux = &alc889A_mb31_capture_source,
860 .dig_out_nid = ALC883_DIGOUT_NID,
861 .unsol_event = alc889A_mb31_unsol_event,
862 .init_hook = alc889A_mb31_automute,
863 },
864};
865
866
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
deleted file mode 100644
index a18952ed4311..000000000000
--- a/sound/pci/hda/alc_quirks.c
+++ /dev/null
@@ -1,480 +0,0 @@
1/*
2 * Common codes for Realtek codec quirks
3 * included by patch_realtek.c
4 */
5
6/*
7 * configuration template - to be copied to the spec instance
8 */
9struct alc_config_preset {
10 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
11 * with spec
12 */
13 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
14 const struct hda_verb *init_verbs[5];
15 unsigned int num_dacs;
16 const hda_nid_t *dac_nids;
17 hda_nid_t dig_out_nid; /* optional */
18 hda_nid_t hp_nid; /* optional */
19 const hda_nid_t *slave_dig_outs;
20 unsigned int num_adc_nids;
21 const hda_nid_t *adc_nids;
22 const hda_nid_t *capsrc_nids;
23 hda_nid_t dig_in_nid;
24 unsigned int num_channel_mode;
25 const struct hda_channel_mode *channel_mode;
26 int need_dac_fix;
27 int const_channel_count;
28 unsigned int num_mux_defs;
29 const struct hda_input_mux *input_mux;
30 void (*unsol_event)(struct hda_codec *, unsigned int);
31 void (*setup)(struct hda_codec *);
32 void (*init_hook)(struct hda_codec *);
33#ifdef CONFIG_SND_HDA_POWER_SAVE
34 const struct hda_amp_list *loopbacks;
35 void (*power_hook)(struct hda_codec *codec);
36#endif
37};
38
39/*
40 * channel mode setting
41 */
42static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_info *uinfo)
44{
45 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
46 struct alc_spec *spec = codec->spec;
47 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
48 spec->num_channel_mode);
49}
50
51static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
52 struct snd_ctl_elem_value *ucontrol)
53{
54 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
55 struct alc_spec *spec = codec->spec;
56 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
57 spec->num_channel_mode,
58 spec->ext_channel_count);
59}
60
61static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65 struct alc_spec *spec = codec->spec;
66 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
67 spec->num_channel_mode,
68 &spec->ext_channel_count);
69 if (err >= 0 && !spec->const_channel_count) {
70 spec->multiout.max_channels = spec->ext_channel_count;
71 if (spec->need_dac_fix)
72 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
73 }
74 return err;
75}
76
77/*
78 * Control the mode of pin widget settings via the mixer. "pc" is used
79 * instead of "%" to avoid consequences of accidentally treating the % as
80 * being part of a format specifier. Maximum allowed length of a value is
81 * 63 characters plus NULL terminator.
82 *
83 * Note: some retasking pin complexes seem to ignore requests for input
84 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
85 * are requested. Therefore order this list so that this behaviour will not
86 * cause problems when mixer clients move through the enum sequentially.
87 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
88 * March 2006.
89 */
90static const char * const alc_pin_mode_names[] = {
91 "Mic 50pc bias", "Mic 80pc bias",
92 "Line in", "Line out", "Headphone out",
93};
94static const unsigned char alc_pin_mode_values[] = {
95 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
96};
97/* The control can present all 5 options, or it can limit the options based
98 * in the pin being assumed to be exclusively an input or an output pin. In
99 * addition, "input" pins may or may not process the mic bias option
100 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
101 * accept requests for bias as of chip versions up to March 2006) and/or
102 * wiring in the computer.
103 */
104#define ALC_PIN_DIR_IN 0x00
105#define ALC_PIN_DIR_OUT 0x01
106#define ALC_PIN_DIR_INOUT 0x02
107#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
108#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
109
110/* Info about the pin modes supported by the different pin direction modes.
111 * For each direction the minimum and maximum values are given.
112 */
113static const signed char alc_pin_mode_dir_info[5][2] = {
114 { 0, 2 }, /* ALC_PIN_DIR_IN */
115 { 3, 4 }, /* ALC_PIN_DIR_OUT */
116 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
117 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
118 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
119};
120#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
121#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
122#define alc_pin_mode_n_items(_dir) \
123 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
124
125static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_info *uinfo)
127{
128 unsigned int item_num = uinfo->value.enumerated.item;
129 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
130
131 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
132 uinfo->count = 1;
133 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
134
135 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
136 item_num = alc_pin_mode_min(dir);
137 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
138 return 0;
139}
140
141static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 unsigned int i;
145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
146 hda_nid_t nid = kcontrol->private_value & 0xffff;
147 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
148 long *valp = ucontrol->value.integer.value;
149 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
150 AC_VERB_GET_PIN_WIDGET_CONTROL,
151 0x00);
152
153 /* Find enumerated value for current pinctl setting */
154 i = alc_pin_mode_min(dir);
155 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
156 i++;
157 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
158 return 0;
159}
160
161static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 signed int change;
165 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166 hda_nid_t nid = kcontrol->private_value & 0xffff;
167 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
168 long val = *ucontrol->value.integer.value;
169 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
170 AC_VERB_GET_PIN_WIDGET_CONTROL,
171 0x00);
172
173 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
174 val = alc_pin_mode_min(dir);
175
176 change = pinctl != alc_pin_mode_values[val];
177 if (change) {
178 /* Set pin mode to that requested */
179 snd_hda_codec_write_cache(codec, nid, 0,
180 AC_VERB_SET_PIN_WIDGET_CONTROL,
181 alc_pin_mode_values[val]);
182
183 /* Also enable the retasking pin's input/output as required
184 * for the requested pin mode. Enum values of 2 or less are
185 * input modes.
186 *
187 * Dynamically switching the input/output buffers probably
188 * reduces noise slightly (particularly on input) so we'll
189 * do it. However, having both input and output buffers
190 * enabled simultaneously doesn't seem to be problematic if
191 * this turns out to be necessary in the future.
192 */
193 if (val <= 2) {
194 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
195 HDA_AMP_MUTE, HDA_AMP_MUTE);
196 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
197 HDA_AMP_MUTE, 0);
198 } else {
199 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
200 HDA_AMP_MUTE, HDA_AMP_MUTE);
201 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
202 HDA_AMP_MUTE, 0);
203 }
204 }
205 return change;
206}
207
208#define ALC_PIN_MODE(xname, nid, dir) \
209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
210 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
211 .info = alc_pin_mode_info, \
212 .get = alc_pin_mode_get, \
213 .put = alc_pin_mode_put, \
214 .private_value = nid | (dir<<16) }
215
216/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
217 * together using a mask with more than one bit set. This control is
218 * currently used only by the ALC260 test model. At this stage they are not
219 * needed for any "production" models.
220 */
221#ifdef CONFIG_SND_DEBUG
222#define alc_gpio_data_info snd_ctl_boolean_mono_info
223
224static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228 hda_nid_t nid = kcontrol->private_value & 0xffff;
229 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
230 long *valp = ucontrol->value.integer.value;
231 unsigned int val = snd_hda_codec_read(codec, nid, 0,
232 AC_VERB_GET_GPIO_DATA, 0x00);
233
234 *valp = (val & mask) != 0;
235 return 0;
236}
237static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 signed int change;
241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
242 hda_nid_t nid = kcontrol->private_value & 0xffff;
243 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
244 long val = *ucontrol->value.integer.value;
245 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
246 AC_VERB_GET_GPIO_DATA,
247 0x00);
248
249 /* Set/unset the masked GPIO bit(s) as needed */
250 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
251 if (val == 0)
252 gpio_data &= ~mask;
253 else
254 gpio_data |= mask;
255 snd_hda_codec_write_cache(codec, nid, 0,
256 AC_VERB_SET_GPIO_DATA, gpio_data);
257
258 return change;
259}
260#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
261 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
262 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
263 .info = alc_gpio_data_info, \
264 .get = alc_gpio_data_get, \
265 .put = alc_gpio_data_put, \
266 .private_value = nid | (mask<<16) }
267#endif /* CONFIG_SND_DEBUG */
268
269/* A switch control to allow the enabling of the digital IO pins on the
270 * ALC260. This is incredibly simplistic; the intention of this control is
271 * to provide something in the test model allowing digital outputs to be
272 * identified if present. If models are found which can utilise these
273 * outputs a more complete mixer control can be devised for those models if
274 * necessary.
275 */
276#ifdef CONFIG_SND_DEBUG
277#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
278
279static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 hda_nid_t nid = kcontrol->private_value & 0xffff;
284 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
285 long *valp = ucontrol->value.integer.value;
286 unsigned int val = snd_hda_codec_read(codec, nid, 0,
287 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
288
289 *valp = (val & mask) != 0;
290 return 0;
291}
292static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 signed int change;
296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297 hda_nid_t nid = kcontrol->private_value & 0xffff;
298 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
299 long val = *ucontrol->value.integer.value;
300 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
301 AC_VERB_GET_DIGI_CONVERT_1,
302 0x00);
303
304 /* Set/unset the masked control bit(s) as needed */
305 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
306 if (val==0)
307 ctrl_data &= ~mask;
308 else
309 ctrl_data |= mask;
310 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
311 ctrl_data);
312
313 return change;
314}
315#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
317 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
318 .info = alc_spdif_ctrl_info, \
319 .get = alc_spdif_ctrl_get, \
320 .put = alc_spdif_ctrl_put, \
321 .private_value = nid | (mask<<16) }
322#endif /* CONFIG_SND_DEBUG */
323
324/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
325 * Again, this is only used in the ALC26x test models to help identify when
326 * the EAPD line must be asserted for features to work.
327 */
328#ifdef CONFIG_SND_DEBUG
329#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
330
331static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_value *ucontrol)
333{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 hda_nid_t nid = kcontrol->private_value & 0xffff;
336 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
337 long *valp = ucontrol->value.integer.value;
338 unsigned int val = snd_hda_codec_read(codec, nid, 0,
339 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
340
341 *valp = (val & mask) != 0;
342 return 0;
343}
344
345static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347{
348 int change;
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 hda_nid_t nid = kcontrol->private_value & 0xffff;
351 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
352 long val = *ucontrol->value.integer.value;
353 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_EAPD_BTLENABLE,
355 0x00);
356
357 /* Set/unset the masked control bit(s) as needed */
358 change = (!val ? 0 : mask) != (ctrl_data & mask);
359 if (!val)
360 ctrl_data &= ~mask;
361 else
362 ctrl_data |= mask;
363 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
364 ctrl_data);
365
366 return change;
367}
368
369#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
370 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
371 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
372 .info = alc_eapd_ctrl_info, \
373 .get = alc_eapd_ctrl_get, \
374 .put = alc_eapd_ctrl_put, \
375 .private_value = nid | (mask<<16) }
376#endif /* CONFIG_SND_DEBUG */
377
378static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
379{
380 struct alc_spec *spec = codec->spec;
381 struct auto_pin_cfg *cfg = &spec->autocfg;
382
383 if (!cfg->line_outs) {
384 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
385 cfg->line_out_pins[cfg->line_outs])
386 cfg->line_outs++;
387 }
388 if (!cfg->speaker_outs) {
389 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
390 cfg->speaker_pins[cfg->speaker_outs])
391 cfg->speaker_outs++;
392 }
393 if (!cfg->hp_outs) {
394 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
395 cfg->hp_pins[cfg->hp_outs])
396 cfg->hp_outs++;
397 }
398}
399
400/*
401 * set up from the preset table
402 */
403static void setup_preset(struct hda_codec *codec,
404 const struct alc_config_preset *preset)
405{
406 struct alc_spec *spec = codec->spec;
407 int i;
408
409 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
410 add_mixer(spec, preset->mixers[i]);
411 spec->cap_mixer = preset->cap_mixer;
412 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
413 i++)
414 add_verb(spec, preset->init_verbs[i]);
415
416 spec->channel_mode = preset->channel_mode;
417 spec->num_channel_mode = preset->num_channel_mode;
418 spec->need_dac_fix = preset->need_dac_fix;
419 spec->const_channel_count = preset->const_channel_count;
420
421 if (preset->const_channel_count)
422 spec->multiout.max_channels = preset->const_channel_count;
423 else
424 spec->multiout.max_channels = spec->channel_mode[0].channels;
425 spec->ext_channel_count = spec->channel_mode[0].channels;
426
427 spec->multiout.num_dacs = preset->num_dacs;
428 spec->multiout.dac_nids = preset->dac_nids;
429 spec->multiout.dig_out_nid = preset->dig_out_nid;
430 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
431 spec->multiout.hp_nid = preset->hp_nid;
432
433 spec->num_mux_defs = preset->num_mux_defs;
434 if (!spec->num_mux_defs)
435 spec->num_mux_defs = 1;
436 spec->input_mux = preset->input_mux;
437
438 spec->num_adc_nids = preset->num_adc_nids;
439 spec->adc_nids = preset->adc_nids;
440 spec->capsrc_nids = preset->capsrc_nids;
441 spec->dig_in_nid = preset->dig_in_nid;
442
443 spec->unsol_event = preset->unsol_event;
444 spec->init_hook = preset->init_hook;
445#ifdef CONFIG_SND_HDA_POWER_SAVE
446 spec->power_hook = preset->power_hook;
447 spec->loopback.amplist = preset->loopbacks;
448#endif
449
450 if (preset->setup)
451 preset->setup(codec);
452
453 alc_fixup_autocfg_pin_nums(codec);
454}
455
456static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
457{
458 int lo_pin = spec->autocfg.line_out_pins[0];
459
460 if (lo_pin == spec->autocfg.speaker_pins[0] ||
461 lo_pin == spec->autocfg.hp_pins[0])
462 lo_pin = 0;
463 spec->automute_mode = mode;
464 spec->detect_hp = !!spec->autocfg.hp_pins[0];
465 spec->detect_lo = !!lo_pin;
466 spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
467 spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
468}
469
470/* auto-toggle front mic */
471static void alc88x_simple_mic_automute(struct hda_codec *codec)
472{
473 unsigned int present;
474 unsigned char bits;
475
476 present = snd_hda_jack_detect(codec, 0x18);
477 bits = present ? HDA_AMP_MUTE : 0;
478 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
479}
480
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 684307372d73..7a8fcc4c15f8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/mm.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -2304,7 +2305,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
2304 2305
2305/* apply the function to all matching slave ctls in the mixer list */ 2306/* apply the function to all matching slave ctls in the mixer list */
2306static int map_slaves(struct hda_codec *codec, const char * const *slaves, 2307static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2307 map_slave_func_t func, void *data) 2308 const char *suffix, map_slave_func_t func, void *data)
2308{ 2309{
2309 struct hda_nid_item *items; 2310 struct hda_nid_item *items;
2310 const char * const *s; 2311 const char * const *s;
@@ -2317,7 +2318,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2317 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) 2318 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
2318 continue; 2319 continue;
2319 for (s = slaves; *s; s++) { 2320 for (s = slaves; *s; s++) {
2320 if (!strcmp(sctl->id.name, *s)) { 2321 char tmpname[sizeof(sctl->id.name)];
2322 const char *name = *s;
2323 if (suffix) {
2324 snprintf(tmpname, sizeof(tmpname), "%s %s",
2325 name, suffix);
2326 name = tmpname;
2327 }
2328 if (!strcmp(sctl->id.name, name)) {
2321 err = func(data, sctl); 2329 err = func(data, sctl);
2322 if (err) 2330 if (err)
2323 return err; 2331 return err;
@@ -2333,12 +2341,65 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2333 return 1; 2341 return 1;
2334} 2342}
2335 2343
2344/* guess the value corresponding to 0dB */
2345static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
2346{
2347 int _tlv[4];
2348 const int *tlv = NULL;
2349 int val = -1;
2350
2351 if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
2352 /* FIXME: set_fs() hack for obtaining user-space TLV data */
2353 mm_segment_t fs = get_fs();
2354 set_fs(get_ds());
2355 if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
2356 tlv = _tlv;
2357 set_fs(fs);
2358 } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
2359 tlv = kctl->tlv.p;
2360 if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE)
2361 val = -tlv[2] / tlv[3];
2362 return val;
2363}
2364
2365/* call kctl->put with the given value(s) */
2366static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
2367{
2368 struct snd_ctl_elem_value *ucontrol;
2369 ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
2370 if (!ucontrol)
2371 return -ENOMEM;
2372 ucontrol->value.integer.value[0] = val;
2373 ucontrol->value.integer.value[1] = val;
2374 kctl->put(kctl, ucontrol);
2375 kfree(ucontrol);
2376 return 0;
2377}
2378
2379/* initialize the slave volume with 0dB */
2380static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
2381{
2382 int offset = get_kctl_0dB_offset(slave);
2383 if (offset > 0)
2384 put_kctl_with_value(slave, offset);
2385 return 0;
2386}
2387
2388/* unmute the slave */
2389static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
2390{
2391 return put_kctl_with_value(slave, 1);
2392}
2393
2336/** 2394/**
2337 * snd_hda_add_vmaster - create a virtual master control and add slaves 2395 * snd_hda_add_vmaster - create a virtual master control and add slaves
2338 * @codec: HD-audio codec 2396 * @codec: HD-audio codec
2339 * @name: vmaster control name 2397 * @name: vmaster control name
2340 * @tlv: TLV data (optional) 2398 * @tlv: TLV data (optional)
2341 * @slaves: slave control names (optional) 2399 * @slaves: slave control names (optional)
2400 * @suffix: suffix string to each slave name (optional)
2401 * @init_slave_vol: initialize slaves to unmute/0dB
2402 * @ctl_ret: store the vmaster kcontrol in return
2342 * 2403 *
2343 * Create a virtual master control with the given name. The TLV data 2404 * Create a virtual master control with the given name. The TLV data
2344 * must be either NULL or a valid data. 2405 * must be either NULL or a valid data.
@@ -2349,13 +2410,18 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2349 * 2410 *
2350 * This function returns zero if successful or a negative error code. 2411 * This function returns zero if successful or a negative error code.
2351 */ 2412 */
2352int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 2413int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2353 unsigned int *tlv, const char * const *slaves) 2414 unsigned int *tlv, const char * const *slaves,
2415 const char *suffix, bool init_slave_vol,
2416 struct snd_kcontrol **ctl_ret)
2354{ 2417{
2355 struct snd_kcontrol *kctl; 2418 struct snd_kcontrol *kctl;
2356 int err; 2419 int err;
2357 2420
2358 err = map_slaves(codec, slaves, check_slave_present, NULL); 2421 if (ctl_ret)
2422 *ctl_ret = NULL;
2423
2424 err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
2359 if (err != 1) { 2425 if (err != 1) {
2360 snd_printdd("No slave found for %s\n", name); 2426 snd_printdd("No slave found for %s\n", name);
2361 return 0; 2427 return 0;
@@ -2367,13 +2433,119 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2367 if (err < 0) 2433 if (err < 0)
2368 return err; 2434 return err;
2369 2435
2370 err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, 2436 err = map_slaves(codec, slaves, suffix,
2371 kctl); 2437 (map_slave_func_t)snd_ctl_add_slave, kctl);
2372 if (err < 0) 2438 if (err < 0)
2373 return err; 2439 return err;
2440
2441 /* init with master mute & zero volume */
2442 put_kctl_with_value(kctl, 0);
2443 if (init_slave_vol)
2444 map_slaves(codec, slaves, suffix,
2445 tlv ? init_slave_0dB : init_slave_unmute, kctl);
2446
2447 if (ctl_ret)
2448 *ctl_ret = kctl;
2374 return 0; 2449 return 0;
2375} 2450}
2376EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 2451EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster);
2452
2453/*
2454 * mute-LED control using vmaster
2455 */
2456static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_info *uinfo)
2458{
2459 static const char * const texts[] = {
2460 "Off", "On", "Follow Master"
2461 };
2462 unsigned int index;
2463
2464 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2465 uinfo->count = 1;
2466 uinfo->value.enumerated.items = 3;
2467 index = uinfo->value.enumerated.item;
2468 if (index >= 3)
2469 index = 2;
2470 strcpy(uinfo->value.enumerated.name, texts[index]);
2471 return 0;
2472}
2473
2474static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
2475 struct snd_ctl_elem_value *ucontrol)
2476{
2477 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2478 ucontrol->value.enumerated.item[0] = hook->mute_mode;
2479 return 0;
2480}
2481
2482static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_value *ucontrol)
2484{
2485 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2486 unsigned int old_mode = hook->mute_mode;
2487
2488 hook->mute_mode = ucontrol->value.enumerated.item[0];
2489 if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
2490 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2491 if (old_mode == hook->mute_mode)
2492 return 0;
2493 snd_hda_sync_vmaster_hook(hook);
2494 return 1;
2495}
2496
2497static struct snd_kcontrol_new vmaster_mute_mode = {
2498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499 .name = "Mute-LED Mode",
2500 .info = vmaster_mute_mode_info,
2501 .get = vmaster_mute_mode_get,
2502 .put = vmaster_mute_mode_put,
2503};
2504
2505/*
2506 * Add a mute-LED hook with the given vmaster switch kctl
2507 * "Mute-LED Mode" control is automatically created and associated with
2508 * the given hook.
2509 */
2510int snd_hda_add_vmaster_hook(struct hda_codec *codec,
2511 struct hda_vmaster_mute_hook *hook,
2512 bool expose_enum_ctl)
2513{
2514 struct snd_kcontrol *kctl;
2515
2516 if (!hook->hook || !hook->sw_kctl)
2517 return 0;
2518 snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
2519 hook->codec = codec;
2520 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2521 if (!expose_enum_ctl)
2522 return 0;
2523 kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
2524 if (!kctl)
2525 return -ENOMEM;
2526 return snd_hda_ctl_add(codec, 0, kctl);
2527}
2528EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook);
2529
2530/*
2531 * Call the hook with the current value for synchronization
2532 * Should be called in init callback
2533 */
2534void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
2535{
2536 if (!hook->hook || !hook->codec)
2537 return;
2538 switch (hook->mute_mode) {
2539 case HDA_VMUTE_FOLLOW_MASTER:
2540 snd_ctl_sync_vmaster_hook(hook->sw_kctl);
2541 break;
2542 default:
2543 hook->hook(hook->codec, hook->mute_mode);
2544 break;
2545 }
2546}
2547EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook);
2548
2377 2549
2378/** 2550/**
2379 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch 2551 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
@@ -5272,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus)
5272 list_for_each_entry(codec, &bus->codec_list, list) { 5444 list_for_each_entry(codec, &bus->codec_list, list) {
5273 if (hda_codec_is_power_on(codec)) 5445 if (hda_codec_is_power_on(codec))
5274 hda_call_codec_suspend(codec); 5446 hda_call_codec_suspend(codec);
5447 else /* forcibly change the power to D3 even if not used */
5448 hda_set_power_state(codec,
5449 codec->afg ? codec->afg : codec->mfg,
5450 AC_PWRST_D3);
5275 if (codec->patch_ops.post_suspend) 5451 if (codec->patch_ops.post_suspend)
5276 codec->patch_ops.post_suspend(codec); 5452 codec->patch_ops.post_suspend(codec);
5277 } 5453 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f0f1943a4b2c..9a9f372e1be4 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -855,6 +855,7 @@ struct hda_codec {
855 unsigned int pins_shutup:1; /* pins are shut up */ 855 unsigned int pins_shutup:1; /* pins are shut up */
856 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 856 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
857 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ 857 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
858 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
858#ifdef CONFIG_SND_HDA_POWER_SAVE 859#ifdef CONFIG_SND_HDA_POWER_SAVE
859 unsigned int power_on :1; /* current (global) power-state */ 860 unsigned int power_on :1; /* current (global) power-state */
860 unsigned int power_transition :1; /* power-state in transition */ 861 unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index c1da422e085a..b58b4b1687fa 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -385,8 +385,8 @@ error:
385static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) 385static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
386{ 386{
387 static unsigned int alsa_rates[] = { 387 static unsigned int alsa_rates[] = {
388 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 388 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
389 96000, 176400, 192000, 384000 389 88200, 96000, 176400, 192000, 384000
390 }; 390 };
391 int i, j; 391 int i, j;
392 392
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 95dfb6874941..c19e71a94e1b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -84,7 +84,7 @@ module_param_array(model, charp, NULL, 0444);
84MODULE_PARM_DESC(model, "Use the given board model."); 84MODULE_PARM_DESC(model, "Use the given board model.");
85module_param_array(position_fix, int, NULL, 0444); 85module_param_array(position_fix, int, NULL, 0444);
86MODULE_PARM_DESC(position_fix, "DMA pointer read method." 86MODULE_PARM_DESC(position_fix, "DMA pointer read method."
87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO)."); 87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
88module_param_array(bdl_pos_adj, int, NULL, 0644); 88module_param_array(bdl_pos_adj, int, NULL, 0644);
89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
90module_param_array(probe_mask, int, NULL, 0444); 90module_param_array(probe_mask, int, NULL, 0444);
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
94module_param(single_cmd, bool, 0444); 94module_param(single_cmd, bool, 0444);
95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
96 "(for debugging only)."); 96 "(for debugging only).");
97module_param(enable_msi, int, 0444); 97module_param(enable_msi, bint, 0444);
98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
99#ifdef CONFIG_SND_HDA_PATCH_LOADER 99#ifdef CONFIG_SND_HDA_PATCH_LOADER
100module_param_array(patch, charp, NULL, 0444); 100module_param_array(patch, charp, NULL, 0444);
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644);
121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); 121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
122#endif 122#endif
123 123
124static bool align_buffer_size = 1; 124static int align_buffer_size = -1;
125module_param(align_buffer_size, bool, 0644); 125module_param(align_buffer_size, bint, 0644);
126MODULE_PARM_DESC(align_buffer_size, 126MODULE_PARM_DESC(align_buffer_size,
127 "Force buffer and period sizes to be multiple of 128 bytes."); 127 "Force buffer and period sizes to be multiple of 128 bytes.");
128 128
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
148 "{Intel, PCH}," 148 "{Intel, PCH},"
149 "{Intel, CPT}," 149 "{Intel, CPT},"
150 "{Intel, PPT}," 150 "{Intel, PPT},"
151 "{Intel, LPT},"
151 "{Intel, PBG}," 152 "{Intel, PBG},"
152 "{Intel, SCH}," 153 "{Intel, SCH},"
153 "{ATI, SB450}," 154 "{ATI, SB450},"
@@ -329,6 +330,7 @@ enum {
329 POS_FIX_LPIB, 330 POS_FIX_LPIB,
330 POS_FIX_POSBUF, 331 POS_FIX_POSBUF,
331 POS_FIX_VIACOMBO, 332 POS_FIX_VIACOMBO,
333 POS_FIX_COMBO,
332}; 334};
333 335
334/* Defines for ATI HD Audio support in SB450 south bridge */ 336/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -515,6 +517,7 @@ enum {
515#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 517#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
516#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ 518#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
517#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ 519#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
520#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
518 521
519/* quirks for ATI SB / AMD Hudson */ 522/* quirks for ATI SB / AMD Hudson */
520#define AZX_DCAPS_PRESET_ATI_SB \ 523#define AZX_DCAPS_PRESET_ATI_SB \
@@ -527,7 +530,8 @@ enum {
527 530
528/* quirks for Nvidia */ 531/* quirks for Nvidia */
529#define AZX_DCAPS_PRESET_NVIDIA \ 532#define AZX_DCAPS_PRESET_NVIDIA \
530 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) 533 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
534 AZX_DCAPS_ALIGN_BUFSIZE)
531 535
532static char *driver_short_names[] __devinitdata = { 536static char *driver_short_names[] __devinitdata = {
533 [AZX_DRIVER_ICH] = "HDA Intel", 537 [AZX_DRIVER_ICH] = "HDA Intel",
@@ -2347,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
2347 * power management 2351 * power management
2348 */ 2352 */
2349 2353
2350static int snd_hda_codecs_inuse(struct hda_bus *bus)
2351{
2352 struct hda_codec *codec;
2353
2354 list_for_each_entry(codec, &bus->codec_list, list) {
2355 if (snd_hda_codec_needs_resume(codec))
2356 return 1;
2357 }
2358 return 0;
2359}
2360
2361static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2354static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2362{ 2355{
2363 struct snd_card *card = pci_get_drvdata(pci); 2356 struct snd_card *card = pci_get_drvdata(pci);
@@ -2404,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci)
2404 return -EIO; 2397 return -EIO;
2405 azx_init_pci(chip); 2398 azx_init_pci(chip);
2406 2399
2407 if (snd_hda_codecs_inuse(chip->bus)) 2400 azx_init_chip(chip, 1);
2408 azx_init_chip(chip, 1);
2409 2401
2410 snd_hda_resume(chip->bus); 2402 snd_hda_resume(chip->bus);
2411 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2403 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2517,6 +2509,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2517 case POS_FIX_LPIB: 2509 case POS_FIX_LPIB:
2518 case POS_FIX_POSBUF: 2510 case POS_FIX_POSBUF:
2519 case POS_FIX_VIACOMBO: 2511 case POS_FIX_VIACOMBO:
2512 case POS_FIX_COMBO:
2520 return fix; 2513 return fix;
2521 } 2514 }
2522 2515
@@ -2696,6 +2689,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2696 2689
2697 chip->position_fix[0] = chip->position_fix[1] = 2690 chip->position_fix[0] = chip->position_fix[1] =
2698 check_position_fix(chip, position_fix[dev]); 2691 check_position_fix(chip, position_fix[dev]);
2692 /* combo mode uses LPIB for playback */
2693 if (chip->position_fix[0] == POS_FIX_COMBO) {
2694 chip->position_fix[0] = POS_FIX_LPIB;
2695 chip->position_fix[1] = POS_FIX_AUTO;
2696 }
2697
2699 check_probe_mask(chip, dev); 2698 check_probe_mask(chip, dev);
2700 2699
2701 chip->single_cmd = single_cmd; 2700 chip->single_cmd = single_cmd;
@@ -2774,9 +2773,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2774 } 2773 }
2775 2774
2776 /* disable buffer size rounding to 128-byte multiples if supported */ 2775 /* disable buffer size rounding to 128-byte multiples if supported */
2777 chip->align_buffer_size = align_buffer_size; 2776 if (align_buffer_size >= 0)
2778 if (chip->driver_caps & AZX_DCAPS_BUFSIZE) 2777 chip->align_buffer_size = !!align_buffer_size;
2779 chip->align_buffer_size = 0; 2778 else {
2779 if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
2780 chip->align_buffer_size = 0;
2781 else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
2782 chip->align_buffer_size = 1;
2783 else
2784 chip->align_buffer_size = 1;
2785 }
2780 2786
2781 /* allow 64bit DMA address if supported by H/W */ 2787 /* allow 64bit DMA address if supported by H/W */
2782 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2788 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2992,6 +2998,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2992 { PCI_DEVICE(0x8086, 0x1e20), 2998 { PCI_DEVICE(0x8086, 0x1e20),
2993 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 2999 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2994 AZX_DCAPS_BUFSIZE}, 3000 AZX_DCAPS_BUFSIZE},
3001 /* Lynx Point */
3002 { PCI_DEVICE(0x8086, 0x8c20),
3003 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3004 AZX_DCAPS_BUFSIZE},
2995 /* SCH */ 3005 /* SCH */
2996 { PCI_DEVICE(0x8086, 0x811b), 3006 { PCI_DEVICE(0x8086, 0x811b),
2997 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3007 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9d819c4b4923..d68948499fbc 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -19,6 +19,22 @@
19#include "hda_local.h" 19#include "hda_local.h"
20#include "hda_jack.h" 20#include "hda_jack.h"
21 21
22bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
23{
24 if (codec->no_jack_detect)
25 return false;
26 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
27 return false;
28 if (!codec->ignore_misc_bit &&
29 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
30 AC_DEFCFG_MISC_NO_PRESENCE))
31 return false;
32 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
33 return false;
34 return true;
35}
36EXPORT_SYMBOL_HDA(is_jack_detectable);
37
22/* execute pin sense measurement */ 38/* execute pin sense measurement */
23static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 39static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
24{ 40{
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index f8f97c71c9c1..c66655cf413a 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
64 64
65static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) 65bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
66{
67 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
68 return false;
69 if (!codec->ignore_misc_bit &&
70 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
71 AC_DEFCFG_MISC_NO_PRESENCE))
72 return false;
73 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
74 return false;
75 return true;
76}
77 66
78int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 67int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
79 const char *name, int idx); 68 const char *name, int idx);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index aca8d3193b95..0ec9248165bc 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -139,10 +139,36 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
139 unsigned int *tlv); 139 unsigned int *tlv);
140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
141 const char *name); 141 const char *name);
142int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 142int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
143 unsigned int *tlv, const char * const *slaves); 143 unsigned int *tlv, const char * const *slaves,
144 const char *suffix, bool init_slave_vol,
145 struct snd_kcontrol **ctl_ret);
146#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
147 __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
144int snd_hda_codec_reset(struct hda_codec *codec); 148int snd_hda_codec_reset(struct hda_codec *codec);
145 149
150enum {
151 HDA_VMUTE_OFF,
152 HDA_VMUTE_ON,
153 HDA_VMUTE_FOLLOW_MASTER,
154};
155
156struct hda_vmaster_mute_hook {
157 /* below two fields must be filled by the caller of
158 * snd_hda_add_vmaster_hook() beforehand
159 */
160 struct snd_kcontrol *sw_kctl;
161 void (*hook)(void *, int);
162 /* below are initialized automatically */
163 unsigned int mute_mode; /* HDA_VMUTE_XXX */
164 struct hda_codec *codec;
165};
166
167int snd_hda_add_vmaster_hook(struct hda_codec *codec,
168 struct hda_vmaster_mute_hook *hook,
169 bool expose_enum_ctl);
170void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
171
146/* amp value bits */ 172/* amp value bits */
147#define HDA_AMP_MUTE 0x80 173#define HDA_AMP_MUTE 0x80
148#define HDA_AMP_UNMUTE 0x00 174#define HDA_AMP_UNMUTE 0x00
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 9cb14b42dfff..7143393927da 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -82,6 +82,7 @@ struct ad198x_spec {
82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */ 82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */ 83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */
84 unsigned int analog_beep: 1; /* analog beep input present */ 84 unsigned int analog_beep: 1; /* analog beep input present */
85 unsigned int avoid_init_slave_vol:1;
85 86
86#ifdef CONFIG_SND_HDA_POWER_SAVE 87#ifdef CONFIG_SND_HDA_POWER_SAVE
87 struct hda_loopback_check loopback; 88 struct hda_loopback_check loopback;
@@ -137,51 +138,17 @@ static int ad198x_init(struct hda_codec *codec)
137 return 0; 138 return 0;
138} 139}
139 140
140static const char * const ad_slave_vols[] = { 141static const char * const ad_slave_pfxs[] = {
141 "Front Playback Volume", 142 "Front", "Surround", "Center", "LFE", "Side",
142 "Surround Playback Volume", 143 "Headphone", "Mono", "Speaker", "IEC958",
143 "Center Playback Volume",
144 "LFE Playback Volume",
145 "Side Playback Volume",
146 "Headphone Playback Volume",
147 "Mono Playback Volume",
148 "Speaker Playback Volume",
149 "IEC958 Playback Volume",
150 NULL 144 NULL
151}; 145};
152 146
153static const char * const ad_slave_sws[] = { 147static const char * const ad1988_6stack_fp_slave_pfxs[] = {
154 "Front Playback Switch", 148 "Front", "Surround", "Center", "LFE", "Side", "IEC958",
155 "Surround Playback Switch",
156 "Center Playback Switch",
157 "LFE Playback Switch",
158 "Side Playback Switch",
159 "Headphone Playback Switch",
160 "Mono Playback Switch",
161 "Speaker Playback Switch",
162 "IEC958 Playback Switch",
163 NULL 149 NULL
164}; 150};
165 151
166static const char * const ad1988_6stack_fp_slave_vols[] = {
167 "Front Playback Volume",
168 "Surround Playback Volume",
169 "Center Playback Volume",
170 "LFE Playback Volume",
171 "Side Playback Volume",
172 "IEC958 Playback Volume",
173 NULL
174};
175
176static const char * const ad1988_6stack_fp_slave_sws[] = {
177 "Front Playback Switch",
178 "Surround Playback Switch",
179 "Center Playback Switch",
180 "LFE Playback Switch",
181 "Side Playback Switch",
182 "IEC958 Playback Switch",
183 NULL
184};
185static void ad198x_free_kctls(struct hda_codec *codec); 152static void ad198x_free_kctls(struct hda_codec *codec);
186 153
187#ifdef CONFIG_SND_HDA_INPUT_BEEP 154#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -257,10 +224,12 @@ static int ad198x_build_controls(struct hda_codec *codec)
257 unsigned int vmaster_tlv[4]; 224 unsigned int vmaster_tlv[4];
258 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 225 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
259 HDA_OUTPUT, vmaster_tlv); 226 HDA_OUTPUT, vmaster_tlv);
260 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 227 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
261 vmaster_tlv, 228 vmaster_tlv,
262 (spec->slave_vols ? 229 (spec->slave_vols ?
263 spec->slave_vols : ad_slave_vols)); 230 spec->slave_vols : ad_slave_pfxs),
231 "Playback Volume",
232 !spec->avoid_init_slave_vol, NULL);
264 if (err < 0) 233 if (err < 0)
265 return err; 234 return err;
266 } 235 }
@@ -268,7 +237,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
268 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 237 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
269 NULL, 238 NULL,
270 (spec->slave_sws ? 239 (spec->slave_sws ?
271 spec->slave_sws : ad_slave_sws)); 240 spec->slave_sws : ad_slave_pfxs),
241 "Playback Switch");
272 if (err < 0) 242 if (err < 0)
273 return err; 243 return err;
274 } 244 }
@@ -3385,8 +3355,8 @@ static int patch_ad1988(struct hda_codec *codec)
3385 3355
3386 if (spec->autocfg.hp_pins[0]) { 3356 if (spec->autocfg.hp_pins[0]) {
3387 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; 3357 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
3388 spec->slave_vols = ad1988_6stack_fp_slave_vols; 3358 spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
3389 spec->slave_sws = ad1988_6stack_fp_slave_sws; 3359 spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
3390 spec->alt_dac_nid = ad1988_alt_dac_nid; 3360 spec->alt_dac_nid = ad1988_alt_dac_nid;
3391 spec->stream_analog_alt_playback = 3361 spec->stream_analog_alt_playback =
3392 &ad198x_pcm_analog_alt_playback; 3362 &ad198x_pcm_analog_alt_playback;
@@ -3594,16 +3564,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
3594#endif 3564#endif
3595 3565
3596static const char * const ad1884_slave_vols[] = { 3566static const char * const ad1884_slave_vols[] = {
3597 "PCM Playback Volume", 3567 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3598 "Mic Playback Volume", 3568 "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
3599 "Mono Playback Volume",
3600 "Front Mic Playback Volume",
3601 "Mic Playback Volume",
3602 "CD Playback Volume",
3603 "Internal Mic Playback Volume",
3604 "Docking Mic Playback Volume",
3605 /* "Beep Playback Volume", */
3606 "IEC958 Playback Volume",
3607 NULL 3569 NULL
3608}; 3570};
3609 3571
@@ -3644,6 +3606,8 @@ static int patch_ad1884(struct hda_codec *codec)
3644 spec->vmaster_nid = 0x04; 3606 spec->vmaster_nid = 0x04;
3645 /* we need to cover all playback volumes */ 3607 /* we need to cover all playback volumes */
3646 spec->slave_vols = ad1884_slave_vols; 3608 spec->slave_vols = ad1884_slave_vols;
3609 /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3610 spec->avoid_init_slave_vol = 1;
3647 3611
3648 codec->patch_ops = ad198x_patch_ops; 3612 codec->patch_ops = ad198x_patch_ops;
3649 3613
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index d29d6d377904..8c6523bbc797 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -70,6 +70,8 @@ struct conexant_spec {
70 const struct snd_kcontrol_new *mixers[5]; 70 const struct snd_kcontrol_new *mixers[5];
71 int num_mixers; 71 int num_mixers;
72 hda_nid_t vmaster_nid; 72 hda_nid_t vmaster_nid;
73 struct hda_vmaster_mute_hook vmaster_mute;
74 bool vmaster_mute_led;
73 75
74 const struct hda_verb *init_verbs[5]; /* initialization verbs 76 const struct hda_verb *init_verbs[5]; /* initialization verbs
75 * don't forget NULL 77 * don't forget NULL
@@ -465,21 +467,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = {
465}; 467};
466#endif 468#endif
467 469
468static const char * const slave_vols[] = { 470static const char * const slave_pfxs[] = {
469 "Headphone Playback Volume", 471 "Headphone", "Speaker", "Front", "Surround", "CLFE",
470 "Speaker Playback Volume",
471 "Front Playback Volume",
472 "Surround Playback Volume",
473 "CLFE Playback Volume",
474 NULL
475};
476
477static const char * const slave_sws[] = {
478 "Headphone Playback Switch",
479 "Speaker Playback Switch",
480 "Front Playback Switch",
481 "Surround Playback Switch",
482 "CLFE Playback Switch",
483 NULL 472 NULL
484}; 473};
485 474
@@ -519,14 +508,17 @@ static int conexant_build_controls(struct hda_codec *codec)
519 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 508 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
520 HDA_OUTPUT, vmaster_tlv); 509 HDA_OUTPUT, vmaster_tlv);
521 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 510 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
522 vmaster_tlv, slave_vols); 511 vmaster_tlv, slave_pfxs,
512 "Playback Volume");
523 if (err < 0) 513 if (err < 0)
524 return err; 514 return err;
525 } 515 }
526 if (spec->vmaster_nid && 516 if (spec->vmaster_nid &&
527 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 517 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
528 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 518 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
529 NULL, slave_sws); 519 NULL, slave_pfxs,
520 "Playback Switch", true,
521 &spec->vmaster_mute.sw_kctl);
530 if (err < 0) 522 if (err < 0)
531 return err; 523 return err;
532 } 524 }
@@ -1643,7 +1635,7 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1643 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1635 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1644 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1636 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1645 pinctl); 1637 pinctl);
1646 /* on ideapad there is an aditional speaker (subwoofer) to mute */ 1638 /* on ideapad there is an additional speaker (subwoofer) to mute */
1647 if (spec->ideapad) 1639 if (spec->ideapad)
1648 snd_hda_codec_write(codec, 0x1b, 0, 1640 snd_hda_codec_write(codec, 0x1b, 0,
1649 AC_VERB_SET_PIN_WIDGET_CONTROL, 1641 AC_VERB_SET_PIN_WIDGET_CONTROL,
@@ -3034,7 +3026,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3034 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 3026 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3035 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 3027 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3036 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), 3028 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3037 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3038 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), 3029 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3039 {} 3030 {}
3040}; 3031};
@@ -3943,6 +3934,63 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3943 snd_hda_jack_detect_enable(codec, pins[i], action); 3934 snd_hda_jack_detect_enable(codec, pins[i], action);
3944} 3935}
3945 3936
3937static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3938{
3939 int i;
3940 for (i = 0; i < nums; i++)
3941 if (list[i] == nid)
3942 return true;
3943 return false;
3944}
3945
3946/* is the given NID found in any of autocfg items? */
3947static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
3948{
3949 int i;
3950
3951 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3952 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3953 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
3954 found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
3955 return true;
3956 for (i = 0; i < cfg->num_inputs; i++)
3957 if (cfg->inputs[i].pin == nid)
3958 return true;
3959 if (cfg->dig_in_pin == nid)
3960 return true;
3961 return false;
3962}
3963
3964/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
3965 * invalid unsol tags by some reason
3966 */
3967static void clear_unsol_on_unused_pins(struct hda_codec *codec)
3968{
3969 struct conexant_spec *spec = codec->spec;
3970 struct auto_pin_cfg *cfg = &spec->autocfg;
3971 int i;
3972
3973 for (i = 0; i < codec->init_pins.used; i++) {
3974 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
3975 if (!found_in_autocfg(cfg, pin->nid))
3976 snd_hda_codec_write(codec, pin->nid, 0,
3977 AC_VERB_SET_UNSOLICITED_ENABLE, 0);
3978 }
3979}
3980
3981/* turn on/off EAPD according to Master switch */
3982static void cx_auto_vmaster_hook(void *private_data, int enabled)
3983{
3984 struct hda_codec *codec = private_data;
3985 struct conexant_spec *spec = codec->spec;
3986
3987 if (enabled && spec->pin_eapd_ctrls) {
3988 cx_auto_update_speakers(codec);
3989 return;
3990 }
3991 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
3992}
3993
3946static void cx_auto_init_output(struct hda_codec *codec) 3994static void cx_auto_init_output(struct hda_codec *codec)
3947{ 3995{
3948 struct conexant_spec *spec = codec->spec; 3996 struct conexant_spec *spec = codec->spec;
@@ -3983,6 +4031,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3983 /* turn on all EAPDs if no individual EAPD control is available */ 4031 /* turn on all EAPDs if no individual EAPD control is available */
3984 if (!spec->pin_eapd_ctrls) 4032 if (!spec->pin_eapd_ctrls)
3985 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4033 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4034 clear_unsol_on_unused_pins(codec);
3986} 4035}
3987 4036
3988static void cx_auto_init_input(struct hda_codec *codec) 4037static void cx_auto_init_input(struct hda_codec *codec)
@@ -4046,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec)
4046 4095
4047static int cx_auto_init(struct hda_codec *codec) 4096static int cx_auto_init(struct hda_codec *codec)
4048{ 4097{
4098 struct conexant_spec *spec = codec->spec;
4049 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ 4099 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4050 cx_auto_init_output(codec); 4100 cx_auto_init_output(codec);
4051 cx_auto_init_input(codec); 4101 cx_auto_init_input(codec);
4052 cx_auto_init_digital(codec); 4102 cx_auto_init_digital(codec);
4053 snd_hda_jack_report_sync(codec); 4103 snd_hda_jack_report_sync(codec);
4104 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4054 return 0; 4105 return 0;
4055} 4106}
4056 4107
@@ -4296,6 +4347,13 @@ static int cx_auto_build_controls(struct hda_codec *codec)
4296 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 4347 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
4297 if (err < 0) 4348 if (err < 0)
4298 return err; 4349 return err;
4350 if (spec->vmaster_mute.sw_kctl) {
4351 spec->vmaster_mute.hook = cx_auto_vmaster_hook;
4352 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
4353 spec->vmaster_mute_led);
4354 if (err < 0)
4355 return err;
4356 }
4299 return 0; 4357 return 0;
4300} 4358}
4301 4359
@@ -4320,7 +4378,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec)
4320 return 0; 4378 return 0;
4321} 4379}
4322 4380
4323
4324static const struct hda_codec_ops cx_auto_patch_ops = { 4381static const struct hda_codec_ops cx_auto_patch_ops = {
4325 .build_controls = cx_auto_build_controls, 4382 .build_controls = cx_auto_build_controls,
4326 .build_pcms = conexant_build_pcms, 4383 .build_pcms = conexant_build_pcms,
@@ -4368,6 +4425,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4368 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 4425 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4369 { 0x17, 0x21a11000 }, /* dock-mic */ 4426 { 0x17, 0x21a11000 }, /* dock-mic */
4370 { 0x19, 0x2121103f }, /* dock-HP */ 4427 { 0x19, 0x2121103f }, /* dock-HP */
4428 { 0x1c, 0x21440100 }, /* dock SPDIF out */
4371 {} 4429 {}
4372}; 4430};
4373 4431
@@ -4421,6 +4479,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
4421 4479
4422 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); 4480 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4423 4481
4482 /* Show mute-led control only on HP laptops
4483 * This is a sort of white-list: on HP laptops, EAPD corresponds
4484 * only to the mute-LED without actualy amp function. Meanwhile,
4485 * others may use EAPD really as an amp switch, so it might be
4486 * not good to expose it blindly.
4487 */
4488 switch (codec->subsystem_id >> 16) {
4489 case 0x103c:
4490 spec->vmaster_mute_led = 1;
4491 break;
4492 }
4493
4424 err = cx_auto_search_adcs(codec); 4494 err = cx_auto_search_adcs(codec);
4425 if (err < 0) 4495 if (err < 0)
4426 return err; 4496 return err;
@@ -4434,6 +4504,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
4434 codec->patch_ops = cx_auto_patch_ops; 4504 codec->patch_ops = cx_auto_patch_ops;
4435 if (spec->beep_amp) 4505 if (spec->beep_amp)
4436 snd_hda_attach_beep_device(codec, spec->beep_amp); 4506 snd_hda_attach_beep_device(codec, spec->beep_amp);
4507
4508 /* Some laptops with Conexant chips show stalls in S3 resume,
4509 * which falls into the single-cmd mode.
4510 * Better to make reset, then.
4511 */
4512 if (!codec->bus->sync_write) {
4513 snd_printd("hda_codec: "
4514 "Enable sync_write for stable communication\n");
4515 codec->bus->sync_write = 1;
4516 codec->bus->allow_bus_reset = 1;
4517 }
4518
4437 return 0; 4519 return 0;
4438} 4520}
4439 4521
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1168ebd3fb5c..540cd13f7f15 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1912,6 +1912,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1916{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1916{} /* terminator */ 1917{} /* terminator */
1917}; 1918};
@@ -1958,6 +1959,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
1958MODULE_ALIAS("snd-hda-codec-id:80862804"); 1959MODULE_ALIAS("snd-hda-codec-id:80862804");
1959MODULE_ALIAS("snd-hda-codec-id:80862805"); 1960MODULE_ALIAS("snd-hda-codec-id:80862805");
1960MODULE_ALIAS("snd-hda-codec-id:80862806"); 1961MODULE_ALIAS("snd-hda-codec-id:80862806");
1962MODULE_ALIAS("snd-hda-codec-id:80862880");
1961MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1963MODULE_ALIAS("snd-hda-codec-id:808629fb");
1962 1964
1963MODULE_LICENSE("GPL"); 1965MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 22c73b78ac6f..8ea2fd654327 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -198,8 +198,11 @@ struct alc_spec {
198 198
199 /* for virtual master */ 199 /* for virtual master */
200 hda_nid_t vmaster_nid; 200 hda_nid_t vmaster_nid;
201 struct hda_vmaster_mute_hook vmaster_mute;
201#ifdef CONFIG_SND_HDA_POWER_SAVE 202#ifdef CONFIG_SND_HDA_POWER_SAVE
202 struct hda_loopback_check loopback; 203 struct hda_loopback_check loopback;
204 int num_loopbacks;
205 struct hda_amp_list loopback_list[8];
203#endif 206#endif
204 207
205 /* for PLL fix */ 208 /* for PLL fix */
@@ -220,8 +223,6 @@ struct alc_spec {
220 struct snd_array bind_ctls; 223 struct snd_array bind_ctls;
221}; 224};
222 225
223#define ALC_MODEL_AUTO 0 /* common for all chips */
224
225static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, 226static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
226 int dir, unsigned int bits) 227 int dir, unsigned int bits)
227{ 228{
@@ -300,6 +301,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
300 int i, type, num_conns; 301 int i, type, num_conns;
301 hda_nid_t nid; 302 hda_nid_t nid;
302 303
304 if (!spec->input_mux)
305 return 0;
306
303 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 307 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
304 imux = &spec->input_mux[mux_idx]; 308 imux = &spec->input_mux[mux_idx];
305 if (!imux->num_items && mux_idx > 0) 309 if (!imux->num_items && mux_idx > 0)
@@ -651,15 +655,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action)
651 snd_hda_jack_report_sync(codec); 655 snd_hda_jack_report_sync(codec);
652} 656}
653 657
658/* update the master volume per volume-knob's unsol event */
659static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
660{
661 unsigned int val;
662 struct snd_kcontrol *kctl;
663 struct snd_ctl_elem_value *uctl;
664
665 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
666 if (!kctl)
667 return;
668 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
669 if (!uctl)
670 return;
671 val = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
673 val &= HDA_AMP_VOLMASK;
674 uctl->value.integer.value[0] = val;
675 uctl->value.integer.value[1] = val;
676 kctl->put(kctl, uctl);
677 kfree(uctl);
678}
679
654/* unsolicited event for HP jack sensing */ 680/* unsolicited event for HP jack sensing */
655static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 681static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
656{ 682{
683 int action;
684
657 if (codec->vendor_id == 0x10ec0880) 685 if (codec->vendor_id == 0x10ec0880)
658 res >>= 28; 686 res >>= 28;
659 else 687 else
660 res >>= 26; 688 res >>= 26;
661 res = snd_hda_jack_get_action(codec, res); 689 action = snd_hda_jack_get_action(codec, res);
662 alc_exec_unsol_event(codec, res); 690 if (action == ALC_DCVOL_EVENT) {
691 /* Execute the dc-vol event here as it requires the NID
692 * but we don't pass NID to alc_exec_unsol_event().
693 * Once when we convert all static quirks to the auto-parser,
694 * this can be integerated into there.
695 */
696 struct hda_jack_tbl *jack;
697 jack = snd_hda_jack_tbl_get_from_tag(codec, res);
698 if (jack)
699 alc_update_knob_master(codec, jack->nid);
700 return;
701 }
702 alc_exec_unsol_event(codec, action);
663} 703}
664 704
665/* call init functions of standard auto-mute helpers */ 705/* call init functions of standard auto-mute helpers */
@@ -1033,45 +1073,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
1033 return true; 1073 return true;
1034} 1074}
1035 1075
1036/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1037static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1038{
1039 struct alc_spec *spec = codec->spec;
1040 struct hda_input_mux *imux;
1041 static char * const texts[3] = {
1042 "Mic", "Internal Mic", "Dock Mic"
1043 };
1044 int i;
1045
1046 if (!spec->auto_mic)
1047 return false;
1048 imux = &spec->private_imux[0];
1049 if (spec->input_mux == imux)
1050 return true;
1051 spec->imux_pins[0] = spec->ext_mic_pin;
1052 spec->imux_pins[1] = spec->int_mic_pin;
1053 spec->imux_pins[2] = spec->dock_mic_pin;
1054 for (i = 0; i < 3; i++) {
1055 strcpy(imux->items[i].label, texts[i]);
1056 if (spec->imux_pins[i]) {
1057 hda_nid_t pin = spec->imux_pins[i];
1058 int c;
1059 for (c = 0; c < spec->num_adc_nids; c++) {
1060 hda_nid_t cap = get_capsrc(spec, c);
1061 int idx = get_connection_index(codec, cap, pin);
1062 if (idx >= 0) {
1063 imux->items[i].index = idx;
1064 break;
1065 }
1066 }
1067 imux->num_items = i + 1;
1068 }
1069 }
1070 spec->num_mux_defs = 1;
1071 spec->input_mux = imux;
1072 return true;
1073}
1074
1075/* check whether all auto-mic pins are valid; setup indices if OK */ 1076/* check whether all auto-mic pins are valid; setup indices if OK */
1076static bool alc_auto_mic_check_imux(struct hda_codec *codec) 1077static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1077{ 1078{
@@ -1441,6 +1442,7 @@ enum {
1441 ALC_FIXUP_ACT_PRE_PROBE, 1442 ALC_FIXUP_ACT_PRE_PROBE,
1442 ALC_FIXUP_ACT_PROBE, 1443 ALC_FIXUP_ACT_PROBE,
1443 ALC_FIXUP_ACT_INIT, 1444 ALC_FIXUP_ACT_INIT,
1445 ALC_FIXUP_ACT_BUILD,
1444}; 1446};
1445 1447
1446static void alc_apply_fixup(struct hda_codec *codec, int action) 1448static void alc_apply_fixup(struct hda_codec *codec, int action)
@@ -1520,6 +1522,13 @@ static void alc_pick_fixup(struct hda_codec *codec,
1520 int id = -1; 1522 int id = -1;
1521 const char *name = NULL; 1523 const char *name = NULL;
1522 1524
1525 /* when model=nofixup is given, don't pick up any fixups */
1526 if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
1527 spec->fixup_list = NULL;
1528 spec->fixup_id = -1;
1529 return;
1530 }
1531
1523 if (codec->modelname && models) { 1532 if (codec->modelname && models) {
1524 while (models->name) { 1533 while (models->name) {
1525 if (!strcmp(codec->modelname, models->name)) { 1534 if (!strcmp(codec->modelname, models->name)) {
@@ -1847,36 +1856,10 @@ DEFINE_CAPMIX_NOSRC(3);
1847/* 1856/*
1848 * slave controls for virtual master 1857 * slave controls for virtual master
1849 */ 1858 */
1850static const char * const alc_slave_vols[] = { 1859static const char * const alc_slave_pfxs[] = {
1851 "Front Playback Volume", 1860 "Front", "Surround", "Center", "LFE", "Side",
1852 "Surround Playback Volume", 1861 "Headphone", "Speaker", "Mono", "Line Out",
1853 "Center Playback Volume", 1862 "CLFE", "Bass Speaker", "PCM",
1854 "LFE Playback Volume",
1855 "Side Playback Volume",
1856 "Headphone Playback Volume",
1857 "Speaker Playback Volume",
1858 "Mono Playback Volume",
1859 "Line Out Playback Volume",
1860 "CLFE Playback Volume",
1861 "Bass Speaker Playback Volume",
1862 "PCM Playback Volume",
1863 NULL,
1864};
1865
1866static const char * const alc_slave_sws[] = {
1867 "Front Playback Switch",
1868 "Surround Playback Switch",
1869 "Center Playback Switch",
1870 "LFE Playback Switch",
1871 "Side Playback Switch",
1872 "Headphone Playback Switch",
1873 "Speaker Playback Switch",
1874 "Mono Playback Switch",
1875 "IEC958 Playback Switch",
1876 "Line Out Playback Switch",
1877 "CLFE Playback Switch",
1878 "Bass Speaker Playback Switch",
1879 "PCM Playback Switch",
1880 NULL, 1863 NULL,
1881}; 1864};
1882 1865
@@ -1967,14 +1950,17 @@ static int __alc_build_controls(struct hda_codec *codec)
1967 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 1950 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1968 HDA_OUTPUT, vmaster_tlv); 1951 HDA_OUTPUT, vmaster_tlv);
1969 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1952 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1970 vmaster_tlv, alc_slave_vols); 1953 vmaster_tlv, alc_slave_pfxs,
1954 "Playback Volume");
1971 if (err < 0) 1955 if (err < 0)
1972 return err; 1956 return err;
1973 } 1957 }
1974 if (!spec->no_analog && 1958 if (!spec->no_analog &&
1975 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1959 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1976 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1960 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1977 NULL, alc_slave_sws); 1961 NULL, alc_slave_pfxs,
1962 "Playback Switch",
1963 true, &spec->vmaster_mute.sw_kctl);
1978 if (err < 0) 1964 if (err < 0)
1979 return err; 1965 return err;
1980 } 1966 }
@@ -2059,7 +2045,11 @@ static int alc_build_controls(struct hda_codec *codec)
2059 int err = __alc_build_controls(codec); 2045 int err = __alc_build_controls(codec);
2060 if (err < 0) 2046 if (err < 0)
2061 return err; 2047 return err;
2062 return snd_hda_jack_add_kctls(codec, &spec->autocfg); 2048 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
2049 if (err < 0)
2050 return err;
2051 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
2052 return 0;
2063} 2053}
2064 2054
2065 2055
@@ -2068,15 +2058,15 @@ static int alc_build_controls(struct hda_codec *codec)
2068 */ 2058 */
2069 2059
2070static void alc_init_special_input_src(struct hda_codec *codec); 2060static void alc_init_special_input_src(struct hda_codec *codec);
2071static int alc269_fill_coef(struct hda_codec *codec); 2061static void alc_auto_init_std(struct hda_codec *codec);
2072 2062
2073static int alc_init(struct hda_codec *codec) 2063static int alc_init(struct hda_codec *codec)
2074{ 2064{
2075 struct alc_spec *spec = codec->spec; 2065 struct alc_spec *spec = codec->spec;
2076 unsigned int i; 2066 unsigned int i;
2077 2067
2078 if (codec->vendor_id == 0x10ec0269) 2068 if (spec->init_hook)
2079 alc269_fill_coef(codec); 2069 spec->init_hook(codec);
2080 2070
2081 alc_fix_pll(codec); 2071 alc_fix_pll(codec);
2082 alc_auto_init_amp(codec, spec->init_amp); 2072 alc_auto_init_amp(codec, spec->init_amp);
@@ -2084,9 +2074,7 @@ static int alc_init(struct hda_codec *codec)
2084 for (i = 0; i < spec->num_init_verbs; i++) 2074 for (i = 0; i < spec->num_init_verbs; i++)
2085 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2075 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2086 alc_init_special_input_src(codec); 2076 alc_init_special_input_src(codec);
2087 2077 alc_auto_init_std(codec);
2088 if (spec->init_hook)
2089 spec->init_hook(codec);
2090 2078
2091 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 2079 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
2092 2080
@@ -2675,6 +2663,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2675 return channel_name[ch]; 2663 return channel_name[ch];
2676} 2664}
2677 2665
2666#ifdef CONFIG_SND_HDA_POWER_SAVE
2667/* add the powersave loopback-list entry */
2668static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
2669{
2670 struct hda_amp_list *list;
2671
2672 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2673 return;
2674 list = spec->loopback_list + spec->num_loopbacks;
2675 list->nid = mix;
2676 list->dir = HDA_INPUT;
2677 list->idx = idx;
2678 spec->num_loopbacks++;
2679 spec->loopback.amplist = spec->loopback_list;
2680}
2681#else
2682#define add_loopback_list(spec, mix, idx) /* NOP */
2683#endif
2684
2678/* create input playback/capture controls for the given pin */ 2685/* create input playback/capture controls for the given pin */
2679static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 2686static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2680 const char *ctlname, int ctlidx, 2687 const char *ctlname, int ctlidx,
@@ -2690,6 +2697,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2690 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 2697 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
2691 if (err < 0) 2698 if (err < 0)
2692 return err; 2699 return err;
2700 add_loopback_list(spec, mix_nid, idx);
2693 return 0; 2701 return 0;
2694} 2702}
2695 2703
@@ -2954,10 +2962,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2954 return 0; 2962 return 0;
2955} 2963}
2956 2964
2965static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
2966{
2967 struct alc_spec *spec = codec->spec;
2968 int i;
2969 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2970 ARRAY_SIZE(spec->private_dac_nids)) ||
2971 found_in_nid_list(nid, spec->multiout.hp_out_nid,
2972 ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
2973 found_in_nid_list(nid, spec->multiout.extra_out_nid,
2974 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2975 return true;
2976 for (i = 0; i < spec->multi_ios; i++) {
2977 if (spec->multi_io[i].dac == nid)
2978 return true;
2979 }
2980 return false;
2981}
2982
2957/* look for an empty DAC slot */ 2983/* look for an empty DAC slot */
2958static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 2984static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2959{ 2985{
2960 struct alc_spec *spec = codec->spec;
2961 hda_nid_t srcs[5]; 2986 hda_nid_t srcs[5];
2962 int i, num; 2987 int i, num;
2963 2988
@@ -2967,16 +2992,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2967 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); 2992 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2968 if (!nid) 2993 if (!nid)
2969 continue; 2994 continue;
2970 if (found_in_nid_list(nid, spec->multiout.dac_nids, 2995 if (!alc_is_dac_already_used(codec, nid))
2971 ARRAY_SIZE(spec->private_dac_nids))) 2996 return nid;
2972 continue;
2973 if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
2974 ARRAY_SIZE(spec->multiout.hp_out_nid)))
2975 continue;
2976 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2977 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2978 continue;
2979 return nid;
2980 } 2997 }
2981 return 0; 2998 return 0;
2982} 2999}
@@ -2988,6 +3005,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
2988 hda_nid_t srcs[5]; 3005 hda_nid_t srcs[5];
2989 int i, num; 3006 int i, num;
2990 3007
3008 if (!pin || !dac)
3009 return false;
2991 pin = alc_go_down_to_selector(codec, pin); 3010 pin = alc_go_down_to_selector(codec, pin);
2992 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 3011 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2993 for (i = 0; i < num; i++) { 3012 for (i = 0; i < num; i++) {
@@ -3000,83 +3019,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
3000 3019
3001static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) 3020static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
3002{ 3021{
3022 struct alc_spec *spec = codec->spec;
3003 hda_nid_t sel = alc_go_down_to_selector(codec, pin); 3023 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
3004 if (snd_hda_get_conn_list(codec, sel, NULL) == 1) 3024 hda_nid_t nid, nid_found, srcs[5];
3025 int i, num = snd_hda_get_connections(codec, sel, srcs,
3026 ARRAY_SIZE(srcs));
3027 if (num == 1)
3005 return alc_auto_look_for_dac(codec, pin); 3028 return alc_auto_look_for_dac(codec, pin);
3006 return 0; 3029 nid_found = 0;
3030 for (i = 0; i < num; i++) {
3031 if (srcs[i] == spec->mixer_nid)
3032 continue;
3033 nid = alc_auto_mix_to_dac(codec, srcs[i]);
3034 if (nid && !alc_is_dac_already_used(codec, nid)) {
3035 if (nid_found)
3036 return 0;
3037 nid_found = nid;
3038 }
3039 }
3040 return nid_found;
3007} 3041}
3008 3042
3009/* return 0 if no possible DAC is found, 1 if one or more found */ 3043/* mark up volume and mute control NIDs: used during badness parsing and
3010static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, 3044 * at creating actual controls
3011 const hda_nid_t *pins, hda_nid_t *dacs) 3045 */
3046static inline unsigned int get_ctl_pos(unsigned int data)
3012{ 3047{
3013 int i; 3048 hda_nid_t nid = get_amp_nid_(data);
3049 unsigned int dir;
3050 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3051 return 0;
3052 dir = get_amp_direction_(data);
3053 return (nid << 1) | dir;
3054}
3014 3055
3015 if (num_outs && !dacs[0]) { 3056#define is_ctl_used(bits, data) \
3016 dacs[0] = alc_auto_look_for_dac(codec, pins[0]); 3057 test_bit(get_ctl_pos(data), bits)
3017 if (!dacs[0]) 3058#define mark_ctl_usage(bits, data) \
3018 return 0; 3059 set_bit(get_ctl_pos(data), bits)
3019 }
3020 3060
3021 for (i = 1; i < num_outs; i++) 3061static void clear_vol_marks(struct hda_codec *codec)
3022 dacs[i] = get_dac_if_single(codec, pins[i]); 3062{
3023 for (i = 1; i < num_outs; i++) { 3063 struct alc_spec *spec = codec->spec;
3064 memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
3065 memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
3066}
3067
3068/* badness definition */
3069enum {
3070 /* No primary DAC is found for the main output */
3071 BAD_NO_PRIMARY_DAC = 0x10000,
3072 /* No DAC is found for the extra output */
3073 BAD_NO_DAC = 0x4000,
3074 /* No possible multi-ios */
3075 BAD_MULTI_IO = 0x103,
3076 /* No individual DAC for extra output */
3077 BAD_NO_EXTRA_DAC = 0x102,
3078 /* No individual DAC for extra surrounds */
3079 BAD_NO_EXTRA_SURR_DAC = 0x101,
3080 /* Primary DAC shared with main surrounds */
3081 BAD_SHARED_SURROUND = 0x100,
3082 /* Primary DAC shared with main CLFE */
3083 BAD_SHARED_CLFE = 0x10,
3084 /* Primary DAC shared with extra surrounds */
3085 BAD_SHARED_EXTRA_SURROUND = 0x10,
3086 /* Volume widget is shared */
3087 BAD_SHARED_VOL = 0x10,
3088};
3089
3090static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3091 hda_nid_t pin, hda_nid_t dac);
3092static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3093 hda_nid_t pin, hda_nid_t dac);
3094
3095static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
3096 hda_nid_t dac)
3097{
3098 struct alc_spec *spec = codec->spec;
3099 hda_nid_t nid;
3100 unsigned int val;
3101 int badness = 0;
3102
3103 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3104 if (nid) {
3105 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3106 if (is_ctl_used(spec->vol_ctls, nid))
3107 badness += BAD_SHARED_VOL;
3108 else
3109 mark_ctl_usage(spec->vol_ctls, val);
3110 } else
3111 badness += BAD_SHARED_VOL;
3112 nid = alc_look_for_out_mute_nid(codec, pin, dac);
3113 if (nid) {
3114 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
3115 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
3116 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3117 else
3118 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
3119 if (is_ctl_used(spec->sw_ctls, val))
3120 badness += BAD_SHARED_VOL;
3121 else
3122 mark_ctl_usage(spec->sw_ctls, val);
3123 } else
3124 badness += BAD_SHARED_VOL;
3125 return badness;
3126}
3127
3128struct badness_table {
3129 int no_primary_dac; /* no primary DAC */
3130 int no_dac; /* no secondary DACs */
3131 int shared_primary; /* primary DAC is shared with main output */
3132 int shared_surr; /* secondary DAC shared with main or primary */
3133 int shared_clfe; /* third DAC shared with main or primary */
3134 int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
3135};
3136
3137static struct badness_table main_out_badness = {
3138 .no_primary_dac = BAD_NO_PRIMARY_DAC,
3139 .no_dac = BAD_NO_DAC,
3140 .shared_primary = BAD_NO_PRIMARY_DAC,
3141 .shared_surr = BAD_SHARED_SURROUND,
3142 .shared_clfe = BAD_SHARED_CLFE,
3143 .shared_surr_main = BAD_SHARED_SURROUND,
3144};
3145
3146static struct badness_table extra_out_badness = {
3147 .no_primary_dac = BAD_NO_DAC,
3148 .no_dac = BAD_NO_DAC,
3149 .shared_primary = BAD_NO_EXTRA_DAC,
3150 .shared_surr = BAD_SHARED_EXTRA_SURROUND,
3151 .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
3152 .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
3153};
3154
3155/* try to assign DACs to pins and return the resultant badness */
3156static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
3157 const hda_nid_t *pins, hda_nid_t *dacs,
3158 const struct badness_table *bad)
3159{
3160 struct alc_spec *spec = codec->spec;
3161 struct auto_pin_cfg *cfg = &spec->autocfg;
3162 int i, j;
3163 int badness = 0;
3164 hda_nid_t dac;
3165
3166 if (!num_outs)
3167 return 0;
3168
3169 for (i = 0; i < num_outs; i++) {
3170 hda_nid_t pin = pins[i];
3024 if (!dacs[i]) 3171 if (!dacs[i])
3025 dacs[i] = alc_auto_look_for_dac(codec, pins[i]); 3172 dacs[i] = alc_auto_look_for_dac(codec, pin);
3173 if (!dacs[i] && !i) {
3174 for (j = 1; j < num_outs; j++) {
3175 if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
3176 dacs[0] = dacs[j];
3177 dacs[j] = 0;
3178 break;
3179 }
3180 }
3181 }
3182 dac = dacs[i];
3183 if (!dac) {
3184 if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
3185 dac = dacs[0];
3186 else if (cfg->line_outs > i &&
3187 alc_auto_is_dac_reachable(codec, pin,
3188 spec->private_dac_nids[i]))
3189 dac = spec->private_dac_nids[i];
3190 if (dac) {
3191 if (!i)
3192 badness += bad->shared_primary;
3193 else if (i == 1)
3194 badness += bad->shared_surr;
3195 else
3196 badness += bad->shared_clfe;
3197 } else if (alc_auto_is_dac_reachable(codec, pin,
3198 spec->private_dac_nids[0])) {
3199 dac = spec->private_dac_nids[0];
3200 badness += bad->shared_surr_main;
3201 } else if (!i)
3202 badness += bad->no_primary_dac;
3203 else
3204 badness += bad->no_dac;
3205 }
3206 if (dac)
3207 badness += eval_shared_vol_badness(codec, pin, dac);
3026 } 3208 }
3027 return 1; 3209
3210 return badness;
3028} 3211}
3029 3212
3030static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3213static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3031 unsigned int location, int offset); 3214 hda_nid_t reference_pin,
3032static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, 3215 bool hardwired, int offset);
3033 hda_nid_t pin, hda_nid_t dac); 3216
3217static bool alc_map_singles(struct hda_codec *codec, int outs,
3218 const hda_nid_t *pins, hda_nid_t *dacs)
3219{
3220 int i;
3221 bool found = false;
3222 for (i = 0; i < outs; i++) {
3223 if (dacs[i])
3224 continue;
3225 dacs[i] = get_dac_if_single(codec, pins[i]);
3226 if (dacs[i])
3227 found = true;
3228 }
3229 return found;
3230}
3034 3231
3035/* fill in the dac_nids table from the parsed pin configuration */ 3232/* fill in the dac_nids table from the parsed pin configuration */
3036static int alc_auto_fill_dac_nids(struct hda_codec *codec) 3233static int fill_and_eval_dacs(struct hda_codec *codec,
3234 bool fill_hardwired,
3235 bool fill_mio_first)
3037{ 3236{
3038 struct alc_spec *spec = codec->spec; 3237 struct alc_spec *spec = codec->spec;
3039 struct auto_pin_cfg *cfg = &spec->autocfg; 3238 struct auto_pin_cfg *cfg = &spec->autocfg;
3040 unsigned int location, defcfg; 3239 int i, err, badness;
3041 int num_pins;
3042 bool redone = false;
3043 int i;
3044 3240
3045 again:
3046 /* set num_dacs once to full for alc_auto_look_for_dac() */ 3241 /* set num_dacs once to full for alc_auto_look_for_dac() */
3047 spec->multiout.num_dacs = cfg->line_outs; 3242 spec->multiout.num_dacs = cfg->line_outs;
3048 spec->multiout.hp_out_nid[0] = 0;
3049 spec->multiout.extra_out_nid[0] = 0;
3050 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3051 spec->multiout.dac_nids = spec->private_dac_nids; 3243 spec->multiout.dac_nids = spec->private_dac_nids;
3244 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3245 memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
3246 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
3052 spec->multi_ios = 0; 3247 spec->multi_ios = 0;
3248 clear_vol_marks(codec);
3249 badness = 0;
3053 3250
3054 /* fill hard-wired DACs first */ 3251 /* fill hard-wired DACs first */
3055 if (!redone) { 3252 if (fill_hardwired) {
3056 for (i = 0; i < cfg->line_outs; i++) 3253 bool mapped;
3057 spec->private_dac_nids[i] = 3254 do {
3058 get_dac_if_single(codec, cfg->line_out_pins[i]); 3255 mapped = alc_map_singles(codec, cfg->line_outs,
3059 if (cfg->hp_outs) 3256 cfg->line_out_pins,
3060 spec->multiout.hp_out_nid[0] = 3257 spec->private_dac_nids);
3061 get_dac_if_single(codec, cfg->hp_pins[0]); 3258 mapped |= alc_map_singles(codec, cfg->hp_outs,
3062 if (cfg->speaker_outs) 3259 cfg->hp_pins,
3063 spec->multiout.extra_out_nid[0] = 3260 spec->multiout.hp_out_nid);
3064 get_dac_if_single(codec, cfg->speaker_pins[0]); 3261 mapped |= alc_map_singles(codec, cfg->speaker_outs,
3262 cfg->speaker_pins,
3263 spec->multiout.extra_out_nid);
3264 if (fill_mio_first && cfg->line_outs == 1 &&
3265 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3266 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
3267 if (!err)
3268 mapped = true;
3269 }
3270 } while (mapped);
3065 } 3271 }
3066 3272
3067 for (i = 0; i < cfg->line_outs; i++) { 3273 badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
3068 hda_nid_t pin = cfg->line_out_pins[i]; 3274 spec->private_dac_nids,
3069 if (spec->private_dac_nids[i]) 3275 &main_out_badness);
3070 continue;
3071 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
3072 if (!spec->private_dac_nids[i] && !redone) {
3073 /* if we can't find primary DACs, re-probe without
3074 * checking the hard-wired DACs
3075 */
3076 redone = true;
3077 goto again;
3078 }
3079 }
3080 3276
3081 /* re-count num_dacs and squash invalid entries */ 3277 /* re-count num_dacs and squash invalid entries */
3082 spec->multiout.num_dacs = 0; 3278 spec->multiout.num_dacs = 0;
@@ -3091,30 +3287,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3091 } 3287 }
3092 } 3288 }
3093 3289
3094 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3290 if (fill_mio_first &&
3291 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3095 /* try to fill multi-io first */ 3292 /* try to fill multi-io first */
3096 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); 3293 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3097 location = get_defcfg_location(defcfg); 3294 if (err < 0)
3098 3295 return err;
3099 num_pins = alc_auto_fill_multi_ios(codec, location, 0); 3296 /* we don't count badness at this stage yet */
3100 if (num_pins > 0) {
3101 spec->multi_ios = num_pins;
3102 spec->ext_channel_count = 2;
3103 spec->multiout.num_dacs = num_pins + 1;
3104 }
3105 } 3297 }
3106 3298
3107 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 3299 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
3108 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, 3300 err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3109 spec->multiout.hp_out_nid); 3301 spec->multiout.hp_out_nid,
3302 &extra_out_badness);
3303 if (err < 0)
3304 return err;
3305 badness += err;
3306 }
3110 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3307 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3111 int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, 3308 err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
3112 cfg->speaker_pins, 3309 cfg->speaker_pins,
3113 spec->multiout.extra_out_nid); 3310 spec->multiout.extra_out_nid,
3114 /* if no speaker volume is assigned, try again as the primary 3311 &extra_out_badness);
3115 * output 3312 if (err < 0)
3116 */ 3313 return err;
3117 if (!err && cfg->speaker_outs > 0 && 3314 badness += err;
3315 }
3316 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3317 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3318 if (err < 0)
3319 return err;
3320 badness += err;
3321 }
3322 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3323 /* try multi-ios with HP + inputs */
3324 int offset = 0;
3325 if (cfg->line_outs >= 3)
3326 offset = 1;
3327 err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
3328 offset);
3329 if (err < 0)
3330 return err;
3331 badness += err;
3332 }
3333
3334 if (spec->multi_ios == 2) {
3335 for (i = 0; i < 2; i++)
3336 spec->private_dac_nids[spec->multiout.num_dacs++] =
3337 spec->multi_io[i].dac;
3338 spec->ext_channel_count = 2;
3339 } else if (spec->multi_ios) {
3340 spec->multi_ios = 0;
3341 badness += BAD_MULTI_IO;
3342 }
3343
3344 return badness;
3345}
3346
3347#define DEBUG_BADNESS
3348
3349#ifdef DEBUG_BADNESS
3350#define debug_badness snd_printdd
3351#else
3352#define debug_badness(...)
3353#endif
3354
3355static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
3356{
3357 debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3358 cfg->line_out_pins[0], cfg->line_out_pins[1],
3359 cfg->line_out_pins[2], cfg->line_out_pins[2],
3360 spec->multiout.dac_nids[0],
3361 spec->multiout.dac_nids[1],
3362 spec->multiout.dac_nids[2],
3363 spec->multiout.dac_nids[3]);
3364 if (spec->multi_ios > 0)
3365 debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
3366 spec->multi_ios,
3367 spec->multi_io[0].pin, spec->multi_io[1].pin,
3368 spec->multi_io[0].dac, spec->multi_io[1].dac);
3369 debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3370 cfg->hp_pins[0], cfg->hp_pins[1],
3371 cfg->hp_pins[2], cfg->hp_pins[2],
3372 spec->multiout.hp_out_nid[0],
3373 spec->multiout.hp_out_nid[1],
3374 spec->multiout.hp_out_nid[2],
3375 spec->multiout.hp_out_nid[3]);
3376 debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3377 cfg->speaker_pins[0], cfg->speaker_pins[1],
3378 cfg->speaker_pins[2], cfg->speaker_pins[3],
3379 spec->multiout.extra_out_nid[0],
3380 spec->multiout.extra_out_nid[1],
3381 spec->multiout.extra_out_nid[2],
3382 spec->multiout.extra_out_nid[3]);
3383}
3384
3385static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3386{
3387 struct alc_spec *spec = codec->spec;
3388 struct auto_pin_cfg *cfg = &spec->autocfg;
3389 struct auto_pin_cfg *best_cfg;
3390 int best_badness = INT_MAX;
3391 int badness;
3392 bool fill_hardwired = true, fill_mio_first = true;
3393 bool best_wired = true, best_mio = true;
3394 bool hp_spk_swapped = false;
3395
3396 best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
3397 if (!best_cfg)
3398 return -ENOMEM;
3399 *best_cfg = *cfg;
3400
3401 for (;;) {
3402 badness = fill_and_eval_dacs(codec, fill_hardwired,
3403 fill_mio_first);
3404 if (badness < 0)
3405 return badness;
3406 debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
3407 cfg->line_out_type, fill_hardwired, fill_mio_first,
3408 badness);
3409 debug_show_configs(spec, cfg);
3410 if (badness < best_badness) {
3411 best_badness = badness;
3412 *best_cfg = *cfg;
3413 best_wired = fill_hardwired;
3414 best_mio = fill_mio_first;
3415 }
3416 if (!badness)
3417 break;
3418 fill_mio_first = !fill_mio_first;
3419 if (!fill_mio_first)
3420 continue;
3421 fill_hardwired = !fill_hardwired;
3422 if (!fill_hardwired)
3423 continue;
3424 if (hp_spk_swapped)
3425 break;
3426 hp_spk_swapped = true;
3427 if (cfg->speaker_outs > 0 &&
3118 cfg->line_out_type == AUTO_PIN_HP_OUT) { 3428 cfg->line_out_type == AUTO_PIN_HP_OUT) {
3119 cfg->hp_outs = cfg->line_outs; 3429 cfg->hp_outs = cfg->line_outs;
3120 memcpy(cfg->hp_pins, cfg->line_out_pins, 3430 memcpy(cfg->hp_pins, cfg->line_out_pins,
@@ -3125,48 +3435,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3125 cfg->speaker_outs = 0; 3435 cfg->speaker_outs = 0;
3126 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 3436 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
3127 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; 3437 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
3128 redone = false; 3438 fill_hardwired = true;
3129 goto again; 3439 continue;
3130 } 3440 }
3441 if (cfg->hp_outs > 0 &&
3442 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3443 cfg->speaker_outs = cfg->line_outs;
3444 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3445 sizeof(cfg->speaker_pins));
3446 cfg->line_outs = cfg->hp_outs;
3447 memcpy(cfg->line_out_pins, cfg->hp_pins,
3448 sizeof(cfg->hp_pins));
3449 cfg->hp_outs = 0;
3450 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3451 cfg->line_out_type = AUTO_PIN_HP_OUT;
3452 fill_hardwired = true;
3453 continue;
3454 }
3455 break;
3131 } 3456 }
3132 3457
3133 if (!spec->multi_ios && 3458 if (badness) {
3134 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 3459 *cfg = *best_cfg;
3135 cfg->hp_outs) { 3460 fill_and_eval_dacs(codec, best_wired, best_mio);
3136 /* try multi-ios with HP + inputs */
3137 defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
3138 location = get_defcfg_location(defcfg);
3139
3140 num_pins = alc_auto_fill_multi_ios(codec, location, 1);
3141 if (num_pins > 0) {
3142 spec->multi_ios = num_pins;
3143 spec->ext_channel_count = 2;
3144 spec->multiout.num_dacs = num_pins + 1;
3145 }
3146 } 3461 }
3462 debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
3463 cfg->line_out_type, best_wired, best_mio);
3464 debug_show_configs(spec, cfg);
3147 3465
3148 if (cfg->line_out_pins[0]) 3466 if (cfg->line_out_pins[0])
3149 spec->vmaster_nid = 3467 spec->vmaster_nid =
3150 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], 3468 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
3151 spec->multiout.dac_nids[0]); 3469 spec->multiout.dac_nids[0]);
3152 return 0;
3153}
3154 3470
3155static inline unsigned int get_ctl_pos(unsigned int data) 3471 /* clear the bitmap flags for creating controls */
3156{ 3472 clear_vol_marks(codec);
3157 hda_nid_t nid = get_amp_nid_(data); 3473 kfree(best_cfg);
3158 unsigned int dir; 3474 return 0;
3159 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3160 return 0;
3161 dir = get_amp_direction_(data);
3162 return (nid << 1) | dir;
3163} 3475}
3164 3476
3165#define is_ctl_used(bits, data) \
3166 test_bit(get_ctl_pos(data), bits)
3167#define mark_ctl_usage(bits, data) \
3168 set_bit(get_ctl_pos(data), bits)
3169
3170static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3477static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3171 const char *pfx, int cidx, 3478 const char *pfx, int cidx,
3172 hda_nid_t nid, unsigned int chs) 3479 hda_nid_t nid, unsigned int chs)
@@ -3278,14 +3585,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3278 dac = spec->multiout.dac_nids[i]; 3585 dac = spec->multiout.dac_nids[i];
3279 if (!dac) 3586 if (!dac)
3280 continue; 3587 continue;
3281 if (i >= cfg->line_outs) 3588 if (i >= cfg->line_outs) {
3282 pin = spec->multi_io[i - 1].pin; 3589 pin = spec->multi_io[i - 1].pin;
3283 else 3590 index = 0;
3591 name = channel_name[i];
3592 } else {
3284 pin = cfg->line_out_pins[i]; 3593 pin = cfg->line_out_pins[i];
3594 name = alc_get_line_out_pfx(spec, i, true, &index);
3595 }
3285 3596
3286 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3597 sw = alc_look_for_out_mute_nid(codec, pin, dac);
3287 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3598 vol = alc_look_for_out_vol_nid(codec, pin, dac);
3288 name = alc_get_line_out_pfx(spec, i, true, &index);
3289 if (!name || !strcmp(name, "CLFE")) { 3599 if (!name || !strcmp(name, "CLFE")) {
3290 /* Center/LFE */ 3600 /* Center/LFE */
3291 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); 3601 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
@@ -3382,41 +3692,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3382 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); 3692 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
3383 } 3693 }
3384 3694
3385 if (dacs[num_pins - 1]) {
3386 /* OK, we have a multi-output system with individual volumes */
3387 for (i = 0; i < num_pins; i++) {
3388 if (num_pins >= 3) {
3389 snprintf(name, sizeof(name), "%s %s",
3390 pfx, channel_name[i]);
3391 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3392 name, 0);
3393 } else {
3394 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3395 pfx, i);
3396 }
3397 if (err < 0)
3398 return err;
3399 }
3400 return 0;
3401 }
3402
3403 /* Let's create a bind-controls */
3404 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
3405 if (!ctl)
3406 return -ENOMEM;
3407 n = 0;
3408 for (i = 0; i < num_pins; i++) { 3695 for (i = 0; i < num_pins; i++) {
3409 if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) 3696 hda_nid_t dac;
3410 ctl->values[n++] = 3697 if (dacs[num_pins - 1])
3411 HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); 3698 dac = dacs[i]; /* with individual volumes */
3412 } 3699 else
3413 if (n) { 3700 dac = 0;
3414 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 3701 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
3415 err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); 3702 err = alc_auto_create_extra_out(codec, pins[i], dac,
3703 "Bass Speaker", 0);
3704 } else if (num_pins >= 3) {
3705 snprintf(name, sizeof(name), "%s %s",
3706 pfx, channel_name[i]);
3707 err = alc_auto_create_extra_out(codec, pins[i], dac,
3708 name, 0);
3709 } else {
3710 err = alc_auto_create_extra_out(codec, pins[i], dac,
3711 pfx, i);
3712 }
3416 if (err < 0) 3713 if (err < 0)
3417 return err; 3714 return err;
3418 } 3715 }
3716 if (dacs[num_pins - 1])
3717 return 0;
3419 3718
3719 /* Let's create a bind-controls for volumes */
3420 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); 3720 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
3421 if (!ctl) 3721 if (!ctl)
3422 return -ENOMEM; 3722 return -ENOMEM;
@@ -3552,58 +3852,111 @@ static void alc_auto_init_extra_out(struct hda_codec *codec)
3552 } 3852 }
3553} 3853}
3554 3854
3855/* check whether the given pin can be a multi-io pin */
3856static bool can_be_multiio_pin(struct hda_codec *codec,
3857 unsigned int location, hda_nid_t nid)
3858{
3859 unsigned int defcfg, caps;
3860
3861 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3862 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3863 return false;
3864 if (location && get_defcfg_location(defcfg) != location)
3865 return false;
3866 caps = snd_hda_query_pin_caps(codec, nid);
3867 if (!(caps & AC_PINCAP_OUT))
3868 return false;
3869 return true;
3870}
3871
3555/* 3872/*
3556 * multi-io helper 3873 * multi-io helper
3874 *
3875 * When hardwired is set, try to fill ony hardwired pins, and returns
3876 * zero if any pins are filled, non-zero if nothing found.
3877 * When hardwired is off, try to fill possible input pins, and returns
3878 * the badness value.
3557 */ 3879 */
3558static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3880static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3559 unsigned int location, 3881 hda_nid_t reference_pin,
3560 int offset) 3882 bool hardwired, int offset)
3561{ 3883{
3562 struct alc_spec *spec = codec->spec; 3884 struct alc_spec *spec = codec->spec;
3563 struct auto_pin_cfg *cfg = &spec->autocfg; 3885 struct auto_pin_cfg *cfg = &spec->autocfg;
3564 hda_nid_t prime_dac = spec->private_dac_nids[0]; 3886 int type, i, j, dacs, num_pins, old_pins;
3565 int type, i, dacs, num_pins = 0; 3887 unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
3888 unsigned int location = get_defcfg_location(defcfg);
3889 int badness = 0;
3890
3891 old_pins = spec->multi_ios;
3892 if (old_pins >= 2)
3893 goto end_fill;
3894
3895 num_pins = 0;
3896 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3897 for (i = 0; i < cfg->num_inputs; i++) {
3898 if (cfg->inputs[i].type != type)
3899 continue;
3900 if (can_be_multiio_pin(codec, location,
3901 cfg->inputs[i].pin))
3902 num_pins++;
3903 }
3904 }
3905 if (num_pins < 2)
3906 goto end_fill;
3566 3907
3567 dacs = spec->multiout.num_dacs; 3908 dacs = spec->multiout.num_dacs;
3568 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { 3909 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3569 for (i = 0; i < cfg->num_inputs; i++) { 3910 for (i = 0; i < cfg->num_inputs; i++) {
3570 hda_nid_t nid = cfg->inputs[i].pin; 3911 hda_nid_t nid = cfg->inputs[i].pin;
3571 hda_nid_t dac = 0; 3912 hda_nid_t dac = 0;
3572 unsigned int defcfg, caps; 3913
3573 if (cfg->inputs[i].type != type) 3914 if (cfg->inputs[i].type != type)
3574 continue; 3915 continue;
3575 defcfg = snd_hda_codec_get_pincfg(codec, nid); 3916 if (!can_be_multiio_pin(codec, location, nid))
3576 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3577 continue;
3578 if (location && get_defcfg_location(defcfg) != location)
3579 continue; 3917 continue;
3580 caps = snd_hda_query_pin_caps(codec, nid); 3918 for (j = 0; j < spec->multi_ios; j++) {
3581 if (!(caps & AC_PINCAP_OUT)) 3919 if (nid == spec->multi_io[j].pin)
3920 break;
3921 }
3922 if (j < spec->multi_ios)
3582 continue; 3923 continue;
3583 if (offset && offset + num_pins < dacs) { 3924
3584 dac = spec->private_dac_nids[offset + num_pins]; 3925 if (offset && offset + spec->multi_ios < dacs) {
3926 dac = spec->private_dac_nids[offset + spec->multi_ios];
3585 if (!alc_auto_is_dac_reachable(codec, nid, dac)) 3927 if (!alc_auto_is_dac_reachable(codec, nid, dac))
3586 dac = 0; 3928 dac = 0;
3587 } 3929 }
3588 if (!dac) 3930 if (hardwired)
3931 dac = get_dac_if_single(codec, nid);
3932 else if (!dac)
3589 dac = alc_auto_look_for_dac(codec, nid); 3933 dac = alc_auto_look_for_dac(codec, nid);
3590 if (!dac) 3934 if (!dac) {
3935 badness++;
3591 continue; 3936 continue;
3592 spec->multi_io[num_pins].pin = nid; 3937 }
3593 spec->multi_io[num_pins].dac = dac; 3938 spec->multi_io[spec->multi_ios].pin = nid;
3594 num_pins++; 3939 spec->multi_io[spec->multi_ios].dac = dac;
3595 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 3940 spec->multi_ios++;
3941 if (spec->multi_ios >= 2)
3942 break;
3596 } 3943 }
3597 } 3944 }
3598 spec->multiout.num_dacs = dacs; 3945 end_fill:
3599 if (num_pins < 2) { 3946 if (badness)
3600 /* clear up again */ 3947 badness = BAD_MULTI_IO;
3601 memset(spec->private_dac_nids + dacs, 0, 3948 if (old_pins == spec->multi_ios) {
3602 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); 3949 if (hardwired)
3603 spec->private_dac_nids[0] = prime_dac; 3950 return 1; /* nothing found */
3604 return 0; 3951 else
3952 return badness; /* no badness if nothing found */
3953 }
3954 if (!hardwired && spec->multi_ios < 2) {
3955 spec->multi_ios = old_pins;
3956 return badness;
3605 } 3957 }
3606 return num_pins; 3958
3959 return 0;
3607} 3960}
3608 3961
3609static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, 3962static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
@@ -3958,6 +4311,7 @@ static const struct snd_pci_quirk beep_white_list[] = {
3958 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 4311 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
3959 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 4312 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
3960 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 4313 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
4314 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
3961 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 4315 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
3962 {} 4316 {}
3963}; 4317};
@@ -4057,6 +4411,9 @@ static int alc_parse_auto_config(struct hda_codec *codec,
4057 if (spec->kctls.list) 4411 if (spec->kctls.list)
4058 add_mixer(spec, spec->kctls.list); 4412 add_mixer(spec, spec->kctls.list);
4059 4413
4414 if (!spec->no_analog && !spec->cap_mixer)
4415 set_capture_mixer(codec);
4416
4060 return 1; 4417 return 1;
4061} 4418}
4062 4419
@@ -4067,26 +4424,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4067 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); 4424 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
4068} 4425}
4069 4426
4070#ifdef CONFIG_SND_HDA_POWER_SAVE
4071static const struct hda_amp_list alc880_loopbacks[] = {
4072 { 0x0b, HDA_INPUT, 0 },
4073 { 0x0b, HDA_INPUT, 1 },
4074 { 0x0b, HDA_INPUT, 2 },
4075 { 0x0b, HDA_INPUT, 3 },
4076 { 0x0b, HDA_INPUT, 4 },
4077 { } /* end */
4078};
4079#endif
4080
4081/* 4427/*
4082 * ALC880 fix-ups 4428 * ALC880 fix-ups
4083 */ 4429 */
4084enum { 4430enum {
4431 ALC880_FIXUP_GPIO1,
4085 ALC880_FIXUP_GPIO2, 4432 ALC880_FIXUP_GPIO2,
4086 ALC880_FIXUP_MEDION_RIM, 4433 ALC880_FIXUP_MEDION_RIM,
4434 ALC880_FIXUP_LG,
4435 ALC880_FIXUP_W810,
4436 ALC880_FIXUP_EAPD_COEF,
4437 ALC880_FIXUP_TCL_S700,
4438 ALC880_FIXUP_VOL_KNOB,
4439 ALC880_FIXUP_FUJITSU,
4440 ALC880_FIXUP_F1734,
4441 ALC880_FIXUP_UNIWILL,
4442 ALC880_FIXUP_UNIWILL_DIG,
4443 ALC880_FIXUP_Z71V,
4444 ALC880_FIXUP_3ST_BASE,
4445 ALC880_FIXUP_3ST,
4446 ALC880_FIXUP_3ST_DIG,
4447 ALC880_FIXUP_5ST_BASE,
4448 ALC880_FIXUP_5ST,
4449 ALC880_FIXUP_5ST_DIG,
4450 ALC880_FIXUP_6ST_BASE,
4451 ALC880_FIXUP_6ST,
4452 ALC880_FIXUP_6ST_DIG,
4087}; 4453};
4088 4454
4455/* enable the volume-knob widget support on NID 0x21 */
4456static void alc880_fixup_vol_knob(struct hda_codec *codec,
4457 const struct alc_fixup *fix, int action)
4458{
4459 if (action == ALC_FIXUP_ACT_PROBE)
4460 snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
4461}
4462
4089static const struct alc_fixup alc880_fixups[] = { 4463static const struct alc_fixup alc880_fixups[] = {
4464 [ALC880_FIXUP_GPIO1] = {
4465 .type = ALC_FIXUP_VERBS,
4466 .v.verbs = alc_gpio1_init_verbs,
4467 },
4090 [ALC880_FIXUP_GPIO2] = { 4468 [ALC880_FIXUP_GPIO2] = {
4091 .type = ALC_FIXUP_VERBS, 4469 .type = ALC_FIXUP_VERBS,
4092 .v.verbs = alc_gpio2_init_verbs, 4470 .v.verbs = alc_gpio2_init_verbs,
@@ -4101,40 +4479,323 @@ static const struct alc_fixup alc880_fixups[] = {
4101 .chained = true, 4479 .chained = true,
4102 .chain_id = ALC880_FIXUP_GPIO2, 4480 .chain_id = ALC880_FIXUP_GPIO2,
4103 }, 4481 },
4482 [ALC880_FIXUP_LG] = {
4483 .type = ALC_FIXUP_PINS,
4484 .v.pins = (const struct alc_pincfg[]) {
4485 /* disable bogus unused pins */
4486 { 0x16, 0x411111f0 },
4487 { 0x18, 0x411111f0 },
4488 { 0x1a, 0x411111f0 },
4489 { }
4490 }
4491 },
4492 [ALC880_FIXUP_W810] = {
4493 .type = ALC_FIXUP_PINS,
4494 .v.pins = (const struct alc_pincfg[]) {
4495 /* disable bogus unused pins */
4496 { 0x17, 0x411111f0 },
4497 { }
4498 },
4499 .chained = true,
4500 .chain_id = ALC880_FIXUP_GPIO2,
4501 },
4502 [ALC880_FIXUP_EAPD_COEF] = {
4503 .type = ALC_FIXUP_VERBS,
4504 .v.verbs = (const struct hda_verb[]) {
4505 /* change to EAPD mode */
4506 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4507 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
4508 {}
4509 },
4510 },
4511 [ALC880_FIXUP_TCL_S700] = {
4512 .type = ALC_FIXUP_VERBS,
4513 .v.verbs = (const struct hda_verb[]) {
4514 /* change to EAPD mode */
4515 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4516 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
4517 {}
4518 },
4519 .chained = true,
4520 .chain_id = ALC880_FIXUP_GPIO2,
4521 },
4522 [ALC880_FIXUP_VOL_KNOB] = {
4523 .type = ALC_FIXUP_FUNC,
4524 .v.func = alc880_fixup_vol_knob,
4525 },
4526 [ALC880_FIXUP_FUJITSU] = {
4527 /* override all pins as BIOS on old Amilo is broken */
4528 .type = ALC_FIXUP_PINS,
4529 .v.pins = (const struct alc_pincfg[]) {
4530 { 0x14, 0x0121411f }, /* HP */
4531 { 0x15, 0x99030120 }, /* speaker */
4532 { 0x16, 0x99030130 }, /* bass speaker */
4533 { 0x17, 0x411111f0 }, /* N/A */
4534 { 0x18, 0x411111f0 }, /* N/A */
4535 { 0x19, 0x01a19950 }, /* mic-in */
4536 { 0x1a, 0x411111f0 }, /* N/A */
4537 { 0x1b, 0x411111f0 }, /* N/A */
4538 { 0x1c, 0x411111f0 }, /* N/A */
4539 { 0x1d, 0x411111f0 }, /* N/A */
4540 { 0x1e, 0x01454140 }, /* SPDIF out */
4541 { }
4542 },
4543 .chained = true,
4544 .chain_id = ALC880_FIXUP_VOL_KNOB,
4545 },
4546 [ALC880_FIXUP_F1734] = {
4547 /* almost compatible with FUJITSU, but no bass and SPDIF */
4548 .type = ALC_FIXUP_PINS,
4549 .v.pins = (const struct alc_pincfg[]) {
4550 { 0x14, 0x0121411f }, /* HP */
4551 { 0x15, 0x99030120 }, /* speaker */
4552 { 0x16, 0x411111f0 }, /* N/A */
4553 { 0x17, 0x411111f0 }, /* N/A */
4554 { 0x18, 0x411111f0 }, /* N/A */
4555 { 0x19, 0x01a19950 }, /* mic-in */
4556 { 0x1a, 0x411111f0 }, /* N/A */
4557 { 0x1b, 0x411111f0 }, /* N/A */
4558 { 0x1c, 0x411111f0 }, /* N/A */
4559 { 0x1d, 0x411111f0 }, /* N/A */
4560 { 0x1e, 0x411111f0 }, /* N/A */
4561 { }
4562 },
4563 .chained = true,
4564 .chain_id = ALC880_FIXUP_VOL_KNOB,
4565 },
4566 [ALC880_FIXUP_UNIWILL] = {
4567 /* need to fix HP and speaker pins to be parsed correctly */
4568 .type = ALC_FIXUP_PINS,
4569 .v.pins = (const struct alc_pincfg[]) {
4570 { 0x14, 0x0121411f }, /* HP */
4571 { 0x15, 0x99030120 }, /* speaker */
4572 { 0x16, 0x99030130 }, /* bass speaker */
4573 { }
4574 },
4575 },
4576 [ALC880_FIXUP_UNIWILL_DIG] = {
4577 .type = ALC_FIXUP_PINS,
4578 .v.pins = (const struct alc_pincfg[]) {
4579 /* disable bogus unused pins */
4580 { 0x17, 0x411111f0 },
4581 { 0x19, 0x411111f0 },
4582 { 0x1b, 0x411111f0 },
4583 { 0x1f, 0x411111f0 },
4584 { }
4585 }
4586 },
4587 [ALC880_FIXUP_Z71V] = {
4588 .type = ALC_FIXUP_PINS,
4589 .v.pins = (const struct alc_pincfg[]) {
4590 /* set up the whole pins as BIOS is utterly broken */
4591 { 0x14, 0x99030120 }, /* speaker */
4592 { 0x15, 0x0121411f }, /* HP */
4593 { 0x16, 0x411111f0 }, /* N/A */
4594 { 0x17, 0x411111f0 }, /* N/A */
4595 { 0x18, 0x01a19950 }, /* mic-in */
4596 { 0x19, 0x411111f0 }, /* N/A */
4597 { 0x1a, 0x01813031 }, /* line-in */
4598 { 0x1b, 0x411111f0 }, /* N/A */
4599 { 0x1c, 0x411111f0 }, /* N/A */
4600 { 0x1d, 0x411111f0 }, /* N/A */
4601 { 0x1e, 0x0144111e }, /* SPDIF */
4602 { }
4603 }
4604 },
4605 [ALC880_FIXUP_3ST_BASE] = {
4606 .type = ALC_FIXUP_PINS,
4607 .v.pins = (const struct alc_pincfg[]) {
4608 { 0x14, 0x01014010 }, /* line-out */
4609 { 0x15, 0x411111f0 }, /* N/A */
4610 { 0x16, 0x411111f0 }, /* N/A */
4611 { 0x17, 0x411111f0 }, /* N/A */
4612 { 0x18, 0x01a19c30 }, /* mic-in */
4613 { 0x19, 0x0121411f }, /* HP */
4614 { 0x1a, 0x01813031 }, /* line-in */
4615 { 0x1b, 0x02a19c40 }, /* front-mic */
4616 { 0x1c, 0x411111f0 }, /* N/A */
4617 { 0x1d, 0x411111f0 }, /* N/A */
4618 /* 0x1e is filled in below */
4619 { 0x1f, 0x411111f0 }, /* N/A */
4620 { }
4621 }
4622 },
4623 [ALC880_FIXUP_3ST] = {
4624 .type = ALC_FIXUP_PINS,
4625 .v.pins = (const struct alc_pincfg[]) {
4626 { 0x1e, 0x411111f0 }, /* N/A */
4627 { }
4628 },
4629 .chained = true,
4630 .chain_id = ALC880_FIXUP_3ST_BASE,
4631 },
4632 [ALC880_FIXUP_3ST_DIG] = {
4633 .type = ALC_FIXUP_PINS,
4634 .v.pins = (const struct alc_pincfg[]) {
4635 { 0x1e, 0x0144111e }, /* SPDIF */
4636 { }
4637 },
4638 .chained = true,
4639 .chain_id = ALC880_FIXUP_3ST_BASE,
4640 },
4641 [ALC880_FIXUP_5ST_BASE] = {
4642 .type = ALC_FIXUP_PINS,
4643 .v.pins = (const struct alc_pincfg[]) {
4644 { 0x14, 0x01014010 }, /* front */
4645 { 0x15, 0x411111f0 }, /* N/A */
4646 { 0x16, 0x01011411 }, /* CLFE */
4647 { 0x17, 0x01016412 }, /* surr */
4648 { 0x18, 0x01a19c30 }, /* mic-in */
4649 { 0x19, 0x0121411f }, /* HP */
4650 { 0x1a, 0x01813031 }, /* line-in */
4651 { 0x1b, 0x02a19c40 }, /* front-mic */
4652 { 0x1c, 0x411111f0 }, /* N/A */
4653 { 0x1d, 0x411111f0 }, /* N/A */
4654 /* 0x1e is filled in below */
4655 { 0x1f, 0x411111f0 }, /* N/A */
4656 { }
4657 }
4658 },
4659 [ALC880_FIXUP_5ST] = {
4660 .type = ALC_FIXUP_PINS,
4661 .v.pins = (const struct alc_pincfg[]) {
4662 { 0x1e, 0x411111f0 }, /* N/A */
4663 { }
4664 },
4665 .chained = true,
4666 .chain_id = ALC880_FIXUP_5ST_BASE,
4667 },
4668 [ALC880_FIXUP_5ST_DIG] = {
4669 .type = ALC_FIXUP_PINS,
4670 .v.pins = (const struct alc_pincfg[]) {
4671 { 0x1e, 0x0144111e }, /* SPDIF */
4672 { }
4673 },
4674 .chained = true,
4675 .chain_id = ALC880_FIXUP_5ST_BASE,
4676 },
4677 [ALC880_FIXUP_6ST_BASE] = {
4678 .type = ALC_FIXUP_PINS,
4679 .v.pins = (const struct alc_pincfg[]) {
4680 { 0x14, 0x01014010 }, /* front */
4681 { 0x15, 0x01016412 }, /* surr */
4682 { 0x16, 0x01011411 }, /* CLFE */
4683 { 0x17, 0x01012414 }, /* side */
4684 { 0x18, 0x01a19c30 }, /* mic-in */
4685 { 0x19, 0x02a19c40 }, /* front-mic */
4686 { 0x1a, 0x01813031 }, /* line-in */
4687 { 0x1b, 0x0121411f }, /* HP */
4688 { 0x1c, 0x411111f0 }, /* N/A */
4689 { 0x1d, 0x411111f0 }, /* N/A */
4690 /* 0x1e is filled in below */
4691 { 0x1f, 0x411111f0 }, /* N/A */
4692 { }
4693 }
4694 },
4695 [ALC880_FIXUP_6ST] = {
4696 .type = ALC_FIXUP_PINS,
4697 .v.pins = (const struct alc_pincfg[]) {
4698 { 0x1e, 0x411111f0 }, /* N/A */
4699 { }
4700 },
4701 .chained = true,
4702 .chain_id = ALC880_FIXUP_6ST_BASE,
4703 },
4704 [ALC880_FIXUP_6ST_DIG] = {
4705 .type = ALC_FIXUP_PINS,
4706 .v.pins = (const struct alc_pincfg[]) {
4707 { 0x1e, 0x0144111e }, /* SPDIF */
4708 { }
4709 },
4710 .chained = true,
4711 .chain_id = ALC880_FIXUP_6ST_BASE,
4712 },
4104}; 4713};
4105 4714
4106static const struct snd_pci_quirk alc880_fixup_tbl[] = { 4715static const struct snd_pci_quirk alc880_fixup_tbl[] = {
4716 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
4717 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
4718 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
4719 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
4720 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
4721 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
4722 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
4723 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
4724 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
4725 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
4107 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), 4726 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
4727 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
4728 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
4729 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
4730 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
4731 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
4732 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
4733 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
4734 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
4735
4736 /* Below is the copied entries from alc880_quirks.c.
4737 * It's not quite sure whether BIOS sets the correct pin-config table
4738 * on these machines, thus they are kept to be compatible with
4739 * the old static quirks. Once when it's confirmed to work without
4740 * these overrides, it'd be better to remove.
4741 */
4742 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
4743 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
4744 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
4745 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
4746 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
4747 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
4748 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
4749 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
4750 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
4751 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
4752 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
4753 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
4754 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
4755 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
4756 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
4757 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
4758 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
4759 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
4760 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
4761 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
4762 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
4763 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
4764 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
4765 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4766 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4767 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4768 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4769 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4770 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4771 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4772 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4773 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4774 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4775 /* default Intel */
4776 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
4777 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
4778 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
4108 {} 4779 {}
4109}; 4780};
4110 4781
4782static const struct alc_model_fixup alc880_fixup_models[] = {
4783 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
4784 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
4785 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
4786 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
4787 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
4788 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
4789 {}
4790};
4111 4791
4112/*
4113 * board setups
4114 */
4115#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4116#define alc_board_config \
4117 snd_hda_check_board_config
4118#define alc_board_codec_sid_config \
4119 snd_hda_check_board_codec_sid_config
4120#include "alc_quirks.c"
4121#else
4122#define alc_board_config(codec, nums, models, tbl) -1
4123#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
4124#define setup_preset(codec, x) /* NOP */
4125#endif
4126 4792
4127/* 4793/*
4128 * OK, here we have finally the patch for ALC880 4794 * OK, here we have finally the patch for ALC880
4129 */ 4795 */
4130#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4131#include "alc880_quirks.c"
4132#endif
4133
4134static int patch_alc880(struct hda_codec *codec) 4796static int patch_alc880(struct hda_codec *codec)
4135{ 4797{
4136 struct alc_spec *spec; 4798 struct alc_spec *spec;
4137 int board_config;
4138 int err; 4799 int err;
4139 4800
4140 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4801 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4146,47 +4807,14 @@ static int patch_alc880(struct hda_codec *codec)
4146 spec->mixer_nid = 0x0b; 4807 spec->mixer_nid = 0x0b;
4147 spec->need_dac_fix = 1; 4808 spec->need_dac_fix = 1;
4148 4809
4149 board_config = alc_board_config(codec, ALC880_MODEL_LAST, 4810 alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
4150 alc880_models, alc880_cfg_tbl); 4811 alc880_fixups);
4151 if (board_config < 0) { 4812 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4152 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4153 codec->chip_name);
4154 board_config = ALC_MODEL_AUTO;
4155 }
4156
4157 if (board_config == ALC_MODEL_AUTO) {
4158 alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
4159 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4160 }
4161
4162 if (board_config == ALC_MODEL_AUTO) {
4163 /* automatic parse from the BIOS config */
4164 err = alc880_parse_auto_config(codec);
4165 if (err < 0)
4166 goto error;
4167#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4168 else if (!err) {
4169 printk(KERN_INFO
4170 "hda_codec: Cannot set up configuration "
4171 "from BIOS. Using 3-stack mode...\n");
4172 board_config = ALC880_3ST;
4173 }
4174#endif
4175 }
4176
4177 if (board_config != ALC_MODEL_AUTO) {
4178 spec->vmaster_nid = 0x0c;
4179 setup_preset(codec, &alc880_presets[board_config]);
4180 }
4181
4182 if (!spec->no_analog && !spec->adc_nids) {
4183 alc_auto_fill_adc_caps(codec);
4184 alc_rebuild_imux_for_auto_mic(codec);
4185 alc_remove_invalid_adc_nids(codec);
4186 }
4187 4813
4188 if (!spec->no_analog && !spec->cap_mixer) 4814 /* automatic parse from the BIOS config */
4189 set_capture_mixer(codec); 4815 err = alc880_parse_auto_config(codec);
4816 if (err < 0)
4817 goto error;
4190 4818
4191 if (!spec->no_analog) { 4819 if (!spec->no_analog) {
4192 err = snd_hda_attach_beep_device(codec, 0x1); 4820 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4195,17 +4823,9 @@ static int patch_alc880(struct hda_codec *codec)
4195 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4823 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4196 } 4824 }
4197 4825
4198 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4199
4200 codec->patch_ops = alc_patch_ops; 4826 codec->patch_ops = alc_patch_ops;
4201 if (board_config == ALC_MODEL_AUTO) 4827
4202 spec->init_hook = alc_auto_init_std; 4828 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4203 else
4204 codec->patch_ops.build_controls = __alc_build_controls;
4205#ifdef CONFIG_SND_HDA_POWER_SAVE
4206 if (!spec->loopback.amplist)
4207 spec->loopback.amplist = alc880_loopbacks;
4208#endif
4209 4829
4210 return 0; 4830 return 0;
4211 4831
@@ -4225,49 +4845,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
4225 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); 4845 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
4226} 4846}
4227 4847
4228#ifdef CONFIG_SND_HDA_POWER_SAVE
4229static const struct hda_amp_list alc260_loopbacks[] = {
4230 { 0x07, HDA_INPUT, 0 },
4231 { 0x07, HDA_INPUT, 1 },
4232 { 0x07, HDA_INPUT, 2 },
4233 { 0x07, HDA_INPUT, 3 },
4234 { 0x07, HDA_INPUT, 4 },
4235 { } /* end */
4236};
4237#endif
4238
4239/* 4848/*
4240 * Pin config fixes 4849 * Pin config fixes
4241 */ 4850 */
4242enum { 4851enum {
4243 PINFIX_HP_DC5750, 4852 ALC260_FIXUP_HP_DC5750,
4853 ALC260_FIXUP_HP_PIN_0F,
4854 ALC260_FIXUP_COEF,
4855 ALC260_FIXUP_GPIO1,
4856 ALC260_FIXUP_GPIO1_TOGGLE,
4857 ALC260_FIXUP_REPLACER,
4858 ALC260_FIXUP_HP_B1900,
4244}; 4859};
4245 4860
4861static void alc260_gpio1_automute(struct hda_codec *codec)
4862{
4863 struct alc_spec *spec = codec->spec;
4864 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4865 spec->hp_jack_present);
4866}
4867
4868static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4869 const struct alc_fixup *fix, int action)
4870{
4871 struct alc_spec *spec = codec->spec;
4872 if (action == ALC_FIXUP_ACT_PROBE) {
4873 /* although the machine has only one output pin, we need to
4874 * toggle GPIO1 according to the jack state
4875 */
4876 spec->automute_hook = alc260_gpio1_automute;
4877 spec->detect_hp = 1;
4878 spec->automute_speaker = 1;
4879 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4880 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4881 spec->unsol_event = alc_sku_unsol_event;
4882 add_verb(codec->spec, alc_gpio1_init_verbs);
4883 }
4884}
4885
4246static const struct alc_fixup alc260_fixups[] = { 4886static const struct alc_fixup alc260_fixups[] = {
4247 [PINFIX_HP_DC5750] = { 4887 [ALC260_FIXUP_HP_DC5750] = {
4248 .type = ALC_FIXUP_PINS, 4888 .type = ALC_FIXUP_PINS,
4249 .v.pins = (const struct alc_pincfg[]) { 4889 .v.pins = (const struct alc_pincfg[]) {
4250 { 0x11, 0x90130110 }, /* speaker */ 4890 { 0x11, 0x90130110 }, /* speaker */
4251 { } 4891 { }
4252 } 4892 }
4253 }, 4893 },
4894 [ALC260_FIXUP_HP_PIN_0F] = {
4895 .type = ALC_FIXUP_PINS,
4896 .v.pins = (const struct alc_pincfg[]) {
4897 { 0x0f, 0x01214000 }, /* HP */
4898 { }
4899 }
4900 },
4901 [ALC260_FIXUP_COEF] = {
4902 .type = ALC_FIXUP_VERBS,
4903 .v.verbs = (const struct hda_verb[]) {
4904 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4905 { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 },
4906 { }
4907 },
4908 .chained = true,
4909 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4910 },
4911 [ALC260_FIXUP_GPIO1] = {
4912 .type = ALC_FIXUP_VERBS,
4913 .v.verbs = alc_gpio1_init_verbs,
4914 },
4915 [ALC260_FIXUP_GPIO1_TOGGLE] = {
4916 .type = ALC_FIXUP_FUNC,
4917 .v.func = alc260_fixup_gpio1_toggle,
4918 .chained = true,
4919 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4920 },
4921 [ALC260_FIXUP_REPLACER] = {
4922 .type = ALC_FIXUP_VERBS,
4923 .v.verbs = (const struct hda_verb[]) {
4924 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4925 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
4926 { }
4927 },
4928 .chained = true,
4929 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
4930 },
4931 [ALC260_FIXUP_HP_B1900] = {
4932 .type = ALC_FIXUP_FUNC,
4933 .v.func = alc260_fixup_gpio1_toggle,
4934 .chained = true,
4935 .chain_id = ALC260_FIXUP_COEF,
4936 }
4254}; 4937};
4255 4938
4256static const struct snd_pci_quirk alc260_fixup_tbl[] = { 4939static const struct snd_pci_quirk alc260_fixup_tbl[] = {
4257 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 4940 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
4941 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
4942 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
4943 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
4944 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
4945 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
4946 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
4947 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
4258 {} 4948 {}
4259}; 4949};
4260 4950
4261/* 4951/*
4262 */ 4952 */
4263#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4264#include "alc260_quirks.c"
4265#endif
4266
4267static int patch_alc260(struct hda_codec *codec) 4953static int patch_alc260(struct hda_codec *codec)
4268{ 4954{
4269 struct alc_spec *spec; 4955 struct alc_spec *spec;
4270 int err, board_config; 4956 int err;
4271 4957
4272 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4958 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4273 if (spec == NULL) 4959 if (spec == NULL)
@@ -4277,47 +4963,13 @@ static int patch_alc260(struct hda_codec *codec)
4277 4963
4278 spec->mixer_nid = 0x07; 4964 spec->mixer_nid = 0x07;
4279 4965
4280 board_config = alc_board_config(codec, ALC260_MODEL_LAST, 4966 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4281 alc260_models, alc260_cfg_tbl); 4967 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4282 if (board_config < 0) {
4283 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4284 codec->chip_name);
4285 board_config = ALC_MODEL_AUTO;
4286 }
4287
4288 if (board_config == ALC_MODEL_AUTO) {
4289 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4290 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4291 }
4292
4293 if (board_config == ALC_MODEL_AUTO) {
4294 /* automatic parse from the BIOS config */
4295 err = alc260_parse_auto_config(codec);
4296 if (err < 0)
4297 goto error;
4298#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4299 else if (!err) {
4300 printk(KERN_INFO
4301 "hda_codec: Cannot set up configuration "
4302 "from BIOS. Using base mode...\n");
4303 board_config = ALC260_BASIC;
4304 }
4305#endif
4306 }
4307
4308 if (board_config != ALC_MODEL_AUTO) {
4309 setup_preset(codec, &alc260_presets[board_config]);
4310 spec->vmaster_nid = 0x08;
4311 }
4312
4313 if (!spec->no_analog && !spec->adc_nids) {
4314 alc_auto_fill_adc_caps(codec);
4315 alc_rebuild_imux_for_auto_mic(codec);
4316 alc_remove_invalid_adc_nids(codec);
4317 }
4318 4968
4319 if (!spec->no_analog && !spec->cap_mixer) 4969 /* automatic parse from the BIOS config */
4320 set_capture_mixer(codec); 4970 err = alc260_parse_auto_config(codec);
4971 if (err < 0)
4972 goto error;
4321 4973
4322 if (!spec->no_analog) { 4974 if (!spec->no_analog) {
4323 err = snd_hda_attach_beep_device(codec, 0x1); 4975 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4326,18 +4978,10 @@ static int patch_alc260(struct hda_codec *codec)
4326 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 4978 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
4327 } 4979 }
4328 4980
4329 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4330
4331 codec->patch_ops = alc_patch_ops; 4981 codec->patch_ops = alc_patch_ops;
4332 if (board_config == ALC_MODEL_AUTO)
4333 spec->init_hook = alc_auto_init_std;
4334 else
4335 codec->patch_ops.build_controls = __alc_build_controls;
4336 spec->shutup = alc_eapd_shutup; 4982 spec->shutup = alc_eapd_shutup;
4337#ifdef CONFIG_SND_HDA_POWER_SAVE 4983
4338 if (!spec->loopback.amplist) 4984 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4339 spec->loopback.amplist = alc260_loopbacks;
4340#endif
4341 4985
4342 return 0; 4986 return 0;
4343 4987
@@ -4358,9 +5002,6 @@ static int patch_alc260(struct hda_codec *codec)
4358 * In addition, an independent DAC for the multi-playback (not used in this 5002 * In addition, an independent DAC for the multi-playback (not used in this
4359 * driver yet). 5003 * driver yet).
4360 */ 5004 */
4361#ifdef CONFIG_SND_HDA_POWER_SAVE
4362#define alc882_loopbacks alc880_loopbacks
4363#endif
4364 5005
4365/* 5006/*
4366 * Pin config fixes 5007 * Pin config fixes
@@ -4377,6 +5018,8 @@ enum {
4377 ALC882_FIXUP_EAPD, 5018 ALC882_FIXUP_EAPD,
4378 ALC883_FIXUP_EAPD, 5019 ALC883_FIXUP_EAPD,
4379 ALC883_FIXUP_ACER_EAPD, 5020 ALC883_FIXUP_ACER_EAPD,
5021 ALC882_FIXUP_GPIO1,
5022 ALC882_FIXUP_GPIO2,
4380 ALC882_FIXUP_GPIO3, 5023 ALC882_FIXUP_GPIO3,
4381 ALC889_FIXUP_COEF, 5024 ALC889_FIXUP_COEF,
4382 ALC882_FIXUP_ASUS_W2JC, 5025 ALC882_FIXUP_ASUS_W2JC,
@@ -4385,6 +5028,8 @@ enum {
4385 ALC882_FIXUP_ASPIRE_8930G_VERBS, 5028 ALC882_FIXUP_ASPIRE_8930G_VERBS,
4386 ALC885_FIXUP_MACPRO_GPIO, 5029 ALC885_FIXUP_MACPRO_GPIO,
4387 ALC889_FIXUP_DAC_ROUTE, 5030 ALC889_FIXUP_DAC_ROUTE,
5031 ALC889_FIXUP_MBP_VREF,
5032 ALC889_FIXUP_IMAC91_VREF,
4388}; 5033};
4389 5034
4390static void alc889_fixup_coef(struct hda_codec *codec, 5035static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4463,6 +5108,51 @@ static void alc889_fixup_dac_route(struct hda_codec *codec,
4463 } 5108 }
4464} 5109}
4465 5110
5111/* Set VREF on HP pin */
5112static void alc889_fixup_mbp_vref(struct hda_codec *codec,
5113 const struct alc_fixup *fix, int action)
5114{
5115 struct alc_spec *spec = codec->spec;
5116 static hda_nid_t nids[2] = { 0x14, 0x15 };
5117 int i;
5118
5119 if (action != ALC_FIXUP_ACT_INIT)
5120 return;
5121 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5122 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
5123 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
5124 continue;
5125 val = snd_hda_codec_read(codec, nids[i], 0,
5126 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5127 val |= AC_PINCTL_VREF_80;
5128 snd_hda_codec_write(codec, nids[i], 0,
5129 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5130 spec->keep_vref_in_automute = 1;
5131 break;
5132 }
5133}
5134
5135/* Set VREF on speaker pins on imac91 */
5136static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5137 const struct alc_fixup *fix, int action)
5138{
5139 struct alc_spec *spec = codec->spec;
5140 static hda_nid_t nids[2] = { 0x18, 0x1a };
5141 int i;
5142
5143 if (action != ALC_FIXUP_ACT_INIT)
5144 return;
5145 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5146 unsigned int val;
5147 val = snd_hda_codec_read(codec, nids[i], 0,
5148 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5149 val |= AC_PINCTL_VREF_50;
5150 snd_hda_codec_write(codec, nids[i], 0,
5151 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5152 }
5153 spec->keep_vref_in_automute = 1;
5154}
5155
4466static const struct alc_fixup alc882_fixups[] = { 5156static const struct alc_fixup alc882_fixups[] = {
4467 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 5157 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
4468 .type = ALC_FIXUP_PINS, 5158 .type = ALC_FIXUP_PINS,
@@ -4548,6 +5238,14 @@ static const struct alc_fixup alc882_fixups[] = {
4548 { } 5238 { }
4549 } 5239 }
4550 }, 5240 },
5241 [ALC882_FIXUP_GPIO1] = {
5242 .type = ALC_FIXUP_VERBS,
5243 .v.verbs = alc_gpio1_init_verbs,
5244 },
5245 [ALC882_FIXUP_GPIO2] = {
5246 .type = ALC_FIXUP_VERBS,
5247 .v.verbs = alc_gpio2_init_verbs,
5248 },
4551 [ALC882_FIXUP_GPIO3] = { 5249 [ALC882_FIXUP_GPIO3] = {
4552 .type = ALC_FIXUP_VERBS, 5250 .type = ALC_FIXUP_VERBS,
4553 .v.verbs = alc_gpio3_init_verbs, 5251 .v.verbs = alc_gpio3_init_verbs,
@@ -4621,6 +5319,18 @@ static const struct alc_fixup alc882_fixups[] = {
4621 .type = ALC_FIXUP_FUNC, 5319 .type = ALC_FIXUP_FUNC,
4622 .v.func = alc889_fixup_dac_route, 5320 .v.func = alc889_fixup_dac_route,
4623 }, 5321 },
5322 [ALC889_FIXUP_MBP_VREF] = {
5323 .type = ALC_FIXUP_FUNC,
5324 .v.func = alc889_fixup_mbp_vref,
5325 .chained = true,
5326 .chain_id = ALC882_FIXUP_GPIO1,
5327 },
5328 [ALC889_FIXUP_IMAC91_VREF] = {
5329 .type = ALC_FIXUP_FUNC,
5330 .v.func = alc889_fixup_imac91_vref,
5331 .chained = true,
5332 .chain_id = ALC882_FIXUP_GPIO1,
5333 },
4624}; 5334};
4625 5335
4626static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5336static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4654,11 +5364,26 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4654 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 5364 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
4655 5365
4656 /* All Apple entries are in codec SSIDs */ 5366 /* All Apple entries are in codec SSIDs */
5367 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
5368 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
5369 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4657 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), 5370 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
4658 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 5371 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
4659 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 5372 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
5373 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
5374 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
4660 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), 5375 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
5376 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
5377 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
5378 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
5379 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4661 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), 5380 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
5381 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
5382 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
5383 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
5384 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
5385 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
5386 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
4662 5387
4663 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), 5388 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
4664 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 5389 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
@@ -4684,14 +5409,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
4684 5409
4685/* 5410/*
4686 */ 5411 */
4687#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4688#include "alc882_quirks.c"
4689#endif
4690
4691static int patch_alc882(struct hda_codec *codec) 5412static int patch_alc882(struct hda_codec *codec)
4692{ 5413{
4693 struct alc_spec *spec; 5414 struct alc_spec *spec;
4694 int err, board_config; 5415 int err;
4695 5416
4696 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5417 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4697 if (spec == NULL) 5418 if (spec == NULL)
@@ -4715,45 +5436,15 @@ static int patch_alc882(struct hda_codec *codec)
4715 if (err < 0) 5436 if (err < 0)
4716 goto error; 5437 goto error;
4717 5438
4718 board_config = alc_board_config(codec, ALC882_MODEL_LAST, 5439 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4719 alc882_models, NULL); 5440 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4720 if (board_config < 0)
4721 board_config = alc_board_codec_sid_config(codec,
4722 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
4723
4724 if (board_config < 0) {
4725 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4726 codec->chip_name);
4727 board_config = ALC_MODEL_AUTO;
4728 }
4729
4730 if (board_config == ALC_MODEL_AUTO) {
4731 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4732 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4733 }
4734 5441
4735 alc_auto_parse_customize_define(codec); 5442 alc_auto_parse_customize_define(codec);
4736 5443
4737 if (board_config == ALC_MODEL_AUTO) { 5444 /* automatic parse from the BIOS config */
4738 /* automatic parse from the BIOS config */ 5445 err = alc882_parse_auto_config(codec);
4739 err = alc882_parse_auto_config(codec); 5446 if (err < 0)
4740 if (err < 0) 5447 goto error;
4741 goto error;
4742 }
4743
4744 if (board_config != ALC_MODEL_AUTO) {
4745 setup_preset(codec, &alc882_presets[board_config]);
4746 spec->vmaster_nid = 0x0c;
4747 }
4748
4749 if (!spec->no_analog && !spec->adc_nids) {
4750 alc_auto_fill_adc_caps(codec);
4751 alc_rebuild_imux_for_auto_mic(codec);
4752 alc_remove_invalid_adc_nids(codec);
4753 }
4754
4755 if (!spec->no_analog && !spec->cap_mixer)
4756 set_capture_mixer(codec);
4757 5448
4758 if (!spec->no_analog && has_cdefine_beep(codec)) { 5449 if (!spec->no_analog && has_cdefine_beep(codec)) {
4759 err = snd_hda_attach_beep_device(codec, 0x1); 5450 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4762,18 +5453,9 @@ static int patch_alc882(struct hda_codec *codec)
4762 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5453 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4763 } 5454 }
4764 5455
4765 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4766
4767 codec->patch_ops = alc_patch_ops; 5456 codec->patch_ops = alc_patch_ops;
4768 if (board_config == ALC_MODEL_AUTO)
4769 spec->init_hook = alc_auto_init_std;
4770 else
4771 codec->patch_ops.build_controls = __alc_build_controls;
4772 5457
4773#ifdef CONFIG_SND_HDA_POWER_SAVE 5458 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4774 if (!spec->loopback.amplist)
4775 spec->loopback.amplist = alc882_loopbacks;
4776#endif
4777 5459
4778 return 0; 5460 return 0;
4779 5461
@@ -4869,10 +5551,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4869}; 5551};
4870 5552
4871 5553
4872#ifdef CONFIG_SND_HDA_POWER_SAVE
4873#define alc262_loopbacks alc880_loopbacks
4874#endif
4875
4876/* 5554/*
4877 */ 5555 */
4878static int patch_alc262(struct hda_codec *codec) 5556static int patch_alc262(struct hda_codec *codec)
@@ -4912,15 +5590,6 @@ static int patch_alc262(struct hda_codec *codec)
4912 if (err < 0) 5590 if (err < 0)
4913 goto error; 5591 goto error;
4914 5592
4915 if (!spec->no_analog && !spec->adc_nids) {
4916 alc_auto_fill_adc_caps(codec);
4917 alc_rebuild_imux_for_auto_mic(codec);
4918 alc_remove_invalid_adc_nids(codec);
4919 }
4920
4921 if (!spec->no_analog && !spec->cap_mixer)
4922 set_capture_mixer(codec);
4923
4924 if (!spec->no_analog && has_cdefine_beep(codec)) { 5593 if (!spec->no_analog && has_cdefine_beep(codec)) {
4925 err = snd_hda_attach_beep_device(codec, 0x1); 5594 err = snd_hda_attach_beep_device(codec, 0x1);
4926 if (err < 0) 5595 if (err < 0)
@@ -4928,16 +5597,10 @@ static int patch_alc262(struct hda_codec *codec)
4928 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5597 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4929 } 5598 }
4930 5599
4931 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4932
4933 codec->patch_ops = alc_patch_ops; 5600 codec->patch_ops = alc_patch_ops;
4934 spec->init_hook = alc_auto_init_std;
4935 spec->shutup = alc_eapd_shutup; 5601 spec->shutup = alc_eapd_shutup;
4936 5602
4937#ifdef CONFIG_SND_HDA_POWER_SAVE 5603 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4938 if (!spec->loopback.amplist)
4939 spec->loopback.amplist = alc262_loopbacks;
4940#endif
4941 5604
4942 return 0; 5605 return 0;
4943 5606
@@ -5031,17 +5694,7 @@ static int patch_alc268(struct hda_codec *codec)
5031 (0 << AC_AMPCAP_MUTE_SHIFT)); 5694 (0 << AC_AMPCAP_MUTE_SHIFT));
5032 } 5695 }
5033 5696
5034 if (!spec->no_analog && !spec->adc_nids) {
5035 alc_auto_fill_adc_caps(codec);
5036 alc_rebuild_imux_for_auto_mic(codec);
5037 alc_remove_invalid_adc_nids(codec);
5038 }
5039
5040 if (!spec->no_analog && !spec->cap_mixer)
5041 set_capture_mixer(codec);
5042
5043 codec->patch_ops = alc_patch_ops; 5697 codec->patch_ops = alc_patch_ops;
5044 spec->init_hook = alc_auto_init_std;
5045 spec->shutup = alc_eapd_shutup; 5698 spec->shutup = alc_eapd_shutup;
5046 5699
5047 return 0; 5700 return 0;
@@ -5054,10 +5707,6 @@ static int patch_alc268(struct hda_codec *codec)
5054/* 5707/*
5055 * ALC269 5708 * ALC269
5056 */ 5709 */
5057#ifdef CONFIG_SND_HDA_POWER_SAVE
5058#define alc269_loopbacks alc880_loopbacks
5059#endif
5060
5061static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 5710static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
5062 .substreams = 1, 5711 .substreams = 1,
5063 .channels_min = 2, 5712 .channels_min = 2,
@@ -5079,35 +5728,6 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
5079 /* NID is set in alc_build_pcms */ 5728 /* NID is set in alc_build_pcms */
5080}; 5729};
5081 5730
5082#ifdef CONFIG_SND_HDA_POWER_SAVE
5083static int alc269_mic2_for_mute_led(struct hda_codec *codec)
5084{
5085 switch (codec->subsystem_id) {
5086 case 0x103c1586:
5087 return 1;
5088 }
5089 return 0;
5090}
5091
5092static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
5093{
5094 /* update mute-LED according to the speaker mute state */
5095 if (nid == 0x01 || nid == 0x14) {
5096 int pinval;
5097 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
5098 HDA_AMP_MUTE)
5099 pinval = 0x24;
5100 else
5101 pinval = 0x20;
5102 /* mic2 vref pin is used for mute LED control */
5103 snd_hda_codec_update_cache(codec, 0x19, 0,
5104 AC_VERB_SET_PIN_WIDGET_CONTROL,
5105 pinval);
5106 }
5107 return alc_check_power_status(codec, nid);
5108}
5109#endif /* CONFIG_SND_HDA_POWER_SAVE */
5110
5111/* different alc269-variants */ 5731/* different alc269-variants */
5112enum { 5732enum {
5113 ALC269_TYPE_ALC269VA, 5733 ALC269_TYPE_ALC269VA,
@@ -5258,6 +5878,31 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
5258 spec->automute_hook = alc269_quanta_automute; 5878 spec->automute_hook = alc269_quanta_automute;
5259} 5879}
5260 5880
5881/* update mute-LED according to the speaker mute state via mic2 VREF pin */
5882static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
5883{
5884 struct hda_codec *codec = private_data;
5885 unsigned int pinval = enabled ? 0x20 : 0x24;
5886 snd_hda_codec_update_cache(codec, 0x19, 0,
5887 AC_VERB_SET_PIN_WIDGET_CONTROL,
5888 pinval);
5889}
5890
5891static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5892 const struct alc_fixup *fix, int action)
5893{
5894 struct alc_spec *spec = codec->spec;
5895 switch (action) {
5896 case ALC_FIXUP_ACT_BUILD:
5897 spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
5898 snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
5899 /* fallthru */
5900 case ALC_FIXUP_ACT_INIT:
5901 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5902 break;
5903 }
5904}
5905
5261enum { 5906enum {
5262 ALC269_FIXUP_SONY_VAIO, 5907 ALC269_FIXUP_SONY_VAIO,
5263 ALC275_FIXUP_SONY_VAIO_GPIO2, 5908 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5275,6 +5920,7 @@ enum {
5275 ALC269_FIXUP_DMIC, 5920 ALC269_FIXUP_DMIC,
5276 ALC269VB_FIXUP_AMIC, 5921 ALC269VB_FIXUP_AMIC,
5277 ALC269VB_FIXUP_DMIC, 5922 ALC269VB_FIXUP_DMIC,
5923 ALC269_FIXUP_MIC2_MUTE_LED,
5278}; 5924};
5279 5925
5280static const struct alc_fixup alc269_fixups[] = { 5926static const struct alc_fixup alc269_fixups[] = {
@@ -5395,9 +6041,14 @@ static const struct alc_fixup alc269_fixups[] = {
5395 { } 6041 { }
5396 }, 6042 },
5397 }, 6043 },
6044 [ALC269_FIXUP_MIC2_MUTE_LED] = {
6045 .type = ALC_FIXUP_FUNC,
6046 .v.func = alc269_fixup_mic2_mute,
6047 },
5398}; 6048};
5399 6049
5400static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6050static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6051 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5401 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6052 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5402 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6053 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5403 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6054 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
@@ -5420,7 +6071,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5420 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6071 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
5421 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6072 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5422 6073
5423#if 1 6074#if 0
5424 /* Below is a quirk table taken from the old code. 6075 /* Below is a quirk table taken from the old code.
5425 * Basically the device should work as is without the fixup table. 6076 * Basically the device should work as is without the fixup table.
5426 * If BIOS doesn't give a proper info, enable the corresponding 6077 * If BIOS doesn't give a proper info, enable the corresponding
@@ -5478,13 +6129,13 @@ static const struct alc_model_fixup alc269_fixup_models[] = {
5478}; 6129};
5479 6130
5480 6131
5481static int alc269_fill_coef(struct hda_codec *codec) 6132static void alc269_fill_coef(struct hda_codec *codec)
5482{ 6133{
5483 struct alc_spec *spec = codec->spec; 6134 struct alc_spec *spec = codec->spec;
5484 int val; 6135 int val;
5485 6136
5486 if (spec->codec_variant != ALC269_TYPE_ALC269VB) 6137 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
5487 return 0; 6138 return;
5488 6139
5489 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { 6140 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5490 alc_write_coef_idx(codec, 0xf, 0x960b); 6141 alc_write_coef_idx(codec, 0xf, 0x960b);
@@ -5520,8 +6171,6 @@ static int alc269_fill_coef(struct hda_codec *codec)
5520 6171
5521 val = alc_read_coef_idx(codec, 0x4); /* HP */ 6172 val = alc_read_coef_idx(codec, 0x4); /* HP */
5522 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 6173 alc_write_coef_idx(codec, 0x4, val | (1<<11));
5523
5524 return 0;
5525} 6174}
5526 6175
5527/* 6176/*
@@ -5565,6 +6214,7 @@ static int patch_alc269(struct hda_codec *codec)
5565 } 6214 }
5566 if (err < 0) 6215 if (err < 0)
5567 goto error; 6216 goto error;
6217 spec->init_hook = alc269_fill_coef;
5568 alc269_fill_coef(codec); 6218 alc269_fill_coef(codec);
5569 } 6219 }
5570 6220
@@ -5577,15 +6227,6 @@ static int patch_alc269(struct hda_codec *codec)
5577 if (err < 0) 6227 if (err < 0)
5578 goto error; 6228 goto error;
5579 6229
5580 if (!spec->no_analog && !spec->adc_nids) {
5581 alc_auto_fill_adc_caps(codec);
5582 alc_rebuild_imux_for_auto_mic(codec);
5583 alc_remove_invalid_adc_nids(codec);
5584 }
5585
5586 if (!spec->no_analog && !spec->cap_mixer)
5587 set_capture_mixer(codec);
5588
5589 if (!spec->no_analog && has_cdefine_beep(codec)) { 6230 if (!spec->no_analog && has_cdefine_beep(codec)) {
5590 err = snd_hda_attach_beep_device(codec, 0x1); 6231 err = snd_hda_attach_beep_device(codec, 0x1);
5591 if (err < 0) 6232 if (err < 0)
@@ -5593,21 +6234,13 @@ static int patch_alc269(struct hda_codec *codec)
5593 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 6234 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5594 } 6235 }
5595 6236
5596 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5597
5598 codec->patch_ops = alc_patch_ops; 6237 codec->patch_ops = alc_patch_ops;
5599#ifdef CONFIG_PM 6238#ifdef CONFIG_PM
5600 codec->patch_ops.resume = alc269_resume; 6239 codec->patch_ops.resume = alc269_resume;
5601#endif 6240#endif
5602 spec->init_hook = alc_auto_init_std;
5603 spec->shutup = alc269_shutup; 6241 spec->shutup = alc269_shutup;
5604 6242
5605#ifdef CONFIG_SND_HDA_POWER_SAVE 6243 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5606 if (!spec->loopback.amplist)
5607 spec->loopback.amplist = alc269_loopbacks;
5608 if (alc269_mic2_for_mute_led(codec))
5609 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
5610#endif
5611 6244
5612 return 0; 6245 return 0;
5613 6246
@@ -5627,21 +6260,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5627 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); 6260 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
5628} 6261}
5629 6262
5630#ifdef CONFIG_SND_HDA_POWER_SAVE
5631static const struct hda_amp_list alc861_loopbacks[] = {
5632 { 0x15, HDA_INPUT, 0 },
5633 { 0x15, HDA_INPUT, 1 },
5634 { 0x15, HDA_INPUT, 2 },
5635 { 0x15, HDA_INPUT, 3 },
5636 { } /* end */
5637};
5638#endif
5639
5640
5641/* Pin config fixes */ 6263/* Pin config fixes */
5642enum { 6264enum {
5643 PINFIX_FSC_AMILO_PI1505, 6265 ALC861_FIXUP_FSC_AMILO_PI1505,
5644 PINFIX_ASUS_A6RP, 6266 ALC861_FIXUP_AMP_VREF_0F,
6267 ALC861_FIXUP_NO_JACK_DETECT,
6268 ALC861_FIXUP_ASUS_A6RP,
5645}; 6269};
5646 6270
5647/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ 6271/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -5663,8 +6287,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5663 spec->keep_vref_in_automute = 1; 6287 spec->keep_vref_in_automute = 1;
5664} 6288}
5665 6289
6290/* suppress the jack-detection */
6291static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6292 const struct alc_fixup *fix, int action)
6293{
6294 if (action == ALC_FIXUP_ACT_PRE_PROBE)
6295 codec->no_jack_detect = 1;
6296}
6297
5666static const struct alc_fixup alc861_fixups[] = { 6298static const struct alc_fixup alc861_fixups[] = {
5667 [PINFIX_FSC_AMILO_PI1505] = { 6299 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
5668 .type = ALC_FIXUP_PINS, 6300 .type = ALC_FIXUP_PINS,
5669 .v.pins = (const struct alc_pincfg[]) { 6301 .v.pins = (const struct alc_pincfg[]) {
5670 { 0x0b, 0x0221101f }, /* HP */ 6302 { 0x0b, 0x0221101f }, /* HP */
@@ -5672,17 +6304,29 @@ static const struct alc_fixup alc861_fixups[] = {
5672 { } 6304 { }
5673 } 6305 }
5674 }, 6306 },
5675 [PINFIX_ASUS_A6RP] = { 6307 [ALC861_FIXUP_AMP_VREF_0F] = {
5676 .type = ALC_FIXUP_FUNC, 6308 .type = ALC_FIXUP_FUNC,
5677 .v.func = alc861_fixup_asus_amp_vref_0f, 6309 .v.func = alc861_fixup_asus_amp_vref_0f,
5678 }, 6310 },
6311 [ALC861_FIXUP_NO_JACK_DETECT] = {
6312 .type = ALC_FIXUP_FUNC,
6313 .v.func = alc_fixup_no_jack_detect,
6314 },
6315 [ALC861_FIXUP_ASUS_A6RP] = {
6316 .type = ALC_FIXUP_FUNC,
6317 .v.func = alc861_fixup_asus_amp_vref_0f,
6318 .chained = true,
6319 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6320 }
5679}; 6321};
5680 6322
5681static const struct snd_pci_quirk alc861_fixup_tbl[] = { 6323static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5682 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), 6324 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5683 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP), 6325 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5684 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 6326 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
5685 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 6327 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6328 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6329 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
5686 {} 6330 {}
5687}; 6331};
5688 6332
@@ -5709,15 +6353,6 @@ static int patch_alc861(struct hda_codec *codec)
5709 if (err < 0) 6353 if (err < 0)
5710 goto error; 6354 goto error;
5711 6355
5712 if (!spec->no_analog && !spec->adc_nids) {
5713 alc_auto_fill_adc_caps(codec);
5714 alc_rebuild_imux_for_auto_mic(codec);
5715 alc_remove_invalid_adc_nids(codec);
5716 }
5717
5718 if (!spec->no_analog && !spec->cap_mixer)
5719 set_capture_mixer(codec);
5720
5721 if (!spec->no_analog) { 6356 if (!spec->no_analog) {
5722 err = snd_hda_attach_beep_device(codec, 0x23); 6357 err = snd_hda_attach_beep_device(codec, 0x23);
5723 if (err < 0) 6358 if (err < 0)
@@ -5725,16 +6360,13 @@ static int patch_alc861(struct hda_codec *codec)
5725 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 6360 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
5726 } 6361 }
5727 6362
5728 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5729
5730 codec->patch_ops = alc_patch_ops; 6363 codec->patch_ops = alc_patch_ops;
5731 spec->init_hook = alc_auto_init_std;
5732#ifdef CONFIG_SND_HDA_POWER_SAVE 6364#ifdef CONFIG_SND_HDA_POWER_SAVE
5733 spec->power_hook = alc_power_eapd; 6365 spec->power_hook = alc_power_eapd;
5734 if (!spec->loopback.amplist)
5735 spec->loopback.amplist = alc861_loopbacks;
5736#endif 6366#endif
5737 6367
6368 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6369
5738 return 0; 6370 return 0;
5739 6371
5740 error: 6372 error:
@@ -5749,10 +6381,6 @@ static int patch_alc861(struct hda_codec *codec)
5749 * 6381 *
5750 * In addition, an independent DAC 6382 * In addition, an independent DAC
5751 */ 6383 */
5752#ifdef CONFIG_SND_HDA_POWER_SAVE
5753#define alc861vd_loopbacks alc880_loopbacks
5754#endif
5755
5756static int alc861vd_parse_auto_config(struct hda_codec *codec) 6384static int alc861vd_parse_auto_config(struct hda_codec *codec)
5757{ 6385{
5758 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 6386 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
@@ -5833,15 +6461,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5833 add_verb(spec, alc660vd_eapd_verbs); 6461 add_verb(spec, alc660vd_eapd_verbs);
5834 } 6462 }
5835 6463
5836 if (!spec->no_analog && !spec->adc_nids) {
5837 alc_auto_fill_adc_caps(codec);
5838 alc_rebuild_imux_for_auto_mic(codec);
5839 alc_remove_invalid_adc_nids(codec);
5840 }
5841
5842 if (!spec->no_analog && !spec->cap_mixer)
5843 set_capture_mixer(codec);
5844
5845 if (!spec->no_analog) { 6464 if (!spec->no_analog) {
5846 err = snd_hda_attach_beep_device(codec, 0x23); 6465 err = snd_hda_attach_beep_device(codec, 0x23);
5847 if (err < 0) 6466 if (err < 0)
@@ -5849,16 +6468,11 @@ static int patch_alc861vd(struct hda_codec *codec)
5849 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 6468 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5850 } 6469 }
5851 6470
5852 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5853
5854 codec->patch_ops = alc_patch_ops; 6471 codec->patch_ops = alc_patch_ops;
5855 6472
5856 spec->init_hook = alc_auto_init_std;
5857 spec->shutup = alc_eapd_shutup; 6473 spec->shutup = alc_eapd_shutup;
5858#ifdef CONFIG_SND_HDA_POWER_SAVE 6474
5859 if (!spec->loopback.amplist) 6475 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5860 spec->loopback.amplist = alc861vd_loopbacks;
5861#endif
5862 6476
5863 return 0; 6477 return 0;
5864 6478
@@ -5878,9 +6492,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5878 * In addition, an independent DAC for the multi-playback (not used in this 6492 * In addition, an independent DAC for the multi-playback (not used in this
5879 * driver yet). 6493 * driver yet).
5880 */ 6494 */
5881#ifdef CONFIG_SND_HDA_POWER_SAVE
5882#define alc662_loopbacks alc880_loopbacks
5883#endif
5884 6495
5885/* 6496/*
5886 * BIOS auto configuration 6497 * BIOS auto configuration
@@ -5930,6 +6541,7 @@ enum {
5930 ALC662_FIXUP_ASUS_MODE6, 6541 ALC662_FIXUP_ASUS_MODE6,
5931 ALC662_FIXUP_ASUS_MODE7, 6542 ALC662_FIXUP_ASUS_MODE7,
5932 ALC662_FIXUP_ASUS_MODE8, 6543 ALC662_FIXUP_ASUS_MODE8,
6544 ALC662_FIXUP_NO_JACK_DETECT,
5933}; 6545};
5934 6546
5935static const struct alc_fixup alc662_fixups[] = { 6547static const struct alc_fixup alc662_fixups[] = {
@@ -6075,6 +6687,10 @@ static const struct alc_fixup alc662_fixups[] = {
6075 .chained = true, 6687 .chained = true,
6076 .chain_id = ALC662_FIXUP_SKU_IGNORE 6688 .chain_id = ALC662_FIXUP_SKU_IGNORE
6077 }, 6689 },
6690 [ALC662_FIXUP_NO_JACK_DETECT] = {
6691 .type = ALC_FIXUP_FUNC,
6692 .v.func = alc_fixup_no_jack_detect,
6693 },
6078}; 6694};
6079 6695
6080static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6696static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6083,6 +6699,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6083 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6699 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6084 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6700 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6085 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6701 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6702 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6086 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 6703 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6087 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 6704 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6088 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 6705 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
@@ -6204,15 +6821,6 @@ static int patch_alc662(struct hda_codec *codec)
6204 if (err < 0) 6821 if (err < 0)
6205 goto error; 6822 goto error;
6206 6823
6207 if (!spec->no_analog && !spec->adc_nids) {
6208 alc_auto_fill_adc_caps(codec);
6209 alc_rebuild_imux_for_auto_mic(codec);
6210 alc_remove_invalid_adc_nids(codec);
6211 }
6212
6213 if (!spec->no_analog && !spec->cap_mixer)
6214 set_capture_mixer(codec);
6215
6216 if (!spec->no_analog && has_cdefine_beep(codec)) { 6824 if (!spec->no_analog && has_cdefine_beep(codec)) {
6217 err = snd_hda_attach_beep_device(codec, 0x1); 6825 err = snd_hda_attach_beep_device(codec, 0x1);
6218 if (err < 0) 6826 if (err < 0)
@@ -6232,16 +6840,10 @@ static int patch_alc662(struct hda_codec *codec)
6232 } 6840 }
6233 } 6841 }
6234 6842
6235 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6236
6237 codec->patch_ops = alc_patch_ops; 6843 codec->patch_ops = alc_patch_ops;
6238 spec->init_hook = alc_auto_init_std;
6239 spec->shutup = alc_eapd_shutup; 6844 spec->shutup = alc_eapd_shutup;
6240 6845
6241#ifdef CONFIG_SND_HDA_POWER_SAVE 6846 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6242 if (!spec->loopback.amplist)
6243 spec->loopback.amplist = alc662_loopbacks;
6244#endif
6245 6847
6246 return 0; 6848 return 0;
6247 6849
@@ -6281,11 +6883,7 @@ static int patch_alc680(struct hda_codec *codec)
6281 return err; 6883 return err;
6282 } 6884 }
6283 6885
6284 if (!spec->no_analog && !spec->cap_mixer)
6285 set_capture_mixer(codec);
6286
6287 codec->patch_ops = alc_patch_ops; 6886 codec->patch_ops = alc_patch_ops;
6288 spec->init_hook = alc_auto_init_std;
6289 6887
6290 return 0; 6888 return 0;
6291} 6889}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9dbb5735d778..33a9946b492c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -99,6 +99,7 @@ enum {
99 STAC_DELL_VOSTRO_3500, 99 STAC_DELL_VOSTRO_3500,
100 STAC_92HD83XXX_HP_cNB11_INTQUAD, 100 STAC_92HD83XXX_HP_cNB11_INTQUAD,
101 STAC_HP_DV7_4000, 101 STAC_HP_DV7_4000,
102 STAC_HP_ZEPHYR,
102 STAC_92HD83XXX_MODELS 103 STAC_92HD83XXX_MODELS
103}; 104};
104 105
@@ -309,6 +310,8 @@ struct sigmatel_spec {
309 unsigned long auto_capvols[MAX_ADCS_NUM]; 310 unsigned long auto_capvols[MAX_ADCS_NUM];
310 unsigned auto_dmic_cnt; 311 unsigned auto_dmic_cnt;
311 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; 312 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
313
314 struct hda_vmaster_mute_hook vmaster_mute;
312}; 315};
313 316
314static const hda_nid_t stac9200_adc_nids[1] = { 317static const hda_nid_t stac9200_adc_nids[1] = {
@@ -662,7 +665,6 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
662 return 0; 665 return 0;
663} 666}
664 667
665#ifdef CONFIG_SND_HDA_POWER_SAVE
666static int stac_vrefout_set(struct hda_codec *codec, 668static int stac_vrefout_set(struct hda_codec *codec,
667 hda_nid_t nid, unsigned int new_vref) 669 hda_nid_t nid, unsigned int new_vref)
668{ 670{
@@ -686,7 +688,6 @@ static int stac_vrefout_set(struct hda_codec *codec,
686 688
687 return 1; 689 return 1;
688} 690}
689#endif
690 691
691static unsigned int stac92xx_vref_set(struct hda_codec *codec, 692static unsigned int stac92xx_vref_set(struct hda_codec *codec,
692 hda_nid_t nid, unsigned int new_vref) 693 hda_nid_t nid, unsigned int new_vref)
@@ -894,6 +895,13 @@ static const struct hda_verb stac92hd83xxx_core_init[] = {
894 {} 895 {}
895}; 896};
896 897
898static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
899 { 0x22, 0x785, 0x43 },
900 { 0x22, 0x782, 0xe0 },
901 { 0x22, 0x795, 0x00 },
902 {}
903};
904
897static const struct hda_verb stac92hd71bxx_core_init[] = { 905static const struct hda_verb stac92hd71bxx_core_init[] = {
898 /* set master volume and direct control */ 906 /* set master volume and direct control */
899 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 907 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -999,8 +1007,8 @@ static const struct hda_verb stac9205_core_init[] = {
999 } 1007 }
1000 1008
1001static const struct snd_kcontrol_new stac9200_mixer[] = { 1009static const struct snd_kcontrol_new stac9200_mixer[] = {
1002 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 1010 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
1003 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 1011 HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
1004 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 1012 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1005 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 1013 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
1006 { } /* end */ 1014 { } /* end */
@@ -1027,8 +1035,8 @@ static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1027}; 1035};
1028 1036
1029static const struct snd_kcontrol_new stac925x_mixer[] = { 1037static const struct snd_kcontrol_new stac925x_mixer[] = {
1030 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), 1038 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
1031 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1039 HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
1032 { } /* end */ 1040 { } /* end */
1033}; 1041};
1034 1042
@@ -1060,34 +1068,25 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1060 .put = stac92xx_smux_enum_put, 1068 .put = stac92xx_smux_enum_put,
1061}; 1069};
1062 1070
1063static const char * const slave_vols[] = { 1071static const char * const slave_pfxs[] = {
1064 "Front Playback Volume", 1072 "Front", "Surround", "Center", "LFE", "Side",
1065 "Surround Playback Volume", 1073 "Headphone", "Speaker", "IEC958",
1066 "Center Playback Volume",
1067 "LFE Playback Volume",
1068 "Side Playback Volume",
1069 "Headphone Playback Volume",
1070 "Speaker Playback Volume",
1071 NULL 1074 NULL
1072}; 1075};
1073 1076
1074static const char * const slave_sws[] = { 1077static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
1075 "Front Playback Switch", 1078
1076 "Surround Playback Switch", 1079static void stac92xx_vmaster_hook(void *private_data, int val)
1077 "Center Playback Switch", 1080{
1078 "LFE Playback Switch", 1081 stac92xx_update_led_status(private_data, val);
1079 "Side Playback Switch", 1082}
1080 "Headphone Playback Switch",
1081 "Speaker Playback Switch",
1082 "IEC958 Playback Switch",
1083 NULL
1084};
1085 1083
1086static void stac92xx_free_kctls(struct hda_codec *codec); 1084static void stac92xx_free_kctls(struct hda_codec *codec);
1087 1085
1088static int stac92xx_build_controls(struct hda_codec *codec) 1086static int stac92xx_build_controls(struct hda_codec *codec)
1089{ 1087{
1090 struct sigmatel_spec *spec = codec->spec; 1088 struct sigmatel_spec *spec = codec->spec;
1089 unsigned int vmaster_tlv[4];
1091 int err; 1090 int err;
1092 int i; 1091 int i;
1093 1092
@@ -1144,22 +1143,28 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1144 } 1143 }
1145 1144
1146 /* if we have no master control, let's create it */ 1145 /* if we have no master control, let's create it */
1147 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 1146 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1148 unsigned int vmaster_tlv[4]; 1147 HDA_OUTPUT, vmaster_tlv);
1149 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1148 /* correct volume offset */
1150 HDA_OUTPUT, vmaster_tlv); 1149 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1151 /* correct volume offset */ 1150 /* minimum value is actually mute */
1152 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; 1151 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1153 /* minimum value is actually mute */ 1152 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1154 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; 1153 vmaster_tlv, slave_pfxs,
1155 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1154 "Playback Volume");
1156 vmaster_tlv, slave_vols); 1155 if (err < 0)
1157 if (err < 0) 1156 return err;
1158 return err; 1157
1159 } 1158 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1160 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1159 NULL, slave_pfxs,
1161 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1160 "Playback Switch", true,
1162 NULL, slave_sws); 1161 &spec->vmaster_mute.sw_kctl);
1162 if (err < 0)
1163 return err;
1164
1165 if (spec->gpio_led) {
1166 spec->vmaster_mute.hook = stac92xx_vmaster_hook;
1167 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
1163 if (err < 0) 1168 if (err < 0)
1164 return err; 1169 return err;
1165 } 1170 }
@@ -1636,6 +1641,12 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
1636 0x40f000f0, 0x40f000f0, 1641 0x40f000f0, 0x40f000f0,
1637}; 1642};
1638 1643
1644static const unsigned int hp_zephyr_pin_configs[10] = {
1645 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
1646 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
1647 0, 0,
1648};
1649
1639static const unsigned int hp_cNB11_intquad_pin_configs[10] = { 1650static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1640 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, 1651 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1641 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, 1652 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
@@ -1649,6 +1660,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1649 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, 1660 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
1650 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, 1661 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1651 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1662 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1663 [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
1652}; 1664};
1653 1665
1654static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1666static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1659,6 +1671,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1659 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", 1671 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
1660 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1672 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1661 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1673 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1674 [STAC_HP_ZEPHYR] = "hp-zephyr",
1662}; 1675};
1663 1676
1664static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1677static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1711,6 +1724,14 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1711 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1712 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, 1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1713 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1728 "HP", STAC_HP_ZEPHYR),
1729 {} /* terminator */
1730};
1731
1732static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1734 "HP", STAC_HP_ZEPHYR),
1714 {} /* terminator */ 1735 {} /* terminator */
1715}; 1736};
1716 1737
@@ -4410,8 +4431,7 @@ static int stac92xx_init(struct hda_codec *codec)
4410 snd_hda_jack_report_sync(codec); 4431 snd_hda_jack_report_sync(codec);
4411 4432
4412 /* sync mute LED */ 4433 /* sync mute LED */
4413 if (spec->gpio_led) 4434 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4414 hda_call_check_power_status(codec, 0x01);
4415 if (spec->dac_list) 4435 if (spec->dac_list)
4416 stac92xx_power_down(codec); 4436 stac92xx_power_down(codec);
4417 return 0; 4437 return 0;
@@ -4989,7 +5009,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4989 return 0; 5009 return 0;
4990} 5010}
4991 5011
4992#ifdef CONFIG_SND_HDA_POWER_SAVE
4993static int stac92xx_pre_resume(struct hda_codec *codec) 5012static int stac92xx_pre_resume(struct hda_codec *codec)
4994{ 5013{
4995 struct sigmatel_spec *spec = codec->spec; 5014 struct sigmatel_spec *spec = codec->spec;
@@ -5024,82 +5043,40 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5024 afg_power_state); 5043 afg_power_state);
5025 snd_hda_codec_set_power_to_all(codec, fg, power_state, true); 5044 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5026} 5045}
5046#else
5047#define stac92xx_suspend NULL
5048#define stac92xx_resume NULL
5049#define stac92xx_pre_resume NULL
5050#define stac92xx_set_power_state NULL
5051#endif /* CONFIG_PM */
5027 5052
5028/* 5053/* update mute-LED accoring to the master switch */
5029 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed 5054static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
5030 * as mute LED state is updated in check_power_status hook
5031 */
5032static int stac92xx_update_led_status(struct hda_codec *codec)
5033{ 5055{
5034 struct sigmatel_spec *spec = codec->spec; 5056 struct sigmatel_spec *spec = codec->spec;
5035 int i, num_ext_dacs, muted = 1; 5057 int muted = !enabled;
5036 unsigned int muted_lvl, notmtd_lvl;
5037 hda_nid_t nid;
5038 5058
5039 if (!spec->gpio_led) 5059 if (!spec->gpio_led)
5040 return 0; 5060 return;
5061
5062 /* LED state is inverted on these systems */
5063 if (spec->gpio_led_polarity)
5064 muted = !muted;
5041 5065
5042 for (i = 0; i < spec->multiout.num_dacs; i++) {
5043 nid = spec->multiout.dac_nids[i];
5044 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5045 HDA_AMP_MUTE)) {
5046 muted = 0; /* something heard */
5047 break;
5048 }
5049 }
5050 if (muted && spec->multiout.hp_nid)
5051 if (!(snd_hda_codec_amp_read(codec,
5052 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
5053 HDA_AMP_MUTE)) {
5054 muted = 0; /* HP is not muted */
5055 }
5056 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
5057 for (i = 0; muted && i < num_ext_dacs; i++) {
5058 nid = spec->multiout.extra_out_nid[i];
5059 if (nid == 0)
5060 break;
5061 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5062 HDA_AMP_MUTE)) {
5063 muted = 0; /* extra output is not muted */
5064 }
5065 }
5066 /*polarity defines *not* muted state level*/ 5066 /*polarity defines *not* muted state level*/
5067 if (!spec->vref_mute_led_nid) { 5067 if (!spec->vref_mute_led_nid) {
5068 if (muted) 5068 if (muted)
5069 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5069 spec->gpio_data &= ~spec->gpio_led; /* orange */
5070 else 5070 else
5071 spec->gpio_data |= spec->gpio_led; /* white */ 5071 spec->gpio_data |= spec->gpio_led; /* white */
5072
5073 if (!spec->gpio_led_polarity) {
5074 /* LED state is inverted on these systems */
5075 spec->gpio_data ^= spec->gpio_led;
5076 }
5077 stac_gpio_set(codec, spec->gpio_mask, 5072 stac_gpio_set(codec, spec->gpio_mask,
5078 spec->gpio_dir, spec->gpio_data); 5073 spec->gpio_dir, spec->gpio_data);
5079 } else { 5074 } else {
5080 notmtd_lvl = spec->gpio_led_polarity ? 5075 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5081 AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5082 muted_lvl = spec->gpio_led_polarity ?
5083 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
5084 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5085 stac_vrefout_set(codec, spec->vref_mute_led_nid, 5076 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5086 spec->vref_led); 5077 spec->vref_led);
5087 } 5078 }
5088 return 0;
5089}
5090
5091/*
5092 * use power check for controlling mute led of HP notebooks
5093 */
5094static int stac92xx_check_power_status(struct hda_codec *codec,
5095 hda_nid_t nid)
5096{
5097 stac92xx_update_led_status(codec);
5098
5099 return 0;
5100} 5079}
5101#endif /* CONFIG_SND_HDA_POWER_SAVE */
5102#endif /* CONFIG_PM */
5103 5080
5104static const struct hda_codec_ops stac92xx_patch_ops = { 5081static const struct hda_codec_ops stac92xx_patch_ops = {
5105 .build_controls = stac92xx_build_controls, 5082 .build_controls = stac92xx_build_controls,
@@ -5580,6 +5557,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5580 STAC_92HD83XXX_MODELS, 5557 STAC_92HD83XXX_MODELS,
5581 stac92hd83xxx_models, 5558 stac92hd83xxx_models,
5582 stac92hd83xxx_cfg_tbl); 5559 stac92hd83xxx_cfg_tbl);
5560 /* check codec subsystem id if not found */
5561 if (spec->board_config < 0)
5562 spec->board_config =
5563 snd_hda_check_board_codec_sid_config(codec,
5564 STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
5565 stac92hd83xxx_codec_id_cfg_tbl);
5583again: 5566again:
5584 if (spec->board_config < 0) 5567 if (spec->board_config < 0)
5585 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5568 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -5590,12 +5573,17 @@ again:
5590 5573
5591 codec->patch_ops = stac92xx_patch_ops; 5574 codec->patch_ops = stac92xx_patch_ops;
5592 5575
5576 switch (spec->board_config) {
5577 case STAC_HP_ZEPHYR:
5578 spec->init = stac92hd83xxx_hp_zephyr_init;
5579 break;
5580 }
5581
5593 if (find_mute_led_cfg(codec, -1/*no default cfg*/)) 5582 if (find_mute_led_cfg(codec, -1/*no default cfg*/))
5594 snd_printd("mute LED gpio %d polarity %d\n", 5583 snd_printd("mute LED gpio %d polarity %d\n",
5595 spec->gpio_led, 5584 spec->gpio_led,
5596 spec->gpio_led_polarity); 5585 spec->gpio_led_polarity);
5597 5586
5598#ifdef CONFIG_SND_HDA_POWER_SAVE
5599 if (spec->gpio_led) { 5587 if (spec->gpio_led) {
5600 if (!spec->vref_mute_led_nid) { 5588 if (!spec->vref_mute_led_nid) {
5601 spec->gpio_mask |= spec->gpio_led; 5589 spec->gpio_mask |= spec->gpio_led;
@@ -5605,11 +5593,10 @@ again:
5605 codec->patch_ops.set_power_state = 5593 codec->patch_ops.set_power_state =
5606 stac92xx_set_power_state; 5594 stac92xx_set_power_state;
5607 } 5595 }
5596#ifdef CONFIG_PM
5608 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5597 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5609 codec->patch_ops.check_power_status = 5598#endif
5610 stac92xx_check_power_status;
5611 } 5599 }
5612#endif
5613 5600
5614 err = stac92xx_parse_auto_config(codec); 5601 err = stac92xx_parse_auto_config(codec);
5615 if (!err) { 5602 if (!err) {
@@ -5906,7 +5893,6 @@ again:
5906 spec->gpio_led, 5893 spec->gpio_led,
5907 spec->gpio_led_polarity); 5894 spec->gpio_led_polarity);
5908 5895
5909#ifdef CONFIG_SND_HDA_POWER_SAVE
5910 if (spec->gpio_led) { 5896 if (spec->gpio_led) {
5911 if (!spec->vref_mute_led_nid) { 5897 if (!spec->vref_mute_led_nid) {
5912 spec->gpio_mask |= spec->gpio_led; 5898 spec->gpio_mask |= spec->gpio_led;
@@ -5916,11 +5902,10 @@ again:
5916 codec->patch_ops.set_power_state = 5902 codec->patch_ops.set_power_state =
5917 stac92xx_set_power_state; 5903 stac92xx_set_power_state;
5918 } 5904 }
5905#ifdef CONFIG_PM
5919 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5906 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5920 codec->patch_ops.check_power_status = 5907#endif
5921 stac92xx_check_power_status;
5922 } 5908 }
5923#endif
5924 5909
5925 spec->multiout.dac_nids = spec->dac_nids; 5910 spec->multiout.dac_nids = spec->dac_nids;
5926 5911
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index dff9a00ee8fb..06214fdc9486 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -550,7 +550,10 @@ static void via_auto_init_output(struct hda_codec *codec,
550 pin = path->path[path->depth - 1]; 550 pin = path->path[path->depth - 1];
551 551
552 init_output_pin(codec, pin, pin_type); 552 init_output_pin(codec, pin, pin_type);
553 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 553 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
554 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
555 else
556 caps = 0;
554 if (caps & AC_AMPCAP_MUTE) { 557 if (caps & AC_AMPCAP_MUTE) {
555 unsigned int val; 558 unsigned int val;
556 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; 559 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
@@ -645,6 +648,10 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
645 648
646 /* init ADCs */ 649 /* init ADCs */
647 for (i = 0; i < spec->num_adc_nids; i++) { 650 for (i = 0; i < spec->num_adc_nids; i++) {
651 hda_nid_t nid = spec->adc_nids[i];
652 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) ||
653 !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE))
654 continue;
648 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 655 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
649 AC_VERB_SET_AMP_GAIN_MUTE, 656 AC_VERB_SET_AMP_GAIN_MUTE,
650 AMP_IN_UNMUTE(0)); 657 AMP_IN_UNMUTE(0));
@@ -1445,25 +1452,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = {
1445/* 1452/*
1446 * slave controls for virtual master 1453 * slave controls for virtual master
1447 */ 1454 */
1448static const char * const via_slave_vols[] = { 1455static const char * const via_slave_pfxs[] = {
1449 "Front Playback Volume", 1456 "Front", "Surround", "Center", "LFE", "Side",
1450 "Surround Playback Volume", 1457 "Headphone", "Speaker",
1451 "Center Playback Volume",
1452 "LFE Playback Volume",
1453 "Side Playback Volume",
1454 "Headphone Playback Volume",
1455 "Speaker Playback Volume",
1456 NULL,
1457};
1458
1459static const char * const via_slave_sws[] = {
1460 "Front Playback Switch",
1461 "Surround Playback Switch",
1462 "Center Playback Switch",
1463 "LFE Playback Switch",
1464 "Side Playback Switch",
1465 "Headphone Playback Switch",
1466 "Speaker Playback Switch",
1467 NULL, 1458 NULL,
1468}; 1459};
1469 1460
@@ -1508,13 +1499,15 @@ static int via_build_controls(struct hda_codec *codec)
1508 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1499 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1509 HDA_OUTPUT, vmaster_tlv); 1500 HDA_OUTPUT, vmaster_tlv);
1510 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1501 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1511 vmaster_tlv, via_slave_vols); 1502 vmaster_tlv, via_slave_pfxs,
1503 "Playback Volume");
1512 if (err < 0) 1504 if (err < 0)
1513 return err; 1505 return err;
1514 } 1506 }
1515 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1507 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1516 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1508 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1517 NULL, via_slave_sws); 1509 NULL, via_slave_pfxs,
1510 "Playback Switch");
1518 if (err < 0) 1511 if (err < 0)
1519 return err; 1512 return err;
1520 } 1513 }
@@ -1522,6 +1515,8 @@ static int via_build_controls(struct hda_codec *codec)
1522 /* assign Capture Source enums to NID */ 1515 /* assign Capture Source enums to NID */
1523 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1516 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1524 for (i = 0; kctl && i < kctl->count; i++) { 1517 for (i = 0; kctl && i < kctl->count; i++) {
1518 if (!spec->mux_nids[i])
1519 continue;
1525 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); 1520 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1526 if (err < 0) 1521 if (err < 0)
1527 return err; 1522 return err;
@@ -2488,6 +2483,8 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2488{ 2483{
2489 struct via_spec *spec = codec->spec; 2484 struct via_spec *spec = codec->spec;
2490 const struct auto_pin_cfg *cfg = &spec->autocfg; 2485 const struct auto_pin_cfg *cfg = &spec->autocfg;
2486 const char *prev_label = NULL;
2487 int type_idx = 0;
2491 int i, err; 2488 int i, err;
2492 2489
2493 for (i = 0; i < cfg->num_inputs; i++) { 2490 for (i = 0; i < cfg->num_inputs; i++) {
@@ -2502,8 +2499,13 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2502 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) 2499 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2503 continue; 2500 continue;
2504 label = hda_get_autocfg_input_label(codec, cfg, i); 2501 label = hda_get_autocfg_input_label(codec, cfg, i);
2502 if (prev_label && !strcmp(label, prev_label))
2503 type_idx++;
2504 else
2505 type_idx = 0;
2506 prev_label = label;
2505 snprintf(name, sizeof(name), "%s Boost Volume", label); 2507 snprintf(name, sizeof(name), "%s Boost Volume", label);
2506 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2508 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
2507 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); 2509 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2508 if (err < 0) 2510 if (err < 0)
2509 return err; 2511 return err;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 92362973764d..812d10e43ae0 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice,
1013 ice->hw_rates); 1013 ice->hw_rates);
1014} 1014}
1015 1015
1016/* if the card has the internal rate locked (is_pro_locked), limit runtime
1017 hw rates to the current internal rate only.
1018*/
1019static void constrain_rate_if_locked(struct snd_pcm_substream *substream)
1020{
1021 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
1022 struct snd_pcm_runtime *runtime = substream->runtime;
1023 unsigned int rate;
1024 if (is_pro_rate_locked(ice)) {
1025 rate = ice->get_rate(ice);
1026 if (rate >= runtime->hw.rate_min
1027 && rate <= runtime->hw.rate_max) {
1028 runtime->hw.rate_min = rate;
1029 runtime->hw.rate_max = rate;
1030 }
1031 }
1032}
1033
1034
1016/* multi-channel playback needs alignment 8x32bit regardless of the channels 1035/* multi-channel playback needs alignment 8x32bit regardless of the channels
1017 * actually used 1036 * actually used
1018 */ 1037 */
@@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1046 VT1724_BUFFER_ALIGN); 1065 VT1724_BUFFER_ALIGN);
1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1066 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1048 VT1724_BUFFER_ALIGN); 1067 VT1724_BUFFER_ALIGN);
1068 constrain_rate_if_locked(substream);
1049 if (ice->pro_open) 1069 if (ice->pro_open)
1050 ice->pro_open(ice, substream); 1070 ice->pro_open(ice, substream);
1051 return 0; 1071 return 0;
@@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1066 VT1724_BUFFER_ALIGN); 1086 VT1724_BUFFER_ALIGN);
1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1087 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1068 VT1724_BUFFER_ALIGN); 1088 VT1724_BUFFER_ALIGN);
1089 constrain_rate_if_locked(substream);
1069 if (ice->pro_open) 1090 if (ice->pro_open)
1070 ice->pro_open(ice, substream); 1091 ice->pro_open(ice, substream);
1071 return 0; 1092 return 0;
@@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
1215 VT1724_BUFFER_ALIGN); 1236 VT1724_BUFFER_ALIGN);
1216 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1237 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1217 VT1724_BUFFER_ALIGN); 1238 VT1724_BUFFER_ALIGN);
1239 constrain_rate_if_locked(substream);
1218 if (ice->spdif.ops.open) 1240 if (ice->spdif.ops.open)
1219 ice->spdif.ops.open(ice, substream); 1241 ice->spdif.ops.open(ice, substream);
1220 return 0; 1242 return 0;
@@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
1251 VT1724_BUFFER_ALIGN); 1273 VT1724_BUFFER_ALIGN);
1252 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1274 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1253 VT1724_BUFFER_ALIGN); 1275 VT1724_BUFFER_ALIGN);
1276 constrain_rate_if_locked(substream);
1254 if (ice->spdif.ops.open) 1277 if (ice->spdif.ops.open)
1255 ice->spdif.ops.open(ice, substream); 1278 ice->spdif.ops.open(ice, substream);
1256 return 0; 1279 return 0;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 12a9a2b03387..a8159b81e9c4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2317,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) 2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); 2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); 2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2320 pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
2321 &chip->saved_dsxg_legacy);
2322 pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2323 &chip->saved_dsxg_elegacy);
2320 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2324 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2321 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); 2325 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2322 snd_ymfpci_disable_dsp(chip); 2326 snd_ymfpci_disable_dsp(chip);
@@ -2351,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2351 2355
2352 snd_ac97_resume(chip->ac97); 2356 snd_ac97_resume(chip->ac97);
2353 2357
2358 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
2359 chip->saved_dsxg_legacy);
2360 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2361 chip->saved_dsxg_elegacy);
2362
2354 /* start hw again */ 2363 /* start hw again */
2355 if (chip->start_count > 0) { 2364 if (chip->start_count > 0) {
2356 spin_lock_irq(&chip->reg_lock); 2365 spin_lock_irq(&chip->reg_lock);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 35e662d270e6..91c985599d32 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -25,6 +25,9 @@ if SND_SOC
25config SND_SOC_AC97_BUS 25config SND_SOC_AC97_BUS
26 bool 26 bool
27 27
28config SND_SOC_DMAENGINE_PCM
29 bool
30
28# All the supported SoCs 31# All the supported SoCs
29source "sound/soc/atmel/Kconfig" 32source "sound/soc/atmel/Kconfig"
30source "sound/soc/au1x/Kconfig" 33source "sound/soc/au1x/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9ea8ac827adc..2feaf376e94b 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,6 +1,9 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-io.o 2snd-soc-core-objs += soc-pcm.o soc-io.o
3 3
4snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
5obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
6
4obj-$(CONFIG_SND_SOC) += snd-soc-core.o 7obj-$(CONFIG_SND_SOC) += snd-soc-core.o
5obj-$(CONFIG_SND_SOC) += codecs/ 8obj-$(CONFIG_SND_SOC) += codecs/
6obj-$(CONFIG_SND_SOC) += atmel/ 9obj-$(CONFIG_SND_SOC) += atmel/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index a21ff459e5d3..9b84f985770e 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = {
362/*--------------------------------------------------------------------------*\ 362/*--------------------------------------------------------------------------*\
363 * ASoC platform driver 363 * ASoC platform driver
364\*--------------------------------------------------------------------------*/ 364\*--------------------------------------------------------------------------*/
365static u64 atmel_pcm_dmamask = 0xffffffff; 365static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
366 366
367static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) 367static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
368{ 368{
@@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
373 if (!card->dev->dma_mask) 373 if (!card->dev->dma_mask)
374 card->dev->dma_mask = &atmel_pcm_dmamask; 374 card->dev->dma_mask = &atmel_pcm_dmamask;
375 if (!card->dev->coherent_dma_mask) 375 if (!card->dev->coherent_dma_mask)
376 card->dev->coherent_dma_mask = 0xffffffff; 376 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
377 377
378 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 378 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
379 ret = atmel_pcm_preallocate_dma_buffer(pcm, 379 ret = atmel_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 4ca667d477f9..f65f08beac31 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -46,29 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
46{ 46{
47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 47 struct snd_soc_pcm_runtime *rtd = substream->private_data;
48 struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 int err; 49 int err;
51 50
52 /* Set codec DAI configuration */
53 err = snd_soc_dai_set_fmt(codec_dai,
54 SND_SOC_DAIFMT_I2S|
55 SND_SOC_DAIFMT_NB_IF |
56 SND_SOC_DAIFMT_CBM_CFM);
57 if (err < 0) {
58 printk(KERN_ERR "can't set codec DAI configuration\n");
59 return err;
60 }
61
62 /* Set cpu DAI configuration */
63 err = snd_soc_dai_set_fmt(cpu_dai,
64 SND_SOC_DAIFMT_I2S |
65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) {
68 printk(KERN_ERR "can't set cpu DAI configuration\n");
69 return err;
70 }
71
72 /* Set the codec system clock for DAC and ADC */ 51 /* Set the codec system clock for DAC and ADC */
73 err = 52 err =
74 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); 53 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -91,7 +70,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
91 SND_SOC_DAPM_MIC("Mic Jack", NULL), 70 SND_SOC_DAPM_MIC("Mic Jack", NULL),
92}; 71};
93 72
94static const struct snd_soc_dapm_route audio_map[] = { 73static const struct snd_soc_dapm_route afeb9260_audio_map[] = {
95 {"Headphone Jack", NULL, "LHPOUT"}, 74 {"Headphone Jack", NULL, "LHPOUT"},
96 {"Headphone Jack", NULL, "RHPOUT"}, 75 {"Headphone Jack", NULL, "RHPOUT"},
97 76
@@ -106,13 +85,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
106 struct snd_soc_codec *codec = rtd->codec; 85 struct snd_soc_codec *codec = rtd->codec;
107 struct snd_soc_dapm_context *dapm = &codec->dapm; 86 struct snd_soc_dapm_context *dapm = &codec->dapm;
108 87
109 /* Add afeb9260 specific widgets */
110 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
111 ARRAY_SIZE(tlv320aic23_dapm_widgets));
112
113 /* Set up afeb9260 specific audio path audio_map */
114 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
115
116 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 88 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
117 snd_soc_dapm_enable_pin(dapm, "Line In"); 89 snd_soc_dapm_enable_pin(dapm, "Line In");
118 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 90 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
@@ -129,6 +101,8 @@ static struct snd_soc_dai_link afeb9260_dai = {
129 .platform_name = "atmel_pcm-audio", 101 .platform_name = "atmel_pcm-audio",
130 .codec_name = "tlv320aic23-codec.0-001a", 102 .codec_name = "tlv320aic23-codec.0-001a",
131 .init = afeb9260_tlv320aic23_init, 103 .init = afeb9260_tlv320aic23_init,
104 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
105 SND_SOC_DAIFMT_CBM_CFM,
132 .ops = &afeb9260_ops, 106 .ops = &afeb9260_ops,
133}; 107};
134 108
@@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = {
138 .owner = THIS_MODULE, 112 .owner = THIS_MODULE,
139 .dai_link = &afeb9260_dai, 113 .dai_link = &afeb9260_dai,
140 .num_links = 1, 114 .num_links = 1,
115
116 .dapm_widgets = tlv320aic23_dapm_widgets,
117 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
118 .dapm_routes = afeb9260_audio_map,
119 .num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map),
141}; 120};
142 121
143static struct platform_device *afeb9260_snd_device; 122static struct platform_device *afeb9260_snd_device;
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 60962ce6cd4d..d542d4063771 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -40,20 +40,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
40{ 40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; 43 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
45 int ret = 0; 44 int ret = 0;
46 /* set cpu DAI configuration */
47 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
48 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0)
50 return ret;
51
52 /* set codec DAI configuration */
53 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
54 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
55 if (ret < 0)
56 return ret;
57 45
58 /* set cpu DAI channel mapping */ 46 /* set cpu DAI channel mapping */
59 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), 47 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
@@ -68,6 +56,9 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
68 .hw_params = bf5xx_ad1836_hw_params, 56 .hw_params = bf5xx_ad1836_hw_params,
69}; 57};
70 58
59#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
60 SND_SOC_DAIFMT_CBM_CFM)
61
71static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { 62static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
72 { 63 {
73 .name = "ad1836", 64 .name = "ad1836",
@@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
77 .platform_name = "bfin-tdm-pcm-audio", 68 .platform_name = "bfin-tdm-pcm-audio",
78 .codec_name = "spi0.4", 69 .codec_name = "spi0.4",
79 .ops = &bf5xx_ad1836_ops, 70 .ops = &bf5xx_ad1836_ops,
71 .dai_fmt = BF5XX_AD1836_DAIFMT,
80 }, 72 },
81 { 73 {
82 .name = "ad1836", 74 .name = "ad1836",
@@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
86 .platform_name = "bfin-tdm-pcm-audio", 78 .platform_name = "bfin-tdm-pcm-audio",
87 .codec_name = "spi0.4", 79 .codec_name = "spi0.4",
88 .ops = &bf5xx_ad1836_ops, 80 .ops = &bf5xx_ad1836_ops,
81 .dai_fmt = BF5XX_AD1836_DAIFMT,
89 }, 82 },
90}; 83};
91 84
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 2d8d82dbc159..0e55e9f2a514 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
60 break; 60 break;
61 } 61 }
62 62
63 /* set cpu DAI configuration */
64 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
65 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 /* set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
71 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
72 if (ret < 0)
73 return ret;
74
75 /* set the codec system clock for DAC and ADC */ 63 /* set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 64 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
77 SND_SOC_CLOCK_IN); 65 SND_SOC_CLOCK_IN);
@@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
92 return 0; 80 return 0;
93} 81}
94 82
83#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
84 SND_SOC_DAIFMT_CBM_CFM)
85
95static struct snd_soc_ops bf5xx_ad193x_ops = { 86static struct snd_soc_ops bf5xx_ad193x_ops = {
96 .hw_params = bf5xx_ad193x_hw_params, 87 .hw_params = bf5xx_ad193x_hw_params,
97}; 88};
@@ -105,6 +96,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
105 .platform_name = "bfin-tdm-pcm-audio", 96 .platform_name = "bfin-tdm-pcm-audio",
106 .codec_name = "spi0.5", 97 .codec_name = "spi0.5",
107 .ops = &bf5xx_ad193x_ops, 98 .ops = &bf5xx_ad193x_ops,
99 .dai_fmt = BF5XX_AD193X_DAIFMT,
108 }, 100 },
109 { 101 {
110 .name = "ad193x", 102 .name = "ad193x",
@@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
114 .platform_name = "bfin-tdm-pcm-audio", 106 .platform_name = "bfin-tdm-pcm-audio",
115 .codec_name = "spi0.5", 107 .codec_name = "spi0.5",
116 .ops = &bf5xx_ad193x_ops, 108 .ops = &bf5xx_ad193x_ops,
109 .dai_fmt = BF5XX_AD193X_DAIFMT,
117 }, 110 },
118}; 111};
119 112
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 8e49508596da..61cc91d4a028 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card)
145 return 0; 145 return 0;
146} 146}
147 147
148static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, 148#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
149 struct snd_pcm_hw_params *params) 149 SND_SOC_DAIFMT_CBM_CFM)
150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153 int ret = 0;
154
155 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
156 params_format(params));
157
158 /* set cpu DAI configuration */
159 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
160 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
161 if (ret < 0)
162 return ret;
163
164 return 0;
165}
166
167
168static struct snd_soc_ops bf5xx_ad73311_ops = {
169 .hw_params = bf5xx_ad73311_hw_params,
170};
171 150
172static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { 151static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
173 { 152 {
@@ -177,7 +156,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
177 .codec_dai_name = "ad73311-hifi", 156 .codec_dai_name = "ad73311-hifi",
178 .platform_name = "bfin-i2s-pcm-audio", 157 .platform_name = "bfin-i2s-pcm-audio",
179 .codec_name = "ad73311", 158 .codec_name = "ad73311",
180 .ops = &bf5xx_ad73311_ops, 159 .dai_fmt = BF5XX_AD7311_DAI_FMT,
181 }, 160 },
182 { 161 {
183 .name = "ad73311", 162 .name = "ad73311",
@@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
186 .codec_dai_name = "ad73311-hifi", 165 .codec_dai_name = "ad73311-hifi",
187 .platform_name = "bfin-i2s-pcm-audio", 166 .platform_name = "bfin-i2s-pcm-audio",
188 .codec_name = "ad73311", 167 .codec_name = "ad73311",
189 .ops = &bf5xx_ad73311_ops, 168 .dai_fmt = BF5XX_AD7311_DAI_FMT,
190 }, 169 },
191}; 170};
192 171
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 030303238042..df3ac73f8778 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -49,7 +49,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
49{ 49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *codec_dai = rtd->codec_dai; 51 struct snd_soc_dai *codec_dai = rtd->codec_dai;
52 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
53 unsigned int clk = 0; 52 unsigned int clk = 0;
54 int ret = 0; 53 int ret = 0;
55 54
@@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
75 break; 74 break;
76 } 75 }
77 76
78 /*
79 * CODEC is master for BCLK and LRC in this configuration.
80 */
81
82 /* set codec DAI configuration */
83 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
84 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
85 if (ret < 0)
86 return ret;
87 /* set cpu DAI configuration */
88 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
89 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
90 if (ret < 0)
91 return ret;
92
93 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk, 77 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
94 SND_SOC_CLOCK_IN); 78 SND_SOC_CLOCK_IN);
95 if (ret < 0) 79 if (ret < 0)
@@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
102 .hw_params = bf5xx_ssm2602_hw_params, 86 .hw_params = bf5xx_ssm2602_hw_params,
103}; 87};
104 88
89/* CODEC is master for BCLK and LRC in this configuration. */
90#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
91 SND_SOC_DAIFMT_CBM_CFM)
92
105static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { 93static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
106 { 94 {
107 .name = "ssm2602", 95 .name = "ssm2602",
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 26b271c62efa..f3adbdbdd5e1 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params) 67 struct snd_pcm_hw_params *params)
68{ 68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data; 69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_dai *codec_dai = rtd->codec_dai; 70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
72 int ret; 71 int ret;
73 int pll_rate; 72 int pll_rate;
74 73
75 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
76 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
77 if (ret)
78 return ret;
79
80 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
81 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
82 if (ret)
83 return ret;
84
85 switch (params_rate(params)) { 74 switch (params_rate(params)) {
86 case 48000: 75 case 48000:
87 case 8000: 76 case 8000:
@@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
143 .codec_name = "adau1373.0-001a", 132 .codec_name = "adau1373.0-001a",
144 .ops = &bfin_eval_adau1373_ops, 133 .ops = &bfin_eval_adau1373_ops,
145 .init = bfin_eval_adau1373_codec_init, 134 .init = bfin_eval_adau1373_codec_init,
135 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
136 SND_SOC_DAIFMT_CBM_CFM,
146}; 137};
147 138
148static struct snd_soc_card bfin_eval_adau1373 = { 139static struct snd_soc_card bfin_eval_adau1373 = {
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index c0064fa1dca6..b0531fc9d814 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params) 37 struct snd_pcm_hw_params *params)
38{ 38{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 int ret; 41 int ret;
43 42
44 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
45 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
46 if (ret)
47 return ret;
48
49 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
50 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
51 if (ret)
52 return ret;
53
54 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000, 43 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
55 SND_SOC_CLOCK_IN); 44 SND_SOC_CLOCK_IN);
56 45
@@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = {
61 .hw_params = bfin_eval_adau1701_hw_params, 50 .hw_params = bfin_eval_adau1701_hw_params,
62}; 51};
63 52
53#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
54 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
55
64static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { 56static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
65 { 57 {
66 .name = "adau1701", 58 .name = "adau1701",
@@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
70 .platform_name = "bfin-i2s-pcm-audio", 62 .platform_name = "bfin-i2s-pcm-audio",
71 .codec_name = "adau1701.0-0034", 63 .codec_name = "adau1701.0-0034",
72 .ops = &bfin_eval_adau1701_ops, 64 .ops = &bfin_eval_adau1701_ops,
65 .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
73 }, 66 },
74 { 67 {
75 .name = "adau1701", 68 .name = "adau1701",
@@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
79 .platform_name = "bfin-i2s-pcm-audio", 72 .platform_name = "bfin-i2s-pcm-audio",
80 .codec_name = "adau1701.0-0034", 73 .codec_name = "adau1701.0-0034",
81 .ops = &bfin_eval_adau1701_ops, 74 .ops = &bfin_eval_adau1701_ops,
75 .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
82 }, 76 },
83}; 77};
84 78
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 4ef079f95e2e..84b09987b7f3 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
34 struct snd_pcm_hw_params *params) 34 struct snd_pcm_hw_params *params)
35{ 35{
36 struct snd_soc_pcm_runtime *rtd = substream->private_data; 36 struct snd_soc_pcm_runtime *rtd = substream->private_data;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
38 struct snd_soc_dai *codec_dai = rtd->codec_dai; 37 struct snd_soc_dai *codec_dai = rtd->codec_dai;
39 int ret; 38 int ret;
40 39
41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
43 if (ret)
44 return ret;
45
46 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
48 if (ret)
49 return ret;
50
51 ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, 40 ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
52 27000000, params_rate(params) * 256); 41 27000000, params_rate(params) * 256);
53 if (ret) 42 if (ret)
@@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
88 .platform_name = "bfin-i2s-pcm-audio", 77 .platform_name = "bfin-i2s-pcm-audio",
89 .init = bfin_eval_adav80x_codec_init, 78 .init = bfin_eval_adav80x_codec_init,
90 .ops = &bfin_eval_adav80x_ops, 79 .ops = &bfin_eval_adav80x_ops,
80 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
81 SND_SOC_DAIFMT_CBM_CFM,
91 }, 82 },
92}; 83};
93 84
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 7c205e77d83a..6508e8b790bb 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS
40 select SND_SOC_MAX98088 if I2C 40 select SND_SOC_MAX98088 if I2C
41 select SND_SOC_MAX98095 if I2C 41 select SND_SOC_MAX98095 if I2C
42 select SND_SOC_MAX9850 if I2C 42 select SND_SOC_MAX9850 if I2C
43 select SND_SOC_MAX9768 if I2C
43 select SND_SOC_MAX9877 if I2C 44 select SND_SOC_MAX9877 if I2C
44 select SND_SOC_PCM3008 45 select SND_SOC_PCM3008
45 select SND_SOC_RT5631 if I2C 46 select SND_SOC_RT5631 if I2C
@@ -62,6 +63,7 @@ config SND_SOC_ALL_CODECS
62 select SND_SOC_WL1273 if MFD_WL1273_CORE 63 select SND_SOC_WL1273 if MFD_WL1273_CORE
63 select SND_SOC_WM1250_EV1 if I2C 64 select SND_SOC_WM1250_EV1 if I2C
64 select SND_SOC_WM2000 if I2C 65 select SND_SOC_WM2000 if I2C
66 select SND_SOC_WM2200 if I2C
65 select SND_SOC_WM5100 if I2C 67 select SND_SOC_WM5100 if I2C
66 select SND_SOC_WM8350 if MFD_WM8350 68 select SND_SOC_WM8350 if MFD_WM8350
67 select SND_SOC_WM8400 if MFD_WM8400 69 select SND_SOC_WM8400 if MFD_WM8400
@@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1
292config SND_SOC_WM2000 294config SND_SOC_WM2000
293 tristate 295 tristate
294 296
297config SND_SOC_WM2200
298 tristate
299
295config SND_SOC_WM5100 300config SND_SOC_WM5100
296 tristate 301 tristate
297 302
@@ -425,6 +430,9 @@ config SND_SOC_WM9713
425config SND_SOC_LM4857 430config SND_SOC_LM4857
426 tristate 431 tristate
427 432
433config SND_SOC_MAX9768
434 tristate
435
428config SND_SOC_MAX9877 436config SND_SOC_MAX9877
429 tristate 437 tristate
430 438
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index de8078178f86..6662eb0cdcc0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o
25snd-soc-jz4740-codec-objs := jz4740.o 25snd-soc-jz4740-codec-objs := jz4740.o
26snd-soc-l3-objs := l3.o 26snd-soc-l3-objs := l3.o
27snd-soc-lm4857-objs := lm4857.o 27snd-soc-lm4857-objs := lm4857.o
28snd-soc-max9768-objs := max9768.o
28snd-soc-max98088-objs := max98088.o 29snd-soc-max98088-objs := max98088.o
29snd-soc-max98095-objs := max98095.o 30snd-soc-max98095-objs := max98095.o
30snd-soc-max9850-objs := max9850.o 31snd-soc-max9850-objs := max9850.o
@@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o
51snd-soc-wl1273-objs := wl1273.o 52snd-soc-wl1273-objs := wl1273.o
52snd-soc-wm1250-ev1-objs := wm1250-ev1.o 53snd-soc-wm1250-ev1-objs := wm1250-ev1.o
53snd-soc-wm2000-objs := wm2000.o 54snd-soc-wm2000-objs := wm2000.o
55snd-soc-wm2200-objs := wm2200.o
54snd-soc-wm5100-objs := wm5100.o wm5100-tables.o 56snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
55snd-soc-wm8350-objs := wm8350.o 57snd-soc-wm8350-objs := wm8350.o
56snd-soc-wm8400-objs := wm8400.o 58snd-soc-wm8400-objs := wm8400.o
@@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
129obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 131obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
130obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 132obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
131obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 133obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
134obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
132obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 135obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
133obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 136obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
134obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 137obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
@@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
153obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 156obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
154obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o 157obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
155obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 158obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
159obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
156obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o 160obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
157obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 161obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
158obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 162obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 982d201c2e86..12e3b4118557 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
277 if (ad1836->type == AD1836) { 277 if (ad1836->type == AD1836) {
278 /* left/right diff:PGA/MUX */ 278 /* left/right diff:PGA/MUX */
279 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); 279 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
280 ret = snd_soc_add_controls(codec, ad1836_controls, 280 ret = snd_soc_add_codec_controls(codec, ad1836_controls,
281 ARRAY_SIZE(ad1836_controls)); 281 ARRAY_SIZE(ad1836_controls));
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
285 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); 285 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
286 } 286 }
287 287
288 ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2); 288 ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
289 if (ret) 289 if (ret)
290 return ret; 290 return ret;
291 291
292 ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs); 292 ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
293 if (ret) 293 if (ret)
294 return ret; 294 return ret;
295 295
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 9bba7f849464..8c39dddd7d00 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
228 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); 228 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
229 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); 229 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
230 230
231 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 231 snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls,
232 ARRAY_SIZE(ad1980_snd_ac97_controls)); 232 ARRAY_SIZE(ad1980_snd_ac97_controls));
233 233
234 return 0; 234 return 0;
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 971ba4529171..44f59064d8de 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1244 return ret; 1244 return ret;
1245 } 1245 }
1246 1246
1247 codec->dapm.idle_bias_off = true;
1248
1249 if (pdata) { 1247 if (pdata) {
1250 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) 1248 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
1251 return -EINVAL; 1249 return -EINVAL;
@@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1259 pdata->drc_setting[i]); 1257 pdata->drc_setting[i]);
1260 } 1258 }
1261 1259
1262 snd_soc_add_controls(codec, adau1373_drc_controls, 1260 snd_soc_add_codec_controls(codec, adau1373_drc_controls,
1263 pdata->num_drc); 1261 pdata->num_drc);
1264 1262
1265 val = 0; 1263 val = 0;
@@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1284 } 1282 }
1285 1283
1286 if (!lineout_differential) { 1284 if (!lineout_differential) {
1287 snd_soc_add_controls(codec, adau1373_lineout2_controls, 1285 snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
1288 ARRAY_SIZE(adau1373_lineout2_controls)); 1286 ARRAY_SIZE(adau1373_lineout2_controls));
1289 } 1287 }
1290 1288
@@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
1340 .suspend = adau1373_suspend, 1338 .suspend = adau1373_suspend,
1341 .resume = adau1373_resume, 1339 .resume = adau1373_resume,
1342 .set_bias_level = adau1373_set_bias_level, 1340 .set_bias_level = adau1373_set_bias_level,
1341 .idle_bias_off = true,
1343 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), 1342 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1344 .reg_cache_default = adau1373_default_regs, 1343 .reg_cache_default = adau1373_default_regs,
1345 .reg_word_size = sizeof(uint8_t), 1344 .reg_word_size = sizeof(uint8_t),
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 6b325ea03869..78e9ce48bb99 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
457{ 457{
458 int ret; 458 int ret;
459 459
460 codec->dapm.idle_bias_off = 1;
461 codec->control_data = to_i2c_client(codec->dev); 460 codec->control_data = to_i2c_client(codec->dev);
462 461
463 ret = adau1701_load_firmware(codec); 462 ret = adau1701_load_firmware(codec);
@@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
473static struct snd_soc_codec_driver adau1701_codec_drv = { 472static struct snd_soc_codec_driver adau1701_codec_drv = {
474 .probe = adau1701_probe, 473 .probe = adau1701_probe,
475 .set_bias_level = adau1701_set_bias_level, 474 .set_bias_level = adau1701_set_bias_level,
475 .idle_bias_off = true,
476 476
477 .reg_cache_size = ADAU1701_NUM_REGS, 477 .reg_cache_size = ADAU1701_NUM_REGS,
478 .reg_word_size = sizeof(u16), 478 .reg_word_size = sizeof(u16),
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index d27b5e4cce99..ceb96ecf5588 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -46,75 +46,15 @@
46#define DRV_NAME "ak4104-codec" 46#define DRV_NAME "ak4104-codec"
47 47
48struct ak4104_private { 48struct ak4104_private {
49 enum snd_soc_control_type control_type; 49 struct regmap *regmap;
50 void *control_data;
51}; 50};
52 51
53static int ak4104_fill_cache(struct snd_soc_codec *codec)
54{
55 int i;
56 u8 *reg_cache = codec->reg_cache;
57 struct spi_device *spi = codec->control_data;
58
59 for (i = 0; i < codec->driver->reg_cache_size; i++) {
60 int ret = spi_w8r8(spi, i | AK4104_READ);
61 if (ret < 0) {
62 dev_err(&spi->dev, "SPI write failure\n");
63 return ret;
64 }
65
66 reg_cache[i] = ret;
67 }
68
69 return 0;
70}
71
72static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg)
74{
75 u8 *reg_cache = codec->reg_cache;
76
77 if (reg >= codec->driver->reg_cache_size)
78 return -EINVAL;
79
80 return reg_cache[reg];
81}
82
83static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
84 unsigned int value)
85{
86 u8 *cache = codec->reg_cache;
87 struct spi_device *spi = codec->control_data;
88
89 if (reg >= codec->driver->reg_cache_size)
90 return -EINVAL;
91
92 /* only write to the hardware if value has changed */
93 if (cache[reg] != value) {
94 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
95
96 if (spi_write(spi, tmp, sizeof(tmp))) {
97 dev_err(&spi->dev, "SPI write failed\n");
98 return -EIO;
99 }
100
101 cache[reg] = value;
102 }
103
104 return 0;
105}
106
107static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, 52static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
108 unsigned int format) 53 unsigned int format)
109{ 54{
110 struct snd_soc_codec *codec = codec_dai->codec; 55 struct snd_soc_codec *codec = codec_dai->codec;
111 int val = 0; 56 int val = 0;
112 57 int ret;
113 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
114 if (val < 0)
115 return val;
116
117 val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1);
118 58
119 /* set DAI format */ 59 /* set DAI format */
120 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 60 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -135,7 +75,13 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
135 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) 75 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
136 return -EINVAL; 76 return -EINVAL;
137 77
138 return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 78 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
79 AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,
80 val);
81 if (ret < 0)
82 return ret;
83
84 return 0;
139} 85}
140 86
141static int ak4104_hw_params(struct snd_pcm_substream *substream, 87static int ak4104_hw_params(struct snd_pcm_substream *substream,
@@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
148 94
149 /* set the IEC958 bits: consumer mode, no copyright bit */ 95 /* set the IEC958 bits: consumer mode, no copyright bit */
150 val |= IEC958_AES0_CON_NOT_COPYRIGHT; 96 val |= IEC958_AES0_CON_NOT_COPYRIGHT;
151 ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); 97 snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val);
152 98
153 val = 0; 99 val = 0;
154 100
@@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
167 return -EINVAL; 113 return -EINVAL;
168 } 114 }
169 115
170 return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); 116 return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val);
171} 117}
172 118
173static const struct snd_soc_dai_ops ak4101_dai_ops = { 119static const struct snd_soc_dai_ops ak4101_dai_ops = {
@@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = {
192static int ak4104_probe(struct snd_soc_codec *codec) 138static int ak4104_probe(struct snd_soc_codec *codec)
193{ 139{
194 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); 140 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
195 int ret, val; 141 int ret;
196
197 codec->control_data = ak4104->control_data;
198 142
199 /* read all regs and fill the cache */ 143 codec->control_data = ak4104->regmap;
200 ret = ak4104_fill_cache(codec); 144 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
201 if (ret < 0) { 145 if (ret != 0)
202 dev_err(codec->dev, "failed to fill register cache\n");
203 return ret; 146 return ret;
204 }
205
206 /* read the 'reserved' register - according to the datasheet, it
207 * should contain 0x5b. Not a good way to verify the presence of
208 * the device, but there is no hardware ID register. */
209 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
210 AK4104_RESERVED_VAL)
211 return -ENODEV;
212 147
213 /* set power-up and non-reset bits */ 148 /* set power-up and non-reset bits */
214 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); 149 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
215 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; 150 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
216 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 151 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
217 if (ret < 0) 152 if (ret < 0)
218 return ret; 153 return ret;
219 154
220 /* enable transmitter */ 155 /* enable transmitter */
221 val = ak4104_read_reg_cache(codec, AK4104_REG_TX); 156 ret = snd_soc_update_bits(codec, AK4104_REG_TX,
222 val |= AK4104_TX_TXE; 157 AK4104_TX_TXE, AK4104_TX_TXE);
223 ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
224 if (ret < 0) 158 if (ret < 0)
225 return ret; 159 return ret;
226 160
227 dev_info(codec->dev, "SPI device initialized\n");
228 return 0; 161 return 0;
229} 162}
230 163
231static int ak4104_remove(struct snd_soc_codec *codec) 164static int ak4104_remove(struct snd_soc_codec *codec)
232{ 165{
233 int val, ret; 166 snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
234 167 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
235 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
236 if (val < 0)
237 return val;
238
239 /* clear power-up and non-reset bits */
240 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
241 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
242 168
243 return ret; 169 return 0;
244} 170}
245 171
246static struct snd_soc_codec_driver soc_codec_device_ak4104 = { 172static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe, 173 .probe = ak4104_probe,
248 .remove = ak4104_remove, 174 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS, 175};
250 .reg_word_size = sizeof(u8), 176
177static const struct regmap_config ak4104_regmap = {
178 .reg_bits = 8,
179 .val_bits = 8,
180
181 .max_register = AK4104_NUM_REGS - 1,
182 .read_flag_mask = AK4104_READ,
183 .write_flag_mask = AK4104_WRITE,
184
185 .cache_type = REGCACHE_RBTREE,
251}; 186};
252 187
253static int ak4104_spi_probe(struct spi_device *spi) 188static int ak4104_spi_probe(struct spi_device *spi)
254{ 189{
255 struct ak4104_private *ak4104; 190 struct ak4104_private *ak4104;
191 unsigned int val;
256 int ret; 192 int ret;
257 193
258 spi->bits_per_word = 8; 194 spi->bits_per_word = 8;
@@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi)
266 if (ak4104 == NULL) 202 if (ak4104 == NULL)
267 return -ENOMEM; 203 return -ENOMEM;
268 204
269 ak4104->control_data = spi; 205 ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
270 ak4104->control_type = SND_SOC_SPI; 206 if (IS_ERR(ak4104->regmap)) {
207 ret = PTR_ERR(ak4104->regmap);
208 return ret;
209 }
210
211 /* read the 'reserved' register - according to the datasheet, it
212 * should contain 0x5b. Not a good way to verify the presence of
213 * the device, but there is no hardware ID register. */
214 ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);
215 if (ret != 0)
216 goto err;
217 if (val != AK4104_RESERVED_VAL) {
218 ret = -ENODEV;
219 goto err;
220 }
221
271 spi_set_drvdata(spi, ak4104); 222 spi_set_drvdata(spi, ak4104);
272 223
273 ret = snd_soc_register_codec(&spi->dev, 224 ret = snd_soc_register_codec(&spi->dev,
274 &soc_codec_device_ak4104, &ak4104_dai, 1); 225 &soc_codec_device_ak4104, &ak4104_dai, 1);
226 if (ret != 0)
227 goto err;
228
229 return 0;
230
231err:
232 regmap_exit(ak4104->regmap);
275 return ret; 233 return ret;
276} 234}
277 235
278static int __devexit ak4104_spi_remove(struct spi_device *spi) 236static int __devexit ak4104_spi_remove(struct spi_device *spi)
279{ 237{
238 struct ak4104_private *ak4101 = spi_get_drvdata(spi);
239 regmap_exit(ak4101->regmap);
280 snd_soc_unregister_codec(&spi->dev); 240 snd_soc_unregister_codec(&spi->dev);
281 return 0; 241 return 0;
282} 242}
@@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = {
290 .remove = __devexit_p(ak4104_spi_remove), 250 .remove = __devexit_p(ak4104_spi_remove),
291}; 251};
292 252
293static int __init ak4104_init(void) 253module_spi_driver(ak4104_spi_driver);
294{
295 return spi_register_driver(&ak4104_spi_driver);
296}
297module_init(ak4104_init);
298
299static void __exit ak4104_exit(void)
300{
301 spi_unregister_driver(&ak4104_spi_driver);
302}
303module_exit(ak4104_exit);
304 254
305MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 255MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
306MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); 256MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 9e809e05d066..838ae8b22b50 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -27,24 +28,43 @@
27 28
28#include "ak4535.h" 29#include "ak4535.h"
29 30
30#define AK4535_VERSION "0.3"
31
32/* codec private data */ 31/* codec private data */
33struct ak4535_priv { 32struct ak4535_priv {
33 struct regmap *regmap;
34 unsigned int sysclk; 34 unsigned int sysclk;
35 enum snd_soc_control_type control_type;
36}; 35};
37 36
38/* 37/*
39 * ak4535 register cache 38 * ak4535 register cache
40 */ 39 */
41static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { 40static const struct reg_default ak4535_reg_defaults[] = {
42 0x00, 0x80, 0x00, 0x03, 41 { 0, 0x00 },
43 0x02, 0x00, 0x11, 0x01, 42 { 1, 0x80 },
44 0x00, 0x40, 0x36, 0x10, 43 { 2, 0x00 },
45 0x00, 0x00, 0x57, 0x00, 44 { 3, 0x03 },
45 { 4, 0x02 },
46 { 5, 0x00 },
47 { 6, 0x11 },
48 { 7, 0x01 },
49 { 8, 0x00 },
50 { 9, 0x40 },
51 { 10, 0x36 },
52 { 11, 0x10 },
53 { 12, 0x00 },
54 { 13, 0x00 },
55 { 14, 0x57 },
46}; 56};
47 57
58static bool ak4535_volatile(struct device *dev, unsigned int reg)
59{
60 switch (reg) {
61 case AK4535_STATUS:
62 return true;
63 default:
64 return false;
65 }
66}
67
48static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 68static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
49static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; 69static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
50static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; 70static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
372 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 392 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
373 int ret; 393 int ret;
374 394
375 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 395 codec->control_data = ak4535->regmap;
376 396 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
377 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
378 if (ret < 0) { 397 if (ret < 0) {
379 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 398 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
380 return ret; 399 return ret;
@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
382 /* power on device */ 401 /* power on device */
383 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 402 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
384 403
385 snd_soc_add_controls(codec, ak4535_snd_controls, 404 snd_soc_add_codec_controls(codec, ak4535_snd_controls,
386 ARRAY_SIZE(ak4535_snd_controls)); 405 ARRAY_SIZE(ak4535_snd_controls));
387 return 0; 406 return 0;
388} 407}
@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
394 return 0; 413 return 0;
395} 414}
396 415
416static const struct regmap_config ak4535_regmap = {
417 .reg_bits = 8,
418 .val_bits = 8,
419
420 .max_register = AK4535_STATUS,
421 .volatile_reg = ak4535_volatile,
422
423 .cache_type = REGCACHE_RBTREE,
424 .reg_defaults = ak4535_reg_defaults,
425 .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
426};
427
397static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { 428static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
398 .probe = ak4535_probe, 429 .probe = ak4535_probe,
399 .remove = ak4535_remove, 430 .remove = ak4535_remove,
400 .suspend = ak4535_suspend, 431 .suspend = ak4535_suspend,
401 .resume = ak4535_resume, 432 .resume = ak4535_resume,
402 .set_bias_level = ak4535_set_bias_level, 433 .set_bias_level = ak4535_set_bias_level,
403 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
404 .reg_word_size = sizeof(u8),
405 .reg_cache_default = ak4535_reg,
406 .dapm_widgets = ak4535_dapm_widgets, 434 .dapm_widgets = ak4535_dapm_widgets,
407 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), 435 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
408 .dapm_routes = ak4535_audio_map, 436 .dapm_routes = ak4535_audio_map,
409 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), 437 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
410}; 438};
411 439
412#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
413static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, 440static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
414 const struct i2c_device_id *id) 441 const struct i2c_device_id *id)
415{ 442{
@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
421 if (ak4535 == NULL) 448 if (ak4535 == NULL)
422 return -ENOMEM; 449 return -ENOMEM;
423 450
451 ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
452 if (IS_ERR(ak4535->regmap)) {
453 ret = PTR_ERR(ak4535->regmap);
454 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
455 return ret;
456 }
457
424 i2c_set_clientdata(i2c, ak4535); 458 i2c_set_clientdata(i2c, ak4535);
425 ak4535->control_type = SND_SOC_I2C;
426 459
427 ret = snd_soc_register_codec(&i2c->dev, 460 ret = snd_soc_register_codec(&i2c->dev,
428 &soc_codec_dev_ak4535, &ak4535_dai, 1); 461 &soc_codec_dev_ak4535, &ak4535_dai, 1);
462 if (ret != 0)
463 regmap_exit(ak4535->regmap);
464
429 return ret; 465 return ret;
430} 466}
431 467
432static __devexit int ak4535_i2c_remove(struct i2c_client *client) 468static __devexit int ak4535_i2c_remove(struct i2c_client *client)
433{ 469{
470 struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
471
434 snd_soc_unregister_codec(&client->dev); 472 snd_soc_unregister_codec(&client->dev);
473 regmap_exit(ak4535->regmap);
435 return 0; 474 return 0;
436} 475}
437 476
@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
443 482
444static struct i2c_driver ak4535_i2c_driver = { 483static struct i2c_driver ak4535_i2c_driver = {
445 .driver = { 484 .driver = {
446 .name = "ak4535-codec", 485 .name = "ak4535",
447 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
448 }, 487 },
449 .probe = ak4535_i2c_probe, 488 .probe = ak4535_i2c_probe,
450 .remove = __devexit_p(ak4535_i2c_remove), 489 .remove = __devexit_p(ak4535_i2c_remove),
451 .id_table = ak4535_i2c_id, 490 .id_table = ak4535_i2c_id,
452}; 491};
453#endif
454 492
455static int __init ak4535_modinit(void) 493module_i2c_driver(ak4535_i2c_driver);
456{
457 int ret = 0;
458#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
459 ret = i2c_add_driver(&ak4535_i2c_driver);
460 if (ret != 0) {
461 printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
462 ret);
463 }
464#endif
465 return ret;
466}
467module_init(ak4535_modinit);
468
469static void __exit ak4535_exit(void)
470{
471#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
472 i2c_del_driver(&ak4535_i2c_driver);
473#endif
474}
475module_exit(ak4535_exit);
476 494
477MODULE_DESCRIPTION("Soc AK4535 driver"); 495MODULE_DESCRIPTION("Soc AK4535 driver");
478MODULE_AUTHOR("Richard Purdie"); 496MODULE_AUTHOR("Richard Purdie");
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index 0431e5f634a2..402de1d274bf 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -34,6 +34,4 @@
34#define AK4535_VOL 0xe 34#define AK4535_VOL 0xe
35#define AK4535_STATUS 0xf 35#define AK4535_STATUS 0xf
36 36
37#define AK4535_CACHEREGNUM 0x10
38
39#endif 37#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 278c0a0575f5..f8e10ced244a 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -477,7 +477,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
477 return ret; 477 return ret;
478 } 478 }
479 479
480 snd_soc_add_controls(codec, ak4642_snd_controls, 480 snd_soc_add_codec_controls(codec, ak4642_snd_controls,
481 ARRAY_SIZE(ak4642_snd_controls)); 481 ARRAY_SIZE(ak4642_snd_controls));
482 482
483 ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 483 ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index a53b152e6a07..5fb7c2a80e6d 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec)
628 return ret; 628 return ret;
629 } 629 }
630 630
631 snd_soc_add_controls(codec, ak4671_snd_controls, 631 snd_soc_add_codec_controls(codec, ak4671_snd_controls,
632 ARRAY_SIZE(ak4671_snd_controls)); 632 ARRAY_SIZE(ak4671_snd_controls));
633 633
634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 3feee569ceea..d47b62ddb210 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec)
925 925
926 switch (alc5623->id) { 926 switch (alc5623->id) {
927 case 0x21: 927 case 0x21:
928 snd_soc_add_controls(codec, alc5621_vol_snd_controls, 928 snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
929 ARRAY_SIZE(alc5621_vol_snd_controls)); 929 ARRAY_SIZE(alc5621_vol_snd_controls));
930 break; 930 break;
931 case 0x22: 931 case 0x22:
932 snd_soc_add_controls(codec, alc5622_vol_snd_controls, 932 snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
933 ARRAY_SIZE(alc5622_vol_snd_controls)); 933 ARRAY_SIZE(alc5622_vol_snd_controls));
934 break; 934 break;
935 case 0x23: 935 case 0x23:
936 snd_soc_add_controls(codec, alc5623_vol_snd_controls, 936 snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
937 ARRAY_SIZE(alc5623_vol_snd_controls)); 937 ARRAY_SIZE(alc5623_vol_snd_controls));
938 break; 938 break;
939 default: 939 default:
940 return -EINVAL; 940 return -EINVAL;
941 } 941 }
942 942
943 snd_soc_add_controls(codec, alc5623_snd_controls, 943 snd_soc_add_codec_controls(codec, alc5623_snd_controls,
944 ARRAY_SIZE(alc5623_snd_controls)); 944 ARRAY_SIZE(alc5623_snd_controls));
945 945
946 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, 946 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
@@ -992,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
992 * low = 0x1a 992 * low = 0x1a
993 * high = 0x1b 993 * high = 0x1b
994 */ 994 */
995static int alc5623_i2c_probe(struct i2c_client *client, 995static __devinit int alc5623_i2c_probe(struct i2c_client *client,
996 const struct i2c_device_id *id) 996 const struct i2c_device_id *id)
997{ 997{
998 struct alc5623_platform_data *pdata; 998 struct alc5623_platform_data *pdata;
@@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1059 return ret; 1059 return ret;
1060} 1060}
1061 1061
1062static int alc5623_i2c_remove(struct i2c_client *client) 1062static __devexit int alc5623_i2c_remove(struct i2c_client *client)
1063{ 1063{
1064 snd_soc_unregister_codec(&client->dev); 1064 snd_soc_unregister_codec(&client->dev);
1065 return 0; 1065 return 0;
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 390e437d7c5e..e2111e0ccad7 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
145/* -16.5db min scale, 1.5db steps, no mute */ 145/* -16.5db min scale, 1.5db steps, no mute */
146static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); 146static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
147static const unsigned int boost_tlv[] = { 147static const unsigned int boost_tlv[] = {
148 TLV_DB_RANGE_HEAD(3), 148 TLV_DB_RANGE_HEAD(2),
149 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 149 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
150 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 150 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
151 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
152}; 151};
153/* 0db min scale, 6 db steps, no mute */ 152/* 0db min scale, 6 db steps, no mute */
154static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); 153static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
155/* 0db min scalem 0.75db steps, no mute */ 154/* 0db min scalem 0.75db steps, no mute */
156static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); 155static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
157 156
158static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { 157static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
159 /* left starts at bit 8, right at bit 0 */ 158 /* left starts at bit 8, right at bit 0 */
@@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = {
176 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), 175 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
177 SOC_SINGLE_TLV("Voice DAC Playback Volume", 176 SOC_SINGLE_TLV("Voice DAC Playback Volume",
178 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), 177 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
179 SOC_SINGLE_TLV("Phone Capture Volume", 178 SOC_SINGLE("Voice DAC Playback Switch",
179 ALC5632_VOICE_DAC_VOL, 12, 1, 1),
180 SOC_SINGLE_TLV("Phone Playback Volume",
180 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), 181 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
181 SOC_DOUBLE_TLV("LineIn Capture Volume", 182 SOC_DOUBLE_TLV("LineIn Playback Volume",
182 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), 183 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
183 SOC_DOUBLE_TLV("Master Playback Volume", 184 SOC_DOUBLE_TLV("Master Playback Volume",
184 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), 185 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
185 SOC_DOUBLE("Master Playback Switch", 186 SOC_DOUBLE("Master Playback Switch",
186 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), 187 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
187 SOC_SINGLE_TLV("Mic1 Capture Volume", 188 SOC_SINGLE_TLV("Mic1 Playback Volume",
188 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), 189 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
189 SOC_SINGLE_TLV("Mic2 Capture Volume", 190 SOC_SINGLE_TLV("Mic2 Playback Volume",
190 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), 191 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
191 SOC_DOUBLE_TLV("Rec Capture Volume", 192 SOC_DOUBLE_TLV("Rec Capture Volume",
192 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), 193 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
193 SOC_SINGLE_TLV("Mic 1 Boost Volume", 194 SOC_SINGLE_TLV("Mic 1 Boost Volume",
194 ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), 195 ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
195 SOC_SINGLE_TLV("Mic 2 Boost Volume", 196 SOC_SINGLE_TLV("Mic 2 Boost Volume",
196 ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), 197 ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
197 SOC_SINGLE_TLV("Digital Boost Volume", 198 SOC_SINGLE_TLV("DMIC Boost Capture Volume",
198 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), 199 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
200 SOC_SINGLE("DMIC En Capture Switch",
201 ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
202 SOC_SINGLE("DMIC PreFilter Capture Switch",
203 ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
199}; 204};
200 205
201/* 206/*
@@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
244 249
245/* Left Record Mixer */ 250/* Left Record Mixer */
246static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { 251static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
247SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), 252SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
248SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), 253SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
249SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), 254SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
250SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), 255SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
251SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), 256SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
252SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), 257SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
253SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), 258SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
254}; 259};
255 260
256/* Right Record Mixer */ 261/* Right Record Mixer */
257static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { 262static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
258SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), 263SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
259SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), 264SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
260SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), 265SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
261SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), 266SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
262SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), 267SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
263SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), 268SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
264SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), 269SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
265}; 270};
266 271
267static const char *alc5632_spk_n_sour_sel[] = { 272/* Dmic Mixer */
273static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
274SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
275};
276static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
277SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
278};
279
280static const char * const alc5632_spk_n_sour_sel[] = {
268 "RN/-R", "RP/+R", "LN/-R", "Mute"}; 281 "RN/-R", "RP/+R", "LN/-R", "Mute"};
269static const char *alc5632_hpl_out_input_sel[] = { 282static const char * const alc5632_hpl_out_input_sel[] = {
270 "Vmid", "HP Left Mix"}; 283 "Vmid", "HP Left Mix"};
271static const char *alc5632_hpr_out_input_sel[] = { 284static const char * const alc5632_hpr_out_input_sel[] = {
272 "Vmid", "HP Right Mix"}; 285 "Vmid", "HP Right Mix"};
273static const char *alc5632_spkout_input_sel[] = { 286static const char * const alc5632_spkout_input_sel[] = {
274 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 287 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
275static const char *alc5632_aux_out_input_sel[] = { 288static const char * const alc5632_aux_out_input_sel[] = {
276 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 289 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
290static const char * const alc5632_adcr_func_sel[] = {
291 "Stereo ADC", "Voice ADC"};
292static const char * const alc5632_i2s_out_sel[] = {
293 "ADC LR", "Voice Stereo Digital"};
277 294
278/* auxout output mux */ 295/* auxout output mux */
279static const struct soc_enum alc5632_aux_out_input_enum = 296static const struct soc_enum alc5632_aux_out_input_enum =
@@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum =
312static const struct snd_kcontrol_new alc5632_amp_mux_controls = 329static const struct snd_kcontrol_new alc5632_amp_mux_controls =
313 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); 330 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
314 331
332/* ADC output select */
333static const struct soc_enum alc5632_adcr_func_enum =
334 SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
335static const struct snd_kcontrol_new alc5632_adcr_func_controls =
336 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
337
338/* I2S out select */
339static const struct soc_enum alc5632_i2s_out_enum =
340 SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
341static const struct snd_kcontrol_new alc5632_i2s_out_controls =
342 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
315 343
316static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { 344static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
317/* Muxes */ 345/* Muxes */
@@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
325 &alc5632_hpr_out_mux_controls), 353 &alc5632_hpr_out_mux_controls),
326SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, 354SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
327 &alc5632_spkoutn_mux_controls), 355 &alc5632_spkoutn_mux_controls),
356SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
357 &alc5632_adcr_func_controls),
358SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
359 &alc5632_i2s_out_controls),
328 360
329/* output mixers */ 361/* output mixers */
330SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, 362SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
@@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
343SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, 375SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
344 &alc5632_speaker_mixer_controls[0], 376 &alc5632_speaker_mixer_controls[0],
345 ARRAY_SIZE(alc5632_speaker_mixer_controls)), 377 ARRAY_SIZE(alc5632_speaker_mixer_controls)),
378SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
379 &alc5632_dmicl_mixer_controls[0],
380 ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
381SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
382 &alc5632_dmicr_mixer_controls[0],
383 ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
346 384
347/* input mixers */ 385/* input mixers */
348SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, 386SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
@@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
352 &alc5632_captureR_mixer_controls[0], 390 &alc5632_captureR_mixer_controls[0],
353 ARRAY_SIZE(alc5632_captureR_mixer_controls)), 391 ARRAY_SIZE(alc5632_captureR_mixer_controls)),
354 392
355SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", 393SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
356 ALC5632_PWR_MANAG_ADD2, 9, 0), 394SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
357SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", 395SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
358 ALC5632_PWR_MANAG_ADD2, 8, 0), 396SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
397SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
398SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
399
400SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
401SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
402SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
403SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
404SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
405
359SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), 406SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
360SND_SOC_DAPM_MIXER("DAC Right Channel", 407SND_SOC_DAPM_MIXER("DAC Right Channel",
361 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), 408 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
362SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), 409SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
363SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 410SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
364SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 411SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
365SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", 412SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
366 ALC5632_PWR_MANAG_ADD2, 7, 0), 413SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
367SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", 414
368 ALC5632_PWR_MANAG_ADD2, 6, 0),
369SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), 415SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
370SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), 416SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
371SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), 417SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
@@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"),
393SND_SOC_DAPM_OUTPUT("HPR"), 439SND_SOC_DAPM_OUTPUT("HPR"),
394SND_SOC_DAPM_OUTPUT("SPKOUT"), 440SND_SOC_DAPM_OUTPUT("SPKOUT"),
395SND_SOC_DAPM_OUTPUT("SPKOUTN"), 441SND_SOC_DAPM_OUTPUT("SPKOUTN"),
442
396SND_SOC_DAPM_INPUT("LINEINL"), 443SND_SOC_DAPM_INPUT("LINEINL"),
397SND_SOC_DAPM_INPUT("LINEINR"), 444SND_SOC_DAPM_INPUT("LINEINR"),
398SND_SOC_DAPM_INPUT("PHONEP"), 445SND_SOC_DAPM_INPUT("PHONEP"),
399SND_SOC_DAPM_INPUT("PHONEN"), 446SND_SOC_DAPM_INPUT("PHONEN"),
447SND_SOC_DAPM_INPUT("DMICDAT"),
400SND_SOC_DAPM_INPUT("MIC1"), 448SND_SOC_DAPM_INPUT("MIC1"),
401SND_SOC_DAPM_INPUT("MIC2"), 449SND_SOC_DAPM_INPUT("MIC2"),
402SND_SOC_DAPM_VMID("Vmid"), 450SND_SOC_DAPM_VMID("Vmid"),
@@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"),
404 452
405 453
406static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { 454static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
455 /* Playback streams */
456 {"Left DAC", NULL, "AIFRXL"},
457 {"Right DAC", NULL, "AIFRXR"},
458
407 /* virtual mixer - mixes left & right channels */ 459 /* virtual mixer - mixes left & right channels */
408 {"I2S Mix", NULL, "Left DAC"}, 460 {"I2S Mix", NULL, "Left DAC"},
409 {"I2S Mix", NULL, "Right DAC"}, 461 {"I2S Mix", NULL, "Right DAC"},
@@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
426 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, 478 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
427 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, 479 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
428 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, 480 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
429 481 {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},
430 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, 482 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
431 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, 483 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
484 {"HPOut Mix", NULL, "HP Mix"},
485 {"HPOut Mix", NULL, "HPR Mix"},
486 {"HPOut Mix", NULL, "HPL Mix"},
432 487
433 /* speaker mixer */ 488 /* speaker mixer */
434 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, 489 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
@@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
436 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, 491 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
437 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, 492 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
438 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, 493 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
439 494 {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},
440
441 495
442 /* mono mixer */ 496 /* mono mixer */
443 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, 497 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
444 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, 498 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
445 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, 499 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
446 {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
447 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, 500 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
448 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, 501 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
449 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, 502 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
503 {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},
450 504
451 /* Left record mixer */ 505 /* Left record mixer */
452 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, 506 {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
453 {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, 507 {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
454 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 508 {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
455 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 509 {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
456 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, 510 {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
457 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 511 {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
458 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 512 {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
459 513
460 /*Right record mixer */ 514 /*Right record mixer */
461 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, 515 {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
462 {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, 516 {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
463 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 517 {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
464 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 518 {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
465 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, 519 {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
466 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 520 {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
467 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 521 {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
468 522
469 /* headphone left mux */ 523 /* headphone left mux */
470 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, 524 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
@@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
504 558
505 /* left ADC */ 559 /* left ADC */
506 {"Left ADC", NULL, "Left Capture Mix"}, 560 {"Left ADC", NULL, "Left Capture Mix"},
561 {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
562 {"Left ADC", NULL, "DMICL Mix"},
563 {"ADCLR", NULL, "Left ADC"},
507 564
508 /* right ADC */ 565 /* right ADC */
509 {"Right ADC", NULL, "Right Capture Mix"}, 566 {"Right ADC", NULL, "Right Capture Mix"},
510 567 {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
568 {"Right ADC", NULL, "DMICR Mix"},
569 {"ADCR Mux", "Stereo ADC", "Right ADC"},
570 {"ADCR Mux", "Voice ADC", "Right ADC"},
571 {"ADCLR", NULL, "ADCR Mux"},
572 {"VAIFTX", NULL, "ADCR Mux"},
573
574 /* Digital I2S out */
575 {"I2SOut Mux", "ADC LR", "ADCLR"},
576 {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
577 {"AIFTXL", NULL, "I2SOut Mux"},
578 {"AIFTXR", NULL, "I2SOut Mux"},
579
580 /* Voice Mix */
581 {"Voice DAC", NULL, "VAIFRX"},
582 {"Voice Mix", NULL, "Voice DAC"},
583
584 /* Speaker Output */
511 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, 585 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
512 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, 586 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
513 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, 587 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
@@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
714 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); 788 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
715 789
716 switch (freq) { 790 switch (freq) {
791 case 4096000:
717 case 8192000: 792 case 8192000:
718 case 11289600: 793 case 11289600:
719 case 12288000: 794 case 12288000:
@@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
994 1069
995 switch (alc5632->id) { 1070 switch (alc5632->id) {
996 case 0x5c: 1071 case 0x5c:
997 snd_soc_add_controls(codec, alc5632_vol_snd_controls, 1072 snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
998 ARRAY_SIZE(alc5632_vol_snd_controls)); 1073 ARRAY_SIZE(alc5632_vol_snd_controls));
999 break; 1074 break;
1000 default: 1075 default:
@@ -1109,7 +1184,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1109 return ret; 1184 return ret;
1110} 1185}
1111 1186
1112static int alc5632_i2c_remove(struct i2c_client *client) 1187static __devexit int alc5632_i2c_remove(struct i2c_client *client)
1113{ 1188{
1114 struct alc5632_priv *alc5632 = i2c_get_clientdata(client); 1189 struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
1115 snd_soc_unregister_codec(&client->dev); 1190 snd_soc_unregister_codec(&client->dev);
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
index 357651ec074e..1b5bda594ea3 100644
--- a/sound/soc/codecs/alc5632.h
+++ b/sound/soc/codecs/alc5632.h
@@ -51,6 +51,7 @@
51#define ALC5632_ADC_REC_MONOMIX (1 << 0) 51#define ALC5632_ADC_REC_MONOMIX (1 << 0)
52 52
53#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ 53#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
54#define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */
54/* ALC5632_OUTPUT_MIXER_CTRL : */ 55/* ALC5632_OUTPUT_MIXER_CTRL : */
55/* same remark as for reg 2 line vs speaker */ 56/* same remark as for reg 2 line vs speaker */
56#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ 57#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 4854b472d5fd..064cd6a93516 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -38,8 +38,6 @@
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/initval.h> 39#include <sound/initval.h>
40 40
41#include <mach/dm365.h>
42
43static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, 41static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
44 unsigned int reg) 42 unsigned int reg)
45{ 43{
@@ -159,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
159 codec->control_data = davinci_vc; 157 codec->control_data = davinci_vc;
160 158
161 /* Set controls */ 159 /* Set controls */
162 snd_soc_add_controls(codec, cq93vc_snd_controls, 160 snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
163 ARRAY_SIZE(cq93vc_snd_controls)); 161 ARRAY_SIZE(cq93vc_snd_controls));
164 162
165 /* Off, with power on */ 163 /* Off, with power on */
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 055536645da9..1d672f528662 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
521 } 521 }
522 522
523 /* Add the non-DAPM controls */ 523 /* Add the non-DAPM controls */
524 ret = snd_soc_add_controls(codec, cs4270_snd_controls, 524 ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
525 ARRAY_SIZE(cs4270_snd_controls)); 525 ARRAY_SIZE(cs4270_snd_controls));
526 if (ret < 0) { 526 if (ret < 0) {
527 dev_err(codec->dev, "failed to add controls\n"); 527 dev_err(codec->dev, "failed to add controls\n");
@@ -715,7 +715,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
715 */ 715 */
716static struct i2c_driver cs4270_i2c_driver = { 716static struct i2c_driver cs4270_i2c_driver = {
717 .driver = { 717 .driver = {
718 .name = "cs4270-codec", 718 .name = "cs4270",
719 .owner = THIS_MODULE, 719 .owner = THIS_MODULE,
720 }, 720 },
721 .id_table = cs4270_id, 721 .id_table = cs4270_id,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index f6fe846b6a6c..bf7141280a74 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
513 /* Power-up sequence requires 85 uS */ 513 /* Power-up sequence requires 85 uS */
514 udelay(85); 514 udelay(85);
515 515
516 return snd_soc_add_controls(codec, cs4271_snd_controls, 516 return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
517 ARRAY_SIZE(cs4271_snd_controls)); 517 ARRAY_SIZE(cs4271_snd_controls));
518} 518}
519 519
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index ab38e93c3543..7843711729bc 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/regmap.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
626 627
627/* Codec private data */ 628/* Codec private data */
628struct da7210_priv { 629struct da7210_priv {
629 enum snd_soc_control_type control_type; 630 struct regmap *regmap;
630}; 631};
631 632
632/* 633static struct reg_default da7210_reg_defaults[] = {
633 * Register cache 634 { 0x01, 0x11 },
634 */ 635 { 0x03, 0x00 },
635static const u8 da7210_reg[] = { 636 { 0x04, 0x00 },
636 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */ 637 { 0x05, 0x00 },
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */ 638 { 0x06, 0x00 },
638 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */ 639 { 0x07, 0x00 },
639 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */ 640 { 0x08, 0x00 },
640 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */ 641 { 0x09, 0x00 },
641 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */ 642 { 0x0a, 0x00 },
642 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */ 643 { 0x0b, 0x00 },
643 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */ 644 { 0x0c, 0x00 },
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */ 645 { 0x0d, 0x00 },
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */ 646 { 0x0e, 0x00 },
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */ 647 { 0x0f, 0x08 },
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */ 648 { 0x10, 0x00 },
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */ 649 { 0x11, 0x00 },
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */ 650 { 0x12, 0x00 },
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */ 651 { 0x13, 0x00 },
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */ 652 { 0x14, 0x08 },
652 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */ 653 { 0x15, 0x10 },
653 0x00, /* R88 */ 654 { 0x16, 0x10 },
655 { 0x17, 0x54 },
656 { 0x18, 0x40 },
657 { 0x19, 0x00 },
658 { 0x1a, 0x00 },
659 { 0x1b, 0x00 },
660 { 0x1c, 0x00 },
661 { 0x1d, 0x00 },
662 { 0x1e, 0x00 },
663 { 0x1f, 0x00 },
664 { 0x20, 0x00 },
665 { 0x21, 0x00 },
666 { 0x22, 0x00 },
667 { 0x23, 0x02 },
668 { 0x24, 0x00 },
669 { 0x25, 0x76 },
670 { 0x26, 0x00 },
671 { 0x27, 0x00 },
672 { 0x28, 0x04 },
673 { 0x29, 0x00 },
674 { 0x2a, 0x00 },
675 { 0x2b, 0x30 },
676 { 0x2c, 0x2A },
677 { 0x83, 0x00 },
678 { 0x84, 0x00 },
679 { 0x85, 0x00 },
680 { 0x86, 0x00 },
681 { 0x87, 0x00 },
682 { 0x88, 0x00 },
654}; 683};
655 684
656static int da7210_volatile_register(struct snd_soc_codec *codec, 685static bool da7210_readable_register(struct device *dev, unsigned int reg)
686{
687 switch (reg) {
688 case DA7210_A_HID_UNLOCK:
689 case DA7210_A_TEST_UNLOCK:
690 case DA7210_A_PLL1:
691 case DA7210_A_CP_MODE:
692 return false;
693 default:
694 return true;
695 }
696}
697
698static bool da7210_volatile_register(struct device *dev,
657 unsigned int reg) 699 unsigned int reg)
658{ 700{
659 switch (reg) { 701 switch (reg) {
660 case DA7210_STATUS: 702 case DA7210_STATUS:
661 return 1; 703 return true;
662 default: 704 default:
663 return 0; 705 return false;
664 } 706 }
665} 707}
666 708
@@ -866,7 +908,8 @@ static int da7210_probe(struct snd_soc_codec *codec)
866 908
867 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 909 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
868 910
869 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); 911 codec->control_data = da7210->regmap;
912 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
870 if (ret < 0) { 913 if (ret < 0) {
871 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 914 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
872 return ret; 915 return ret;
@@ -983,12 +1026,14 @@ static int da7210_probe(struct snd_soc_codec *codec)
983 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); 1026 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
984 1027
985 /* As suggested by Dialog */ 1028 /* As suggested by Dialog */
986 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ 1029 /* unlock */
987 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); 1030 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
988 snd_soc_write(codec, DA7210_A_PLL1, 0x01); 1031 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
989 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); 1032 regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
990 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ 1033 regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
991 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); 1034 /* re-lock */
1035 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
1036 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
992 1037
993 /* Activate all enabled subsystem */ 1038 /* Activate all enabled subsystem */
994 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 1039 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
@@ -1000,10 +1045,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
1000 1045
1001static struct snd_soc_codec_driver soc_codec_dev_da7210 = { 1046static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1002 .probe = da7210_probe, 1047 .probe = da7210_probe,
1003 .reg_cache_size = ARRAY_SIZE(da7210_reg),
1004 .reg_word_size = sizeof(u8),
1005 .reg_cache_default = da7210_reg,
1006 .volatile_register = da7210_volatile_register,
1007 1048
1008 .controls = da7210_snd_controls, 1049 .controls = da7210_snd_controls,
1009 .num_controls = ARRAY_SIZE(da7210_snd_controls), 1050 .num_controls = ARRAY_SIZE(da7210_snd_controls),
@@ -1014,6 +1055,17 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1014 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), 1055 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
1015}; 1056};
1016 1057
1058static struct regmap_config da7210_regmap = {
1059 .reg_bits = 8,
1060 .val_bits = 8,
1061
1062 .reg_defaults = da7210_reg_defaults,
1063 .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
1064 .volatile_reg = da7210_volatile_register,
1065 .readable_reg = da7210_readable_register,
1066 .cache_type = REGCACHE_RBTREE,
1067};
1068
1017#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1018static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 1070static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1019 const struct i2c_device_id *id) 1071 const struct i2c_device_id *id)
@@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1027 return -ENOMEM; 1079 return -ENOMEM;
1028 1080
1029 i2c_set_clientdata(i2c, da7210); 1081 i2c_set_clientdata(i2c, da7210);
1030 da7210->control_type = SND_SOC_I2C; 1082
1083 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap);
1084 if (IS_ERR(da7210->regmap)) {
1085 ret = PTR_ERR(da7210->regmap);
1086 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1087 return ret;
1088 }
1031 1089
1032 ret = snd_soc_register_codec(&i2c->dev, 1090 ret = snd_soc_register_codec(&i2c->dev,
1033 &soc_codec_dev_da7210, &da7210_dai, 1); 1091 &soc_codec_dev_da7210, &da7210_dai, 1);
1092 if (ret < 0) {
1093 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1094 goto err_regmap;
1095 }
1096 return ret;
1097
1098err_regmap:
1099 regmap_exit(da7210->regmap);
1100
1034 return ret; 1101 return ret;
1035} 1102}
1036 1103
1037static int __devexit da7210_i2c_remove(struct i2c_client *client) 1104static int __devexit da7210_i2c_remove(struct i2c_client *client)
1038{ 1105{
1106 struct da7210_priv *da7210 = i2c_get_clientdata(client);
1107
1039 snd_soc_unregister_codec(&client->dev); 1108 snd_soc_unregister_codec(&client->dev);
1109 regmap_exit(da7210->regmap);
1040 return 0; 1110 return 0;
1041} 1111}
1042 1112
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 319039240e0f..ba4fafb93e56 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec)
179 179
180 codec->control_data = lm4857->i2c; 180 codec->control_data = lm4857->i2c;
181 181
182 ret = snd_soc_add_controls(codec, lm4857_controls, 182 ret = snd_soc_add_codec_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls)); 183 ARRAY_SIZE(lm4857_controls));
184 if (ret) 184 if (ret)
185 return ret; 185 return ret;
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
new file mode 100644
index 000000000000..17b3ec2d05cb
--- /dev/null
+++ b/sound/soc/codecs/max9768.c
@@ -0,0 +1,247 @@
1/*
2 * MAX9768 AMP driver
3 *
4 * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/i2c.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/regmap.h>
17
18#include <sound/core.h>
19#include <sound/soc.h>
20#include <sound/tlv.h>
21#include <sound/max9768.h>
22
23/* "Registers" */
24#define MAX9768_VOL 0
25#define MAX9768_CTRL 3
26
27/* Commands */
28#define MAX9768_CTRL_PWM 0x15
29#define MAX9768_CTRL_FILTERLESS 0x16
30
31struct max9768 {
32 struct regmap *regmap;
33 int mute_gpio;
34 int shdn_gpio;
35 u32 flags;
36};
37
38static struct reg_default max9768_default_regs[] = {
39 { 0, 0 },
40 { 3, MAX9768_CTRL_FILTERLESS},
41};
42
43static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
44 struct snd_ctl_elem_value *ucontrol)
45{
46 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
47 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
48 int val = gpio_get_value_cansleep(max9768->mute_gpio);
49
50 ucontrol->value.integer.value[0] = !val;
51
52 return 0;
53}
54
55static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
56 struct snd_ctl_elem_value *ucontrol)
57{
58 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
59 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
60
61 gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
62
63 return 0;
64}
65
66static const unsigned int volume_tlv[] = {
67 TLV_DB_RANGE_HEAD(43),
68 0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
69 1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
70 2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
71 3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
72 4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
73 5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
74 6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
75 7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
76 8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
77 9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
78 10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
79 11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
80 12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
81 13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
82 14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
83 15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
84 18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
85 19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
86 20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
87 21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
88 22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
89 23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
90 24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
91 25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
92 26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
93 27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
94 28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
95 31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
96 32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
97 35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
98 38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
99 40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
100 41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
101 42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
102 43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
103 44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
104 45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
105 46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
106 47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
107 51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
108 58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
109 59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
110 63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
111};
112
113static const struct snd_kcontrol_new max9768_volume[] = {
114 SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
115};
116
117static const struct snd_kcontrol_new max9768_mute[] = {
118 SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
119};
120
121static int max9768_probe(struct snd_soc_codec *codec)
122{
123 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
124 int ret;
125
126 codec->control_data = max9768->regmap;
127 ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
128 if (ret)
129 return ret;
130
131 if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
132 ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
133 if (ret)
134 return ret;
135 }
136
137 if (gpio_is_valid(max9768->mute_gpio)) {
138 ret = snd_soc_add_codec_controls(codec, max9768_mute,
139 ARRAY_SIZE(max9768_mute));
140 if (ret)
141 return ret;
142 }
143
144 return 0;
145}
146
147static struct snd_soc_codec_driver max9768_codec_driver = {
148 .probe = max9768_probe,
149 .controls = max9768_volume,
150 .num_controls = ARRAY_SIZE(max9768_volume),
151};
152
153static const struct regmap_config max9768_i2c_regmap_config = {
154 .reg_bits = 2,
155 .val_bits = 6,
156 .max_register = 3,
157 .reg_defaults = max9768_default_regs,
158 .num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
159 .cache_type = REGCACHE_RBTREE,
160};
161
162static int __devinit max9768_i2c_probe(struct i2c_client *client,
163 const struct i2c_device_id *id)
164{
165 struct max9768 *max9768;
166 struct max9768_pdata *pdata = client->dev.platform_data;
167 int err;
168
169 max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
170 if (!max9768)
171 return -ENOMEM;
172
173 if (pdata) {
174 /* Mute on powerup to avoid clicks */
175 err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
176 max9768->mute_gpio = err ?: pdata->mute_gpio;
177
178 /* Activate chip by releasing shutdown, enables I2C */
179 err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
180 max9768->shdn_gpio = err ?: pdata->shdn_gpio;
181
182 max9768->flags = pdata->flags;
183 } else {
184 max9768->shdn_gpio = -EINVAL;
185 max9768->mute_gpio = -EINVAL;
186 }
187
188 i2c_set_clientdata(client, max9768);
189
190 max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
191 if (IS_ERR(max9768->regmap)) {
192 err = PTR_ERR(max9768->regmap);
193 goto err_gpio_free;
194 }
195
196 err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
197 if (err)
198 goto err_regmap_free;
199
200 return 0;
201
202 err_regmap_free:
203 regmap_exit(max9768->regmap);
204 err_gpio_free:
205 if (gpio_is_valid(max9768->shdn_gpio))
206 gpio_free(max9768->shdn_gpio);
207 if (gpio_is_valid(max9768->mute_gpio))
208 gpio_free(max9768->mute_gpio);
209
210 return err;
211}
212
213static int __devexit max9768_i2c_remove(struct i2c_client *client)
214{
215 struct max9768 *max9768 = i2c_get_clientdata(client);
216
217 snd_soc_unregister_codec(&client->dev);
218 regmap_exit(max9768->regmap);
219
220 if (gpio_is_valid(max9768->shdn_gpio))
221 gpio_free(max9768->shdn_gpio);
222 if (gpio_is_valid(max9768->mute_gpio))
223 gpio_free(max9768->mute_gpio);
224
225 return 0;
226}
227
228static const struct i2c_device_id max9768_i2c_id[] = {
229 { "max9768", 0 },
230 { }
231};
232MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
233
234static struct i2c_driver max9768_i2c_driver = {
235 .driver = {
236 .name = "max9768",
237 .owner = THIS_MODULE,
238 },
239 .probe = max9768_i2c_probe,
240 .remove = __devexit_p(max9768_i2c_remove),
241 .id_table = max9768_i2c_id,
242};
243module_i2c_driver(max9768_i2c_driver);
244
245MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
246MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
247MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 006efcfe6dda..af7324b79dd0 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1908 max98088->eq_enum.texts = max98088->eq_texts; 1908 max98088->eq_enum.texts = max98088->eq_texts;
1909 max98088->eq_enum.max = max98088->eq_textcnt; 1909 max98088->eq_enum.max = max98088->eq_textcnt;
1910 1910
1911 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 1911 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1912 if (ret != 0) 1912 if (ret != 0)
1913 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1913 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1914} 1914}
@@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
2030 2030
2031 max98088_handle_pdata(codec); 2031 max98088_handle_pdata(codec);
2032 2032
2033 snd_soc_add_controls(codec, max98088_snd_controls, 2033 snd_soc_add_codec_controls(codec, max98088_snd_controls,
2034 ARRAY_SIZE(max98088_snd_controls)); 2034 ARRAY_SIZE(max98088_snd_controls));
2035 2035
2036err_access: 2036err_access:
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index fcfa7497d7b7..0bb511a0388d 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
1284 1284
1285static int max98095_add_widgets(struct snd_soc_codec *codec) 1285static int max98095_add_widgets(struct snd_soc_codec *codec)
1286{ 1286{
1287 snd_soc_add_controls(codec, max98095_snd_controls, 1287 snd_soc_add_codec_controls(codec, max98095_snd_controls,
1288 ARRAY_SIZE(max98095_snd_controls)); 1288 ARRAY_SIZE(max98095_snd_controls));
1289 1289
1290 return 0; 1290 return 0;
@@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1984 max98095->eq_enum.texts = max98095->eq_texts; 1984 max98095->eq_enum.texts = max98095->eq_texts;
1985 max98095->eq_enum.max = max98095->eq_textcnt; 1985 max98095->eq_enum.max = max98095->eq_textcnt;
1986 1986
1987 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 1987 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1988 if (ret != 0) 1988 if (ret != 0)
1989 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1989 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1990} 1990}
@@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2139 max98095->bq_enum.texts = max98095->bq_texts; 2139 max98095->bq_enum.texts = max98095->bq_texts;
2140 max98095->bq_enum.max = max98095->bq_textcnt; 2140 max98095->bq_enum.max = max98095->bq_textcnt;
2141 2141
2142 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 2142 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
2143 if (ret != 0) 2143 if (ret != 0)
2144 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); 2144 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
2145} 2145}
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index dcf6f2a1600a..3a2ba3d8fd6d 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = {
253/* This function is called from ASoC machine driver */ 253/* This function is called from ASoC machine driver */
254int max9877_add_controls(struct snd_soc_codec *codec) 254int max9877_add_controls(struct snd_soc_codec *codec)
255{ 255{
256 return snd_soc_add_controls(codec, max9877_controls, 256 return snd_soc_add_codec_controls(codec, max9877_controls,
257 ARRAY_SIZE(max9877_controls)); 257 ARRAY_SIZE(max9877_controls));
258} 258}
259EXPORT_SYMBOL_GPL(max9877_add_controls); 259EXPORT_SYMBOL_GPL(max9877_add_controls);
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7f4ba819a9f6..d1926266fe00 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
227}; 227};
228 228
229/* routes for sgtl5000 */ 229/* routes for sgtl5000 */
230static const struct snd_soc_dapm_route audio_map[] = { 230static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
231 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ 231 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
232 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ 232 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
233 233
@@ -1248,7 +1248,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1248 } 1248 }
1249 1249
1250 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; 1250 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1251 dev_info(codec->dev, "sgtl5000 revision %d\n", rev); 1251 dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
1252 1252
1253 /* 1253 /*
1254 * workaround for revision 0x11 and later, 1254 * workaround for revision 0x11 and later,
@@ -1353,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1353 if (ret) 1353 if (ret)
1354 goto err; 1354 goto err;
1355 1355
1356 snd_soc_add_controls(codec, sgtl5000_snd_controls,
1357 ARRAY_SIZE(sgtl5000_snd_controls));
1358
1359 snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
1360 ARRAY_SIZE(sgtl5000_dapm_widgets));
1361
1362 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1363 ARRAY_SIZE(audio_map));
1364
1365 snd_soc_dapm_new_widgets(&codec->dapm); 1356 snd_soc_dapm_new_widgets(&codec->dapm);
1366 1357
1367 return 0; 1358 return 0;
@@ -1402,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
1402 .reg_cache_step = 2, 1393 .reg_cache_step = 2,
1403 .reg_cache_default = sgtl5000_regs, 1394 .reg_cache_default = sgtl5000_regs,
1404 .volatile_register = sgtl5000_volatile_register, 1395 .volatile_register = sgtl5000_volatile_register,
1396 .controls = sgtl5000_snd_controls,
1397 .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
1398 .dapm_widgets = sgtl5000_dapm_widgets,
1399 .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
1400 .dapm_routes = sgtl5000_dapm_routes,
1401 .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
1405}; 1402};
1406 1403
1407static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, 1404static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index f99baa0b8c39..50dbdb9357ea 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
827{ 827{
828 pr_debug("codec_probe called\n"); 828 pr_debug("codec_probe called\n");
829 829
830 codec->dapm.idle_bias_off = 1;
831
832 /* PCM interface config 830 /* PCM interface config
833 * This sets the pcm rx slot conguration to max 6 slots 831 * This sets the pcm rx slot conguration to max 6 slots
834 * for max 4 dais (2 stereo and 2 mono) 832 * for max 4 dais (2 stereo and 2 mono)
@@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
871 snd_soc_write(codec, SN95031_SSR2, 0x10); 869 snd_soc_write(codec, SN95031_SSR2, 0x10);
872 snd_soc_write(codec, SN95031_SSR3, 0x40); 870 snd_soc_write(codec, SN95031_SSR3, 0x40);
873 871
874 snd_soc_add_controls(codec, sn95031_snd_controls, 872 snd_soc_add_codec_controls(codec, sn95031_snd_controls,
875 ARRAY_SIZE(sn95031_snd_controls)); 873 ARRAY_SIZE(sn95031_snd_controls));
876 874
877 return 0; 875 return 0;
@@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = {
891 .read = sn95031_read, 889 .read = sn95031_read,
892 .write = sn95031_write, 890 .write = sn95031_write,
893 .set_bias_level = sn95031_set_vaud_bias, 891 .set_bias_level = sn95031_set_vaud_bias,
892 .idle_bias_off = true,
894 .dapm_widgets = sn95031_dapm_widgets, 893 .dapm_widgets = sn95031_dapm_widgets,
895 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), 894 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
896 .dapm_routes = sn95031_audio_map, 895 .dapm_routes = sn95031_audio_map,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 333dd98af39c..de2b20544ceb 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
548 snd_soc_update_bits(codec, SSM2602_ROUT1V, 548 snd_soc_update_bits(codec, SSM2602_ROUT1V,
549 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); 549 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
550 550
551 ret = snd_soc_add_controls(codec, ssm2602_snd_controls, 551 ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
552 ARRAY_SIZE(ssm2602_snd_controls)); 552 ARRAY_SIZE(ssm2602_snd_controls));
553 if (ret) 553 if (ret)
554 return ret; 554 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index cc0566c22ec1..982e437799a8 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
355 355
356 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 356 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
357 357
358 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 358 snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
359 ARRAY_SIZE(stac9766_snd_ac97_controls)); 359 ARRAY_SIZE(stac9766_snd_ac97_controls));
360 360
361 return 0; 361 return 0;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index dfa41a96599b..16d55f91a653 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
593 593
594 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); 594 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
595 595
596 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 596 snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
597 ARRAY_SIZE(tlv320aic23_snd_controls)); 597 ARRAY_SIZE(tlv320aic23_snd_controls));
598 598
599 return 0; 599 return 0;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index a038daec682b..802064b5030d 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
389 389
390 /* register controls */ 390 /* register controls */
391 dev_dbg(codec->dev, "Registering controls\n"); 391 dev_dbg(codec->dev, "Registering controls\n");
392 err = snd_soc_add_controls(codec, aic26_snd_controls, 392 err = snd_soc_add_codec_controls(codec, aic26_snd_controls,
393 ARRAY_SIZE(aic26_snd_controls)); 393 ARRAY_SIZE(aic26_snd_controls));
394 WARN_ON(err < 0); 394 WARN_ON(err < 0);
395 395
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 372b0b83bd9f..b0a73d37ed52 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
671 } 671 }
672 672
673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
674 snd_soc_add_controls(codec, aic32x4_snd_controls, 674 snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
675 ARRAY_SIZE(aic32x4_snd_controls)); 675 ARRAY_SIZE(aic32x4_snd_controls));
676 aic32x4_add_widgets(codec); 676 aic32x4_add_widgets(codec);
677 677
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 492f22f8a4d7..8d20f6ec20f3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
121 0x00, 0x00, 0x02, /* 100 */ 121 0x00, 0x00, 0x02, /* 100 */
122}; 122};
123 123
124/*
125 * read from the aic3x register space. Only use for this function is if
126 * wanting to read volatile bits from those registers that has both read-only
127 * and read/write bits. All other cases should use snd_soc_read.
128 */
129static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
130 u8 *value)
131{
132 u8 *cache = codec->reg_cache;
133
134 if (codec->cache_only)
135 return -EINVAL;
136 if (reg >= AIC3X_CACHEREGNUM)
137 return -1;
138
139 codec->cache_bypass = 1;
140 *value = snd_soc_read(codec, reg);
141 codec->cache_bypass = 0;
142
143 cache[reg] = *value;
144
145 return 0;
146}
147
148#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 124#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
149{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 125{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
150 .info = snd_soc_info_volsw, \ 126 .info = snd_soc_info_volsw, \
@@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1185 return 0; 1161 return 0;
1186} 1162}
1187 1163
1188void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1189{
1190 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1191 u8 bit = gpio ? 3: 0;
1192 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1193 snd_soc_write(codec, reg, val | (!!state << bit));
1194}
1195EXPORT_SYMBOL_GPL(aic3x_set_gpio);
1196
1197int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
1198{
1199 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1200 u8 val = 0, bit = gpio ? 2 : 1;
1201
1202 aic3x_read(codec, reg, &val);
1203 return (val >> bit) & 1;
1204}
1205EXPORT_SYMBOL_GPL(aic3x_get_gpio);
1206
1207void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, 1164void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1208 int headset_debounce, int button_debounce) 1165 int headset_debounce, int button_debounce)
1209{ 1166{
@@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1221 1178
1222 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); 1179 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1223} 1180}
1224EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1225
1226int aic3x_headset_detected(struct snd_soc_codec *codec)
1227{
1228 u8 val = 0;
1229 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1230 return (val >> 4) & 1;
1231}
1232EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1233
1234int aic3x_button_pressed(struct snd_soc_codec *codec)
1235{
1236 u8 val = 0;
1237 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1238 return (val >> 5) & 1;
1239}
1240EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1241 1181
1242#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1182#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1243#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1183#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1377 1317
1378 INIT_LIST_HEAD(&aic3x->list); 1318 INIT_LIST_HEAD(&aic3x->list);
1379 aic3x->codec = codec; 1319 aic3x->codec = codec;
1380 codec->dapm.idle_bias_off = 1;
1381 1320
1382 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); 1321 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1383 if (ret != 0) { 1322 if (ret != 0) {
@@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1426 (aic3x->setup->gpio_func[1] & 0xf) << 4); 1365 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1427 } 1366 }
1428 1367
1429 snd_soc_add_controls(codec, aic3x_snd_controls, 1368 snd_soc_add_codec_controls(codec, aic3x_snd_controls,
1430 ARRAY_SIZE(aic3x_snd_controls)); 1369 ARRAY_SIZE(aic3x_snd_controls));
1431 if (aic3x->model == AIC3X_MODEL_3007) 1370 if (aic3x->model == AIC3X_MODEL_3007)
1432 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1371 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1433 1372
1434 aic3x_add_widgets(codec); 1373 aic3x_add_widgets(codec);
1435 list_add(&aic3x->list, &reset_list); 1374 list_add(&aic3x->list, &reset_list);
@@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1471 1410
1472static struct snd_soc_codec_driver soc_codec_dev_aic3x = { 1411static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1473 .set_bias_level = aic3x_set_bias_level, 1412 .set_bias_level = aic3x_set_bias_level,
1413 .idle_bias_off = true,
1474 .reg_cache_size = ARRAY_SIZE(aic3x_reg), 1414 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1475 .reg_word_size = sizeof(u8), 1415 .reg_word_size = sizeof(u8),
1476 .reg_cache_default = aic3x_reg, 1416 .reg_cache_default = aic3x_reg,
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 06a19784b162..6f097fb60683 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -212,9 +212,6 @@
212/* Default input volume */ 212/* Default input volume */
213#define DEFAULT_GAIN 0x20 213#define DEFAULT_GAIN 0x20
214 214
215void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
216int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
217
218/* headset detection / button API */ 215/* headset detection / button API */
219 216
220/* The AIC3x supports detection of stereo headsets (GND + left + right signal) 217/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
@@ -252,10 +249,4 @@ enum {
252#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 249#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
253#define AIC3X_BUTTON_DEBOUNCE_MASK 3 250#define AIC3X_BUTTON_DEBOUNCE_MASK 3
254 251
255/* see the enums above for valid parameters to this function */
256void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
257 int headset_debounce, int button_debounce);
258int aic3x_headset_detected(struct snd_soc_codec *codec);
259int aic3x_button_pressed(struct snd_soc_codec *codec);
260
261#endif /* _AIC3X_H */ 252#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index f0aad26cdb31..4587ddd0fbf8 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream,
806 /* Stream started, save the substream pointer */ 806 /* Stream started, save the substream pointer */
807 dac33->substream = substream; 807 dac33->substream = substream;
808 808
809 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
810
811 return 0; 809 return 0;
812} 810}
813 811
@@ -1397,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1397 1395
1398 codec->control_data = dac33->control_data; 1396 codec->control_data = dac33->control_data;
1399 codec->hw_write = (hw_write_t) i2c_master_send; 1397 codec->hw_write = (hw_write_t) i2c_master_send;
1400 codec->dapm.idle_bias_off = 1;
1401 dac33->codec = codec; 1398 dac33->codec = codec;
1402 1399
1403 /* Read the tlv320dac33 ID registers */ 1400 /* Read the tlv320dac33 ID registers */
@@ -1440,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1440 1437
1441 /* Only add the FIFO controls, if we have valid IRQ number */ 1438 /* Only add the FIFO controls, if we have valid IRQ number */
1442 if (dac33->irq >= 0) 1439 if (dac33->irq >= 0)
1443 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1440 snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
1444 ARRAY_SIZE(dac33_mode_snd_controls)); 1441 ARRAY_SIZE(dac33_mode_snd_controls));
1445 1442
1446err_power: 1443err_power:
@@ -1478,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1478 .read = dac33_read_reg_cache, 1475 .read = dac33_read_reg_cache,
1479 .write = dac33_write_locked, 1476 .write = dac33_write_locked,
1480 .set_bias_level = dac33_set_bias_level, 1477 .set_bias_level = dac33_set_bias_level,
1478 .idle_bias_off = true,
1481 .reg_cache_size = ARRAY_SIZE(dac33_reg), 1479 .reg_cache_size = ARRAY_SIZE(dac33_reg),
1482 .reg_word_size = sizeof(u8), 1480 .reg_word_size = sizeof(u8),
1483 .reg_cache_default = dac33_reg, 1481 .reg_cache_default = dac33_reg,
@@ -1515,7 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = {
1515 .channels_min = 2, 1513 .channels_min = 2,
1516 .channels_max = 2, 1514 .channels_max = 2,
1517 .rates = DAC33_RATES, 1515 .rates = DAC33_RATES,
1518 .formats = DAC33_FORMATS,}, 1516 .formats = DAC33_FORMATS,
1517 .sig_bits = 24,
1518 },
1519 .ops = &dac33_dai_ops, 1519 .ops = &dac33_dai_ops,
1520}; 1520};
1521 1521
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 363b99dad8e9..6fe4aa3ac544 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
351 data = i2c_get_clientdata(tpa6130a2_client); 351 data = i2c_get_clientdata(tpa6130a2_client);
352 352
353 if (data->id == TPA6140A2) 353 if (data->id == TPA6140A2)
354 return snd_soc_add_controls(codec, tpa6140a2_controls, 354 return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
355 ARRAY_SIZE(tpa6140a2_controls)); 355 ARRAY_SIZE(tpa6140a2_controls));
356 else 356 else
357 return snd_soc_add_controls(codec, tpa6130a2_controls, 357 return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
358 ARRAY_SIZE(tpa6130a2_controls)); 358 ARRAY_SIZE(tpa6130a2_controls));
359} 359}
360EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 360EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 18e71014cc2e..170cf9a8fc79 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
1002 unsigned short mask, bitmask; 1002 unsigned short mask, bitmask;
1003 1003
1004 if (twl4030->configured) { 1004 if (twl4030->configured) {
1005 printk(KERN_ERR "twl4030 operation mode cannot be " 1005 dev_err(codec->dev,
1006 "changed on-the-fly\n"); 1006 "operation mode cannot be changed on-the-fly\n");
1007 return -EBUSY; 1007 return -EBUSY;
1008 } 1008 }
1009 1009
@@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1689 struct snd_soc_codec *codec = rtd->codec; 1689 struct snd_soc_codec *codec = rtd->codec;
1690 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1690 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1691 1691
1692 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
1693 if (twl4030->master_substream) { 1692 if (twl4030->master_substream) {
1694 twl4030->slave_substream = substream; 1693 twl4030->slave_substream = substream;
1695 /* The DAI has one configuration for playback and capture, so 1694 /* The DAI has one configuration for playback and capture, so
@@ -1801,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1801 mode |= TWL4030_APLL_RATE_96000; 1800 mode |= TWL4030_APLL_RATE_96000;
1802 break; 1801 break;
1803 default: 1802 default:
1804 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", 1803 dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
1805 params_rate(params)); 1804 params_rate(params));
1806 return -EINVAL; 1805 return -EINVAL;
1807 } 1806 }
@@ -1818,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1818 format |= TWL4030_DATA_WIDTH_32S_24W; 1817 format |= TWL4030_DATA_WIDTH_32S_24W;
1819 break; 1818 break;
1820 default: 1819 default:
1821 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n", 1820 dev_err(codec->dev, "%s: unknown format %d\n", __func__,
1822 params_format(params)); 1821 params_format(params));
1823 return -EINVAL; 1822 return -EINVAL;
1824 } 1823 }
@@ -1868,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1868 case 38400000: 1867 case 38400000:
1869 break; 1868 break;
1870 default: 1869 default:
1871 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq); 1870 dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
1872 return -EINVAL; 1871 return -EINVAL;
1873 } 1872 }
1874 1873
1875 if ((freq / 1000) != twl4030->sysclk) { 1874 if ((freq / 1000) != twl4030->sysclk) {
1876 dev_err(codec->dev, 1875 dev_err(codec->dev,
1877 "Mismatch in APLL mclk: %u (configured: %u)\n", 1876 "Mismatch in HFCLKIN: %u (configured: %u)\n",
1878 freq, twl4030->sysclk * 1000); 1877 freq, twl4030->sysclk * 1000);
1879 return -EINVAL; 1878 return -EINVAL;
1880 } 1879 }
@@ -1984,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1984 * not available. 1983 * not available.
1985 */ 1984 */
1986 if (twl4030->sysclk != 26000) { 1985 if (twl4030->sysclk != 26000) {
1987 dev_err(codec->dev, "The board is configured for %u Hz, while" 1986 dev_err(codec->dev,
1988 "the Voice interface needs 26MHz APLL mclk\n", 1987 "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
1989 twl4030->sysclk * 1000); 1988 __func__, twl4030->sysclk);
1990 return -EINVAL; 1989 return -EINVAL;
1991 } 1990 }
1992 1991
@@ -1997,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1997 & TWL4030_OPT_MODE; 1996 & TWL4030_OPT_MODE;
1998 1997
1999 if (mode != TWL4030_OPTION_2) { 1998 if (mode != TWL4030_OPTION_2) {
2000 printk(KERN_ERR "TWL4030 voice startup: " 1999 dev_err(codec->dev, "%s: the codec mode is not option2\n",
2001 "the codec mode is not option2\n"); 2000 __func__);
2002 return -EINVAL; 2001 return -EINVAL;
2003 } 2002 }
2004 2003
@@ -2039,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2039 mode |= TWL4030_SEL_16K; 2038 mode |= TWL4030_SEL_16K;
2040 break; 2039 break;
2041 default: 2040 default:
2042 printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", 2041 dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
2043 params_rate(params)); 2042 params_rate(params));
2044 return -EINVAL; 2043 return -EINVAL;
2045 } 2044 }
@@ -2068,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2068 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2067 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2069 2068
2070 if (freq != 26000000) { 2069 if (freq != 26000000) {
2071 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" 2070 dev_err(codec->dev,
2072 "interface needs 26MHz APLL mclk\n", freq); 2071 "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
2072 __func__, freq / 1000);
2073 return -EINVAL; 2073 return -EINVAL;
2074 } 2074 }
2075 if ((freq / 1000) != twl4030->sysclk) { 2075 if ((freq / 1000) != twl4030->sysclk) {
2076 dev_err(codec->dev, 2076 dev_err(codec->dev,
2077 "Mismatch in APLL mclk: %u (configured: %u)\n", 2077 "Mismatch in HFCLKIN: %u (configured: %u)\n",
2078 freq, twl4030->sysclk * 1000); 2078 freq, twl4030->sysclk * 1000);
2079 return -EINVAL; 2079 return -EINVAL;
2080 } 2080 }
@@ -2175,13 +2175,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
2175 .channels_min = 2, 2175 .channels_min = 2,
2176 .channels_max = 4, 2176 .channels_max = 4,
2177 .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, 2177 .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
2178 .formats = TWL4030_FORMATS,}, 2178 .formats = TWL4030_FORMATS,
2179 .sig_bits = 24,},
2179 .capture = { 2180 .capture = {
2180 .stream_name = "Capture", 2181 .stream_name = "Capture",
2181 .channels_min = 2, 2182 .channels_min = 2,
2182 .channels_max = 4, 2183 .channels_max = 4,
2183 .rates = TWL4030_RATES, 2184 .rates = TWL4030_RATES,
2184 .formats = TWL4030_FORMATS,}, 2185 .formats = TWL4030_FORMATS,
2186 .sig_bits = 24,},
2185 .ops = &twl4030_dai_hifi_ops, 2187 .ops = &twl4030_dai_hifi_ops,
2186}, 2188},
2187{ 2189{
@@ -2220,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2220 2222
2221 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2223 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2222 if (twl4030 == NULL) { 2224 if (twl4030 == NULL) {
2223 printk("Can not allocate memroy\n"); 2225 dev_err(codec->dev, "Can not allocate memory\n");
2224 return -ENOMEM; 2226 return -ENOMEM;
2225 } 2227 }
2226 snd_soc_codec_set_drvdata(codec, twl4030); 2228 snd_soc_codec_set_drvdata(codec, twl4030);
2227 /* Set the defaults, and power up the codec */ 2229 /* Set the defaults, and power up the codec */
2228 twl4030->sysclk = twl4030_audio_get_mclk() / 1000; 2230 twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
2229 codec->dapm.idle_bias_off = 1;
2230 2231
2231 twl4030_init_chip(codec); 2232 twl4030_init_chip(codec);
2232 2233
@@ -2252,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2252 .read = twl4030_read_reg_cache, 2253 .read = twl4030_read_reg_cache,
2253 .write = twl4030_write, 2254 .write = twl4030_write,
2254 .set_bias_level = twl4030_set_bias_level, 2255 .set_bias_level = twl4030_set_bias_level,
2256 .idle_bias_off = true,
2255 .reg_cache_size = sizeof(twl4030_reg), 2257 .reg_cache_size = sizeof(twl4030_reg),
2256 .reg_word_size = sizeof(u8), 2258 .reg_word_size = sizeof(u8),
2257 .reg_cache_default = twl4030_reg, 2259 .reg_cache_default = twl4030_reg,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 5b9c79b6f65e..2d8c6b825e57 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1052,6 +1052,19 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
1052} 1052}
1053EXPORT_SYMBOL_GPL(twl6040_get_trim_value); 1053EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
1054 1054
1055int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
1056{
1057 struct twl6040 *twl6040 = codec->control_data;
1058
1059 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2)
1060 /* For ES under ES_1.3 HS step is 2 mV */
1061 return 2;
1062 else
1063 /* For ES_1.3 HS step is 1 mV */
1064 return 1;
1065}
1066EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
1067
1055static const struct snd_kcontrol_new twl6040_snd_controls[] = { 1068static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1056 /* Capture gains */ 1069 /* Capture gains */
1057 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 1070 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1125,14 +1138,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1125 TWL6040_REG_MICRCTL, 2, 0), 1138 TWL6040_REG_MICRCTL, 2, 0),
1126 1139
1127 /* Microphone bias */ 1140 /* Microphone bias */
1128 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", 1141 SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
1129 TWL6040_REG_AMICBCTL, 0, 0), 1142 TWL6040_REG_AMICBCTL, 0, 0, NULL, 0),
1130 SND_SOC_DAPM_MICBIAS("Main Mic Bias", 1143 SND_SOC_DAPM_SUPPLY("Main Mic Bias",
1131 TWL6040_REG_AMICBCTL, 4, 0), 1144 TWL6040_REG_AMICBCTL, 4, 0, NULL, 0),
1132 SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias", 1145 SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
1133 TWL6040_REG_DMICBCTL, 0, 0), 1146 TWL6040_REG_DMICBCTL, 0, 0, NULL, 0),
1134 SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias", 1147 SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
1135 TWL6040_REG_DMICBCTL, 4, 0), 1148 TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
1136 1149
1137 /* DACs */ 1150 /* DACs */
1138 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), 1151 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
@@ -1527,7 +1540,6 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1527 1540
1528 priv->codec = codec; 1541 priv->codec = codec;
1529 codec->control_data = dev_get_drvdata(codec->dev->parent); 1542 codec->control_data = dev_get_drvdata(codec->dev->parent);
1530 codec->ignore_pmdown_time = 1;
1531 1543
1532 if (pdata && pdata->hs_left_step && pdata->hs_right_step) { 1544 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1533 priv->hs_left_step = pdata->hs_left_step; 1545 priv->hs_left_step = pdata->hs_left_step;
@@ -1613,6 +1625,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1613 .reg_cache_size = ARRAY_SIZE(twl6040_reg), 1625 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1614 .reg_word_size = sizeof(u8), 1626 .reg_word_size = sizeof(u8),
1615 .reg_cache_default = twl6040_reg, 1627 .reg_cache_default = twl6040_reg,
1628 .ignore_pmdown_time = true,
1616 1629
1617 .controls = twl6040_snd_controls, 1630 .controls = twl6040_snd_controls,
1618 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1631 .num_controls = ARRAY_SIZE(twl6040_snd_controls),
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index ef273f1fac2f..0611406ca7c0 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -39,5 +39,6 @@ void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
39 struct snd_soc_jack *jack, int report); 39 struct snd_soc_jack *jack, int report);
40int twl6040_get_clk_id(struct snd_soc_codec *codec); 40int twl6040_get_clk_id(struct snd_soc_codec *codec);
41int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim); 41int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
42int twl6040_get_hs_step_size(struct snd_soc_codec *codec);
42 43
43#endif /* End of __TWL6040_H__ */ 44#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 8f4f469d6411..797b0dde2c68 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -531,15 +531,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
531 switch (pd->model) { 531 switch (pd->model) {
532 case UDA134X_UDA1340: 532 case UDA134X_UDA1340:
533 case UDA134X_UDA1344: 533 case UDA134X_UDA1344:
534 ret = snd_soc_add_controls(codec, uda1340_snd_controls, 534 ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
535 ARRAY_SIZE(uda1340_snd_controls)); 535 ARRAY_SIZE(uda1340_snd_controls));
536 break; 536 break;
537 case UDA134X_UDA1341: 537 case UDA134X_UDA1341:
538 ret = snd_soc_add_controls(codec, uda1341_snd_controls, 538 ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
539 ARRAY_SIZE(uda1341_snd_controls)); 539 ARRAY_SIZE(uda1341_snd_controls));
540 break; 540 break;
541 case UDA134X_UDA1345: 541 case UDA134X_UDA1345:
542 ret = snd_soc_add_controls(codec, uda1345_snd_controls, 542 ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
543 ARRAY_SIZE(uda1345_snd_controls)); 543 ARRAY_SIZE(uda1345_snd_controls));
544 break; 544 break;
545 default: 545 default:
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 44aacf927ba9..3d868dc40092 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -464,7 +464,7 @@ static int wl1273_probe(struct snd_soc_codec *codec)
464 464
465 snd_soc_codec_set_drvdata(codec, wl1273); 465 snd_soc_codec_set_drvdata(codec, wl1273);
466 466
467 r = snd_soc_add_controls(codec, wl1273_controls, 467 r = snd_soc_add_codec_controls(codec, wl1273_controls,
468 ARRAY_SIZE(wl1273_controls)); 468 ARRAY_SIZE(wl1273_controls));
469 if (r) 469 if (r)
470 kfree(wl1273); 470 kfree(wl1273);
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
new file mode 100644
index 000000000000..acbdc5fde923
--- /dev/null
+++ b/sound/soc/codecs/wm2200.c
@@ -0,0 +1,2286 @@
1/*
2 * wm2200.c -- WM2200 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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 version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/gcd.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/pm_runtime.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <sound/wm2200.h>
33
34#include "wm2200.h"
35
36/* The code assumes DCVDD is generated internally */
37#define WM2200_NUM_CORE_SUPPLIES 2
38static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
39 "DBVDD",
40 "LDOVDD",
41};
42
43struct wm2200_fll {
44 int fref;
45 int fout;
46 int src;
47 struct completion lock;
48};
49
50/* codec private data */
51struct wm2200_priv {
52 struct regmap *regmap;
53 struct device *dev;
54 struct snd_soc_codec *codec;
55 struct wm2200_pdata pdata;
56 struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
57
58 struct completion fll_lock;
59 int fll_fout;
60 int fll_fref;
61 int fll_src;
62
63 int rev;
64 int sysclk;
65};
66
67static struct reg_default wm2200_reg_defaults[] = {
68 { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */
69 { 0x0102, 0x0000 }, /* R258 - Clocking 3 */
70 { 0x0103, 0x0011 }, /* R259 - Clocking 4 */
71 { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */
72 { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */
73 { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */
74 { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */
75 { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */
76 { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */
77 { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */
78 { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */
79 { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */
80 { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */
81 { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */
82 { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */
83 { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */
84 { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */
85 { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */
86 { 0x0301, 0x0000 }, /* R769 - Input Enables */
87 { 0x0302, 0x2240 }, /* R770 - IN1L Control */
88 { 0x0303, 0x0040 }, /* R771 - IN1R Control */
89 { 0x0304, 0x2240 }, /* R772 - IN2L Control */
90 { 0x0305, 0x0040 }, /* R773 - IN2R Control */
91 { 0x0306, 0x2240 }, /* R774 - IN3L Control */
92 { 0x0307, 0x0040 }, /* R775 - IN3R Control */
93 { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */
94 { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */
95 { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */
96 { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */
97 { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */
98 { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */
99 { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */
100 { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */
101 { 0x0400, 0x0000 }, /* R1024 - Output Enables */
102 { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */
103 { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */
104 { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */
105 { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */
106 { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */
107 { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */
108 { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */
109 { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */
110 { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */
111 { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */
112 { 0x0417, 0x0069 }, /* R1047 - PDM 1 */
113 { 0x0418, 0x0000 }, /* R1048 - PDM 2 */
114 { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */
115 { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */
116 { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */
117 { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */
118 { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */
119 { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */
120 { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */
121 { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */
122 { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */
123 { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */
124 { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */
125 { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */
126 { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */
127 { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */
128 { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */
129 { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */
130 { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */
131 { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */
132 { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */
133 { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */
134 { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */
135 { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */
136 { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */
137 { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */
138 { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */
139 { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */
140 { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */
141 { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */
142 { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */
143 { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */
144 { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */
145 { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */
146 { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */
147 { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */
148 { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */
149 { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */
150 { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */
151 { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */
152 { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */
153 { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */
154 { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */
155 { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */
156 { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */
157 { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */
158 { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */
159 { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */
160 { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */
161 { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */
162 { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */
163 { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */
164 { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */
165 { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */
166 { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */
167 { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */
168 { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */
169 { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */
170 { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */
171 { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */
172 { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */
173 { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */
174 { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */
175 { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */
176 { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */
177 { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */
178 { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */
179 { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */
180 { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */
181 { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */
182 { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */
183 { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */
184 { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */
185 { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */
186 { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */
187 { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */
188 { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */
189 { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */
190 { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */
191 { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */
192 { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */
193 { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */
194 { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */
195 { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */
196 { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */
197 { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */
198 { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */
199 { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */
200 { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */
201 { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */
202 { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */
203 { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */
204 { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */
205 { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */
206 { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */
207 { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */
208 { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */
209 { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */
210 { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */
211 { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */
212 { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */
213 { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */
214 { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */
215 { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */
216 { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */
217 { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */
218 { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */
219 { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */
220 { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */
221 { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */
222 { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */
223 { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */
224 { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */
225 { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */
226 { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */
227 { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */
228 { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */
229 { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */
230 { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */
231 { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */
232 { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */
233 { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */
234 { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */
235 { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */
236 { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */
237 { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */
238 { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */
239 { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */
240 { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */
241 { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */
242 { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */
243 { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */
244 { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */
245 { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */
246 { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */
247 { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */
248 { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */
249 { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */
250 { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */
251 { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */
252 { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */
253 { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */
254 { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */
255 { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */
256 { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */
257 { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */
258 { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */
259 { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */
260 { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */
261 { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */
262 { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */
263 { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */
264 { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */
265 { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */
266 { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */
267 { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */
268 { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */
269 { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */
270 { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */
271 { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */
272 { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */
273 { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */
274 { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */
275 { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */
276 { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */
277 { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */
278 { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */
279 { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */
280 { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */
281 { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */
282 { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */
283 { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */
284 { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */
285 { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */
286 { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */
287 { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */
288 { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */
289 { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */
290 { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */
291 { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */
292 { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */
293 { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */
294 { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */
295 { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */
296 { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */
297 { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */
298 { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */
299 { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */
300 { 0x0900, 0x0000 }, /* R2304 - EQL_1 */
301 { 0x0901, 0x0000 }, /* R2305 - EQL_2 */
302 { 0x0902, 0x0000 }, /* R2306 - EQL_3 */
303 { 0x0903, 0x0000 }, /* R2307 - EQL_4 */
304 { 0x0904, 0x0000 }, /* R2308 - EQL_5 */
305 { 0x0905, 0x0000 }, /* R2309 - EQL_6 */
306 { 0x0906, 0x0000 }, /* R2310 - EQL_7 */
307 { 0x0907, 0x0000 }, /* R2311 - EQL_8 */
308 { 0x0908, 0x0000 }, /* R2312 - EQL_9 */
309 { 0x0909, 0x0000 }, /* R2313 - EQL_10 */
310 { 0x090A, 0x0000 }, /* R2314 - EQL_11 */
311 { 0x090B, 0x0000 }, /* R2315 - EQL_12 */
312 { 0x090C, 0x0000 }, /* R2316 - EQL_13 */
313 { 0x090D, 0x0000 }, /* R2317 - EQL_14 */
314 { 0x090E, 0x0000 }, /* R2318 - EQL_15 */
315 { 0x090F, 0x0000 }, /* R2319 - EQL_16 */
316 { 0x0910, 0x0000 }, /* R2320 - EQL_17 */
317 { 0x0911, 0x0000 }, /* R2321 - EQL_18 */
318 { 0x0912, 0x0000 }, /* R2322 - EQL_19 */
319 { 0x0913, 0x0000 }, /* R2323 - EQL_20 */
320 { 0x0916, 0x0000 }, /* R2326 - EQR_1 */
321 { 0x0917, 0x0000 }, /* R2327 - EQR_2 */
322 { 0x0918, 0x0000 }, /* R2328 - EQR_3 */
323 { 0x0919, 0x0000 }, /* R2329 - EQR_4 */
324 { 0x091A, 0x0000 }, /* R2330 - EQR_5 */
325 { 0x091B, 0x0000 }, /* R2331 - EQR_6 */
326 { 0x091C, 0x0000 }, /* R2332 - EQR_7 */
327 { 0x091D, 0x0000 }, /* R2333 - EQR_8 */
328 { 0x091E, 0x0000 }, /* R2334 - EQR_9 */
329 { 0x091F, 0x0000 }, /* R2335 - EQR_10 */
330 { 0x0920, 0x0000 }, /* R2336 - EQR_11 */
331 { 0x0921, 0x0000 }, /* R2337 - EQR_12 */
332 { 0x0922, 0x0000 }, /* R2338 - EQR_13 */
333 { 0x0923, 0x0000 }, /* R2339 - EQR_14 */
334 { 0x0924, 0x0000 }, /* R2340 - EQR_15 */
335 { 0x0925, 0x0000 }, /* R2341 - EQR_16 */
336 { 0x0926, 0x0000 }, /* R2342 - EQR_17 */
337 { 0x0927, 0x0000 }, /* R2343 - EQR_18 */
338 { 0x0928, 0x0000 }, /* R2344 - EQR_19 */
339 { 0x0929, 0x0000 }, /* R2345 - EQR_20 */
340 { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */
341 { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */
342 { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */
343 { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */
344 { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */
345 { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */
346 { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */
347 { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */
348 { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */
349 { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */
350 { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */
351 { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */
352 { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */
353 { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */
354 { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */
355 { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */
356 { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */
357 { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */
358 { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */
359 { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */
360 { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */
361 { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */
362 { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */
363 { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */
364 { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */
365 { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */
366 { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */
367 { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */
368 { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */
369 { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */
370 { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */
371 { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */
372 { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */
373 { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */
374 { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */
375 { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */
376 { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */
377 { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */
378 { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */
379 { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */
380 { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */
381 { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */
382 { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */
383 { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */
384 { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */
385 { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */
386 { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */
387 { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */
388 { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */
389 { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */
390 { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */
391 { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */
392 { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */
393 { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */
394 { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */
395 { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */
396 { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */
397 { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */
398 { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */
399 { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */
400 { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */
401 { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */
402 { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */
403 { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */
404 { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */
405 { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */
406};
407
408static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
409{
410 switch (reg) {
411 case WM2200_SOFTWARE_RESET:
412 case WM2200_DEVICE_REVISION:
413 case WM2200_ADPS1_IRQ0:
414 case WM2200_ADPS1_IRQ1:
415 case WM2200_INTERRUPT_STATUS_1:
416 case WM2200_INTERRUPT_STATUS_2:
417 case WM2200_INTERRUPT_RAW_STATUS_2:
418 return true;
419 default:
420 return false;
421 }
422}
423
424static bool wm2200_readable_register(struct device *dev, unsigned int reg)
425{
426 switch (reg) {
427 case WM2200_SOFTWARE_RESET:
428 case WM2200_DEVICE_REVISION:
429 case WM2200_TONE_GENERATOR_1:
430 case WM2200_CLOCKING_3:
431 case WM2200_CLOCKING_4:
432 case WM2200_FLL_CONTROL_1:
433 case WM2200_FLL_CONTROL_2:
434 case WM2200_FLL_CONTROL_3:
435 case WM2200_FLL_CONTROL_4:
436 case WM2200_FLL_CONTROL_6:
437 case WM2200_FLL_CONTROL_7:
438 case WM2200_FLL_EFS_1:
439 case WM2200_FLL_EFS_2:
440 case WM2200_MIC_CHARGE_PUMP_1:
441 case WM2200_MIC_CHARGE_PUMP_2:
442 case WM2200_DM_CHARGE_PUMP_1:
443 case WM2200_MIC_BIAS_CTRL_1:
444 case WM2200_MIC_BIAS_CTRL_2:
445 case WM2200_EAR_PIECE_CTRL_1:
446 case WM2200_EAR_PIECE_CTRL_2:
447 case WM2200_INPUT_ENABLES:
448 case WM2200_IN1L_CONTROL:
449 case WM2200_IN1R_CONTROL:
450 case WM2200_IN2L_CONTROL:
451 case WM2200_IN2R_CONTROL:
452 case WM2200_IN3L_CONTROL:
453 case WM2200_IN3R_CONTROL:
454 case WM2200_RXANC_SRC:
455 case WM2200_INPUT_VOLUME_RAMP:
456 case WM2200_ADC_DIGITAL_VOLUME_1L:
457 case WM2200_ADC_DIGITAL_VOLUME_1R:
458 case WM2200_ADC_DIGITAL_VOLUME_2L:
459 case WM2200_ADC_DIGITAL_VOLUME_2R:
460 case WM2200_ADC_DIGITAL_VOLUME_3L:
461 case WM2200_ADC_DIGITAL_VOLUME_3R:
462 case WM2200_OUTPUT_ENABLES:
463 case WM2200_DAC_VOLUME_LIMIT_1L:
464 case WM2200_DAC_VOLUME_LIMIT_1R:
465 case WM2200_DAC_VOLUME_LIMIT_2L:
466 case WM2200_DAC_VOLUME_LIMIT_2R:
467 case WM2200_DAC_AEC_CONTROL_1:
468 case WM2200_OUTPUT_VOLUME_RAMP:
469 case WM2200_DAC_DIGITAL_VOLUME_1L:
470 case WM2200_DAC_DIGITAL_VOLUME_1R:
471 case WM2200_DAC_DIGITAL_VOLUME_2L:
472 case WM2200_DAC_DIGITAL_VOLUME_2R:
473 case WM2200_PDM_1:
474 case WM2200_PDM_2:
475 case WM2200_AUDIO_IF_1_1:
476 case WM2200_AUDIO_IF_1_2:
477 case WM2200_AUDIO_IF_1_3:
478 case WM2200_AUDIO_IF_1_4:
479 case WM2200_AUDIO_IF_1_5:
480 case WM2200_AUDIO_IF_1_6:
481 case WM2200_AUDIO_IF_1_7:
482 case WM2200_AUDIO_IF_1_8:
483 case WM2200_AUDIO_IF_1_9:
484 case WM2200_AUDIO_IF_1_10:
485 case WM2200_AUDIO_IF_1_11:
486 case WM2200_AUDIO_IF_1_12:
487 case WM2200_AUDIO_IF_1_13:
488 case WM2200_AUDIO_IF_1_14:
489 case WM2200_AUDIO_IF_1_15:
490 case WM2200_AUDIO_IF_1_16:
491 case WM2200_AUDIO_IF_1_17:
492 case WM2200_AUDIO_IF_1_18:
493 case WM2200_AUDIO_IF_1_19:
494 case WM2200_AUDIO_IF_1_20:
495 case WM2200_AUDIO_IF_1_21:
496 case WM2200_AUDIO_IF_1_22:
497 case WM2200_OUT1LMIX_INPUT_1_SOURCE:
498 case WM2200_OUT1LMIX_INPUT_1_VOLUME:
499 case WM2200_OUT1LMIX_INPUT_2_SOURCE:
500 case WM2200_OUT1LMIX_INPUT_2_VOLUME:
501 case WM2200_OUT1LMIX_INPUT_3_SOURCE:
502 case WM2200_OUT1LMIX_INPUT_3_VOLUME:
503 case WM2200_OUT1LMIX_INPUT_4_SOURCE:
504 case WM2200_OUT1LMIX_INPUT_4_VOLUME:
505 case WM2200_OUT1RMIX_INPUT_1_SOURCE:
506 case WM2200_OUT1RMIX_INPUT_1_VOLUME:
507 case WM2200_OUT1RMIX_INPUT_2_SOURCE:
508 case WM2200_OUT1RMIX_INPUT_2_VOLUME:
509 case WM2200_OUT1RMIX_INPUT_3_SOURCE:
510 case WM2200_OUT1RMIX_INPUT_3_VOLUME:
511 case WM2200_OUT1RMIX_INPUT_4_SOURCE:
512 case WM2200_OUT1RMIX_INPUT_4_VOLUME:
513 case WM2200_OUT2LMIX_INPUT_1_SOURCE:
514 case WM2200_OUT2LMIX_INPUT_1_VOLUME:
515 case WM2200_OUT2LMIX_INPUT_2_SOURCE:
516 case WM2200_OUT2LMIX_INPUT_2_VOLUME:
517 case WM2200_OUT2LMIX_INPUT_3_SOURCE:
518 case WM2200_OUT2LMIX_INPUT_3_VOLUME:
519 case WM2200_OUT2LMIX_INPUT_4_SOURCE:
520 case WM2200_OUT2LMIX_INPUT_4_VOLUME:
521 case WM2200_OUT2RMIX_INPUT_1_SOURCE:
522 case WM2200_OUT2RMIX_INPUT_1_VOLUME:
523 case WM2200_OUT2RMIX_INPUT_2_SOURCE:
524 case WM2200_OUT2RMIX_INPUT_2_VOLUME:
525 case WM2200_OUT2RMIX_INPUT_3_SOURCE:
526 case WM2200_OUT2RMIX_INPUT_3_VOLUME:
527 case WM2200_OUT2RMIX_INPUT_4_SOURCE:
528 case WM2200_OUT2RMIX_INPUT_4_VOLUME:
529 case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
530 case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
531 case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
532 case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
533 case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
534 case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
535 case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
536 case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
537 case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
538 case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
539 case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
540 case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
541 case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
542 case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
543 case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
544 case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
545 case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
546 case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
547 case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
548 case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
549 case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
550 case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
551 case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
552 case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
553 case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
554 case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
555 case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
556 case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
557 case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
558 case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
559 case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
560 case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
561 case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
562 case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
563 case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
564 case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
565 case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
566 case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
567 case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
568 case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
569 case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
570 case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
571 case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
572 case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
573 case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
574 case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
575 case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
576 case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
577 case WM2200_EQLMIX_INPUT_1_SOURCE:
578 case WM2200_EQLMIX_INPUT_1_VOLUME:
579 case WM2200_EQLMIX_INPUT_2_SOURCE:
580 case WM2200_EQLMIX_INPUT_2_VOLUME:
581 case WM2200_EQLMIX_INPUT_3_SOURCE:
582 case WM2200_EQLMIX_INPUT_3_VOLUME:
583 case WM2200_EQLMIX_INPUT_4_SOURCE:
584 case WM2200_EQLMIX_INPUT_4_VOLUME:
585 case WM2200_EQRMIX_INPUT_1_SOURCE:
586 case WM2200_EQRMIX_INPUT_1_VOLUME:
587 case WM2200_EQRMIX_INPUT_2_SOURCE:
588 case WM2200_EQRMIX_INPUT_2_VOLUME:
589 case WM2200_EQRMIX_INPUT_3_SOURCE:
590 case WM2200_EQRMIX_INPUT_3_VOLUME:
591 case WM2200_EQRMIX_INPUT_4_SOURCE:
592 case WM2200_EQRMIX_INPUT_4_VOLUME:
593 case WM2200_LHPF1MIX_INPUT_1_SOURCE:
594 case WM2200_LHPF1MIX_INPUT_1_VOLUME:
595 case WM2200_LHPF1MIX_INPUT_2_SOURCE:
596 case WM2200_LHPF1MIX_INPUT_2_VOLUME:
597 case WM2200_LHPF1MIX_INPUT_3_SOURCE:
598 case WM2200_LHPF1MIX_INPUT_3_VOLUME:
599 case WM2200_LHPF1MIX_INPUT_4_SOURCE:
600 case WM2200_LHPF1MIX_INPUT_4_VOLUME:
601 case WM2200_LHPF2MIX_INPUT_1_SOURCE:
602 case WM2200_LHPF2MIX_INPUT_1_VOLUME:
603 case WM2200_LHPF2MIX_INPUT_2_SOURCE:
604 case WM2200_LHPF2MIX_INPUT_2_VOLUME:
605 case WM2200_LHPF2MIX_INPUT_3_SOURCE:
606 case WM2200_LHPF2MIX_INPUT_3_VOLUME:
607 case WM2200_LHPF2MIX_INPUT_4_SOURCE:
608 case WM2200_LHPF2MIX_INPUT_4_VOLUME:
609 case WM2200_DSP1LMIX_INPUT_1_SOURCE:
610 case WM2200_DSP1LMIX_INPUT_1_VOLUME:
611 case WM2200_DSP1LMIX_INPUT_2_SOURCE:
612 case WM2200_DSP1LMIX_INPUT_2_VOLUME:
613 case WM2200_DSP1LMIX_INPUT_3_SOURCE:
614 case WM2200_DSP1LMIX_INPUT_3_VOLUME:
615 case WM2200_DSP1LMIX_INPUT_4_SOURCE:
616 case WM2200_DSP1LMIX_INPUT_4_VOLUME:
617 case WM2200_DSP1RMIX_INPUT_1_SOURCE:
618 case WM2200_DSP1RMIX_INPUT_1_VOLUME:
619 case WM2200_DSP1RMIX_INPUT_2_SOURCE:
620 case WM2200_DSP1RMIX_INPUT_2_VOLUME:
621 case WM2200_DSP1RMIX_INPUT_3_SOURCE:
622 case WM2200_DSP1RMIX_INPUT_3_VOLUME:
623 case WM2200_DSP1RMIX_INPUT_4_SOURCE:
624 case WM2200_DSP1RMIX_INPUT_4_VOLUME:
625 case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
626 case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
627 case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
628 case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
629 case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
630 case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
631 case WM2200_DSP2LMIX_INPUT_1_SOURCE:
632 case WM2200_DSP2LMIX_INPUT_1_VOLUME:
633 case WM2200_DSP2LMIX_INPUT_2_SOURCE:
634 case WM2200_DSP2LMIX_INPUT_2_VOLUME:
635 case WM2200_DSP2LMIX_INPUT_3_SOURCE:
636 case WM2200_DSP2LMIX_INPUT_3_VOLUME:
637 case WM2200_DSP2LMIX_INPUT_4_SOURCE:
638 case WM2200_DSP2LMIX_INPUT_4_VOLUME:
639 case WM2200_DSP2RMIX_INPUT_1_SOURCE:
640 case WM2200_DSP2RMIX_INPUT_1_VOLUME:
641 case WM2200_DSP2RMIX_INPUT_2_SOURCE:
642 case WM2200_DSP2RMIX_INPUT_2_VOLUME:
643 case WM2200_DSP2RMIX_INPUT_3_SOURCE:
644 case WM2200_DSP2RMIX_INPUT_3_VOLUME:
645 case WM2200_DSP2RMIX_INPUT_4_SOURCE:
646 case WM2200_DSP2RMIX_INPUT_4_VOLUME:
647 case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
648 case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
649 case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
650 case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
651 case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
652 case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
653 case WM2200_GPIO_CTRL_1:
654 case WM2200_GPIO_CTRL_2:
655 case WM2200_GPIO_CTRL_3:
656 case WM2200_GPIO_CTRL_4:
657 case WM2200_ADPS1_IRQ0:
658 case WM2200_ADPS1_IRQ1:
659 case WM2200_MISC_PAD_CTRL_1:
660 case WM2200_INTERRUPT_STATUS_1:
661 case WM2200_INTERRUPT_STATUS_1_MASK:
662 case WM2200_INTERRUPT_STATUS_2:
663 case WM2200_INTERRUPT_RAW_STATUS_2:
664 case WM2200_INTERRUPT_STATUS_2_MASK:
665 case WM2200_INTERRUPT_CONTROL:
666 case WM2200_EQL_1:
667 case WM2200_EQL_2:
668 case WM2200_EQL_3:
669 case WM2200_EQL_4:
670 case WM2200_EQL_5:
671 case WM2200_EQL_6:
672 case WM2200_EQL_7:
673 case WM2200_EQL_8:
674 case WM2200_EQL_9:
675 case WM2200_EQL_10:
676 case WM2200_EQL_11:
677 case WM2200_EQL_12:
678 case WM2200_EQL_13:
679 case WM2200_EQL_14:
680 case WM2200_EQL_15:
681 case WM2200_EQL_16:
682 case WM2200_EQL_17:
683 case WM2200_EQL_18:
684 case WM2200_EQL_19:
685 case WM2200_EQL_20:
686 case WM2200_EQR_1:
687 case WM2200_EQR_2:
688 case WM2200_EQR_3:
689 case WM2200_EQR_4:
690 case WM2200_EQR_5:
691 case WM2200_EQR_6:
692 case WM2200_EQR_7:
693 case WM2200_EQR_8:
694 case WM2200_EQR_9:
695 case WM2200_EQR_10:
696 case WM2200_EQR_11:
697 case WM2200_EQR_12:
698 case WM2200_EQR_13:
699 case WM2200_EQR_14:
700 case WM2200_EQR_15:
701 case WM2200_EQR_16:
702 case WM2200_EQR_17:
703 case WM2200_EQR_18:
704 case WM2200_EQR_19:
705 case WM2200_EQR_20:
706 case WM2200_HPLPF1_1:
707 case WM2200_HPLPF1_2:
708 case WM2200_HPLPF2_1:
709 case WM2200_HPLPF2_2:
710 case WM2200_DSP1_CONTROL_1:
711 case WM2200_DSP1_CONTROL_2:
712 case WM2200_DSP1_CONTROL_3:
713 case WM2200_DSP1_CONTROL_4:
714 case WM2200_DSP1_CONTROL_5:
715 case WM2200_DSP1_CONTROL_6:
716 case WM2200_DSP1_CONTROL_7:
717 case WM2200_DSP1_CONTROL_8:
718 case WM2200_DSP1_CONTROL_9:
719 case WM2200_DSP1_CONTROL_10:
720 case WM2200_DSP1_CONTROL_11:
721 case WM2200_DSP1_CONTROL_12:
722 case WM2200_DSP1_CONTROL_13:
723 case WM2200_DSP1_CONTROL_14:
724 case WM2200_DSP1_CONTROL_15:
725 case WM2200_DSP1_CONTROL_16:
726 case WM2200_DSP1_CONTROL_17:
727 case WM2200_DSP1_CONTROL_18:
728 case WM2200_DSP1_CONTROL_19:
729 case WM2200_DSP1_CONTROL_20:
730 case WM2200_DSP1_CONTROL_21:
731 case WM2200_DSP1_CONTROL_22:
732 case WM2200_DSP1_CONTROL_23:
733 case WM2200_DSP1_CONTROL_24:
734 case WM2200_DSP1_CONTROL_25:
735 case WM2200_DSP1_CONTROL_26:
736 case WM2200_DSP1_CONTROL_27:
737 case WM2200_DSP1_CONTROL_28:
738 case WM2200_DSP1_CONTROL_29:
739 case WM2200_DSP1_CONTROL_30:
740 case WM2200_DSP1_CONTROL_31:
741 case WM2200_DSP2_CONTROL_1:
742 case WM2200_DSP2_CONTROL_2:
743 case WM2200_DSP2_CONTROL_3:
744 case WM2200_DSP2_CONTROL_4:
745 case WM2200_DSP2_CONTROL_5:
746 case WM2200_DSP2_CONTROL_6:
747 case WM2200_DSP2_CONTROL_7:
748 case WM2200_DSP2_CONTROL_8:
749 case WM2200_DSP2_CONTROL_9:
750 case WM2200_DSP2_CONTROL_10:
751 case WM2200_DSP2_CONTROL_11:
752 case WM2200_DSP2_CONTROL_12:
753 case WM2200_DSP2_CONTROL_13:
754 case WM2200_DSP2_CONTROL_14:
755 case WM2200_DSP2_CONTROL_15:
756 case WM2200_DSP2_CONTROL_16:
757 case WM2200_DSP2_CONTROL_17:
758 case WM2200_DSP2_CONTROL_18:
759 case WM2200_DSP2_CONTROL_19:
760 case WM2200_DSP2_CONTROL_20:
761 case WM2200_DSP2_CONTROL_21:
762 case WM2200_DSP2_CONTROL_22:
763 case WM2200_DSP2_CONTROL_23:
764 case WM2200_DSP2_CONTROL_24:
765 case WM2200_DSP2_CONTROL_25:
766 case WM2200_DSP2_CONTROL_26:
767 case WM2200_DSP2_CONTROL_27:
768 case WM2200_DSP2_CONTROL_28:
769 case WM2200_DSP2_CONTROL_29:
770 case WM2200_DSP2_CONTROL_30:
771 case WM2200_DSP2_CONTROL_31:
772 return true;
773 default:
774 return false;
775 }
776}
777
778static const struct reg_default wm2200_reva_patch[] = {
779 { 0x07, 0x0003 },
780 { 0x102, 0x0200 },
781 { 0x203, 0x0084 },
782 { 0x201, 0x83FF },
783 { 0x20C, 0x0062 },
784 { 0x20D, 0x0062 },
785 { 0x207, 0x2002 },
786 { 0x208, 0x20C0 },
787 { 0x21D, 0x01C0 },
788 { 0x50A, 0x0001 },
789 { 0x50B, 0x0002 },
790 { 0x50C, 0x0003 },
791 { 0x50D, 0x0004 },
792 { 0x50E, 0x0005 },
793 { 0x510, 0x0001 },
794 { 0x511, 0x0002 },
795 { 0x512, 0x0003 },
796 { 0x513, 0x0004 },
797 { 0x514, 0x0005 },
798 { 0x515, 0x0000 },
799 { 0x201, 0x8084 },
800 { 0x202, 0xBBDE },
801 { 0x203, 0x00EC },
802 { 0x500, 0x8000 },
803 { 0x507, 0x1820 },
804 { 0x508, 0x1820 },
805 { 0x505, 0x0300 },
806 { 0x506, 0x0300 },
807 { 0x302, 0x2280 },
808 { 0x303, 0x0080 },
809 { 0x304, 0x2280 },
810 { 0x305, 0x0080 },
811 { 0x306, 0x2280 },
812 { 0x307, 0x0080 },
813 { 0x401, 0x0080 },
814 { 0x402, 0x0080 },
815 { 0x417, 0x3069 },
816 { 0x900, 0x6318 },
817 { 0x901, 0x6300 },
818 { 0x902, 0x0FC8 },
819 { 0x903, 0x03FE },
820 { 0x904, 0x00E0 },
821 { 0x905, 0x1EC4 },
822 { 0x906, 0xF136 },
823 { 0x907, 0x0409 },
824 { 0x908, 0x04CC },
825 { 0x909, 0x1C9B },
826 { 0x90A, 0xF337 },
827 { 0x90B, 0x040B },
828 { 0x90C, 0x0CBB },
829 { 0x90D, 0x16F8 },
830 { 0x90E, 0xF7D9 },
831 { 0x90F, 0x040A },
832 { 0x910, 0x1F14 },
833 { 0x911, 0x058C },
834 { 0x912, 0x0563 },
835 { 0x913, 0x4000 },
836 { 0x916, 0x6318 },
837 { 0x917, 0x6300 },
838 { 0x918, 0x0FC8 },
839 { 0x919, 0x03FE },
840 { 0x91A, 0x00E0 },
841 { 0x91B, 0x1EC4 },
842 { 0x91C, 0xF136 },
843 { 0x91D, 0x0409 },
844 { 0x91E, 0x04CC },
845 { 0x91F, 0x1C9B },
846 { 0x920, 0xF337 },
847 { 0x921, 0x040B },
848 { 0x922, 0x0CBB },
849 { 0x923, 0x16F8 },
850 { 0x924, 0xF7D9 },
851 { 0x925, 0x040A },
852 { 0x926, 0x1F14 },
853 { 0x927, 0x058C },
854 { 0x928, 0x0563 },
855 { 0x929, 0x4000 },
856 { 0x709, 0x2000 },
857 { 0x207, 0x200E },
858 { 0x208, 0x20D4 },
859 { 0x20A, 0x0080 },
860 { 0x07, 0x0000 },
861};
862
863static int wm2200_reset(struct wm2200_priv *wm2200)
864{
865 if (wm2200->pdata.reset) {
866 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
867 gpio_set_value_cansleep(wm2200->pdata.reset, 1);
868
869 return 0;
870 } else {
871 return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
872 0x2200);
873 }
874}
875
876static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
877static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
878static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
879
880static const char *wm2200_mixer_texts[] = {
881 "None",
882 "Tone Generator",
883 "AEC loopback",
884 "IN1L",
885 "IN1R",
886 "IN2L",
887 "IN2R",
888 "IN3L",
889 "IN3R",
890 "AIF1RX1",
891 "AIF1RX2",
892 "AIF1RX3",
893 "AIF1RX4",
894 "AIF1RX5",
895 "AIF1RX6",
896 "EQL",
897 "EQR",
898 "LHPF1",
899 "LHPF2",
900 "LHPF3",
901 "LHPF4",
902 "DSP1.1",
903 "DSP1.2",
904 "DSP1.3",
905 "DSP1.4",
906 "DSP1.5",
907 "DSP1.6",
908 "DSP2.1",
909 "DSP2.2",
910 "DSP2.3",
911 "DSP2.4",
912 "DSP2.5",
913 "DSP2.6",
914};
915
916static int wm2200_mixer_values[] = {
917 0x00,
918 0x04, /* Tone */
919 0x08, /* AEC */
920 0x10, /* Input */
921 0x11,
922 0x12,
923 0x13,
924 0x14,
925 0x15,
926 0x20, /* AIF */
927 0x21,
928 0x22,
929 0x23,
930 0x24,
931 0x25,
932 0x50, /* EQ */
933 0x51,
934 0x52,
935 0x60, /* LHPF1 */
936 0x61, /* LHPF2 */
937 0x68, /* DSP1 */
938 0x69,
939 0x6a,
940 0x6b,
941 0x6c,
942 0x6d,
943 0x70, /* DSP2 */
944 0x71,
945 0x72,
946 0x73,
947 0x74,
948 0x75,
949};
950
951#define WM2200_MIXER_CONTROLS(name, base) \
952 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
953 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
954 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
955 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
956 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
957 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
958 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
959 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
960
961#define WM2200_MUX_ENUM_DECL(name, reg) \
962 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
963 wm2200_mixer_texts, wm2200_mixer_values)
964
965#define WM2200_MUX_CTL_DECL(name) \
966 const struct snd_kcontrol_new name##_mux = \
967 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
968
969#define WM2200_MIXER_ENUMS(name, base_reg) \
970 static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
971 static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
972 static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
973 static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
974 static WM2200_MUX_CTL_DECL(name##_in1); \
975 static WM2200_MUX_CTL_DECL(name##_in2); \
976 static WM2200_MUX_CTL_DECL(name##_in3); \
977 static WM2200_MUX_CTL_DECL(name##_in4)
978
979static const struct snd_kcontrol_new wm2200_snd_controls[] = {
980SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
981 WM2200_IN1_OSR_SHIFT, 1, 0),
982SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
983 WM2200_IN2_OSR_SHIFT, 1, 0),
984SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
985 WM2200_IN3_OSR_SHIFT, 1, 0),
986
987SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
988 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
989SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
990 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
991SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
992 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
993
994SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
995 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
996SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
997 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
998SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
999 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1000
1001SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
1002 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
1003 0xbf, 0, digital_tlv),
1004SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
1005 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
1006 0xbf, 0, digital_tlv),
1007SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1008 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1009 0xbf, 0, digital_tlv),
1010
1011SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1012 WM2200_OUT1_OSR_SHIFT, 1, 0),
1013SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1014 WM2200_OUT2_OSR_SHIFT, 1, 0),
1015
1016SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1017 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
1018SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
1019 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
1020 digital_tlv),
1021SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
1022 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
1023 0x46, 0, out_tlv),
1024
1025SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1026 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
1027SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1028 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
1029 digital_tlv),
1030SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1031 WM2200_SPK1R_MUTE_SHIFT, 1, 0),
1032};
1033
1034WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
1035WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
1036WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
1037WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
1038
1039WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
1040WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
1041WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
1042WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
1043WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
1044WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
1045
1046WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
1047WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
1048
1049WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
1050WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
1051WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
1052WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
1053
1054WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
1055WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
1056
1057#define WM2200_MUX(name, ctrl) \
1058 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
1059
1060#define WM2200_MIXER_WIDGETS(name, name_str) \
1061 WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
1062 WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
1063 WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
1064 WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
1065 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
1066
1067#define WM2200_MIXER_INPUT_ROUTES(name) \
1068 { name, "Tone Generator", "Tone Generator" }, \
1069 { name, "IN1L", "IN1L PGA" }, \
1070 { name, "IN1R", "IN1R PGA" }, \
1071 { name, "IN2L", "IN2L PGA" }, \
1072 { name, "IN2R", "IN2R PGA" }, \
1073 { name, "IN3L", "IN3L PGA" }, \
1074 { name, "IN3R", "IN3R PGA" }, \
1075 { name, "DSP1.1", "DSP1" }, \
1076 { name, "DSP1.2", "DSP1" }, \
1077 { name, "DSP1.3", "DSP1" }, \
1078 { name, "DSP1.4", "DSP1" }, \
1079 { name, "DSP1.5", "DSP1" }, \
1080 { name, "DSP1.6", "DSP1" }, \
1081 { name, "DSP2.1", "DSP2" }, \
1082 { name, "DSP2.2", "DSP2" }, \
1083 { name, "DSP2.3", "DSP2" }, \
1084 { name, "DSP2.4", "DSP2" }, \
1085 { name, "DSP2.5", "DSP2" }, \
1086 { name, "DSP2.6", "DSP2" }, \
1087 { name, "AIF1RX1", "AIF1RX1" }, \
1088 { name, "AIF1RX2", "AIF1RX2" }, \
1089 { name, "AIF1RX3", "AIF1RX3" }, \
1090 { name, "AIF1RX4", "AIF1RX4" }, \
1091 { name, "AIF1RX5", "AIF1RX5" }, \
1092 { name, "AIF1RX6", "AIF1RX6" }, \
1093 { name, "EQL", "EQL" }, \
1094 { name, "EQR", "EQR" }, \
1095 { name, "LHPF1", "LHPF1" }, \
1096 { name, "LHPF2", "LHPF2" }
1097
1098#define WM2200_MIXER_ROUTES(widget, name) \
1099 { widget, NULL, name " Mixer" }, \
1100 { name " Mixer", NULL, name " Input 1" }, \
1101 { name " Mixer", NULL, name " Input 2" }, \
1102 { name " Mixer", NULL, name " Input 3" }, \
1103 { name " Mixer", NULL, name " Input 4" }, \
1104 WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
1105 WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
1106 WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
1107 WM2200_MIXER_INPUT_ROUTES(name " Input 4")
1108
1109static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
1110SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
1111 NULL, 0),
1112SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
1113 NULL, 0),
1114SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
1115 NULL, 0),
1116SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
1117 0, NULL, 0),
1118SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
1119 0, NULL, 0),
1120SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
1121SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
1122
1123SND_SOC_DAPM_INPUT("IN1L"),
1124SND_SOC_DAPM_INPUT("IN1R"),
1125SND_SOC_DAPM_INPUT("IN2L"),
1126SND_SOC_DAPM_INPUT("IN2R"),
1127SND_SOC_DAPM_INPUT("IN3L"),
1128SND_SOC_DAPM_INPUT("IN3R"),
1129
1130SND_SOC_DAPM_SIGGEN("TONE"),
1131SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
1132 WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
1133
1134SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
1135 NULL, 0),
1136SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
1137 NULL, 0),
1138SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
1139 NULL, 0),
1140SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
1141 NULL, 0),
1142SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
1143 NULL, 0),
1144SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
1145 NULL, 0),
1146
1147SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
1148 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
1149SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
1150 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
1151SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
1152 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
1153SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
1154 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
1155SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
1156 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
1157SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
1158 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
1159
1160SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
1161SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
1162
1163SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
1164 NULL, 0),
1165SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
1166 NULL, 0),
1167
1168SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
1169SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0),
1170
1171SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
1172 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
1173SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
1174 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
1175SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
1176 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
1177SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
1178 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
1179SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
1180 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
1181SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
1182 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
1183
1184SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
1185 WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
1186SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
1187 WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
1188
1189SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1190 WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
1191SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1192 WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
1193SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1194 WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
1195
1196SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1197 WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
1198SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1199 WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
1200SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1201 WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
1202
1203SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1204 WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
1205SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1206 WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
1207SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1208 WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
1209
1210SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1211 WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
1212SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1213 WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
1214SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1215 WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
1216
1217SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
1218 0, NULL, 0),
1219SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
1220 0, NULL, 0),
1221
1222SND_SOC_DAPM_OUTPUT("EPOUTLN"),
1223SND_SOC_DAPM_OUTPUT("EPOUTLP"),
1224SND_SOC_DAPM_OUTPUT("EPOUTRN"),
1225SND_SOC_DAPM_OUTPUT("EPOUTRP"),
1226SND_SOC_DAPM_OUTPUT("SPK"),
1227
1228WM2200_MIXER_WIDGETS(EQL, "EQL"),
1229WM2200_MIXER_WIDGETS(EQR, "EQR"),
1230
1231WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
1232WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
1233
1234WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"),
1235WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"),
1236WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"),
1237WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"),
1238
1239WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1240WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1241WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1242WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1243WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1244WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1245
1246WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
1247WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
1248WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
1249WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
1250};
1251
1252static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
1253 /* Everything needs SYSCLK but only hook up things on the edge
1254 * of the chip */
1255 { "IN1L", NULL, "SYSCLK" },
1256 { "IN1R", NULL, "SYSCLK" },
1257 { "IN2L", NULL, "SYSCLK" },
1258 { "IN2R", NULL, "SYSCLK" },
1259 { "IN3L", NULL, "SYSCLK" },
1260 { "IN3R", NULL, "SYSCLK" },
1261 { "OUT1L", NULL, "SYSCLK" },
1262 { "OUT1R", NULL, "SYSCLK" },
1263 { "OUT2L", NULL, "SYSCLK" },
1264 { "OUT2R", NULL, "SYSCLK" },
1265 { "AIF1RX1", NULL, "SYSCLK" },
1266 { "AIF1RX2", NULL, "SYSCLK" },
1267 { "AIF1RX3", NULL, "SYSCLK" },
1268 { "AIF1RX4", NULL, "SYSCLK" },
1269 { "AIF1RX5", NULL, "SYSCLK" },
1270 { "AIF1RX6", NULL, "SYSCLK" },
1271 { "AIF1TX1", NULL, "SYSCLK" },
1272 { "AIF1TX2", NULL, "SYSCLK" },
1273 { "AIF1TX3", NULL, "SYSCLK" },
1274 { "AIF1TX4", NULL, "SYSCLK" },
1275 { "AIF1TX5", NULL, "SYSCLK" },
1276 { "AIF1TX6", NULL, "SYSCLK" },
1277
1278 { "IN1L", NULL, "AVDD" },
1279 { "IN1R", NULL, "AVDD" },
1280 { "IN2L", NULL, "AVDD" },
1281 { "IN2R", NULL, "AVDD" },
1282 { "IN3L", NULL, "AVDD" },
1283 { "IN3R", NULL, "AVDD" },
1284 { "OUT1L", NULL, "AVDD" },
1285 { "OUT1R", NULL, "AVDD" },
1286
1287 { "IN1L PGA", NULL, "IN1L" },
1288 { "IN1R PGA", NULL, "IN1R" },
1289 { "IN2L PGA", NULL, "IN2L" },
1290 { "IN2R PGA", NULL, "IN2R" },
1291 { "IN3L PGA", NULL, "IN3L" },
1292 { "IN3R PGA", NULL, "IN3R" },
1293
1294 { "Tone Generator", NULL, "TONE" },
1295
1296 { "CP2", NULL, "CPVDD" },
1297 { "MICBIAS1", NULL, "CP2" },
1298 { "MICBIAS2", NULL, "CP2" },
1299
1300 { "CP1", NULL, "CPVDD" },
1301 { "EPD_LN", NULL, "CP1" },
1302 { "EPD_LP", NULL, "CP1" },
1303 { "EPD_RN", NULL, "CP1" },
1304 { "EPD_RP", NULL, "CP1" },
1305
1306 { "EPD_LP", NULL, "OUT1L" },
1307 { "EPD_OUTP_LP", NULL, "EPD_LP" },
1308 { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
1309 { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
1310
1311 { "EPD_LN", NULL, "OUT1L" },
1312 { "EPD_OUTP_LN", NULL, "EPD_LN" },
1313 { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
1314 { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
1315
1316 { "EPD_RP", NULL, "OUT1R" },
1317 { "EPD_OUTP_RP", NULL, "EPD_RP" },
1318 { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
1319 { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
1320
1321 { "EPD_RN", NULL, "OUT1R" },
1322 { "EPD_OUTP_RN", NULL, "EPD_RN" },
1323 { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
1324 { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
1325
1326 { "SPK", NULL, "OUT2L" },
1327 { "SPK", NULL, "OUT2R" },
1328
1329 WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
1330 WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
1331 WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
1332 WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
1333
1334 WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
1335 WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
1336 WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
1337 WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
1338
1339 WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1340 WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1341 WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1342 WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1343 WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1344 WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1345
1346 WM2200_MIXER_ROUTES("EQL", "EQL"),
1347 WM2200_MIXER_ROUTES("EQR", "EQR"),
1348
1349 WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
1350 WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
1351};
1352
1353static int wm2200_probe(struct snd_soc_codec *codec)
1354{
1355 struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
1356 int ret;
1357
1358 wm2200->codec = codec;
1359 codec->control_data = wm2200->regmap;
1360 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1361
1362 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1363 if (ret != 0) {
1364 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1365 return ret;
1366 }
1367
1368 return ret;
1369}
1370
1371static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1372{
1373 struct snd_soc_codec *codec = dai->codec;
1374 int lrclk, bclk, fmt_val;
1375
1376 lrclk = 0;
1377 bclk = 0;
1378
1379 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1380 case SND_SOC_DAIFMT_DSP_A:
1381 fmt_val = 0;
1382 break;
1383 case SND_SOC_DAIFMT_DSP_B:
1384 fmt_val = 1;
1385 break;
1386 case SND_SOC_DAIFMT_I2S:
1387 fmt_val = 2;
1388 break;
1389 case SND_SOC_DAIFMT_LEFT_J:
1390 fmt_val = 3;
1391 break;
1392 default:
1393 dev_err(codec->dev, "Unsupported DAI format %d\n",
1394 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1395 return -EINVAL;
1396 }
1397
1398 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1399 case SND_SOC_DAIFMT_CBS_CFS:
1400 break;
1401 case SND_SOC_DAIFMT_CBS_CFM:
1402 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1403 break;
1404 case SND_SOC_DAIFMT_CBM_CFS:
1405 bclk |= WM2200_AIF1_BCLK_MSTR;
1406 break;
1407 case SND_SOC_DAIFMT_CBM_CFM:
1408 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1409 bclk |= WM2200_AIF1_BCLK_MSTR;
1410 break;
1411 default:
1412 dev_err(codec->dev, "Unsupported master mode %d\n",
1413 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1414 return -EINVAL;
1415 }
1416
1417 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1418 case SND_SOC_DAIFMT_NB_NF:
1419 break;
1420 case SND_SOC_DAIFMT_IB_IF:
1421 bclk |= WM2200_AIF1_BCLK_INV;
1422 lrclk |= WM2200_AIF1TX_LRCLK_INV;
1423 break;
1424 case SND_SOC_DAIFMT_IB_NF:
1425 bclk |= WM2200_AIF1_BCLK_INV;
1426 break;
1427 case SND_SOC_DAIFMT_NB_IF:
1428 lrclk |= WM2200_AIF1TX_LRCLK_INV;
1429 break;
1430 default:
1431 return -EINVAL;
1432 }
1433
1434 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
1435 WM2200_AIF1_BCLK_INV, bclk);
1436 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1437 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1438 lrclk);
1439 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
1440 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1441 lrclk);
1442 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
1443 WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
1444
1445 return 0;
1446}
1447
1448static int wm2200_sr_code[] = {
1449 0,
1450 12000,
1451 24000,
1452 48000,
1453 96000,
1454 192000,
1455 384000,
1456 768000,
1457 0,
1458 11025,
1459 22050,
1460 44100,
1461 88200,
1462 176400,
1463 352800,
1464 705600,
1465 4000,
1466 8000,
1467 16000,
1468 32000,
1469 64000,
1470 128000,
1471 256000,
1472 512000,
1473};
1474
1475#define WM2200_NUM_BCLK_RATES 12
1476
1477static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
1478 6144000,
1479 3072000,
1480 2048000,
1481 1536000,
1482 768000,
1483 512000,
1484 384000,
1485 256000,
1486 192000,
1487 128000,
1488 96000,
1489 64000,
1490};
1491
1492static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
1493 5644800,
1494 2882400,
1495 1881600,
1496 1411200,
1497 705600,
1498 470400,
1499 352800,
1500 176400,
1501 117600,
1502 88200,
1503 58800,
1504};
1505
1506static int wm2200_hw_params(struct snd_pcm_substream *substream,
1507 struct snd_pcm_hw_params *params,
1508 struct snd_soc_dai *dai)
1509{
1510 struct snd_soc_codec *codec = dai->codec;
1511 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1512 int i, bclk, lrclk, wl, fl, sr_code;
1513 int *bclk_rates;
1514
1515 /* Data sizes if not using TDM */
1516 wl = snd_pcm_format_width(params_format(params));
1517 if (wl < 0)
1518 return wl;
1519 fl = snd_soc_params_to_frame_size(params);
1520 if (fl < 0)
1521 return fl;
1522
1523 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1524 wl, fl);
1525
1526 /* Target BCLK rate */
1527 bclk = snd_soc_params_to_bclk(params);
1528 if (bclk < 0)
1529 return bclk;
1530
1531 if (!wm2200->sysclk) {
1532 dev_err(codec->dev, "SYSCLK has no rate set\n");
1533 return -EINVAL;
1534 }
1535
1536 for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
1537 if (wm2200_sr_code[i] == params_rate(params))
1538 break;
1539 if (i == ARRAY_SIZE(wm2200_sr_code)) {
1540 dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
1541 params_rate(params));
1542 return -EINVAL;
1543 }
1544 sr_code = i;
1545
1546 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
1547 bclk, wm2200->sysclk);
1548
1549 if (wm2200->sysclk % 4000)
1550 bclk_rates = wm2200_bclk_rates_cd;
1551 else
1552 bclk_rates = wm2200_bclk_rates_dat;
1553
1554 for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
1555 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1556 break;
1557 if (i == WM2200_NUM_BCLK_RATES) {
1558 dev_err(codec->dev,
1559 "No valid BCLK for %dHz found from %dHz SYSCLK\n",
1560 bclk, wm2200->sysclk);
1561 return -EINVAL;
1562 }
1563
1564 bclk = i;
1565 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1566 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
1567 WM2200_AIF1_BCLK_DIV_MASK, bclk);
1568
1569 lrclk = bclk_rates[bclk] / params_rate(params);
1570 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1571 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1572 dai->symmetric_rates)
1573 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
1574 WM2200_AIF1RX_BCPF_MASK, lrclk);
1575 else
1576 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
1577 WM2200_AIF1TX_BCPF_MASK, lrclk);
1578
1579 i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
1580 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1581 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
1582 WM2200_AIF1RX_WL_MASK |
1583 WM2200_AIF1RX_SLOT_LEN_MASK, i);
1584 else
1585 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
1586 WM2200_AIF1TX_WL_MASK |
1587 WM2200_AIF1TX_SLOT_LEN_MASK, i);
1588
1589 snd_soc_update_bits(codec, WM2200_CLOCKING_4,
1590 WM2200_SAMPLE_RATE_1_MASK, sr_code);
1591
1592 return 0;
1593}
1594
1595static const struct snd_soc_dai_ops wm2200_dai_ops = {
1596 .set_fmt = wm2200_set_fmt,
1597 .hw_params = wm2200_hw_params,
1598};
1599
1600static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1601 int source, unsigned int freq, int dir)
1602{
1603 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1604 int fval;
1605
1606 switch (clk_id) {
1607 case WM2200_CLK_SYSCLK:
1608 break;
1609
1610 default:
1611 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1612 return -EINVAL;
1613 }
1614
1615 switch (source) {
1616 case WM2200_CLKSRC_MCLK1:
1617 case WM2200_CLKSRC_MCLK2:
1618 case WM2200_CLKSRC_FLL:
1619 case WM2200_CLKSRC_BCLK1:
1620 break;
1621 default:
1622 dev_err(codec->dev, "Invalid source %d\n", source);
1623 return -EINVAL;
1624 }
1625
1626 switch (freq) {
1627 case 22579200:
1628 case 24576000:
1629 fval = 2;
1630 break;
1631 default:
1632 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1633 return -EINVAL;
1634 }
1635
1636 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1637 * match.
1638 */
1639
1640 snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
1641 WM2200_SYSCLK_SRC_MASK,
1642 fval << WM2200_SYSCLK_FREQ_SHIFT | source);
1643
1644 wm2200->sysclk = freq;
1645
1646 return 0;
1647}
1648
1649struct _fll_div {
1650 u16 fll_fratio;
1651 u16 fll_outdiv;
1652 u16 fll_refclk_div;
1653 u16 n;
1654 u16 theta;
1655 u16 lambda;
1656};
1657
1658static struct {
1659 unsigned int min;
1660 unsigned int max;
1661 u16 fll_fratio;
1662 int ratio;
1663} fll_fratios[] = {
1664 { 0, 64000, 4, 16 },
1665 { 64000, 128000, 3, 8 },
1666 { 128000, 256000, 2, 4 },
1667 { 256000, 1000000, 1, 2 },
1668 { 1000000, 13500000, 0, 1 },
1669};
1670
1671static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1672 unsigned int Fout)
1673{
1674 unsigned int target;
1675 unsigned int div;
1676 unsigned int fratio, gcd_fll;
1677 int i;
1678
1679 /* Fref must be <=13.5MHz */
1680 div = 1;
1681 fll_div->fll_refclk_div = 0;
1682 while ((Fref / div) > 13500000) {
1683 div *= 2;
1684 fll_div->fll_refclk_div++;
1685
1686 if (div > 8) {
1687 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1688 Fref);
1689 return -EINVAL;
1690 }
1691 }
1692
1693 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1694
1695 /* Apply the division for our remaining calculations */
1696 Fref /= div;
1697
1698 /* Fvco should be 90-100MHz; don't check the upper bound */
1699 div = 2;
1700 while (Fout * div < 90000000) {
1701 div++;
1702 if (div > 64) {
1703 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1704 Fout);
1705 return -EINVAL;
1706 }
1707 }
1708 target = Fout * div;
1709 fll_div->fll_outdiv = div - 1;
1710
1711 pr_debug("FLL Fvco=%dHz\n", target);
1712
1713 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1714 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1715 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1716 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1717 fratio = fll_fratios[i].ratio;
1718 break;
1719 }
1720 }
1721 if (i == ARRAY_SIZE(fll_fratios)) {
1722 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1723 return -EINVAL;
1724 }
1725
1726 fll_div->n = target / (fratio * Fref);
1727
1728 if (target % Fref == 0) {
1729 fll_div->theta = 0;
1730 fll_div->lambda = 0;
1731 } else {
1732 gcd_fll = gcd(target, fratio * Fref);
1733
1734 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1735 / gcd_fll;
1736 fll_div->lambda = (fratio * Fref) / gcd_fll;
1737 }
1738
1739 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1740 fll_div->n, fll_div->theta, fll_div->lambda);
1741 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1742 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1743 fll_div->fll_refclk_div);
1744
1745 return 0;
1746}
1747
1748static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1749 unsigned int Fref, unsigned int Fout)
1750{
1751 struct i2c_client *i2c = to_i2c_client(codec->dev);
1752 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1753 struct _fll_div factors;
1754 int ret, i, timeout;
1755
1756 if (!Fout) {
1757 dev_dbg(codec->dev, "FLL disabled");
1758
1759 if (wm2200->fll_fout)
1760 pm_runtime_put(codec->dev);
1761
1762 wm2200->fll_fout = 0;
1763 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1764 WM2200_FLL_ENA, 0);
1765 return 0;
1766 }
1767
1768 switch (source) {
1769 case WM2200_FLL_SRC_MCLK1:
1770 case WM2200_FLL_SRC_MCLK2:
1771 case WM2200_FLL_SRC_BCLK:
1772 break;
1773 default:
1774 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1775 return -EINVAL;
1776 }
1777
1778 ret = fll_factors(&factors, Fref, Fout);
1779 if (ret < 0)
1780 return ret;
1781
1782 /* Disable the FLL while we reconfigure */
1783 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
1784
1785 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
1786 WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
1787 (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
1788 factors.fll_fratio);
1789 if (factors.theta) {
1790 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1791 WM2200_FLL_FRACN_ENA,
1792 WM2200_FLL_FRACN_ENA);
1793 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1794 WM2200_FLL_EFS_ENA,
1795 WM2200_FLL_EFS_ENA);
1796 } else {
1797 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1798 WM2200_FLL_FRACN_ENA, 0);
1799 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1800 WM2200_FLL_EFS_ENA, 0);
1801 }
1802
1803 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
1804 factors.theta);
1805 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
1806 factors.n);
1807 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
1808 WM2200_FLL_CLK_REF_DIV_MASK |
1809 WM2200_FLL_CLK_REF_SRC_MASK,
1810 (factors.fll_refclk_div
1811 << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
1812 snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
1813 WM2200_FLL_LAMBDA_MASK, factors.lambda);
1814
1815 /* Clear any pending completions */
1816 try_wait_for_completion(&wm2200->fll_lock);
1817
1818 pm_runtime_get_sync(codec->dev);
1819
1820 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1821 WM2200_FLL_ENA, WM2200_FLL_ENA);
1822
1823 if (i2c->irq)
1824 timeout = 2;
1825 else
1826 timeout = 50;
1827
1828 snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
1829 WM2200_SYSCLK_ENA);
1830
1831 /* Poll for the lock; will use the interrupt to exit quickly */
1832 for (i = 0; i < timeout; i++) {
1833 if (i2c->irq) {
1834 ret = wait_for_completion_timeout(&wm2200->fll_lock,
1835 msecs_to_jiffies(25));
1836 if (ret > 0)
1837 break;
1838 } else {
1839 msleep(1);
1840 }
1841
1842 ret = snd_soc_read(codec,
1843 WM2200_INTERRUPT_RAW_STATUS_2);
1844 if (ret < 0) {
1845 dev_err(codec->dev,
1846 "Failed to read FLL status: %d\n",
1847 ret);
1848 continue;
1849 }
1850 if (ret & WM2200_FLL_LOCK_STS)
1851 break;
1852 }
1853 if (i == timeout) {
1854 dev_err(codec->dev, "FLL lock timed out\n");
1855 pm_runtime_put(codec->dev);
1856 return -ETIMEDOUT;
1857 }
1858
1859 wm2200->fll_src = source;
1860 wm2200->fll_fref = Fref;
1861 wm2200->fll_fout = Fout;
1862
1863 dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
1864
1865 return 0;
1866}
1867
1868static int wm2200_dai_probe(struct snd_soc_dai *dai)
1869{
1870 struct snd_soc_codec *codec = dai->codec;
1871 unsigned int val = 0;
1872 int ret;
1873
1874 ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
1875 if (ret >= 0) {
1876 if ((ret & WM2200_GP1_FN_MASK) != 0) {
1877 dai->symmetric_rates = true;
1878 val = WM2200_AIF1TX_LRCLK_SRC;
1879 }
1880 } else {
1881 dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
1882 }
1883
1884 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1885 WM2200_AIF1TX_LRCLK_SRC, val);
1886
1887 return 0;
1888}
1889
1890#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
1891
1892#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1893 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1894
1895static struct snd_soc_dai_driver wm2200_dai = {
1896 .name = "wm2200",
1897 .probe = wm2200_dai_probe,
1898 .playback = {
1899 .stream_name = "Playback",
1900 .channels_min = 2,
1901 .channels_max = 2,
1902 .rates = WM2200_RATES,
1903 .formats = WM2200_FORMATS,
1904 },
1905 .capture = {
1906 .stream_name = "Capture",
1907 .channels_min = 2,
1908 .channels_max = 2,
1909 .rates = WM2200_RATES,
1910 .formats = WM2200_FORMATS,
1911 },
1912 .ops = &wm2200_dai_ops,
1913};
1914
1915static struct snd_soc_codec_driver soc_codec_wm2200 = {
1916 .probe = wm2200_probe,
1917
1918 .idle_bias_off = true,
1919 .ignore_pmdown_time = true,
1920 .set_sysclk = wm2200_set_sysclk,
1921 .set_pll = wm2200_set_fll,
1922
1923 .controls = wm2200_snd_controls,
1924 .num_controls = ARRAY_SIZE(wm2200_snd_controls),
1925 .dapm_widgets = wm2200_dapm_widgets,
1926 .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
1927 .dapm_routes = wm2200_dapm_routes,
1928 .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
1929};
1930
1931static irqreturn_t wm2200_irq(int irq, void *data)
1932{
1933 struct wm2200_priv *wm2200 = data;
1934 unsigned int val, mask;
1935 int ret;
1936
1937 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
1938 if (ret != 0) {
1939 dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
1940 return IRQ_NONE;
1941 }
1942
1943 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
1944 &mask);
1945 if (ret != 0) {
1946 dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
1947 mask = 0;
1948 }
1949
1950 val &= ~mask;
1951
1952 if (val & WM2200_FLL_LOCK_EINT) {
1953 dev_dbg(wm2200->dev, "FLL locked\n");
1954 complete(&wm2200->fll_lock);
1955 }
1956
1957 if (val) {
1958 regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
1959
1960 return IRQ_HANDLED;
1961 } else {
1962 return IRQ_NONE;
1963 }
1964}
1965
1966static const struct regmap_config wm2200_regmap = {
1967 .reg_bits = 16,
1968 .val_bits = 16,
1969
1970 .max_register = WM2200_MAX_REGISTER,
1971 .reg_defaults = wm2200_reg_defaults,
1972 .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
1973 .volatile_reg = wm2200_volatile_register,
1974 .readable_reg = wm2200_readable_register,
1975 .cache_type = REGCACHE_RBTREE,
1976};
1977
1978static const unsigned int wm2200_dig_vu[] = {
1979 WM2200_DAC_DIGITAL_VOLUME_1L,
1980 WM2200_DAC_DIGITAL_VOLUME_1R,
1981 WM2200_DAC_DIGITAL_VOLUME_2L,
1982 WM2200_DAC_DIGITAL_VOLUME_2R,
1983 WM2200_ADC_DIGITAL_VOLUME_1L,
1984 WM2200_ADC_DIGITAL_VOLUME_1R,
1985 WM2200_ADC_DIGITAL_VOLUME_2L,
1986 WM2200_ADC_DIGITAL_VOLUME_2R,
1987 WM2200_ADC_DIGITAL_VOLUME_3L,
1988 WM2200_ADC_DIGITAL_VOLUME_3R,
1989};
1990
1991static const unsigned int wm2200_mic_ctrl_reg[] = {
1992 WM2200_IN1L_CONTROL,
1993 WM2200_IN2L_CONTROL,
1994 WM2200_IN3L_CONTROL,
1995};
1996
1997static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
1998 const struct i2c_device_id *id)
1999{
2000 struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
2001 struct wm2200_priv *wm2200;
2002 unsigned int reg;
2003 int ret, i;
2004
2005 wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2006 GFP_KERNEL);
2007 if (wm2200 == NULL)
2008 return -ENOMEM;
2009
2010 wm2200->dev = &i2c->dev;
2011 init_completion(&wm2200->fll_lock);
2012
2013 wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
2014 if (IS_ERR(wm2200->regmap)) {
2015 ret = PTR_ERR(wm2200->regmap);
2016 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2017 ret);
2018 goto err;
2019 }
2020
2021 if (pdata)
2022 wm2200->pdata = *pdata;
2023
2024 i2c_set_clientdata(i2c, wm2200);
2025
2026 for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
2027 wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
2028
2029 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies),
2030 wm2200->core_supplies);
2031 if (ret != 0) {
2032 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2033 ret);
2034 goto err_regmap;
2035 }
2036
2037 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2038 wm2200->core_supplies);
2039 if (ret != 0) {
2040 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2041 ret);
2042 goto err_core;
2043 }
2044
2045 if (wm2200->pdata.ldo_ena) {
2046 ret = gpio_request_one(wm2200->pdata.ldo_ena,
2047 GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
2048 if (ret < 0) {
2049 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2050 wm2200->pdata.ldo_ena, ret);
2051 goto err_enable;
2052 }
2053 msleep(2);
2054 }
2055
2056 if (wm2200->pdata.reset) {
2057 ret = gpio_request_one(wm2200->pdata.reset,
2058 GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
2059 if (ret < 0) {
2060 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2061 wm2200->pdata.reset, ret);
2062 goto err_ldo;
2063 }
2064 }
2065
2066 ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
2067 if (ret < 0) {
2068 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2069 goto err_reset;
2070 }
2071 switch (reg) {
2072 case 0x2200:
2073 break;
2074
2075 default:
2076 dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
2077 ret = -EINVAL;
2078 goto err_reset;
2079 }
2080
2081 ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
2082 if (ret < 0) {
2083 dev_err(&i2c->dev, "Failed to read revision register\n");
2084 goto err_reset;
2085 }
2086
2087 wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
2088
2089 dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
2090
2091 switch (wm2200->rev) {
2092 case 0:
2093 ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
2094 ARRAY_SIZE(wm2200_reva_patch));
2095 if (ret != 0) {
2096 dev_err(&i2c->dev, "Failed to register patch: %d\n",
2097 ret);
2098 }
2099 break;
2100 default:
2101 break;
2102 }
2103
2104 ret = wm2200_reset(wm2200);
2105 if (ret < 0) {
2106 dev_err(&i2c->dev, "Failed to issue reset\n");
2107 goto err_reset;
2108 }
2109
2110 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
2111 if (!wm2200->pdata.gpio_defaults[i])
2112 continue;
2113
2114 regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
2115 wm2200->pdata.gpio_defaults[i]);
2116 }
2117
2118 for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
2119 regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
2120 WM2200_OUT_VU, WM2200_OUT_VU);
2121
2122 /* Assign slots 1-6 to channels 1-6 for both TX and RX */
2123 for (i = 0; i < 6; i++) {
2124 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
2125 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2126 }
2127
2128 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2129 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2130 WM2200_IN1_MODE_MASK |
2131 WM2200_IN1_DMIC_SUP_MASK,
2132 (wm2200->pdata.in_mode[i] <<
2133 WM2200_IN1_MODE_SHIFT) |
2134 (wm2200->pdata.dmic_sup[i] <<
2135 WM2200_IN1_DMIC_SUP_SHIFT));
2136 }
2137
2138 if (i2c->irq) {
2139 ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
2140 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
2141 "wm2200", wm2200);
2142 if (ret == 0)
2143 regmap_update_bits(wm2200->regmap,
2144 WM2200_INTERRUPT_STATUS_2_MASK,
2145 WM2200_FLL_LOCK_EINT, 0);
2146 else
2147 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2148 i2c->irq, ret);
2149 }
2150
2151 pm_runtime_set_active(&i2c->dev);
2152 pm_runtime_enable(&i2c->dev);
2153 pm_request_idle(&i2c->dev);
2154
2155 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
2156 &wm2200_dai, 1);
2157 if (ret != 0) {
2158 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
2159 goto err_pm_runtime;
2160 }
2161
2162 return 0;
2163
2164err_pm_runtime:
2165 pm_runtime_disable(&i2c->dev);
2166err_reset:
2167 if (wm2200->pdata.reset) {
2168 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2169 gpio_free(wm2200->pdata.reset);
2170 }
2171err_ldo:
2172 if (wm2200->pdata.ldo_ena) {
2173 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2174 gpio_free(wm2200->pdata.ldo_ena);
2175 }
2176err_enable:
2177 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2178 wm2200->core_supplies);
2179err_core:
2180 regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2181 wm2200->core_supplies);
2182err_regmap:
2183 regmap_exit(wm2200->regmap);
2184err:
2185 return ret;
2186}
2187
2188static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
2189{
2190 struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
2191
2192 snd_soc_unregister_codec(&i2c->dev);
2193 if (i2c->irq)
2194 free_irq(i2c->irq, wm2200);
2195 if (wm2200->pdata.reset) {
2196 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2197 gpio_free(wm2200->pdata.reset);
2198 }
2199 if (wm2200->pdata.ldo_ena) {
2200 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2201 gpio_free(wm2200->pdata.ldo_ena);
2202 }
2203 regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2204 wm2200->core_supplies);
2205 regmap_exit(wm2200->regmap);
2206
2207 return 0;
2208}
2209
2210#ifdef CONFIG_PM_RUNTIME
2211static int wm2200_runtime_suspend(struct device *dev)
2212{
2213 struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2214
2215 regcache_cache_only(wm2200->regmap, true);
2216 regcache_mark_dirty(wm2200->regmap);
2217 if (wm2200->pdata.ldo_ena)
2218 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2219 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2220 wm2200->core_supplies);
2221
2222 return 0;
2223}
2224
2225static int wm2200_runtime_resume(struct device *dev)
2226{
2227 struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2228 int ret;
2229
2230 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2231 wm2200->core_supplies);
2232 if (ret != 0) {
2233 dev_err(dev, "Failed to enable supplies: %d\n",
2234 ret);
2235 return ret;
2236 }
2237
2238 if (wm2200->pdata.ldo_ena) {
2239 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
2240 msleep(2);
2241 }
2242
2243 regcache_cache_only(wm2200->regmap, false);
2244 regcache_sync(wm2200->regmap);
2245
2246 return 0;
2247}
2248#endif
2249
2250static struct dev_pm_ops wm2200_pm = {
2251 SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
2252 NULL)
2253};
2254
2255static const struct i2c_device_id wm2200_i2c_id[] = {
2256 { "wm2200", 0 },
2257 { }
2258};
2259MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
2260
2261static struct i2c_driver wm2200_i2c_driver = {
2262 .driver = {
2263 .name = "wm2200",
2264 .owner = THIS_MODULE,
2265 .pm = &wm2200_pm,
2266 },
2267 .probe = wm2200_i2c_probe,
2268 .remove = __devexit_p(wm2200_i2c_remove),
2269 .id_table = wm2200_i2c_id,
2270};
2271
2272static int __init wm2200_modinit(void)
2273{
2274 return i2c_add_driver(&wm2200_i2c_driver);
2275}
2276module_init(wm2200_modinit);
2277
2278static void __exit wm2200_exit(void)
2279{
2280 i2c_del_driver(&wm2200_i2c_driver);
2281}
2282module_exit(wm2200_exit);
2283
2284MODULE_DESCRIPTION("ASoC WM2200 driver");
2285MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2286MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2200.h b/sound/soc/codecs/wm2200.h
new file mode 100644
index 000000000000..5d719d6b4a8d
--- /dev/null
+++ b/sound/soc/codecs/wm2200.h
@@ -0,0 +1,3674 @@
1/*
2 * wm2200.h - WM2200 audio codec interface
3 *
4 * Copyright 2012 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM2200_H
14#define _WM2200_H
15
16#define WM2200_CLK_SYSCLK 1
17
18#define WM2200_CLKSRC_MCLK1 0
19#define WM2200_CLKSRC_MCLK2 1
20#define WM2200_CLKSRC_FLL 4
21#define WM2200_CLKSRC_BCLK1 8
22
23#define WM2200_FLL_SRC_MCLK1 0
24#define WM2200_FLL_SRC_MCLK2 1
25#define WM2200_FLL_SRC_BCLK 2
26
27/*
28 * Register values.
29 */
30#define WM2200_SOFTWARE_RESET 0x00
31#define WM2200_DEVICE_REVISION 0x01
32#define WM2200_TONE_GENERATOR_1 0x0B
33#define WM2200_CLOCKING_3 0x102
34#define WM2200_CLOCKING_4 0x103
35#define WM2200_FLL_CONTROL_1 0x111
36#define WM2200_FLL_CONTROL_2 0x112
37#define WM2200_FLL_CONTROL_3 0x113
38#define WM2200_FLL_CONTROL_4 0x114
39#define WM2200_FLL_CONTROL_6 0x116
40#define WM2200_FLL_CONTROL_7 0x117
41#define WM2200_FLL_EFS_1 0x119
42#define WM2200_FLL_EFS_2 0x11A
43#define WM2200_MIC_CHARGE_PUMP_1 0x200
44#define WM2200_MIC_CHARGE_PUMP_2 0x201
45#define WM2200_DM_CHARGE_PUMP_1 0x202
46#define WM2200_MIC_BIAS_CTRL_1 0x20C
47#define WM2200_MIC_BIAS_CTRL_2 0x20D
48#define WM2200_EAR_PIECE_CTRL_1 0x20F
49#define WM2200_EAR_PIECE_CTRL_2 0x210
50#define WM2200_INPUT_ENABLES 0x301
51#define WM2200_IN1L_CONTROL 0x302
52#define WM2200_IN1R_CONTROL 0x303
53#define WM2200_IN2L_CONTROL 0x304
54#define WM2200_IN2R_CONTROL 0x305
55#define WM2200_IN3L_CONTROL 0x306
56#define WM2200_IN3R_CONTROL 0x307
57#define WM2200_RXANC_SRC 0x30A
58#define WM2200_INPUT_VOLUME_RAMP 0x30B
59#define WM2200_ADC_DIGITAL_VOLUME_1L 0x30C
60#define WM2200_ADC_DIGITAL_VOLUME_1R 0x30D
61#define WM2200_ADC_DIGITAL_VOLUME_2L 0x30E
62#define WM2200_ADC_DIGITAL_VOLUME_2R 0x30F
63#define WM2200_ADC_DIGITAL_VOLUME_3L 0x310
64#define WM2200_ADC_DIGITAL_VOLUME_3R 0x311
65#define WM2200_OUTPUT_ENABLES 0x400
66#define WM2200_DAC_VOLUME_LIMIT_1L 0x401
67#define WM2200_DAC_VOLUME_LIMIT_1R 0x402
68#define WM2200_DAC_VOLUME_LIMIT_2L 0x403
69#define WM2200_DAC_VOLUME_LIMIT_2R 0x404
70#define WM2200_DAC_AEC_CONTROL_1 0x409
71#define WM2200_OUTPUT_VOLUME_RAMP 0x40A
72#define WM2200_DAC_DIGITAL_VOLUME_1L 0x40B
73#define WM2200_DAC_DIGITAL_VOLUME_1R 0x40C
74#define WM2200_DAC_DIGITAL_VOLUME_2L 0x40D
75#define WM2200_DAC_DIGITAL_VOLUME_2R 0x40E
76#define WM2200_PDM_1 0x417
77#define WM2200_PDM_2 0x418
78#define WM2200_AUDIO_IF_1_1 0x500
79#define WM2200_AUDIO_IF_1_2 0x501
80#define WM2200_AUDIO_IF_1_3 0x502
81#define WM2200_AUDIO_IF_1_4 0x503
82#define WM2200_AUDIO_IF_1_5 0x504
83#define WM2200_AUDIO_IF_1_6 0x505
84#define WM2200_AUDIO_IF_1_7 0x506
85#define WM2200_AUDIO_IF_1_8 0x507
86#define WM2200_AUDIO_IF_1_9 0x508
87#define WM2200_AUDIO_IF_1_10 0x509
88#define WM2200_AUDIO_IF_1_11 0x50A
89#define WM2200_AUDIO_IF_1_12 0x50B
90#define WM2200_AUDIO_IF_1_13 0x50C
91#define WM2200_AUDIO_IF_1_14 0x50D
92#define WM2200_AUDIO_IF_1_15 0x50E
93#define WM2200_AUDIO_IF_1_16 0x50F
94#define WM2200_AUDIO_IF_1_17 0x510
95#define WM2200_AUDIO_IF_1_18 0x511
96#define WM2200_AUDIO_IF_1_19 0x512
97#define WM2200_AUDIO_IF_1_20 0x513
98#define WM2200_AUDIO_IF_1_21 0x514
99#define WM2200_AUDIO_IF_1_22 0x515
100#define WM2200_OUT1LMIX_INPUT_1_SOURCE 0x600
101#define WM2200_OUT1LMIX_INPUT_1_VOLUME 0x601
102#define WM2200_OUT1LMIX_INPUT_2_SOURCE 0x602
103#define WM2200_OUT1LMIX_INPUT_2_VOLUME 0x603
104#define WM2200_OUT1LMIX_INPUT_3_SOURCE 0x604
105#define WM2200_OUT1LMIX_INPUT_3_VOLUME 0x605
106#define WM2200_OUT1LMIX_INPUT_4_SOURCE 0x606
107#define WM2200_OUT1LMIX_INPUT_4_VOLUME 0x607
108#define WM2200_OUT1RMIX_INPUT_1_SOURCE 0x608
109#define WM2200_OUT1RMIX_INPUT_1_VOLUME 0x609
110#define WM2200_OUT1RMIX_INPUT_2_SOURCE 0x60A
111#define WM2200_OUT1RMIX_INPUT_2_VOLUME 0x60B
112#define WM2200_OUT1RMIX_INPUT_3_SOURCE 0x60C
113#define WM2200_OUT1RMIX_INPUT_3_VOLUME 0x60D
114#define WM2200_OUT1RMIX_INPUT_4_SOURCE 0x60E
115#define WM2200_OUT1RMIX_INPUT_4_VOLUME 0x60F
116#define WM2200_OUT2LMIX_INPUT_1_SOURCE 0x610
117#define WM2200_OUT2LMIX_INPUT_1_VOLUME 0x611
118#define WM2200_OUT2LMIX_INPUT_2_SOURCE 0x612
119#define WM2200_OUT2LMIX_INPUT_2_VOLUME 0x613
120#define WM2200_OUT2LMIX_INPUT_3_SOURCE 0x614
121#define WM2200_OUT2LMIX_INPUT_3_VOLUME 0x615
122#define WM2200_OUT2LMIX_INPUT_4_SOURCE 0x616
123#define WM2200_OUT2LMIX_INPUT_4_VOLUME 0x617
124#define WM2200_OUT2RMIX_INPUT_1_SOURCE 0x618
125#define WM2200_OUT2RMIX_INPUT_1_VOLUME 0x619
126#define WM2200_OUT2RMIX_INPUT_2_SOURCE 0x61A
127#define WM2200_OUT2RMIX_INPUT_2_VOLUME 0x61B
128#define WM2200_OUT2RMIX_INPUT_3_SOURCE 0x61C
129#define WM2200_OUT2RMIX_INPUT_3_VOLUME 0x61D
130#define WM2200_OUT2RMIX_INPUT_4_SOURCE 0x61E
131#define WM2200_OUT2RMIX_INPUT_4_VOLUME 0x61F
132#define WM2200_AIF1TX1MIX_INPUT_1_SOURCE 0x620
133#define WM2200_AIF1TX1MIX_INPUT_1_VOLUME 0x621
134#define WM2200_AIF1TX1MIX_INPUT_2_SOURCE 0x622
135#define WM2200_AIF1TX1MIX_INPUT_2_VOLUME 0x623
136#define WM2200_AIF1TX1MIX_INPUT_3_SOURCE 0x624
137#define WM2200_AIF1TX1MIX_INPUT_3_VOLUME 0x625
138#define WM2200_AIF1TX1MIX_INPUT_4_SOURCE 0x626
139#define WM2200_AIF1TX1MIX_INPUT_4_VOLUME 0x627
140#define WM2200_AIF1TX2MIX_INPUT_1_SOURCE 0x628
141#define WM2200_AIF1TX2MIX_INPUT_1_VOLUME 0x629
142#define WM2200_AIF1TX2MIX_INPUT_2_SOURCE 0x62A
143#define WM2200_AIF1TX2MIX_INPUT_2_VOLUME 0x62B
144#define WM2200_AIF1TX2MIX_INPUT_3_SOURCE 0x62C
145#define WM2200_AIF1TX2MIX_INPUT_3_VOLUME 0x62D
146#define WM2200_AIF1TX2MIX_INPUT_4_SOURCE 0x62E
147#define WM2200_AIF1TX2MIX_INPUT_4_VOLUME 0x62F
148#define WM2200_AIF1TX3MIX_INPUT_1_SOURCE 0x630
149#define WM2200_AIF1TX3MIX_INPUT_1_VOLUME 0x631
150#define WM2200_AIF1TX3MIX_INPUT_2_SOURCE 0x632
151#define WM2200_AIF1TX3MIX_INPUT_2_VOLUME 0x633
152#define WM2200_AIF1TX3MIX_INPUT_3_SOURCE 0x634
153#define WM2200_AIF1TX3MIX_INPUT_3_VOLUME 0x635
154#define WM2200_AIF1TX3MIX_INPUT_4_SOURCE 0x636
155#define WM2200_AIF1TX3MIX_INPUT_4_VOLUME 0x637
156#define WM2200_AIF1TX4MIX_INPUT_1_SOURCE 0x638
157#define WM2200_AIF1TX4MIX_INPUT_1_VOLUME 0x639
158#define WM2200_AIF1TX4MIX_INPUT_2_SOURCE 0x63A
159#define WM2200_AIF1TX4MIX_INPUT_2_VOLUME 0x63B
160#define WM2200_AIF1TX4MIX_INPUT_3_SOURCE 0x63C
161#define WM2200_AIF1TX4MIX_INPUT_3_VOLUME 0x63D
162#define WM2200_AIF1TX4MIX_INPUT_4_SOURCE 0x63E
163#define WM2200_AIF1TX4MIX_INPUT_4_VOLUME 0x63F
164#define WM2200_AIF1TX5MIX_INPUT_1_SOURCE 0x640
165#define WM2200_AIF1TX5MIX_INPUT_1_VOLUME 0x641
166#define WM2200_AIF1TX5MIX_INPUT_2_SOURCE 0x642
167#define WM2200_AIF1TX5MIX_INPUT_2_VOLUME 0x643
168#define WM2200_AIF1TX5MIX_INPUT_3_SOURCE 0x644
169#define WM2200_AIF1TX5MIX_INPUT_3_VOLUME 0x645
170#define WM2200_AIF1TX5MIX_INPUT_4_SOURCE 0x646
171#define WM2200_AIF1TX5MIX_INPUT_4_VOLUME 0x647
172#define WM2200_AIF1TX6MIX_INPUT_1_SOURCE 0x648
173#define WM2200_AIF1TX6MIX_INPUT_1_VOLUME 0x649
174#define WM2200_AIF1TX6MIX_INPUT_2_SOURCE 0x64A
175#define WM2200_AIF1TX6MIX_INPUT_2_VOLUME 0x64B
176#define WM2200_AIF1TX6MIX_INPUT_3_SOURCE 0x64C
177#define WM2200_AIF1TX6MIX_INPUT_3_VOLUME 0x64D
178#define WM2200_AIF1TX6MIX_INPUT_4_SOURCE 0x64E
179#define WM2200_AIF1TX6MIX_INPUT_4_VOLUME 0x64F
180#define WM2200_EQLMIX_INPUT_1_SOURCE 0x650
181#define WM2200_EQLMIX_INPUT_1_VOLUME 0x651
182#define WM2200_EQLMIX_INPUT_2_SOURCE 0x652
183#define WM2200_EQLMIX_INPUT_2_VOLUME 0x653
184#define WM2200_EQLMIX_INPUT_3_SOURCE 0x654
185#define WM2200_EQLMIX_INPUT_3_VOLUME 0x655
186#define WM2200_EQLMIX_INPUT_4_SOURCE 0x656
187#define WM2200_EQLMIX_INPUT_4_VOLUME 0x657
188#define WM2200_EQRMIX_INPUT_1_SOURCE 0x658
189#define WM2200_EQRMIX_INPUT_1_VOLUME 0x659
190#define WM2200_EQRMIX_INPUT_2_SOURCE 0x65A
191#define WM2200_EQRMIX_INPUT_2_VOLUME 0x65B
192#define WM2200_EQRMIX_INPUT_3_SOURCE 0x65C
193#define WM2200_EQRMIX_INPUT_3_VOLUME 0x65D
194#define WM2200_EQRMIX_INPUT_4_SOURCE 0x65E
195#define WM2200_EQRMIX_INPUT_4_VOLUME 0x65F
196#define WM2200_LHPF1MIX_INPUT_1_SOURCE 0x660
197#define WM2200_LHPF1MIX_INPUT_1_VOLUME 0x661
198#define WM2200_LHPF1MIX_INPUT_2_SOURCE 0x662
199#define WM2200_LHPF1MIX_INPUT_2_VOLUME 0x663
200#define WM2200_LHPF1MIX_INPUT_3_SOURCE 0x664
201#define WM2200_LHPF1MIX_INPUT_3_VOLUME 0x665
202#define WM2200_LHPF1MIX_INPUT_4_SOURCE 0x666
203#define WM2200_LHPF1MIX_INPUT_4_VOLUME 0x667
204#define WM2200_LHPF2MIX_INPUT_1_SOURCE 0x668
205#define WM2200_LHPF2MIX_INPUT_1_VOLUME 0x669
206#define WM2200_LHPF2MIX_INPUT_2_SOURCE 0x66A
207#define WM2200_LHPF2MIX_INPUT_2_VOLUME 0x66B
208#define WM2200_LHPF2MIX_INPUT_3_SOURCE 0x66C
209#define WM2200_LHPF2MIX_INPUT_3_VOLUME 0x66D
210#define WM2200_LHPF2MIX_INPUT_4_SOURCE 0x66E
211#define WM2200_LHPF2MIX_INPUT_4_VOLUME 0x66F
212#define WM2200_DSP1LMIX_INPUT_1_SOURCE 0x670
213#define WM2200_DSP1LMIX_INPUT_1_VOLUME 0x671
214#define WM2200_DSP1LMIX_INPUT_2_SOURCE 0x672
215#define WM2200_DSP1LMIX_INPUT_2_VOLUME 0x673
216#define WM2200_DSP1LMIX_INPUT_3_SOURCE 0x674
217#define WM2200_DSP1LMIX_INPUT_3_VOLUME 0x675
218#define WM2200_DSP1LMIX_INPUT_4_SOURCE 0x676
219#define WM2200_DSP1LMIX_INPUT_4_VOLUME 0x677
220#define WM2200_DSP1RMIX_INPUT_1_SOURCE 0x678
221#define WM2200_DSP1RMIX_INPUT_1_VOLUME 0x679
222#define WM2200_DSP1RMIX_INPUT_2_SOURCE 0x67A
223#define WM2200_DSP1RMIX_INPUT_2_VOLUME 0x67B
224#define WM2200_DSP1RMIX_INPUT_3_SOURCE 0x67C
225#define WM2200_DSP1RMIX_INPUT_3_VOLUME 0x67D
226#define WM2200_DSP1RMIX_INPUT_4_SOURCE 0x67E
227#define WM2200_DSP1RMIX_INPUT_4_VOLUME 0x67F
228#define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE 0x680
229#define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE 0x681
230#define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE 0x682
231#define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE 0x683
232#define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE 0x684
233#define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE 0x685
234#define WM2200_DSP2LMIX_INPUT_1_SOURCE 0x686
235#define WM2200_DSP2LMIX_INPUT_1_VOLUME 0x687
236#define WM2200_DSP2LMIX_INPUT_2_SOURCE 0x688
237#define WM2200_DSP2LMIX_INPUT_2_VOLUME 0x689
238#define WM2200_DSP2LMIX_INPUT_3_SOURCE 0x68A
239#define WM2200_DSP2LMIX_INPUT_3_VOLUME 0x68B
240#define WM2200_DSP2LMIX_INPUT_4_SOURCE 0x68C
241#define WM2200_DSP2LMIX_INPUT_4_VOLUME 0x68D
242#define WM2200_DSP2RMIX_INPUT_1_SOURCE 0x68E
243#define WM2200_DSP2RMIX_INPUT_1_VOLUME 0x68F
244#define WM2200_DSP2RMIX_INPUT_2_SOURCE 0x690
245#define WM2200_DSP2RMIX_INPUT_2_VOLUME 0x691
246#define WM2200_DSP2RMIX_INPUT_3_SOURCE 0x692
247#define WM2200_DSP2RMIX_INPUT_3_VOLUME 0x693
248#define WM2200_DSP2RMIX_INPUT_4_SOURCE 0x694
249#define WM2200_DSP2RMIX_INPUT_4_VOLUME 0x695
250#define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE 0x696
251#define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE 0x697
252#define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE 0x698
253#define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE 0x699
254#define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE 0x69A
255#define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE 0x69B
256#define WM2200_GPIO_CTRL_1 0x700
257#define WM2200_GPIO_CTRL_2 0x701
258#define WM2200_GPIO_CTRL_3 0x702
259#define WM2200_GPIO_CTRL_4 0x703
260#define WM2200_ADPS1_IRQ0 0x707
261#define WM2200_ADPS1_IRQ1 0x708
262#define WM2200_MISC_PAD_CTRL_1 0x709
263#define WM2200_INTERRUPT_STATUS_1 0x800
264#define WM2200_INTERRUPT_STATUS_1_MASK 0x801
265#define WM2200_INTERRUPT_STATUS_2 0x802
266#define WM2200_INTERRUPT_RAW_STATUS_2 0x803
267#define WM2200_INTERRUPT_STATUS_2_MASK 0x804
268#define WM2200_INTERRUPT_CONTROL 0x808
269#define WM2200_EQL_1 0x900
270#define WM2200_EQL_2 0x901
271#define WM2200_EQL_3 0x902
272#define WM2200_EQL_4 0x903
273#define WM2200_EQL_5 0x904
274#define WM2200_EQL_6 0x905
275#define WM2200_EQL_7 0x906
276#define WM2200_EQL_8 0x907
277#define WM2200_EQL_9 0x908
278#define WM2200_EQL_10 0x909
279#define WM2200_EQL_11 0x90A
280#define WM2200_EQL_12 0x90B
281#define WM2200_EQL_13 0x90C
282#define WM2200_EQL_14 0x90D
283#define WM2200_EQL_15 0x90E
284#define WM2200_EQL_16 0x90F
285#define WM2200_EQL_17 0x910
286#define WM2200_EQL_18 0x911
287#define WM2200_EQL_19 0x912
288#define WM2200_EQL_20 0x913
289#define WM2200_EQR_1 0x916
290#define WM2200_EQR_2 0x917
291#define WM2200_EQR_3 0x918
292#define WM2200_EQR_4 0x919
293#define WM2200_EQR_5 0x91A
294#define WM2200_EQR_6 0x91B
295#define WM2200_EQR_7 0x91C
296#define WM2200_EQR_8 0x91D
297#define WM2200_EQR_9 0x91E
298#define WM2200_EQR_10 0x91F
299#define WM2200_EQR_11 0x920
300#define WM2200_EQR_12 0x921
301#define WM2200_EQR_13 0x922
302#define WM2200_EQR_14 0x923
303#define WM2200_EQR_15 0x924
304#define WM2200_EQR_16 0x925
305#define WM2200_EQR_17 0x926
306#define WM2200_EQR_18 0x927
307#define WM2200_EQR_19 0x928
308#define WM2200_EQR_20 0x929
309#define WM2200_HPLPF1_1 0x93E
310#define WM2200_HPLPF1_2 0x93F
311#define WM2200_HPLPF2_1 0x942
312#define WM2200_HPLPF2_2 0x943
313#define WM2200_DSP1_CONTROL_1 0xA00
314#define WM2200_DSP1_CONTROL_2 0xA02
315#define WM2200_DSP1_CONTROL_3 0xA03
316#define WM2200_DSP1_CONTROL_4 0xA04
317#define WM2200_DSP1_CONTROL_5 0xA06
318#define WM2200_DSP1_CONTROL_6 0xA07
319#define WM2200_DSP1_CONTROL_7 0xA08
320#define WM2200_DSP1_CONTROL_8 0xA09
321#define WM2200_DSP1_CONTROL_9 0xA0A
322#define WM2200_DSP1_CONTROL_10 0xA0B
323#define WM2200_DSP1_CONTROL_11 0xA0C
324#define WM2200_DSP1_CONTROL_12 0xA0D
325#define WM2200_DSP1_CONTROL_13 0xA0F
326#define WM2200_DSP1_CONTROL_14 0xA10
327#define WM2200_DSP1_CONTROL_15 0xA11
328#define WM2200_DSP1_CONTROL_16 0xA12
329#define WM2200_DSP1_CONTROL_17 0xA13
330#define WM2200_DSP1_CONTROL_18 0xA14
331#define WM2200_DSP1_CONTROL_19 0xA16
332#define WM2200_DSP1_CONTROL_20 0xA17
333#define WM2200_DSP1_CONTROL_21 0xA18
334#define WM2200_DSP1_CONTROL_22 0xA1A
335#define WM2200_DSP1_CONTROL_23 0xA1B
336#define WM2200_DSP1_CONTROL_24 0xA1C
337#define WM2200_DSP1_CONTROL_25 0xA1E
338#define WM2200_DSP1_CONTROL_26 0xA20
339#define WM2200_DSP1_CONTROL_27 0xA21
340#define WM2200_DSP1_CONTROL_28 0xA22
341#define WM2200_DSP1_CONTROL_29 0xA23
342#define WM2200_DSP1_CONTROL_30 0xA24
343#define WM2200_DSP1_CONTROL_31 0xA26
344#define WM2200_DSP2_CONTROL_1 0xB00
345#define WM2200_DSP2_CONTROL_2 0xB02
346#define WM2200_DSP2_CONTROL_3 0xB03
347#define WM2200_DSP2_CONTROL_4 0xB04
348#define WM2200_DSP2_CONTROL_5 0xB06
349#define WM2200_DSP2_CONTROL_6 0xB07
350#define WM2200_DSP2_CONTROL_7 0xB08
351#define WM2200_DSP2_CONTROL_8 0xB09
352#define WM2200_DSP2_CONTROL_9 0xB0A
353#define WM2200_DSP2_CONTROL_10 0xB0B
354#define WM2200_DSP2_CONTROL_11 0xB0C
355#define WM2200_DSP2_CONTROL_12 0xB0D
356#define WM2200_DSP2_CONTROL_13 0xB0F
357#define WM2200_DSP2_CONTROL_14 0xB10
358#define WM2200_DSP2_CONTROL_15 0xB11
359#define WM2200_DSP2_CONTROL_16 0xB12
360#define WM2200_DSP2_CONTROL_17 0xB13
361#define WM2200_DSP2_CONTROL_18 0xB14
362#define WM2200_DSP2_CONTROL_19 0xB16
363#define WM2200_DSP2_CONTROL_20 0xB17
364#define WM2200_DSP2_CONTROL_21 0xB18
365#define WM2200_DSP2_CONTROL_22 0xB1A
366#define WM2200_DSP2_CONTROL_23 0xB1B
367#define WM2200_DSP2_CONTROL_24 0xB1C
368#define WM2200_DSP2_CONTROL_25 0xB1E
369#define WM2200_DSP2_CONTROL_26 0xB20
370#define WM2200_DSP2_CONTROL_27 0xB21
371#define WM2200_DSP2_CONTROL_28 0xB22
372#define WM2200_DSP2_CONTROL_29 0xB23
373#define WM2200_DSP2_CONTROL_30 0xB24
374#define WM2200_DSP2_CONTROL_31 0xB26
375#define WM2200_ANC_CTRL1 0xD00
376#define WM2200_ANC_CTRL2 0xD01
377#define WM2200_ANC_CTRL3 0xD02
378#define WM2200_ANC_CTRL7 0xD08
379#define WM2200_ANC_CTRL8 0xD09
380#define WM2200_ANC_CTRL9 0xD0A
381#define WM2200_ANC_CTRL10 0xD0B
382#define WM2200_ANC_CTRL11 0xD0C
383#define WM2200_ANC_CTRL12 0xD0D
384#define WM2200_ANC_CTRL13 0xD0E
385#define WM2200_ANC_CTRL14 0xD0F
386#define WM2200_ANC_CTRL15 0xD10
387#define WM2200_ANC_CTRL16 0xD11
388#define WM2200_ANC_CTRL17 0xD12
389#define WM2200_ANC_CTRL18 0xD15
390#define WM2200_ANC_CTRL19 0xD16
391#define WM2200_ANC_CTRL20 0xD17
392#define WM2200_ANC_CTRL21 0xD18
393#define WM2200_ANC_CTRL22 0xD19
394#define WM2200_ANC_CTRL23 0xD1A
395#define WM2200_ANC_CTRL24 0xD1B
396#define WM2200_ANC_CTRL25 0xD1C
397#define WM2200_ANC_CTRL26 0xD1D
398#define WM2200_ANC_CTRL27 0xD1E
399#define WM2200_ANC_CTRL28 0xD1F
400#define WM2200_ANC_CTRL29 0xD20
401#define WM2200_ANC_CTRL30 0xD21
402#define WM2200_ANC_CTRL31 0xD23
403#define WM2200_ANC_CTRL32 0xD24
404#define WM2200_ANC_CTRL33 0xD25
405#define WM2200_ANC_CTRL34 0xD27
406#define WM2200_ANC_CTRL35 0xD28
407#define WM2200_ANC_CTRL36 0xD29
408#define WM2200_ANC_CTRL37 0xD2A
409#define WM2200_ANC_CTRL38 0xD2B
410#define WM2200_ANC_CTRL39 0xD2C
411#define WM2200_ANC_CTRL40 0xD2D
412#define WM2200_ANC_CTRL41 0xD2E
413#define WM2200_ANC_CTRL42 0xD2F
414#define WM2200_ANC_CTRL43 0xD30
415#define WM2200_ANC_CTRL44 0xD31
416#define WM2200_ANC_CTRL45 0xD32
417#define WM2200_ANC_CTRL46 0xD33
418#define WM2200_ANC_CTRL47 0xD34
419#define WM2200_ANC_CTRL48 0xD35
420#define WM2200_ANC_CTRL49 0xD36
421#define WM2200_ANC_CTRL50 0xD37
422#define WM2200_ANC_CTRL51 0xD38
423#define WM2200_ANC_CTRL52 0xD39
424#define WM2200_ANC_CTRL53 0xD3A
425#define WM2200_ANC_CTRL54 0xD3B
426#define WM2200_ANC_CTRL55 0xD3C
427#define WM2200_ANC_CTRL56 0xD3D
428#define WM2200_ANC_CTRL57 0xD3E
429#define WM2200_ANC_CTRL58 0xD3F
430#define WM2200_ANC_CTRL59 0xD40
431#define WM2200_ANC_CTRL60 0xD41
432#define WM2200_ANC_CTRL61 0xD42
433#define WM2200_ANC_CTRL62 0xD43
434#define WM2200_ANC_CTRL63 0xD44
435#define WM2200_ANC_CTRL64 0xD45
436#define WM2200_ANC_CTRL65 0xD46
437#define WM2200_ANC_CTRL66 0xD47
438#define WM2200_ANC_CTRL67 0xD48
439#define WM2200_ANC_CTRL68 0xD49
440#define WM2200_ANC_CTRL69 0xD4A
441#define WM2200_ANC_CTRL70 0xD4B
442#define WM2200_ANC_CTRL71 0xD4C
443#define WM2200_ANC_CTRL72 0xD4D
444#define WM2200_ANC_CTRL73 0xD4E
445#define WM2200_ANC_CTRL74 0xD4F
446#define WM2200_ANC_CTRL75 0xD50
447#define WM2200_ANC_CTRL76 0xD51
448#define WM2200_ANC_CTRL77 0xD52
449#define WM2200_ANC_CTRL78 0xD53
450#define WM2200_ANC_CTRL79 0xD54
451#define WM2200_ANC_CTRL80 0xD55
452#define WM2200_ANC_CTRL81 0xD56
453#define WM2200_ANC_CTRL82 0xD57
454#define WM2200_ANC_CTRL83 0xD58
455#define WM2200_ANC_CTRL84 0xD5B
456#define WM2200_ANC_CTRL85 0xD5C
457#define WM2200_ANC_CTRL86 0xD5F
458#define WM2200_ANC_CTRL87 0xD60
459#define WM2200_ANC_CTRL88 0xD61
460#define WM2200_ANC_CTRL89 0xD62
461#define WM2200_ANC_CTRL90 0xD63
462#define WM2200_ANC_CTRL91 0xD64
463#define WM2200_ANC_CTRL92 0xD65
464#define WM2200_ANC_CTRL93 0xD66
465#define WM2200_ANC_CTRL94 0xD67
466#define WM2200_ANC_CTRL95 0xD68
467#define WM2200_ANC_CTRL96 0xD69
468#define WM2200_DSP1_DM_0 0x3000
469#define WM2200_DSP1_DM_1 0x3001
470#define WM2200_DSP1_DM_2 0x3002
471#define WM2200_DSP1_DM_3 0x3003
472#define WM2200_DSP1_DM_2044 0x37FC
473#define WM2200_DSP1_DM_2045 0x37FD
474#define WM2200_DSP1_DM_2046 0x37FE
475#define WM2200_DSP1_DM_2047 0x37FF
476#define WM2200_DSP1_PM_0 0x3800
477#define WM2200_DSP1_PM_1 0x3801
478#define WM2200_DSP1_PM_2 0x3802
479#define WM2200_DSP1_PM_3 0x3803
480#define WM2200_DSP1_PM_4 0x3804
481#define WM2200_DSP1_PM_5 0x3805
482#define WM2200_DSP1_PM_762 0x3AFA
483#define WM2200_DSP1_PM_763 0x3AFB
484#define WM2200_DSP1_PM_764 0x3AFC
485#define WM2200_DSP1_PM_765 0x3AFD
486#define WM2200_DSP1_PM_766 0x3AFE
487#define WM2200_DSP1_PM_767 0x3AFF
488#define WM2200_DSP1_ZM_0 0x3C00
489#define WM2200_DSP1_ZM_1 0x3C01
490#define WM2200_DSP1_ZM_2 0x3C02
491#define WM2200_DSP1_ZM_3 0x3C03
492#define WM2200_DSP1_ZM_1020 0x3FFC
493#define WM2200_DSP1_ZM_1021 0x3FFD
494#define WM2200_DSP1_ZM_1022 0x3FFE
495#define WM2200_DSP1_ZM_1023 0x3FFF
496#define WM2200_DSP2_DM_0 0x4000
497#define WM2200_DSP2_DM_1 0x4001
498#define WM2200_DSP2_DM_2 0x4002
499#define WM2200_DSP2_DM_3 0x4003
500#define WM2200_DSP2_DM_2044 0x47FC
501#define WM2200_DSP2_DM_2045 0x47FD
502#define WM2200_DSP2_DM_2046 0x47FE
503#define WM2200_DSP2_DM_2047 0x47FF
504#define WM2200_DSP2_PM_0 0x4800
505#define WM2200_DSP2_PM_1 0x4801
506#define WM2200_DSP2_PM_2 0x4802
507#define WM2200_DSP2_PM_3 0x4803
508#define WM2200_DSP2_PM_4 0x4804
509#define WM2200_DSP2_PM_5 0x4805
510#define WM2200_DSP2_PM_762 0x4AFA
511#define WM2200_DSP2_PM_763 0x4AFB
512#define WM2200_DSP2_PM_764 0x4AFC
513#define WM2200_DSP2_PM_765 0x4AFD
514#define WM2200_DSP2_PM_766 0x4AFE
515#define WM2200_DSP2_PM_767 0x4AFF
516#define WM2200_DSP2_ZM_0 0x4C00
517#define WM2200_DSP2_ZM_1 0x4C01
518#define WM2200_DSP2_ZM_2 0x4C02
519#define WM2200_DSP2_ZM_3 0x4C03
520#define WM2200_DSP2_ZM_1020 0x4FFC
521#define WM2200_DSP2_ZM_1021 0x4FFD
522#define WM2200_DSP2_ZM_1022 0x4FFE
523#define WM2200_DSP2_ZM_1023 0x4FFF
524
525#define WM2200_REGISTER_COUNT 494
526#define WM2200_MAX_REGISTER 0x4FFF
527
528/*
529 * Field Definitions.
530 */
531
532/*
533 * R0 (0x00) - software reset
534 */
535#define WM2200_SW_RESET_CHIP_ID1_MASK 0xFFFF /* SW_RESET_CHIP_ID1 - [15:0] */
536#define WM2200_SW_RESET_CHIP_ID1_SHIFT 0 /* SW_RESET_CHIP_ID1 - [15:0] */
537#define WM2200_SW_RESET_CHIP_ID1_WIDTH 16 /* SW_RESET_CHIP_ID1 - [15:0] */
538
539/*
540 * R1 (0x01) - Device Revision
541 */
542#define WM2200_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
543#define WM2200_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
544#define WM2200_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
545
546/*
547 * R11 (0x0B) - Tone Generator 1
548 */
549#define WM2200_TONE_ENA 0x0001 /* TONE_ENA */
550#define WM2200_TONE_ENA_MASK 0x0001 /* TONE_ENA */
551#define WM2200_TONE_ENA_SHIFT 0 /* TONE_ENA */
552#define WM2200_TONE_ENA_WIDTH 1 /* TONE_ENA */
553
554/*
555 * R258 (0x102) - Clocking 3
556 */
557#define WM2200_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
558#define WM2200_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
559#define WM2200_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
560#define WM2200_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
561#define WM2200_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
562#define WM2200_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
563#define WM2200_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
564#define WM2200_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
565#define WM2200_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
566#define WM2200_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
567
568/*
569 * R259 (0x103) - Clocking 4
570 */
571#define WM2200_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
572#define WM2200_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
573#define WM2200_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
574
575/*
576 * R273 (0x111) - FLL Control 1
577 */
578#define WM2200_FLL_ENA 0x0001 /* FLL_ENA */
579#define WM2200_FLL_ENA_MASK 0x0001 /* FLL_ENA */
580#define WM2200_FLL_ENA_SHIFT 0 /* FLL_ENA */
581#define WM2200_FLL_ENA_WIDTH 1 /* FLL_ENA */
582
583/*
584 * R274 (0x112) - FLL Control 2
585 */
586#define WM2200_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
587#define WM2200_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
588#define WM2200_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
589#define WM2200_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
590#define WM2200_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
591#define WM2200_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
592
593/*
594 * R275 (0x113) - FLL Control 3
595 */
596#define WM2200_FLL_FRACN_ENA 0x0001 /* FLL_FRACN_ENA */
597#define WM2200_FLL_FRACN_ENA_MASK 0x0001 /* FLL_FRACN_ENA */
598#define WM2200_FLL_FRACN_ENA_SHIFT 0 /* FLL_FRACN_ENA */
599#define WM2200_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
600
601/*
602 * R276 (0x114) - FLL Control 4
603 */
604#define WM2200_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
605#define WM2200_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
606#define WM2200_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
607
608/*
609 * R278 (0x116) - FLL Control 6
610 */
611#define WM2200_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
612#define WM2200_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
613#define WM2200_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
614
615/*
616 * R279 (0x117) - FLL Control 7
617 */
618#define WM2200_FLL_CLK_REF_DIV_MASK 0x0030 /* FLL_CLK_REF_DIV - [5:4] */
619#define WM2200_FLL_CLK_REF_DIV_SHIFT 4 /* FLL_CLK_REF_DIV - [5:4] */
620#define WM2200_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [5:4] */
621#define WM2200_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
622#define WM2200_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
623#define WM2200_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
624
625/*
626 * R281 (0x119) - FLL EFS 1
627 */
628#define WM2200_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
629#define WM2200_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
630#define WM2200_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
631
632/*
633 * R282 (0x11A) - FLL EFS 2
634 */
635#define WM2200_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
636#define WM2200_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
637#define WM2200_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
638#define WM2200_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
639
640/*
641 * R512 (0x200) - Mic Charge Pump 1
642 */
643#define WM2200_CPMIC_BYPASS_MODE 0x0020 /* CPMIC_BYPASS_MODE */
644#define WM2200_CPMIC_BYPASS_MODE_MASK 0x0020 /* CPMIC_BYPASS_MODE */
645#define WM2200_CPMIC_BYPASS_MODE_SHIFT 5 /* CPMIC_BYPASS_MODE */
646#define WM2200_CPMIC_BYPASS_MODE_WIDTH 1 /* CPMIC_BYPASS_MODE */
647#define WM2200_CPMIC_ENA 0x0001 /* CPMIC_ENA */
648#define WM2200_CPMIC_ENA_MASK 0x0001 /* CPMIC_ENA */
649#define WM2200_CPMIC_ENA_SHIFT 0 /* CPMIC_ENA */
650#define WM2200_CPMIC_ENA_WIDTH 1 /* CPMIC_ENA */
651
652/*
653 * R513 (0x201) - Mic Charge Pump 2
654 */
655#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK 0xF800 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
656#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT 11 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
657#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH 5 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
658
659/*
660 * R514 (0x202) - DM Charge Pump 1
661 */
662#define WM2200_CPDM_ENA 0x0001 /* CPDM_ENA */
663#define WM2200_CPDM_ENA_MASK 0x0001 /* CPDM_ENA */
664#define WM2200_CPDM_ENA_SHIFT 0 /* CPDM_ENA */
665#define WM2200_CPDM_ENA_WIDTH 1 /* CPDM_ENA */
666
667/*
668 * R524 (0x20C) - Mic Bias Ctrl 1
669 */
670#define WM2200_MICB1_DISCH 0x0040 /* MICB1_DISCH */
671#define WM2200_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
672#define WM2200_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
673#define WM2200_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
674#define WM2200_MICB1_RATE 0x0020 /* MICB1_RATE */
675#define WM2200_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
676#define WM2200_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
677#define WM2200_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
678#define WM2200_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
679#define WM2200_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
680#define WM2200_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
681#define WM2200_MICB1_MODE 0x0002 /* MICB1_MODE */
682#define WM2200_MICB1_MODE_MASK 0x0002 /* MICB1_MODE */
683#define WM2200_MICB1_MODE_SHIFT 1 /* MICB1_MODE */
684#define WM2200_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
685#define WM2200_MICB1_ENA 0x0001 /* MICB1_ENA */
686#define WM2200_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
687#define WM2200_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
688#define WM2200_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
689
690/*
691 * R525 (0x20D) - Mic Bias Ctrl 2
692 */
693#define WM2200_MICB2_DISCH 0x0040 /* MICB2_DISCH */
694#define WM2200_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
695#define WM2200_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
696#define WM2200_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
697#define WM2200_MICB2_RATE 0x0020 /* MICB2_RATE */
698#define WM2200_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
699#define WM2200_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
700#define WM2200_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
701#define WM2200_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
702#define WM2200_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
703#define WM2200_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
704#define WM2200_MICB2_MODE 0x0002 /* MICB2_MODE */
705#define WM2200_MICB2_MODE_MASK 0x0002 /* MICB2_MODE */
706#define WM2200_MICB2_MODE_SHIFT 1 /* MICB2_MODE */
707#define WM2200_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
708#define WM2200_MICB2_ENA 0x0001 /* MICB2_ENA */
709#define WM2200_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
710#define WM2200_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
711#define WM2200_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
712
713/*
714 * R527 (0x20F) - Ear Piece Ctrl 1
715 */
716#define WM2200_EPD_LP_ENA 0x4000 /* EPD_LP_ENA */
717#define WM2200_EPD_LP_ENA_MASK 0x4000 /* EPD_LP_ENA */
718#define WM2200_EPD_LP_ENA_SHIFT 14 /* EPD_LP_ENA */
719#define WM2200_EPD_LP_ENA_WIDTH 1 /* EPD_LP_ENA */
720#define WM2200_EPD_OUTP_LP_ENA 0x2000 /* EPD_OUTP_LP_ENA */
721#define WM2200_EPD_OUTP_LP_ENA_MASK 0x2000 /* EPD_OUTP_LP_ENA */
722#define WM2200_EPD_OUTP_LP_ENA_SHIFT 13 /* EPD_OUTP_LP_ENA */
723#define WM2200_EPD_OUTP_LP_ENA_WIDTH 1 /* EPD_OUTP_LP_ENA */
724#define WM2200_EPD_RMV_SHRT_LP 0x1000 /* EPD_RMV_SHRT_LP */
725#define WM2200_EPD_RMV_SHRT_LP_MASK 0x1000 /* EPD_RMV_SHRT_LP */
726#define WM2200_EPD_RMV_SHRT_LP_SHIFT 12 /* EPD_RMV_SHRT_LP */
727#define WM2200_EPD_RMV_SHRT_LP_WIDTH 1 /* EPD_RMV_SHRT_LP */
728#define WM2200_EPD_LN_ENA 0x0800 /* EPD_LN_ENA */
729#define WM2200_EPD_LN_ENA_MASK 0x0800 /* EPD_LN_ENA */
730#define WM2200_EPD_LN_ENA_SHIFT 11 /* EPD_LN_ENA */
731#define WM2200_EPD_LN_ENA_WIDTH 1 /* EPD_LN_ENA */
732#define WM2200_EPD_OUTP_LN_ENA 0x0400 /* EPD_OUTP_LN_ENA */
733#define WM2200_EPD_OUTP_LN_ENA_MASK 0x0400 /* EPD_OUTP_LN_ENA */
734#define WM2200_EPD_OUTP_LN_ENA_SHIFT 10 /* EPD_OUTP_LN_ENA */
735#define WM2200_EPD_OUTP_LN_ENA_WIDTH 1 /* EPD_OUTP_LN_ENA */
736#define WM2200_EPD_RMV_SHRT_LN 0x0200 /* EPD_RMV_SHRT_LN */
737#define WM2200_EPD_RMV_SHRT_LN_MASK 0x0200 /* EPD_RMV_SHRT_LN */
738#define WM2200_EPD_RMV_SHRT_LN_SHIFT 9 /* EPD_RMV_SHRT_LN */
739#define WM2200_EPD_RMV_SHRT_LN_WIDTH 1 /* EPD_RMV_SHRT_LN */
740
741/*
742 * R528 (0x210) - Ear Piece Ctrl 2
743 */
744#define WM2200_EPD_RP_ENA 0x4000 /* EPD_RP_ENA */
745#define WM2200_EPD_RP_ENA_MASK 0x4000 /* EPD_RP_ENA */
746#define WM2200_EPD_RP_ENA_SHIFT 14 /* EPD_RP_ENA */
747#define WM2200_EPD_RP_ENA_WIDTH 1 /* EPD_RP_ENA */
748#define WM2200_EPD_OUTP_RP_ENA 0x2000 /* EPD_OUTP_RP_ENA */
749#define WM2200_EPD_OUTP_RP_ENA_MASK 0x2000 /* EPD_OUTP_RP_ENA */
750#define WM2200_EPD_OUTP_RP_ENA_SHIFT 13 /* EPD_OUTP_RP_ENA */
751#define WM2200_EPD_OUTP_RP_ENA_WIDTH 1 /* EPD_OUTP_RP_ENA */
752#define WM2200_EPD_RMV_SHRT_RP 0x1000 /* EPD_RMV_SHRT_RP */
753#define WM2200_EPD_RMV_SHRT_RP_MASK 0x1000 /* EPD_RMV_SHRT_RP */
754#define WM2200_EPD_RMV_SHRT_RP_SHIFT 12 /* EPD_RMV_SHRT_RP */
755#define WM2200_EPD_RMV_SHRT_RP_WIDTH 1 /* EPD_RMV_SHRT_RP */
756#define WM2200_EPD_RN_ENA 0x0800 /* EPD_RN_ENA */
757#define WM2200_EPD_RN_ENA_MASK 0x0800 /* EPD_RN_ENA */
758#define WM2200_EPD_RN_ENA_SHIFT 11 /* EPD_RN_ENA */
759#define WM2200_EPD_RN_ENA_WIDTH 1 /* EPD_RN_ENA */
760#define WM2200_EPD_OUTP_RN_ENA 0x0400 /* EPD_OUTP_RN_ENA */
761#define WM2200_EPD_OUTP_RN_ENA_MASK 0x0400 /* EPD_OUTP_RN_ENA */
762#define WM2200_EPD_OUTP_RN_ENA_SHIFT 10 /* EPD_OUTP_RN_ENA */
763#define WM2200_EPD_OUTP_RN_ENA_WIDTH 1 /* EPD_OUTP_RN_ENA */
764#define WM2200_EPD_RMV_SHRT_RN 0x0200 /* EPD_RMV_SHRT_RN */
765#define WM2200_EPD_RMV_SHRT_RN_MASK 0x0200 /* EPD_RMV_SHRT_RN */
766#define WM2200_EPD_RMV_SHRT_RN_SHIFT 9 /* EPD_RMV_SHRT_RN */
767#define WM2200_EPD_RMV_SHRT_RN_WIDTH 1 /* EPD_RMV_SHRT_RN */
768
769/*
770 * R769 (0x301) - Input Enables
771 */
772#define WM2200_IN3L_ENA 0x0020 /* IN3L_ENA */
773#define WM2200_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
774#define WM2200_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
775#define WM2200_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
776#define WM2200_IN3R_ENA 0x0010 /* IN3R_ENA */
777#define WM2200_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
778#define WM2200_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
779#define WM2200_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
780#define WM2200_IN2L_ENA 0x0008 /* IN2L_ENA */
781#define WM2200_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
782#define WM2200_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
783#define WM2200_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
784#define WM2200_IN2R_ENA 0x0004 /* IN2R_ENA */
785#define WM2200_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
786#define WM2200_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
787#define WM2200_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
788#define WM2200_IN1L_ENA 0x0002 /* IN1L_ENA */
789#define WM2200_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
790#define WM2200_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
791#define WM2200_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
792#define WM2200_IN1R_ENA 0x0001 /* IN1R_ENA */
793#define WM2200_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
794#define WM2200_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
795#define WM2200_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
796
797/*
798 * R770 (0x302) - IN1L Control
799 */
800#define WM2200_IN1_OSR 0x2000 /* IN1_OSR */
801#define WM2200_IN1_OSR_MASK 0x2000 /* IN1_OSR */
802#define WM2200_IN1_OSR_SHIFT 13 /* IN1_OSR */
803#define WM2200_IN1_OSR_WIDTH 1 /* IN1_OSR */
804#define WM2200_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
805#define WM2200_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
806#define WM2200_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
807#define WM2200_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
808#define WM2200_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
809#define WM2200_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
810#define WM2200_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
811#define WM2200_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
812#define WM2200_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
813
814/*
815 * R771 (0x303) - IN1R Control
816 */
817#define WM2200_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
818#define WM2200_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
819#define WM2200_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
820
821/*
822 * R772 (0x304) - IN2L Control
823 */
824#define WM2200_IN2_OSR 0x2000 /* IN2_OSR */
825#define WM2200_IN2_OSR_MASK 0x2000 /* IN2_OSR */
826#define WM2200_IN2_OSR_SHIFT 13 /* IN2_OSR */
827#define WM2200_IN2_OSR_WIDTH 1 /* IN2_OSR */
828#define WM2200_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
829#define WM2200_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
830#define WM2200_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
831#define WM2200_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
832#define WM2200_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
833#define WM2200_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
834#define WM2200_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
835#define WM2200_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
836#define WM2200_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
837
838/*
839 * R773 (0x305) - IN2R Control
840 */
841#define WM2200_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
842#define WM2200_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
843#define WM2200_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
844
845/*
846 * R774 (0x306) - IN3L Control
847 */
848#define WM2200_IN3_OSR 0x2000 /* IN3_OSR */
849#define WM2200_IN3_OSR_MASK 0x2000 /* IN3_OSR */
850#define WM2200_IN3_OSR_SHIFT 13 /* IN3_OSR */
851#define WM2200_IN3_OSR_WIDTH 1 /* IN3_OSR */
852#define WM2200_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
853#define WM2200_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
854#define WM2200_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
855#define WM2200_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
856#define WM2200_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
857#define WM2200_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
858#define WM2200_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
859#define WM2200_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
860#define WM2200_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
861
862/*
863 * R775 (0x307) - IN3R Control
864 */
865#define WM2200_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
866#define WM2200_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
867#define WM2200_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
868
869/*
870 * R778 (0x30A) - RXANC_SRC
871 */
872#define WM2200_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
873#define WM2200_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
874#define WM2200_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
875
876/*
877 * R779 (0x30B) - Input Volume Ramp
878 */
879#define WM2200_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
880#define WM2200_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
881#define WM2200_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
882#define WM2200_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
883#define WM2200_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
884#define WM2200_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
885
886/*
887 * R780 (0x30C) - ADC Digital Volume 1L
888 */
889#define WM2200_IN_VU 0x0200 /* IN_VU */
890#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
891#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
892#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
893#define WM2200_IN1L_MUTE 0x0100 /* IN1L_MUTE */
894#define WM2200_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
895#define WM2200_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
896#define WM2200_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
897#define WM2200_IN1L_DIG_VOL_MASK 0x00FF /* IN1L_DIG_VOL - [7:0] */
898#define WM2200_IN1L_DIG_VOL_SHIFT 0 /* IN1L_DIG_VOL - [7:0] */
899#define WM2200_IN1L_DIG_VOL_WIDTH 8 /* IN1L_DIG_VOL - [7:0] */
900
901/*
902 * R781 (0x30D) - ADC Digital Volume 1R
903 */
904#define WM2200_IN_VU 0x0200 /* IN_VU */
905#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
906#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
907#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
908#define WM2200_IN1R_MUTE 0x0100 /* IN1R_MUTE */
909#define WM2200_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
910#define WM2200_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
911#define WM2200_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
912#define WM2200_IN1R_DIG_VOL_MASK 0x00FF /* IN1R_DIG_VOL - [7:0] */
913#define WM2200_IN1R_DIG_VOL_SHIFT 0 /* IN1R_DIG_VOL - [7:0] */
914#define WM2200_IN1R_DIG_VOL_WIDTH 8 /* IN1R_DIG_VOL - [7:0] */
915
916/*
917 * R782 (0x30E) - ADC Digital Volume 2L
918 */
919#define WM2200_IN_VU 0x0200 /* IN_VU */
920#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
921#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
922#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
923#define WM2200_IN2L_MUTE 0x0100 /* IN2L_MUTE */
924#define WM2200_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
925#define WM2200_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
926#define WM2200_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
927#define WM2200_IN2L_DIG_VOL_MASK 0x00FF /* IN2L_DIG_VOL - [7:0] */
928#define WM2200_IN2L_DIG_VOL_SHIFT 0 /* IN2L_DIG_VOL - [7:0] */
929#define WM2200_IN2L_DIG_VOL_WIDTH 8 /* IN2L_DIG_VOL - [7:0] */
930
931/*
932 * R783 (0x30F) - ADC Digital Volume 2R
933 */
934#define WM2200_IN_VU 0x0200 /* IN_VU */
935#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
936#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
937#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
938#define WM2200_IN2R_MUTE 0x0100 /* IN2R_MUTE */
939#define WM2200_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
940#define WM2200_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
941#define WM2200_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
942#define WM2200_IN2R_DIG_VOL_MASK 0x00FF /* IN2R_DIG_VOL - [7:0] */
943#define WM2200_IN2R_DIG_VOL_SHIFT 0 /* IN2R_DIG_VOL - [7:0] */
944#define WM2200_IN2R_DIG_VOL_WIDTH 8 /* IN2R_DIG_VOL - [7:0] */
945
946/*
947 * R784 (0x310) - ADC Digital Volume 3L
948 */
949#define WM2200_IN_VU 0x0200 /* IN_VU */
950#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
951#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
952#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
953#define WM2200_IN3L_MUTE 0x0100 /* IN3L_MUTE */
954#define WM2200_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
955#define WM2200_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
956#define WM2200_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
957#define WM2200_IN3L_DIG_VOL_MASK 0x00FF /* IN3L_DIG_VOL - [7:0] */
958#define WM2200_IN3L_DIG_VOL_SHIFT 0 /* IN3L_DIG_VOL - [7:0] */
959#define WM2200_IN3L_DIG_VOL_WIDTH 8 /* IN3L_DIG_VOL - [7:0] */
960
961/*
962 * R785 (0x311) - ADC Digital Volume 3R
963 */
964#define WM2200_IN_VU 0x0200 /* IN_VU */
965#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
966#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
967#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
968#define WM2200_IN3R_MUTE 0x0100 /* IN3R_MUTE */
969#define WM2200_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
970#define WM2200_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
971#define WM2200_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
972#define WM2200_IN3R_DIG_VOL_MASK 0x00FF /* IN3R_DIG_VOL - [7:0] */
973#define WM2200_IN3R_DIG_VOL_SHIFT 0 /* IN3R_DIG_VOL - [7:0] */
974#define WM2200_IN3R_DIG_VOL_WIDTH 8 /* IN3R_DIG_VOL - [7:0] */
975
976/*
977 * R1024 (0x400) - Output Enables
978 */
979#define WM2200_OUT2L_ENA 0x0008 /* OUT2L_ENA */
980#define WM2200_OUT2L_ENA_MASK 0x0008 /* OUT2L_ENA */
981#define WM2200_OUT2L_ENA_SHIFT 3 /* OUT2L_ENA */
982#define WM2200_OUT2L_ENA_WIDTH 1 /* OUT2L_ENA */
983#define WM2200_OUT2R_ENA 0x0004 /* OUT2R_ENA */
984#define WM2200_OUT2R_ENA_MASK 0x0004 /* OUT2R_ENA */
985#define WM2200_OUT2R_ENA_SHIFT 2 /* OUT2R_ENA */
986#define WM2200_OUT2R_ENA_WIDTH 1 /* OUT2R_ENA */
987#define WM2200_OUT1L_ENA 0x0002 /* OUT1L_ENA */
988#define WM2200_OUT1L_ENA_MASK 0x0002 /* OUT1L_ENA */
989#define WM2200_OUT1L_ENA_SHIFT 1 /* OUT1L_ENA */
990#define WM2200_OUT1L_ENA_WIDTH 1 /* OUT1L_ENA */
991#define WM2200_OUT1R_ENA 0x0001 /* OUT1R_ENA */
992#define WM2200_OUT1R_ENA_MASK 0x0001 /* OUT1R_ENA */
993#define WM2200_OUT1R_ENA_SHIFT 0 /* OUT1R_ENA */
994#define WM2200_OUT1R_ENA_WIDTH 1 /* OUT1R_ENA */
995
996/*
997 * R1025 (0x401) - DAC Volume Limit 1L
998 */
999#define WM2200_OUT1_OSR 0x2000 /* OUT1_OSR */
1000#define WM2200_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
1001#define WM2200_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
1002#define WM2200_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
1003#define WM2200_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
1004#define WM2200_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
1005#define WM2200_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
1006#define WM2200_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
1007#define WM2200_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
1008#define WM2200_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
1009#define WM2200_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
1010
1011/*
1012 * R1026 (0x402) - DAC Volume Limit 1R
1013 */
1014#define WM2200_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
1015#define WM2200_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
1016#define WM2200_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
1017#define WM2200_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
1018#define WM2200_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
1019#define WM2200_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
1020#define WM2200_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
1021
1022/*
1023 * R1027 (0x403) - DAC Volume Limit 2L
1024 */
1025#define WM2200_OUT2_OSR 0x2000 /* OUT2_OSR */
1026#define WM2200_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
1027#define WM2200_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
1028#define WM2200_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
1029#define WM2200_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
1030#define WM2200_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
1031#define WM2200_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
1032#define WM2200_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
1033
1034/*
1035 * R1028 (0x404) - DAC Volume Limit 2R
1036 */
1037#define WM2200_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
1038#define WM2200_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
1039#define WM2200_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
1040#define WM2200_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
1041
1042/*
1043 * R1033 (0x409) - DAC AEC Control 1
1044 */
1045#define WM2200_AEC_LOOPBACK_ENA 0x0004 /* AEC_LOOPBACK_ENA */
1046#define WM2200_AEC_LOOPBACK_ENA_MASK 0x0004 /* AEC_LOOPBACK_ENA */
1047#define WM2200_AEC_LOOPBACK_ENA_SHIFT 2 /* AEC_LOOPBACK_ENA */
1048#define WM2200_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
1049#define WM2200_AEC_LOOPBACK_SRC_MASK 0x0003 /* AEC_LOOPBACK_SRC - [1:0] */
1050#define WM2200_AEC_LOOPBACK_SRC_SHIFT 0 /* AEC_LOOPBACK_SRC - [1:0] */
1051#define WM2200_AEC_LOOPBACK_SRC_WIDTH 2 /* AEC_LOOPBACK_SRC - [1:0] */
1052
1053/*
1054 * R1034 (0x40A) - Output Volume Ramp
1055 */
1056#define WM2200_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
1057#define WM2200_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
1058#define WM2200_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
1059#define WM2200_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
1060#define WM2200_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
1061#define WM2200_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
1062
1063/*
1064 * R1035 (0x40B) - DAC Digital Volume 1L
1065 */
1066#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1067#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1068#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1069#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1070#define WM2200_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
1071#define WM2200_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
1072#define WM2200_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
1073#define WM2200_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
1074#define WM2200_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
1075#define WM2200_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
1076#define WM2200_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
1077
1078/*
1079 * R1036 (0x40C) - DAC Digital Volume 1R
1080 */
1081#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1082#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1083#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1084#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1085#define WM2200_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
1086#define WM2200_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
1087#define WM2200_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
1088#define WM2200_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
1089#define WM2200_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
1090#define WM2200_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
1091#define WM2200_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
1092
1093/*
1094 * R1037 (0x40D) - DAC Digital Volume 2L
1095 */
1096#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1097#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1098#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1099#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1100#define WM2200_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
1101#define WM2200_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
1102#define WM2200_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
1103#define WM2200_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
1104#define WM2200_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
1105#define WM2200_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
1106#define WM2200_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
1107
1108/*
1109 * R1038 (0x40E) - DAC Digital Volume 2R
1110 */
1111#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1112#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1113#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1114#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1115#define WM2200_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
1116#define WM2200_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
1117#define WM2200_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
1118#define WM2200_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
1119#define WM2200_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
1120#define WM2200_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
1121#define WM2200_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
1122
1123/*
1124 * R1047 (0x417) - PDM 1
1125 */
1126#define WM2200_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
1127#define WM2200_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
1128#define WM2200_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
1129#define WM2200_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
1130#define WM2200_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
1131#define WM2200_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
1132#define WM2200_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
1133#define WM2200_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
1134#define WM2200_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
1135#define WM2200_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
1136#define WM2200_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
1137#define WM2200_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
1138#define WM2200_SPK1_MUTE_SEQL_MASK 0x00FF /* SPK1_MUTE_SEQL - [7:0] */
1139#define WM2200_SPK1_MUTE_SEQL_SHIFT 0 /* SPK1_MUTE_SEQL - [7:0] */
1140#define WM2200_SPK1_MUTE_SEQL_WIDTH 8 /* SPK1_MUTE_SEQL - [7:0] */
1141
1142/*
1143 * R1048 (0x418) - PDM 2
1144 */
1145#define WM2200_SPK1_FMT 0x0001 /* SPK1_FMT */
1146#define WM2200_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
1147#define WM2200_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
1148#define WM2200_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
1149
1150/*
1151 * R1280 (0x500) - Audio IF 1_1
1152 */
1153#define WM2200_AIF1_BCLK_INV 0x0040 /* AIF1_BCLK_INV */
1154#define WM2200_AIF1_BCLK_INV_MASK 0x0040 /* AIF1_BCLK_INV */
1155#define WM2200_AIF1_BCLK_INV_SHIFT 6 /* AIF1_BCLK_INV */
1156#define WM2200_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1157#define WM2200_AIF1_BCLK_FRC 0x0020 /* AIF1_BCLK_FRC */
1158#define WM2200_AIF1_BCLK_FRC_MASK 0x0020 /* AIF1_BCLK_FRC */
1159#define WM2200_AIF1_BCLK_FRC_SHIFT 5 /* AIF1_BCLK_FRC */
1160#define WM2200_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1161#define WM2200_AIF1_BCLK_MSTR 0x0010 /* AIF1_BCLK_MSTR */
1162#define WM2200_AIF1_BCLK_MSTR_MASK 0x0010 /* AIF1_BCLK_MSTR */
1163#define WM2200_AIF1_BCLK_MSTR_SHIFT 4 /* AIF1_BCLK_MSTR */
1164#define WM2200_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1165#define WM2200_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1166#define WM2200_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1167#define WM2200_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1168
1169/*
1170 * R1281 (0x501) - Audio IF 1_2
1171 */
1172#define WM2200_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
1173#define WM2200_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
1174#define WM2200_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
1175#define WM2200_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1176#define WM2200_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
1177#define WM2200_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
1178#define WM2200_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
1179#define WM2200_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
1180#define WM2200_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1181#define WM2200_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1182#define WM2200_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1183#define WM2200_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1184#define WM2200_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1185#define WM2200_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1186#define WM2200_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1187#define WM2200_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1188#define WM2200_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1189#define WM2200_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1190#define WM2200_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1191#define WM2200_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1192
1193/*
1194 * R1282 (0x502) - Audio IF 1_3
1195 */
1196#define WM2200_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1197#define WM2200_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1198#define WM2200_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1199#define WM2200_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1200#define WM2200_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1201#define WM2200_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1202#define WM2200_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1203#define WM2200_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1204#define WM2200_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1205#define WM2200_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1206#define WM2200_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1207#define WM2200_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1208
1209/*
1210 * R1283 (0x503) - Audio IF 1_4
1211 */
1212#define WM2200_AIF1_TRI 0x0040 /* AIF1_TRI */
1213#define WM2200_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
1214#define WM2200_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
1215#define WM2200_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1216
1217/*
1218 * R1284 (0x504) - Audio IF 1_5
1219 */
1220#define WM2200_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
1221#define WM2200_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
1222#define WM2200_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
1223
1224/*
1225 * R1285 (0x505) - Audio IF 1_6
1226 */
1227#define WM2200_AIF1TX_BCPF_MASK 0x07FF /* AIF1TX_BCPF - [10:0] */
1228#define WM2200_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [10:0] */
1229#define WM2200_AIF1TX_BCPF_WIDTH 11 /* AIF1TX_BCPF - [10:0] */
1230
1231/*
1232 * R1286 (0x506) - Audio IF 1_7
1233 */
1234#define WM2200_AIF1RX_BCPF_MASK 0x07FF /* AIF1RX_BCPF - [10:0] */
1235#define WM2200_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [10:0] */
1236#define WM2200_AIF1RX_BCPF_WIDTH 11 /* AIF1RX_BCPF - [10:0] */
1237
1238/*
1239 * R1287 (0x507) - Audio IF 1_8
1240 */
1241#define WM2200_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
1242#define WM2200_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
1243#define WM2200_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
1244#define WM2200_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1245#define WM2200_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1246#define WM2200_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1247
1248/*
1249 * R1288 (0x508) - Audio IF 1_9
1250 */
1251#define WM2200_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
1252#define WM2200_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
1253#define WM2200_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
1254#define WM2200_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1255#define WM2200_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1256#define WM2200_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1257
1258/*
1259 * R1289 (0x509) - Audio IF 1_10
1260 */
1261#define WM2200_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
1262#define WM2200_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
1263#define WM2200_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
1264
1265/*
1266 * R1290 (0x50A) - Audio IF 1_11
1267 */
1268#define WM2200_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
1269#define WM2200_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
1270#define WM2200_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
1271
1272/*
1273 * R1291 (0x50B) - Audio IF 1_12
1274 */
1275#define WM2200_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
1276#define WM2200_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
1277#define WM2200_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
1278
1279/*
1280 * R1292 (0x50C) - Audio IF 1_13
1281 */
1282#define WM2200_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
1283#define WM2200_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
1284#define WM2200_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
1285
1286/*
1287 * R1293 (0x50D) - Audio IF 1_14
1288 */
1289#define WM2200_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
1290#define WM2200_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
1291#define WM2200_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
1292
1293/*
1294 * R1294 (0x50E) - Audio IF 1_15
1295 */
1296#define WM2200_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
1297#define WM2200_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
1298#define WM2200_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
1299
1300/*
1301 * R1295 (0x50F) - Audio IF 1_16
1302 */
1303#define WM2200_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
1304#define WM2200_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
1305#define WM2200_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
1306
1307/*
1308 * R1296 (0x510) - Audio IF 1_17
1309 */
1310#define WM2200_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
1311#define WM2200_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
1312#define WM2200_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
1313
1314/*
1315 * R1297 (0x511) - Audio IF 1_18
1316 */
1317#define WM2200_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
1318#define WM2200_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
1319#define WM2200_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
1320
1321/*
1322 * R1298 (0x512) - Audio IF 1_19
1323 */
1324#define WM2200_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
1325#define WM2200_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
1326#define WM2200_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
1327
1328/*
1329 * R1299 (0x513) - Audio IF 1_20
1330 */
1331#define WM2200_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
1332#define WM2200_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
1333#define WM2200_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
1334
1335/*
1336 * R1300 (0x514) - Audio IF 1_21
1337 */
1338#define WM2200_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
1339#define WM2200_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
1340#define WM2200_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
1341
1342/*
1343 * R1301 (0x515) - Audio IF 1_22
1344 */
1345#define WM2200_AIF1RX6_ENA 0x0800 /* AIF1RX6_ENA */
1346#define WM2200_AIF1RX6_ENA_MASK 0x0800 /* AIF1RX6_ENA */
1347#define WM2200_AIF1RX6_ENA_SHIFT 11 /* AIF1RX6_ENA */
1348#define WM2200_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
1349#define WM2200_AIF1RX5_ENA 0x0400 /* AIF1RX5_ENA */
1350#define WM2200_AIF1RX5_ENA_MASK 0x0400 /* AIF1RX5_ENA */
1351#define WM2200_AIF1RX5_ENA_SHIFT 10 /* AIF1RX5_ENA */
1352#define WM2200_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
1353#define WM2200_AIF1RX4_ENA 0x0200 /* AIF1RX4_ENA */
1354#define WM2200_AIF1RX4_ENA_MASK 0x0200 /* AIF1RX4_ENA */
1355#define WM2200_AIF1RX4_ENA_SHIFT 9 /* AIF1RX4_ENA */
1356#define WM2200_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
1357#define WM2200_AIF1RX3_ENA 0x0100 /* AIF1RX3_ENA */
1358#define WM2200_AIF1RX3_ENA_MASK 0x0100 /* AIF1RX3_ENA */
1359#define WM2200_AIF1RX3_ENA_SHIFT 8 /* AIF1RX3_ENA */
1360#define WM2200_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
1361#define WM2200_AIF1RX2_ENA 0x0080 /* AIF1RX2_ENA */
1362#define WM2200_AIF1RX2_ENA_MASK 0x0080 /* AIF1RX2_ENA */
1363#define WM2200_AIF1RX2_ENA_SHIFT 7 /* AIF1RX2_ENA */
1364#define WM2200_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
1365#define WM2200_AIF1RX1_ENA 0x0040 /* AIF1RX1_ENA */
1366#define WM2200_AIF1RX1_ENA_MASK 0x0040 /* AIF1RX1_ENA */
1367#define WM2200_AIF1RX1_ENA_SHIFT 6 /* AIF1RX1_ENA */
1368#define WM2200_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
1369#define WM2200_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
1370#define WM2200_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
1371#define WM2200_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
1372#define WM2200_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
1373#define WM2200_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
1374#define WM2200_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
1375#define WM2200_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
1376#define WM2200_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
1377#define WM2200_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
1378#define WM2200_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
1379#define WM2200_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
1380#define WM2200_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
1381#define WM2200_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
1382#define WM2200_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
1383#define WM2200_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
1384#define WM2200_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
1385#define WM2200_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
1386#define WM2200_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
1387#define WM2200_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
1388#define WM2200_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
1389#define WM2200_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
1390#define WM2200_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
1391#define WM2200_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
1392#define WM2200_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
1393
1394/*
1395 * R1536 (0x600) - OUT1LMIX Input 1 Source
1396 */
1397#define WM2200_OUT1LMIX_SRC1_MASK 0x007F /* OUT1LMIX_SRC1 - [6:0] */
1398#define WM2200_OUT1LMIX_SRC1_SHIFT 0 /* OUT1LMIX_SRC1 - [6:0] */
1399#define WM2200_OUT1LMIX_SRC1_WIDTH 7 /* OUT1LMIX_SRC1 - [6:0] */
1400
1401/*
1402 * R1537 (0x601) - OUT1LMIX Input 1 Volume
1403 */
1404#define WM2200_OUT1LMIX_VOL1_MASK 0x00FE /* OUT1LMIX_VOL1 - [7:1] */
1405#define WM2200_OUT1LMIX_VOL1_SHIFT 1 /* OUT1LMIX_VOL1 - [7:1] */
1406#define WM2200_OUT1LMIX_VOL1_WIDTH 7 /* OUT1LMIX_VOL1 - [7:1] */
1407
1408/*
1409 * R1538 (0x602) - OUT1LMIX Input 2 Source
1410 */
1411#define WM2200_OUT1LMIX_SRC2_MASK 0x007F /* OUT1LMIX_SRC2 - [6:0] */
1412#define WM2200_OUT1LMIX_SRC2_SHIFT 0 /* OUT1LMIX_SRC2 - [6:0] */
1413#define WM2200_OUT1LMIX_SRC2_WIDTH 7 /* OUT1LMIX_SRC2 - [6:0] */
1414
1415/*
1416 * R1539 (0x603) - OUT1LMIX Input 2 Volume
1417 */
1418#define WM2200_OUT1LMIX_VOL2_MASK 0x00FE /* OUT1LMIX_VOL2 - [7:1] */
1419#define WM2200_OUT1LMIX_VOL2_SHIFT 1 /* OUT1LMIX_VOL2 - [7:1] */
1420#define WM2200_OUT1LMIX_VOL2_WIDTH 7 /* OUT1LMIX_VOL2 - [7:1] */
1421
1422/*
1423 * R1540 (0x604) - OUT1LMIX Input 3 Source
1424 */
1425#define WM2200_OUT1LMIX_SRC3_MASK 0x007F /* OUT1LMIX_SRC3 - [6:0] */
1426#define WM2200_OUT1LMIX_SRC3_SHIFT 0 /* OUT1LMIX_SRC3 - [6:0] */
1427#define WM2200_OUT1LMIX_SRC3_WIDTH 7 /* OUT1LMIX_SRC3 - [6:0] */
1428
1429/*
1430 * R1541 (0x605) - OUT1LMIX Input 3 Volume
1431 */
1432#define WM2200_OUT1LMIX_VOL3_MASK 0x00FE /* OUT1LMIX_VOL3 - [7:1] */
1433#define WM2200_OUT1LMIX_VOL3_SHIFT 1 /* OUT1LMIX_VOL3 - [7:1] */
1434#define WM2200_OUT1LMIX_VOL3_WIDTH 7 /* OUT1LMIX_VOL3 - [7:1] */
1435
1436/*
1437 * R1542 (0x606) - OUT1LMIX Input 4 Source
1438 */
1439#define WM2200_OUT1LMIX_SRC4_MASK 0x007F /* OUT1LMIX_SRC4 - [6:0] */
1440#define WM2200_OUT1LMIX_SRC4_SHIFT 0 /* OUT1LMIX_SRC4 - [6:0] */
1441#define WM2200_OUT1LMIX_SRC4_WIDTH 7 /* OUT1LMIX_SRC4 - [6:0] */
1442
1443/*
1444 * R1543 (0x607) - OUT1LMIX Input 4 Volume
1445 */
1446#define WM2200_OUT1LMIX_VOL4_MASK 0x00FE /* OUT1LMIX_VOL4 - [7:1] */
1447#define WM2200_OUT1LMIX_VOL4_SHIFT 1 /* OUT1LMIX_VOL4 - [7:1] */
1448#define WM2200_OUT1LMIX_VOL4_WIDTH 7 /* OUT1LMIX_VOL4 - [7:1] */
1449
1450/*
1451 * R1544 (0x608) - OUT1RMIX Input 1 Source
1452 */
1453#define WM2200_OUT1RMIX_SRC1_MASK 0x007F /* OUT1RMIX_SRC1 - [6:0] */
1454#define WM2200_OUT1RMIX_SRC1_SHIFT 0 /* OUT1RMIX_SRC1 - [6:0] */
1455#define WM2200_OUT1RMIX_SRC1_WIDTH 7 /* OUT1RMIX_SRC1 - [6:0] */
1456
1457/*
1458 * R1545 (0x609) - OUT1RMIX Input 1 Volume
1459 */
1460#define WM2200_OUT1RMIX_VOL1_MASK 0x00FE /* OUT1RMIX_VOL1 - [7:1] */
1461#define WM2200_OUT1RMIX_VOL1_SHIFT 1 /* OUT1RMIX_VOL1 - [7:1] */
1462#define WM2200_OUT1RMIX_VOL1_WIDTH 7 /* OUT1RMIX_VOL1 - [7:1] */
1463
1464/*
1465 * R1546 (0x60A) - OUT1RMIX Input 2 Source
1466 */
1467#define WM2200_OUT1RMIX_SRC2_MASK 0x007F /* OUT1RMIX_SRC2 - [6:0] */
1468#define WM2200_OUT1RMIX_SRC2_SHIFT 0 /* OUT1RMIX_SRC2 - [6:0] */
1469#define WM2200_OUT1RMIX_SRC2_WIDTH 7 /* OUT1RMIX_SRC2 - [6:0] */
1470
1471/*
1472 * R1547 (0x60B) - OUT1RMIX Input 2 Volume
1473 */
1474#define WM2200_OUT1RMIX_VOL2_MASK 0x00FE /* OUT1RMIX_VOL2 - [7:1] */
1475#define WM2200_OUT1RMIX_VOL2_SHIFT 1 /* OUT1RMIX_VOL2 - [7:1] */
1476#define WM2200_OUT1RMIX_VOL2_WIDTH 7 /* OUT1RMIX_VOL2 - [7:1] */
1477
1478/*
1479 * R1548 (0x60C) - OUT1RMIX Input 3 Source
1480 */
1481#define WM2200_OUT1RMIX_SRC3_MASK 0x007F /* OUT1RMIX_SRC3 - [6:0] */
1482#define WM2200_OUT1RMIX_SRC3_SHIFT 0 /* OUT1RMIX_SRC3 - [6:0] */
1483#define WM2200_OUT1RMIX_SRC3_WIDTH 7 /* OUT1RMIX_SRC3 - [6:0] */
1484
1485/*
1486 * R1549 (0x60D) - OUT1RMIX Input 3 Volume
1487 */
1488#define WM2200_OUT1RMIX_VOL3_MASK 0x00FE /* OUT1RMIX_VOL3 - [7:1] */
1489#define WM2200_OUT1RMIX_VOL3_SHIFT 1 /* OUT1RMIX_VOL3 - [7:1] */
1490#define WM2200_OUT1RMIX_VOL3_WIDTH 7 /* OUT1RMIX_VOL3 - [7:1] */
1491
1492/*
1493 * R1550 (0x60E) - OUT1RMIX Input 4 Source
1494 */
1495#define WM2200_OUT1RMIX_SRC4_MASK 0x007F /* OUT1RMIX_SRC4 - [6:0] */
1496#define WM2200_OUT1RMIX_SRC4_SHIFT 0 /* OUT1RMIX_SRC4 - [6:0] */
1497#define WM2200_OUT1RMIX_SRC4_WIDTH 7 /* OUT1RMIX_SRC4 - [6:0] */
1498
1499/*
1500 * R1551 (0x60F) - OUT1RMIX Input 4 Volume
1501 */
1502#define WM2200_OUT1RMIX_VOL4_MASK 0x00FE /* OUT1RMIX_VOL4 - [7:1] */
1503#define WM2200_OUT1RMIX_VOL4_SHIFT 1 /* OUT1RMIX_VOL4 - [7:1] */
1504#define WM2200_OUT1RMIX_VOL4_WIDTH 7 /* OUT1RMIX_VOL4 - [7:1] */
1505
1506/*
1507 * R1552 (0x610) - OUT2LMIX Input 1 Source
1508 */
1509#define WM2200_OUT2LMIX_SRC1_MASK 0x007F /* OUT2LMIX_SRC1 - [6:0] */
1510#define WM2200_OUT2LMIX_SRC1_SHIFT 0 /* OUT2LMIX_SRC1 - [6:0] */
1511#define WM2200_OUT2LMIX_SRC1_WIDTH 7 /* OUT2LMIX_SRC1 - [6:0] */
1512
1513/*
1514 * R1553 (0x611) - OUT2LMIX Input 1 Volume
1515 */
1516#define WM2200_OUT2LMIX_VOL1_MASK 0x00FE /* OUT2LMIX_VOL1 - [7:1] */
1517#define WM2200_OUT2LMIX_VOL1_SHIFT 1 /* OUT2LMIX_VOL1 - [7:1] */
1518#define WM2200_OUT2LMIX_VOL1_WIDTH 7 /* OUT2LMIX_VOL1 - [7:1] */
1519
1520/*
1521 * R1554 (0x612) - OUT2LMIX Input 2 Source
1522 */
1523#define WM2200_OUT2LMIX_SRC2_MASK 0x007F /* OUT2LMIX_SRC2 - [6:0] */
1524#define WM2200_OUT2LMIX_SRC2_SHIFT 0 /* OUT2LMIX_SRC2 - [6:0] */
1525#define WM2200_OUT2LMIX_SRC2_WIDTH 7 /* OUT2LMIX_SRC2 - [6:0] */
1526
1527/*
1528 * R1555 (0x613) - OUT2LMIX Input 2 Volume
1529 */
1530#define WM2200_OUT2LMIX_VOL2_MASK 0x00FE /* OUT2LMIX_VOL2 - [7:1] */
1531#define WM2200_OUT2LMIX_VOL2_SHIFT 1 /* OUT2LMIX_VOL2 - [7:1] */
1532#define WM2200_OUT2LMIX_VOL2_WIDTH 7 /* OUT2LMIX_VOL2 - [7:1] */
1533
1534/*
1535 * R1556 (0x614) - OUT2LMIX Input 3 Source
1536 */
1537#define WM2200_OUT2LMIX_SRC3_MASK 0x007F /* OUT2LMIX_SRC3 - [6:0] */
1538#define WM2200_OUT2LMIX_SRC3_SHIFT 0 /* OUT2LMIX_SRC3 - [6:0] */
1539#define WM2200_OUT2LMIX_SRC3_WIDTH 7 /* OUT2LMIX_SRC3 - [6:0] */
1540
1541/*
1542 * R1557 (0x615) - OUT2LMIX Input 3 Volume
1543 */
1544#define WM2200_OUT2LMIX_VOL3_MASK 0x00FE /* OUT2LMIX_VOL3 - [7:1] */
1545#define WM2200_OUT2LMIX_VOL3_SHIFT 1 /* OUT2LMIX_VOL3 - [7:1] */
1546#define WM2200_OUT2LMIX_VOL3_WIDTH 7 /* OUT2LMIX_VOL3 - [7:1] */
1547
1548/*
1549 * R1558 (0x616) - OUT2LMIX Input 4 Source
1550 */
1551#define WM2200_OUT2LMIX_SRC4_MASK 0x007F /* OUT2LMIX_SRC4 - [6:0] */
1552#define WM2200_OUT2LMIX_SRC4_SHIFT 0 /* OUT2LMIX_SRC4 - [6:0] */
1553#define WM2200_OUT2LMIX_SRC4_WIDTH 7 /* OUT2LMIX_SRC4 - [6:0] */
1554
1555/*
1556 * R1559 (0x617) - OUT2LMIX Input 4 Volume
1557 */
1558#define WM2200_OUT2LMIX_VOL4_MASK 0x00FE /* OUT2LMIX_VOL4 - [7:1] */
1559#define WM2200_OUT2LMIX_VOL4_SHIFT 1 /* OUT2LMIX_VOL4 - [7:1] */
1560#define WM2200_OUT2LMIX_VOL4_WIDTH 7 /* OUT2LMIX_VOL4 - [7:1] */
1561
1562/*
1563 * R1560 (0x618) - OUT2RMIX Input 1 Source
1564 */
1565#define WM2200_OUT2RMIX_SRC1_MASK 0x007F /* OUT2RMIX_SRC1 - [6:0] */
1566#define WM2200_OUT2RMIX_SRC1_SHIFT 0 /* OUT2RMIX_SRC1 - [6:0] */
1567#define WM2200_OUT2RMIX_SRC1_WIDTH 7 /* OUT2RMIX_SRC1 - [6:0] */
1568
1569/*
1570 * R1561 (0x619) - OUT2RMIX Input 1 Volume
1571 */
1572#define WM2200_OUT2RMIX_VOL1_MASK 0x00FE /* OUT2RMIX_VOL1 - [7:1] */
1573#define WM2200_OUT2RMIX_VOL1_SHIFT 1 /* OUT2RMIX_VOL1 - [7:1] */
1574#define WM2200_OUT2RMIX_VOL1_WIDTH 7 /* OUT2RMIX_VOL1 - [7:1] */
1575
1576/*
1577 * R1562 (0x61A) - OUT2RMIX Input 2 Source
1578 */
1579#define WM2200_OUT2RMIX_SRC2_MASK 0x007F /* OUT2RMIX_SRC2 - [6:0] */
1580#define WM2200_OUT2RMIX_SRC2_SHIFT 0 /* OUT2RMIX_SRC2 - [6:0] */
1581#define WM2200_OUT2RMIX_SRC2_WIDTH 7 /* OUT2RMIX_SRC2 - [6:0] */
1582
1583/*
1584 * R1563 (0x61B) - OUT2RMIX Input 2 Volume
1585 */
1586#define WM2200_OUT2RMIX_VOL2_MASK 0x00FE /* OUT2RMIX_VOL2 - [7:1] */
1587#define WM2200_OUT2RMIX_VOL2_SHIFT 1 /* OUT2RMIX_VOL2 - [7:1] */
1588#define WM2200_OUT2RMIX_VOL2_WIDTH 7 /* OUT2RMIX_VOL2 - [7:1] */
1589
1590/*
1591 * R1564 (0x61C) - OUT2RMIX Input 3 Source
1592 */
1593#define WM2200_OUT2RMIX_SRC3_MASK 0x007F /* OUT2RMIX_SRC3 - [6:0] */
1594#define WM2200_OUT2RMIX_SRC3_SHIFT 0 /* OUT2RMIX_SRC3 - [6:0] */
1595#define WM2200_OUT2RMIX_SRC3_WIDTH 7 /* OUT2RMIX_SRC3 - [6:0] */
1596
1597/*
1598 * R1565 (0x61D) - OUT2RMIX Input 3 Volume
1599 */
1600#define WM2200_OUT2RMIX_VOL3_MASK 0x00FE /* OUT2RMIX_VOL3 - [7:1] */
1601#define WM2200_OUT2RMIX_VOL3_SHIFT 1 /* OUT2RMIX_VOL3 - [7:1] */
1602#define WM2200_OUT2RMIX_VOL3_WIDTH 7 /* OUT2RMIX_VOL3 - [7:1] */
1603
1604/*
1605 * R1566 (0x61E) - OUT2RMIX Input 4 Source
1606 */
1607#define WM2200_OUT2RMIX_SRC4_MASK 0x007F /* OUT2RMIX_SRC4 - [6:0] */
1608#define WM2200_OUT2RMIX_SRC4_SHIFT 0 /* OUT2RMIX_SRC4 - [6:0] */
1609#define WM2200_OUT2RMIX_SRC4_WIDTH 7 /* OUT2RMIX_SRC4 - [6:0] */
1610
1611/*
1612 * R1567 (0x61F) - OUT2RMIX Input 4 Volume
1613 */
1614#define WM2200_OUT2RMIX_VOL4_MASK 0x00FE /* OUT2RMIX_VOL4 - [7:1] */
1615#define WM2200_OUT2RMIX_VOL4_SHIFT 1 /* OUT2RMIX_VOL4 - [7:1] */
1616#define WM2200_OUT2RMIX_VOL4_WIDTH 7 /* OUT2RMIX_VOL4 - [7:1] */
1617
1618/*
1619 * R1568 (0x620) - AIF1TX1MIX Input 1 Source
1620 */
1621#define WM2200_AIF1TX1MIX_SRC1_MASK 0x007F /* AIF1TX1MIX_SRC1 - [6:0] */
1622#define WM2200_AIF1TX1MIX_SRC1_SHIFT 0 /* AIF1TX1MIX_SRC1 - [6:0] */
1623#define WM2200_AIF1TX1MIX_SRC1_WIDTH 7 /* AIF1TX1MIX_SRC1 - [6:0] */
1624
1625/*
1626 * R1569 (0x621) - AIF1TX1MIX Input 1 Volume
1627 */
1628#define WM2200_AIF1TX1MIX_VOL1_MASK 0x00FE /* AIF1TX1MIX_VOL1 - [7:1] */
1629#define WM2200_AIF1TX1MIX_VOL1_SHIFT 1 /* AIF1TX1MIX_VOL1 - [7:1] */
1630#define WM2200_AIF1TX1MIX_VOL1_WIDTH 7 /* AIF1TX1MIX_VOL1 - [7:1] */
1631
1632/*
1633 * R1570 (0x622) - AIF1TX1MIX Input 2 Source
1634 */
1635#define WM2200_AIF1TX1MIX_SRC2_MASK 0x007F /* AIF1TX1MIX_SRC2 - [6:0] */
1636#define WM2200_AIF1TX1MIX_SRC2_SHIFT 0 /* AIF1TX1MIX_SRC2 - [6:0] */
1637#define WM2200_AIF1TX1MIX_SRC2_WIDTH 7 /* AIF1TX1MIX_SRC2 - [6:0] */
1638
1639/*
1640 * R1571 (0x623) - AIF1TX1MIX Input 2 Volume
1641 */
1642#define WM2200_AIF1TX1MIX_VOL2_MASK 0x00FE /* AIF1TX1MIX_VOL2 - [7:1] */
1643#define WM2200_AIF1TX1MIX_VOL2_SHIFT 1 /* AIF1TX1MIX_VOL2 - [7:1] */
1644#define WM2200_AIF1TX1MIX_VOL2_WIDTH 7 /* AIF1TX1MIX_VOL2 - [7:1] */
1645
1646/*
1647 * R1572 (0x624) - AIF1TX1MIX Input 3 Source
1648 */
1649#define WM2200_AIF1TX1MIX_SRC3_MASK 0x007F /* AIF1TX1MIX_SRC3 - [6:0] */
1650#define WM2200_AIF1TX1MIX_SRC3_SHIFT 0 /* AIF1TX1MIX_SRC3 - [6:0] */
1651#define WM2200_AIF1TX1MIX_SRC3_WIDTH 7 /* AIF1TX1MIX_SRC3 - [6:0] */
1652
1653/*
1654 * R1573 (0x625) - AIF1TX1MIX Input 3 Volume
1655 */
1656#define WM2200_AIF1TX1MIX_VOL3_MASK 0x00FE /* AIF1TX1MIX_VOL3 - [7:1] */
1657#define WM2200_AIF1TX1MIX_VOL3_SHIFT 1 /* AIF1TX1MIX_VOL3 - [7:1] */
1658#define WM2200_AIF1TX1MIX_VOL3_WIDTH 7 /* AIF1TX1MIX_VOL3 - [7:1] */
1659
1660/*
1661 * R1574 (0x626) - AIF1TX1MIX Input 4 Source
1662 */
1663#define WM2200_AIF1TX1MIX_SRC4_MASK 0x007F /* AIF1TX1MIX_SRC4 - [6:0] */
1664#define WM2200_AIF1TX1MIX_SRC4_SHIFT 0 /* AIF1TX1MIX_SRC4 - [6:0] */
1665#define WM2200_AIF1TX1MIX_SRC4_WIDTH 7 /* AIF1TX1MIX_SRC4 - [6:0] */
1666
1667/*
1668 * R1575 (0x627) - AIF1TX1MIX Input 4 Volume
1669 */
1670#define WM2200_AIF1TX1MIX_VOL4_MASK 0x00FE /* AIF1TX1MIX_VOL4 - [7:1] */
1671#define WM2200_AIF1TX1MIX_VOL4_SHIFT 1 /* AIF1TX1MIX_VOL4 - [7:1] */
1672#define WM2200_AIF1TX1MIX_VOL4_WIDTH 7 /* AIF1TX1MIX_VOL4 - [7:1] */
1673
1674/*
1675 * R1576 (0x628) - AIF1TX2MIX Input 1 Source
1676 */
1677#define WM2200_AIF1TX2MIX_SRC1_MASK 0x007F /* AIF1TX2MIX_SRC1 - [6:0] */
1678#define WM2200_AIF1TX2MIX_SRC1_SHIFT 0 /* AIF1TX2MIX_SRC1 - [6:0] */
1679#define WM2200_AIF1TX2MIX_SRC1_WIDTH 7 /* AIF1TX2MIX_SRC1 - [6:0] */
1680
1681/*
1682 * R1577 (0x629) - AIF1TX2MIX Input 1 Volume
1683 */
1684#define WM2200_AIF1TX2MIX_VOL1_MASK 0x00FE /* AIF1TX2MIX_VOL1 - [7:1] */
1685#define WM2200_AIF1TX2MIX_VOL1_SHIFT 1 /* AIF1TX2MIX_VOL1 - [7:1] */
1686#define WM2200_AIF1TX2MIX_VOL1_WIDTH 7 /* AIF1TX2MIX_VOL1 - [7:1] */
1687
1688/*
1689 * R1578 (0x62A) - AIF1TX2MIX Input 2 Source
1690 */
1691#define WM2200_AIF1TX2MIX_SRC2_MASK 0x007F /* AIF1TX2MIX_SRC2 - [6:0] */
1692#define WM2200_AIF1TX2MIX_SRC2_SHIFT 0 /* AIF1TX2MIX_SRC2 - [6:0] */
1693#define WM2200_AIF1TX2MIX_SRC2_WIDTH 7 /* AIF1TX2MIX_SRC2 - [6:0] */
1694
1695/*
1696 * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume
1697 */
1698#define WM2200_AIF1TX2MIX_VOL2_MASK 0x00FE /* AIF1TX2MIX_VOL2 - [7:1] */
1699#define WM2200_AIF1TX2MIX_VOL2_SHIFT 1 /* AIF1TX2MIX_VOL2 - [7:1] */
1700#define WM2200_AIF1TX2MIX_VOL2_WIDTH 7 /* AIF1TX2MIX_VOL2 - [7:1] */
1701
1702/*
1703 * R1580 (0x62C) - AIF1TX2MIX Input 3 Source
1704 */
1705#define WM2200_AIF1TX2MIX_SRC3_MASK 0x007F /* AIF1TX2MIX_SRC3 - [6:0] */
1706#define WM2200_AIF1TX2MIX_SRC3_SHIFT 0 /* AIF1TX2MIX_SRC3 - [6:0] */
1707#define WM2200_AIF1TX2MIX_SRC3_WIDTH 7 /* AIF1TX2MIX_SRC3 - [6:0] */
1708
1709/*
1710 * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume
1711 */
1712#define WM2200_AIF1TX2MIX_VOL3_MASK 0x00FE /* AIF1TX2MIX_VOL3 - [7:1] */
1713#define WM2200_AIF1TX2MIX_VOL3_SHIFT 1 /* AIF1TX2MIX_VOL3 - [7:1] */
1714#define WM2200_AIF1TX2MIX_VOL3_WIDTH 7 /* AIF1TX2MIX_VOL3 - [7:1] */
1715
1716/*
1717 * R1582 (0x62E) - AIF1TX2MIX Input 4 Source
1718 */
1719#define WM2200_AIF1TX2MIX_SRC4_MASK 0x007F /* AIF1TX2MIX_SRC4 - [6:0] */
1720#define WM2200_AIF1TX2MIX_SRC4_SHIFT 0 /* AIF1TX2MIX_SRC4 - [6:0] */
1721#define WM2200_AIF1TX2MIX_SRC4_WIDTH 7 /* AIF1TX2MIX_SRC4 - [6:0] */
1722
1723/*
1724 * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume
1725 */
1726#define WM2200_AIF1TX2MIX_VOL4_MASK 0x00FE /* AIF1TX2MIX_VOL4 - [7:1] */
1727#define WM2200_AIF1TX2MIX_VOL4_SHIFT 1 /* AIF1TX2MIX_VOL4 - [7:1] */
1728#define WM2200_AIF1TX2MIX_VOL4_WIDTH 7 /* AIF1TX2MIX_VOL4 - [7:1] */
1729
1730/*
1731 * R1584 (0x630) - AIF1TX3MIX Input 1 Source
1732 */
1733#define WM2200_AIF1TX3MIX_SRC1_MASK 0x007F /* AIF1TX3MIX_SRC1 - [6:0] */
1734#define WM2200_AIF1TX3MIX_SRC1_SHIFT 0 /* AIF1TX3MIX_SRC1 - [6:0] */
1735#define WM2200_AIF1TX3MIX_SRC1_WIDTH 7 /* AIF1TX3MIX_SRC1 - [6:0] */
1736
1737/*
1738 * R1585 (0x631) - AIF1TX3MIX Input 1 Volume
1739 */
1740#define WM2200_AIF1TX3MIX_VOL1_MASK 0x00FE /* AIF1TX3MIX_VOL1 - [7:1] */
1741#define WM2200_AIF1TX3MIX_VOL1_SHIFT 1 /* AIF1TX3MIX_VOL1 - [7:1] */
1742#define WM2200_AIF1TX3MIX_VOL1_WIDTH 7 /* AIF1TX3MIX_VOL1 - [7:1] */
1743
1744/*
1745 * R1586 (0x632) - AIF1TX3MIX Input 2 Source
1746 */
1747#define WM2200_AIF1TX3MIX_SRC2_MASK 0x007F /* AIF1TX3MIX_SRC2 - [6:0] */
1748#define WM2200_AIF1TX3MIX_SRC2_SHIFT 0 /* AIF1TX3MIX_SRC2 - [6:0] */
1749#define WM2200_AIF1TX3MIX_SRC2_WIDTH 7 /* AIF1TX3MIX_SRC2 - [6:0] */
1750
1751/*
1752 * R1587 (0x633) - AIF1TX3MIX Input 2 Volume
1753 */
1754#define WM2200_AIF1TX3MIX_VOL2_MASK 0x00FE /* AIF1TX3MIX_VOL2 - [7:1] */
1755#define WM2200_AIF1TX3MIX_VOL2_SHIFT 1 /* AIF1TX3MIX_VOL2 - [7:1] */
1756#define WM2200_AIF1TX3MIX_VOL2_WIDTH 7 /* AIF1TX3MIX_VOL2 - [7:1] */
1757
1758/*
1759 * R1588 (0x634) - AIF1TX3MIX Input 3 Source
1760 */
1761#define WM2200_AIF1TX3MIX_SRC3_MASK 0x007F /* AIF1TX3MIX_SRC3 - [6:0] */
1762#define WM2200_AIF1TX3MIX_SRC3_SHIFT 0 /* AIF1TX3MIX_SRC3 - [6:0] */
1763#define WM2200_AIF1TX3MIX_SRC3_WIDTH 7 /* AIF1TX3MIX_SRC3 - [6:0] */
1764
1765/*
1766 * R1589 (0x635) - AIF1TX3MIX Input 3 Volume
1767 */
1768#define WM2200_AIF1TX3MIX_VOL3_MASK 0x00FE /* AIF1TX3MIX_VOL3 - [7:1] */
1769#define WM2200_AIF1TX3MIX_VOL3_SHIFT 1 /* AIF1TX3MIX_VOL3 - [7:1] */
1770#define WM2200_AIF1TX3MIX_VOL3_WIDTH 7 /* AIF1TX3MIX_VOL3 - [7:1] */
1771
1772/*
1773 * R1590 (0x636) - AIF1TX3MIX Input 4 Source
1774 */
1775#define WM2200_AIF1TX3MIX_SRC4_MASK 0x007F /* AIF1TX3MIX_SRC4 - [6:0] */
1776#define WM2200_AIF1TX3MIX_SRC4_SHIFT 0 /* AIF1TX3MIX_SRC4 - [6:0] */
1777#define WM2200_AIF1TX3MIX_SRC4_WIDTH 7 /* AIF1TX3MIX_SRC4 - [6:0] */
1778
1779/*
1780 * R1591 (0x637) - AIF1TX3MIX Input 4 Volume
1781 */
1782#define WM2200_AIF1TX3MIX_VOL4_MASK 0x00FE /* AIF1TX3MIX_VOL4 - [7:1] */
1783#define WM2200_AIF1TX3MIX_VOL4_SHIFT 1 /* AIF1TX3MIX_VOL4 - [7:1] */
1784#define WM2200_AIF1TX3MIX_VOL4_WIDTH 7 /* AIF1TX3MIX_VOL4 - [7:1] */
1785
1786/*
1787 * R1592 (0x638) - AIF1TX4MIX Input 1 Source
1788 */
1789#define WM2200_AIF1TX4MIX_SRC1_MASK 0x007F /* AIF1TX4MIX_SRC1 - [6:0] */
1790#define WM2200_AIF1TX4MIX_SRC1_SHIFT 0 /* AIF1TX4MIX_SRC1 - [6:0] */
1791#define WM2200_AIF1TX4MIX_SRC1_WIDTH 7 /* AIF1TX4MIX_SRC1 - [6:0] */
1792
1793/*
1794 * R1593 (0x639) - AIF1TX4MIX Input 1 Volume
1795 */
1796#define WM2200_AIF1TX4MIX_VOL1_MASK 0x00FE /* AIF1TX4MIX_VOL1 - [7:1] */
1797#define WM2200_AIF1TX4MIX_VOL1_SHIFT 1 /* AIF1TX4MIX_VOL1 - [7:1] */
1798#define WM2200_AIF1TX4MIX_VOL1_WIDTH 7 /* AIF1TX4MIX_VOL1 - [7:1] */
1799
1800/*
1801 * R1594 (0x63A) - AIF1TX4MIX Input 2 Source
1802 */
1803#define WM2200_AIF1TX4MIX_SRC2_MASK 0x007F /* AIF1TX4MIX_SRC2 - [6:0] */
1804#define WM2200_AIF1TX4MIX_SRC2_SHIFT 0 /* AIF1TX4MIX_SRC2 - [6:0] */
1805#define WM2200_AIF1TX4MIX_SRC2_WIDTH 7 /* AIF1TX4MIX_SRC2 - [6:0] */
1806
1807/*
1808 * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume
1809 */
1810#define WM2200_AIF1TX4MIX_VOL2_MASK 0x00FE /* AIF1TX4MIX_VOL2 - [7:1] */
1811#define WM2200_AIF1TX4MIX_VOL2_SHIFT 1 /* AIF1TX4MIX_VOL2 - [7:1] */
1812#define WM2200_AIF1TX4MIX_VOL2_WIDTH 7 /* AIF1TX4MIX_VOL2 - [7:1] */
1813
1814/*
1815 * R1596 (0x63C) - AIF1TX4MIX Input 3 Source
1816 */
1817#define WM2200_AIF1TX4MIX_SRC3_MASK 0x007F /* AIF1TX4MIX_SRC3 - [6:0] */
1818#define WM2200_AIF1TX4MIX_SRC3_SHIFT 0 /* AIF1TX4MIX_SRC3 - [6:0] */
1819#define WM2200_AIF1TX4MIX_SRC3_WIDTH 7 /* AIF1TX4MIX_SRC3 - [6:0] */
1820
1821/*
1822 * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume
1823 */
1824#define WM2200_AIF1TX4MIX_VOL3_MASK 0x00FE /* AIF1TX4MIX_VOL3 - [7:1] */
1825#define WM2200_AIF1TX4MIX_VOL3_SHIFT 1 /* AIF1TX4MIX_VOL3 - [7:1] */
1826#define WM2200_AIF1TX4MIX_VOL3_WIDTH 7 /* AIF1TX4MIX_VOL3 - [7:1] */
1827
1828/*
1829 * R1598 (0x63E) - AIF1TX4MIX Input 4 Source
1830 */
1831#define WM2200_AIF1TX4MIX_SRC4_MASK 0x007F /* AIF1TX4MIX_SRC4 - [6:0] */
1832#define WM2200_AIF1TX4MIX_SRC4_SHIFT 0 /* AIF1TX4MIX_SRC4 - [6:0] */
1833#define WM2200_AIF1TX4MIX_SRC4_WIDTH 7 /* AIF1TX4MIX_SRC4 - [6:0] */
1834
1835/*
1836 * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume
1837 */
1838#define WM2200_AIF1TX4MIX_VOL4_MASK 0x00FE /* AIF1TX4MIX_VOL4 - [7:1] */
1839#define WM2200_AIF1TX4MIX_VOL4_SHIFT 1 /* AIF1TX4MIX_VOL4 - [7:1] */
1840#define WM2200_AIF1TX4MIX_VOL4_WIDTH 7 /* AIF1TX4MIX_VOL4 - [7:1] */
1841
1842/*
1843 * R1600 (0x640) - AIF1TX5MIX Input 1 Source
1844 */
1845#define WM2200_AIF1TX5MIX_SRC1_MASK 0x007F /* AIF1TX5MIX_SRC1 - [6:0] */
1846#define WM2200_AIF1TX5MIX_SRC1_SHIFT 0 /* AIF1TX5MIX_SRC1 - [6:0] */
1847#define WM2200_AIF1TX5MIX_SRC1_WIDTH 7 /* AIF1TX5MIX_SRC1 - [6:0] */
1848
1849/*
1850 * R1601 (0x641) - AIF1TX5MIX Input 1 Volume
1851 */
1852#define WM2200_AIF1TX5MIX_VOL1_MASK 0x00FE /* AIF1TX5MIX_VOL1 - [7:1] */
1853#define WM2200_AIF1TX5MIX_VOL1_SHIFT 1 /* AIF1TX5MIX_VOL1 - [7:1] */
1854#define WM2200_AIF1TX5MIX_VOL1_WIDTH 7 /* AIF1TX5MIX_VOL1 - [7:1] */
1855
1856/*
1857 * R1602 (0x642) - AIF1TX5MIX Input 2 Source
1858 */
1859#define WM2200_AIF1TX5MIX_SRC2_MASK 0x007F /* AIF1TX5MIX_SRC2 - [6:0] */
1860#define WM2200_AIF1TX5MIX_SRC2_SHIFT 0 /* AIF1TX5MIX_SRC2 - [6:0] */
1861#define WM2200_AIF1TX5MIX_SRC2_WIDTH 7 /* AIF1TX5MIX_SRC2 - [6:0] */
1862
1863/*
1864 * R1603 (0x643) - AIF1TX5MIX Input 2 Volume
1865 */
1866#define WM2200_AIF1TX5MIX_VOL2_MASK 0x00FE /* AIF1TX5MIX_VOL2 - [7:1] */
1867#define WM2200_AIF1TX5MIX_VOL2_SHIFT 1 /* AIF1TX5MIX_VOL2 - [7:1] */
1868#define WM2200_AIF1TX5MIX_VOL2_WIDTH 7 /* AIF1TX5MIX_VOL2 - [7:1] */
1869
1870/*
1871 * R1604 (0x644) - AIF1TX5MIX Input 3 Source
1872 */
1873#define WM2200_AIF1TX5MIX_SRC3_MASK 0x007F /* AIF1TX5MIX_SRC3 - [6:0] */
1874#define WM2200_AIF1TX5MIX_SRC3_SHIFT 0 /* AIF1TX5MIX_SRC3 - [6:0] */
1875#define WM2200_AIF1TX5MIX_SRC3_WIDTH 7 /* AIF1TX5MIX_SRC3 - [6:0] */
1876
1877/*
1878 * R1605 (0x645) - AIF1TX5MIX Input 3 Volume
1879 */
1880#define WM2200_AIF1TX5MIX_VOL3_MASK 0x00FE /* AIF1TX5MIX_VOL3 - [7:1] */
1881#define WM2200_AIF1TX5MIX_VOL3_SHIFT 1 /* AIF1TX5MIX_VOL3 - [7:1] */
1882#define WM2200_AIF1TX5MIX_VOL3_WIDTH 7 /* AIF1TX5MIX_VOL3 - [7:1] */
1883
1884/*
1885 * R1606 (0x646) - AIF1TX5MIX Input 4 Source
1886 */
1887#define WM2200_AIF1TX5MIX_SRC4_MASK 0x007F /* AIF1TX5MIX_SRC4 - [6:0] */
1888#define WM2200_AIF1TX5MIX_SRC4_SHIFT 0 /* AIF1TX5MIX_SRC4 - [6:0] */
1889#define WM2200_AIF1TX5MIX_SRC4_WIDTH 7 /* AIF1TX5MIX_SRC4 - [6:0] */
1890
1891/*
1892 * R1607 (0x647) - AIF1TX5MIX Input 4 Volume
1893 */
1894#define WM2200_AIF1TX5MIX_VOL4_MASK 0x00FE /* AIF1TX5MIX_VOL4 - [7:1] */
1895#define WM2200_AIF1TX5MIX_VOL4_SHIFT 1 /* AIF1TX5MIX_VOL4 - [7:1] */
1896#define WM2200_AIF1TX5MIX_VOL4_WIDTH 7 /* AIF1TX5MIX_VOL4 - [7:1] */
1897
1898/*
1899 * R1608 (0x648) - AIF1TX6MIX Input 1 Source
1900 */
1901#define WM2200_AIF1TX6MIX_SRC1_MASK 0x007F /* AIF1TX6MIX_SRC1 - [6:0] */
1902#define WM2200_AIF1TX6MIX_SRC1_SHIFT 0 /* AIF1TX6MIX_SRC1 - [6:0] */
1903#define WM2200_AIF1TX6MIX_SRC1_WIDTH 7 /* AIF1TX6MIX_SRC1 - [6:0] */
1904
1905/*
1906 * R1609 (0x649) - AIF1TX6MIX Input 1 Volume
1907 */
1908#define WM2200_AIF1TX6MIX_VOL1_MASK 0x00FE /* AIF1TX6MIX_VOL1 - [7:1] */
1909#define WM2200_AIF1TX6MIX_VOL1_SHIFT 1 /* AIF1TX6MIX_VOL1 - [7:1] */
1910#define WM2200_AIF1TX6MIX_VOL1_WIDTH 7 /* AIF1TX6MIX_VOL1 - [7:1] */
1911
1912/*
1913 * R1610 (0x64A) - AIF1TX6MIX Input 2 Source
1914 */
1915#define WM2200_AIF1TX6MIX_SRC2_MASK 0x007F /* AIF1TX6MIX_SRC2 - [6:0] */
1916#define WM2200_AIF1TX6MIX_SRC2_SHIFT 0 /* AIF1TX6MIX_SRC2 - [6:0] */
1917#define WM2200_AIF1TX6MIX_SRC2_WIDTH 7 /* AIF1TX6MIX_SRC2 - [6:0] */
1918
1919/*
1920 * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume
1921 */
1922#define WM2200_AIF1TX6MIX_VOL2_MASK 0x00FE /* AIF1TX6MIX_VOL2 - [7:1] */
1923#define WM2200_AIF1TX6MIX_VOL2_SHIFT 1 /* AIF1TX6MIX_VOL2 - [7:1] */
1924#define WM2200_AIF1TX6MIX_VOL2_WIDTH 7 /* AIF1TX6MIX_VOL2 - [7:1] */
1925
1926/*
1927 * R1612 (0x64C) - AIF1TX6MIX Input 3 Source
1928 */
1929#define WM2200_AIF1TX6MIX_SRC3_MASK 0x007F /* AIF1TX6MIX_SRC3 - [6:0] */
1930#define WM2200_AIF1TX6MIX_SRC3_SHIFT 0 /* AIF1TX6MIX_SRC3 - [6:0] */
1931#define WM2200_AIF1TX6MIX_SRC3_WIDTH 7 /* AIF1TX6MIX_SRC3 - [6:0] */
1932
1933/*
1934 * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume
1935 */
1936#define WM2200_AIF1TX6MIX_VOL3_MASK 0x00FE /* AIF1TX6MIX_VOL3 - [7:1] */
1937#define WM2200_AIF1TX6MIX_VOL3_SHIFT 1 /* AIF1TX6MIX_VOL3 - [7:1] */
1938#define WM2200_AIF1TX6MIX_VOL3_WIDTH 7 /* AIF1TX6MIX_VOL3 - [7:1] */
1939
1940/*
1941 * R1614 (0x64E) - AIF1TX6MIX Input 4 Source
1942 */
1943#define WM2200_AIF1TX6MIX_SRC4_MASK 0x007F /* AIF1TX6MIX_SRC4 - [6:0] */
1944#define WM2200_AIF1TX6MIX_SRC4_SHIFT 0 /* AIF1TX6MIX_SRC4 - [6:0] */
1945#define WM2200_AIF1TX6MIX_SRC4_WIDTH 7 /* AIF1TX6MIX_SRC4 - [6:0] */
1946
1947/*
1948 * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume
1949 */
1950#define WM2200_AIF1TX6MIX_VOL4_MASK 0x00FE /* AIF1TX6MIX_VOL4 - [7:1] */
1951#define WM2200_AIF1TX6MIX_VOL4_SHIFT 1 /* AIF1TX6MIX_VOL4 - [7:1] */
1952#define WM2200_AIF1TX6MIX_VOL4_WIDTH 7 /* AIF1TX6MIX_VOL4 - [7:1] */
1953
1954/*
1955 * R1616 (0x650) - EQLMIX Input 1 Source
1956 */
1957#define WM2200_EQLMIX_SRC1_MASK 0x007F /* EQLMIX_SRC1 - [6:0] */
1958#define WM2200_EQLMIX_SRC1_SHIFT 0 /* EQLMIX_SRC1 - [6:0] */
1959#define WM2200_EQLMIX_SRC1_WIDTH 7 /* EQLMIX_SRC1 - [6:0] */
1960
1961/*
1962 * R1617 (0x651) - EQLMIX Input 1 Volume
1963 */
1964#define WM2200_EQLMIX_VOL1_MASK 0x00FE /* EQLMIX_VOL1 - [7:1] */
1965#define WM2200_EQLMIX_VOL1_SHIFT 1 /* EQLMIX_VOL1 - [7:1] */
1966#define WM2200_EQLMIX_VOL1_WIDTH 7 /* EQLMIX_VOL1 - [7:1] */
1967
1968/*
1969 * R1618 (0x652) - EQLMIX Input 2 Source
1970 */
1971#define WM2200_EQLMIX_SRC2_MASK 0x007F /* EQLMIX_SRC2 - [6:0] */
1972#define WM2200_EQLMIX_SRC2_SHIFT 0 /* EQLMIX_SRC2 - [6:0] */
1973#define WM2200_EQLMIX_SRC2_WIDTH 7 /* EQLMIX_SRC2 - [6:0] */
1974
1975/*
1976 * R1619 (0x653) - EQLMIX Input 2 Volume
1977 */
1978#define WM2200_EQLMIX_VOL2_MASK 0x00FE /* EQLMIX_VOL2 - [7:1] */
1979#define WM2200_EQLMIX_VOL2_SHIFT 1 /* EQLMIX_VOL2 - [7:1] */
1980#define WM2200_EQLMIX_VOL2_WIDTH 7 /* EQLMIX_VOL2 - [7:1] */
1981
1982/*
1983 * R1620 (0x654) - EQLMIX Input 3 Source
1984 */
1985#define WM2200_EQLMIX_SRC3_MASK 0x007F /* EQLMIX_SRC3 - [6:0] */
1986#define WM2200_EQLMIX_SRC3_SHIFT 0 /* EQLMIX_SRC3 - [6:0] */
1987#define WM2200_EQLMIX_SRC3_WIDTH 7 /* EQLMIX_SRC3 - [6:0] */
1988
1989/*
1990 * R1621 (0x655) - EQLMIX Input 3 Volume
1991 */
1992#define WM2200_EQLMIX_VOL3_MASK 0x00FE /* EQLMIX_VOL3 - [7:1] */
1993#define WM2200_EQLMIX_VOL3_SHIFT 1 /* EQLMIX_VOL3 - [7:1] */
1994#define WM2200_EQLMIX_VOL3_WIDTH 7 /* EQLMIX_VOL3 - [7:1] */
1995
1996/*
1997 * R1622 (0x656) - EQLMIX Input 4 Source
1998 */
1999#define WM2200_EQLMIX_SRC4_MASK 0x007F /* EQLMIX_SRC4 - [6:0] */
2000#define WM2200_EQLMIX_SRC4_SHIFT 0 /* EQLMIX_SRC4 - [6:0] */
2001#define WM2200_EQLMIX_SRC4_WIDTH 7 /* EQLMIX_SRC4 - [6:0] */
2002
2003/*
2004 * R1623 (0x657) - EQLMIX Input 4 Volume
2005 */
2006#define WM2200_EQLMIX_VOL4_MASK 0x00FE /* EQLMIX_VOL4 - [7:1] */
2007#define WM2200_EQLMIX_VOL4_SHIFT 1 /* EQLMIX_VOL4 - [7:1] */
2008#define WM2200_EQLMIX_VOL4_WIDTH 7 /* EQLMIX_VOL4 - [7:1] */
2009
2010/*
2011 * R1624 (0x658) - EQRMIX Input 1 Source
2012 */
2013#define WM2200_EQRMIX_SRC1_MASK 0x007F /* EQRMIX_SRC1 - [6:0] */
2014#define WM2200_EQRMIX_SRC1_SHIFT 0 /* EQRMIX_SRC1 - [6:0] */
2015#define WM2200_EQRMIX_SRC1_WIDTH 7 /* EQRMIX_SRC1 - [6:0] */
2016
2017/*
2018 * R1625 (0x659) - EQRMIX Input 1 Volume
2019 */
2020#define WM2200_EQRMIX_VOL1_MASK 0x00FE /* EQRMIX_VOL1 - [7:1] */
2021#define WM2200_EQRMIX_VOL1_SHIFT 1 /* EQRMIX_VOL1 - [7:1] */
2022#define WM2200_EQRMIX_VOL1_WIDTH 7 /* EQRMIX_VOL1 - [7:1] */
2023
2024/*
2025 * R1626 (0x65A) - EQRMIX Input 2 Source
2026 */
2027#define WM2200_EQRMIX_SRC2_MASK 0x007F /* EQRMIX_SRC2 - [6:0] */
2028#define WM2200_EQRMIX_SRC2_SHIFT 0 /* EQRMIX_SRC2 - [6:0] */
2029#define WM2200_EQRMIX_SRC2_WIDTH 7 /* EQRMIX_SRC2 - [6:0] */
2030
2031/*
2032 * R1627 (0x65B) - EQRMIX Input 2 Volume
2033 */
2034#define WM2200_EQRMIX_VOL2_MASK 0x00FE /* EQRMIX_VOL2 - [7:1] */
2035#define WM2200_EQRMIX_VOL2_SHIFT 1 /* EQRMIX_VOL2 - [7:1] */
2036#define WM2200_EQRMIX_VOL2_WIDTH 7 /* EQRMIX_VOL2 - [7:1] */
2037
2038/*
2039 * R1628 (0x65C) - EQRMIX Input 3 Source
2040 */
2041#define WM2200_EQRMIX_SRC3_MASK 0x007F /* EQRMIX_SRC3 - [6:0] */
2042#define WM2200_EQRMIX_SRC3_SHIFT 0 /* EQRMIX_SRC3 - [6:0] */
2043#define WM2200_EQRMIX_SRC3_WIDTH 7 /* EQRMIX_SRC3 - [6:0] */
2044
2045/*
2046 * R1629 (0x65D) - EQRMIX Input 3 Volume
2047 */
2048#define WM2200_EQRMIX_VOL3_MASK 0x00FE /* EQRMIX_VOL3 - [7:1] */
2049#define WM2200_EQRMIX_VOL3_SHIFT 1 /* EQRMIX_VOL3 - [7:1] */
2050#define WM2200_EQRMIX_VOL3_WIDTH 7 /* EQRMIX_VOL3 - [7:1] */
2051
2052/*
2053 * R1630 (0x65E) - EQRMIX Input 4 Source
2054 */
2055#define WM2200_EQRMIX_SRC4_MASK 0x007F /* EQRMIX_SRC4 - [6:0] */
2056#define WM2200_EQRMIX_SRC4_SHIFT 0 /* EQRMIX_SRC4 - [6:0] */
2057#define WM2200_EQRMIX_SRC4_WIDTH 7 /* EQRMIX_SRC4 - [6:0] */
2058
2059/*
2060 * R1631 (0x65F) - EQRMIX Input 4 Volume
2061 */
2062#define WM2200_EQRMIX_VOL4_MASK 0x00FE /* EQRMIX_VOL4 - [7:1] */
2063#define WM2200_EQRMIX_VOL4_SHIFT 1 /* EQRMIX_VOL4 - [7:1] */
2064#define WM2200_EQRMIX_VOL4_WIDTH 7 /* EQRMIX_VOL4 - [7:1] */
2065
2066/*
2067 * R1632 (0x660) - LHPF1MIX Input 1 Source
2068 */
2069#define WM2200_LHPF1MIX_SRC1_MASK 0x007F /* LHPF1MIX_SRC1 - [6:0] */
2070#define WM2200_LHPF1MIX_SRC1_SHIFT 0 /* LHPF1MIX_SRC1 - [6:0] */
2071#define WM2200_LHPF1MIX_SRC1_WIDTH 7 /* LHPF1MIX_SRC1 - [6:0] */
2072
2073/*
2074 * R1633 (0x661) - LHPF1MIX Input 1 Volume
2075 */
2076#define WM2200_LHPF1MIX_VOL1_MASK 0x00FE /* LHPF1MIX_VOL1 - [7:1] */
2077#define WM2200_LHPF1MIX_VOL1_SHIFT 1 /* LHPF1MIX_VOL1 - [7:1] */
2078#define WM2200_LHPF1MIX_VOL1_WIDTH 7 /* LHPF1MIX_VOL1 - [7:1] */
2079
2080/*
2081 * R1634 (0x662) - LHPF1MIX Input 2 Source
2082 */
2083#define WM2200_LHPF1MIX_SRC2_MASK 0x007F /* LHPF1MIX_SRC2 - [6:0] */
2084#define WM2200_LHPF1MIX_SRC2_SHIFT 0 /* LHPF1MIX_SRC2 - [6:0] */
2085#define WM2200_LHPF1MIX_SRC2_WIDTH 7 /* LHPF1MIX_SRC2 - [6:0] */
2086
2087/*
2088 * R1635 (0x663) - LHPF1MIX Input 2 Volume
2089 */
2090#define WM2200_LHPF1MIX_VOL2_MASK 0x00FE /* LHPF1MIX_VOL2 - [7:1] */
2091#define WM2200_LHPF1MIX_VOL2_SHIFT 1 /* LHPF1MIX_VOL2 - [7:1] */
2092#define WM2200_LHPF1MIX_VOL2_WIDTH 7 /* LHPF1MIX_VOL2 - [7:1] */
2093
2094/*
2095 * R1636 (0x664) - LHPF1MIX Input 3 Source
2096 */
2097#define WM2200_LHPF1MIX_SRC3_MASK 0x007F /* LHPF1MIX_SRC3 - [6:0] */
2098#define WM2200_LHPF1MIX_SRC3_SHIFT 0 /* LHPF1MIX_SRC3 - [6:0] */
2099#define WM2200_LHPF1MIX_SRC3_WIDTH 7 /* LHPF1MIX_SRC3 - [6:0] */
2100
2101/*
2102 * R1637 (0x665) - LHPF1MIX Input 3 Volume
2103 */
2104#define WM2200_LHPF1MIX_VOL3_MASK 0x00FE /* LHPF1MIX_VOL3 - [7:1] */
2105#define WM2200_LHPF1MIX_VOL3_SHIFT 1 /* LHPF1MIX_VOL3 - [7:1] */
2106#define WM2200_LHPF1MIX_VOL3_WIDTH 7 /* LHPF1MIX_VOL3 - [7:1] */
2107
2108/*
2109 * R1638 (0x666) - LHPF1MIX Input 4 Source
2110 */
2111#define WM2200_LHPF1MIX_SRC4_MASK 0x007F /* LHPF1MIX_SRC4 - [6:0] */
2112#define WM2200_LHPF1MIX_SRC4_SHIFT 0 /* LHPF1MIX_SRC4 - [6:0] */
2113#define WM2200_LHPF1MIX_SRC4_WIDTH 7 /* LHPF1MIX_SRC4 - [6:0] */
2114
2115/*
2116 * R1639 (0x667) - LHPF1MIX Input 4 Volume
2117 */
2118#define WM2200_LHPF1MIX_VOL4_MASK 0x00FE /* LHPF1MIX_VOL4 - [7:1] */
2119#define WM2200_LHPF1MIX_VOL4_SHIFT 1 /* LHPF1MIX_VOL4 - [7:1] */
2120#define WM2200_LHPF1MIX_VOL4_WIDTH 7 /* LHPF1MIX_VOL4 - [7:1] */
2121
2122/*
2123 * R1640 (0x668) - LHPF2MIX Input 1 Source
2124 */
2125#define WM2200_LHPF2MIX_SRC1_MASK 0x007F /* LHPF2MIX_SRC1 - [6:0] */
2126#define WM2200_LHPF2MIX_SRC1_SHIFT 0 /* LHPF2MIX_SRC1 - [6:0] */
2127#define WM2200_LHPF2MIX_SRC1_WIDTH 7 /* LHPF2MIX_SRC1 - [6:0] */
2128
2129/*
2130 * R1641 (0x669) - LHPF2MIX Input 1 Volume
2131 */
2132#define WM2200_LHPF2MIX_VOL1_MASK 0x00FE /* LHPF2MIX_VOL1 - [7:1] */
2133#define WM2200_LHPF2MIX_VOL1_SHIFT 1 /* LHPF2MIX_VOL1 - [7:1] */
2134#define WM2200_LHPF2MIX_VOL1_WIDTH 7 /* LHPF2MIX_VOL1 - [7:1] */
2135
2136/*
2137 * R1642 (0x66A) - LHPF2MIX Input 2 Source
2138 */
2139#define WM2200_LHPF2MIX_SRC2_MASK 0x007F /* LHPF2MIX_SRC2 - [6:0] */
2140#define WM2200_LHPF2MIX_SRC2_SHIFT 0 /* LHPF2MIX_SRC2 - [6:0] */
2141#define WM2200_LHPF2MIX_SRC2_WIDTH 7 /* LHPF2MIX_SRC2 - [6:0] */
2142
2143/*
2144 * R1643 (0x66B) - LHPF2MIX Input 2 Volume
2145 */
2146#define WM2200_LHPF2MIX_VOL2_MASK 0x00FE /* LHPF2MIX_VOL2 - [7:1] */
2147#define WM2200_LHPF2MIX_VOL2_SHIFT 1 /* LHPF2MIX_VOL2 - [7:1] */
2148#define WM2200_LHPF2MIX_VOL2_WIDTH 7 /* LHPF2MIX_VOL2 - [7:1] */
2149
2150/*
2151 * R1644 (0x66C) - LHPF2MIX Input 3 Source
2152 */
2153#define WM2200_LHPF2MIX_SRC3_MASK 0x007F /* LHPF2MIX_SRC3 - [6:0] */
2154#define WM2200_LHPF2MIX_SRC3_SHIFT 0 /* LHPF2MIX_SRC3 - [6:0] */
2155#define WM2200_LHPF2MIX_SRC3_WIDTH 7 /* LHPF2MIX_SRC3 - [6:0] */
2156
2157/*
2158 * R1645 (0x66D) - LHPF2MIX Input 3 Volume
2159 */
2160#define WM2200_LHPF2MIX_VOL3_MASK 0x00FE /* LHPF2MIX_VOL3 - [7:1] */
2161#define WM2200_LHPF2MIX_VOL3_SHIFT 1 /* LHPF2MIX_VOL3 - [7:1] */
2162#define WM2200_LHPF2MIX_VOL3_WIDTH 7 /* LHPF2MIX_VOL3 - [7:1] */
2163
2164/*
2165 * R1646 (0x66E) - LHPF2MIX Input 4 Source
2166 */
2167#define WM2200_LHPF2MIX_SRC4_MASK 0x007F /* LHPF2MIX_SRC4 - [6:0] */
2168#define WM2200_LHPF2MIX_SRC4_SHIFT 0 /* LHPF2MIX_SRC4 - [6:0] */
2169#define WM2200_LHPF2MIX_SRC4_WIDTH 7 /* LHPF2MIX_SRC4 - [6:0] */
2170
2171/*
2172 * R1647 (0x66F) - LHPF2MIX Input 4 Volume
2173 */
2174#define WM2200_LHPF2MIX_VOL4_MASK 0x00FE /* LHPF2MIX_VOL4 - [7:1] */
2175#define WM2200_LHPF2MIX_VOL4_SHIFT 1 /* LHPF2MIX_VOL4 - [7:1] */
2176#define WM2200_LHPF2MIX_VOL4_WIDTH 7 /* LHPF2MIX_VOL4 - [7:1] */
2177
2178/*
2179 * R1648 (0x670) - DSP1LMIX Input 1 Source
2180 */
2181#define WM2200_DSP1LMIX_SRC1_MASK 0x007F /* DSP1LMIX_SRC1 - [6:0] */
2182#define WM2200_DSP1LMIX_SRC1_SHIFT 0 /* DSP1LMIX_SRC1 - [6:0] */
2183#define WM2200_DSP1LMIX_SRC1_WIDTH 7 /* DSP1LMIX_SRC1 - [6:0] */
2184
2185/*
2186 * R1649 (0x671) - DSP1LMIX Input 1 Volume
2187 */
2188#define WM2200_DSP1LMIX_VOL1_MASK 0x00FE /* DSP1LMIX_VOL1 - [7:1] */
2189#define WM2200_DSP1LMIX_VOL1_SHIFT 1 /* DSP1LMIX_VOL1 - [7:1] */
2190#define WM2200_DSP1LMIX_VOL1_WIDTH 7 /* DSP1LMIX_VOL1 - [7:1] */
2191
2192/*
2193 * R1650 (0x672) - DSP1LMIX Input 2 Source
2194 */
2195#define WM2200_DSP1LMIX_SRC2_MASK 0x007F /* DSP1LMIX_SRC2 - [6:0] */
2196#define WM2200_DSP1LMIX_SRC2_SHIFT 0 /* DSP1LMIX_SRC2 - [6:0] */
2197#define WM2200_DSP1LMIX_SRC2_WIDTH 7 /* DSP1LMIX_SRC2 - [6:0] */
2198
2199/*
2200 * R1651 (0x673) - DSP1LMIX Input 2 Volume
2201 */
2202#define WM2200_DSP1LMIX_VOL2_MASK 0x00FE /* DSP1LMIX_VOL2 - [7:1] */
2203#define WM2200_DSP1LMIX_VOL2_SHIFT 1 /* DSP1LMIX_VOL2 - [7:1] */
2204#define WM2200_DSP1LMIX_VOL2_WIDTH 7 /* DSP1LMIX_VOL2 - [7:1] */
2205
2206/*
2207 * R1652 (0x674) - DSP1LMIX Input 3 Source
2208 */
2209#define WM2200_DSP1LMIX_SRC3_MASK 0x007F /* DSP1LMIX_SRC3 - [6:0] */
2210#define WM2200_DSP1LMIX_SRC3_SHIFT 0 /* DSP1LMIX_SRC3 - [6:0] */
2211#define WM2200_DSP1LMIX_SRC3_WIDTH 7 /* DSP1LMIX_SRC3 - [6:0] */
2212
2213/*
2214 * R1653 (0x675) - DSP1LMIX Input 3 Volume
2215 */
2216#define WM2200_DSP1LMIX_VOL3_MASK 0x00FE /* DSP1LMIX_VOL3 - [7:1] */
2217#define WM2200_DSP1LMIX_VOL3_SHIFT 1 /* DSP1LMIX_VOL3 - [7:1] */
2218#define WM2200_DSP1LMIX_VOL3_WIDTH 7 /* DSP1LMIX_VOL3 - [7:1] */
2219
2220/*
2221 * R1654 (0x676) - DSP1LMIX Input 4 Source
2222 */
2223#define WM2200_DSP1LMIX_SRC4_MASK 0x007F /* DSP1LMIX_SRC4 - [6:0] */
2224#define WM2200_DSP1LMIX_SRC4_SHIFT 0 /* DSP1LMIX_SRC4 - [6:0] */
2225#define WM2200_DSP1LMIX_SRC4_WIDTH 7 /* DSP1LMIX_SRC4 - [6:0] */
2226
2227/*
2228 * R1655 (0x677) - DSP1LMIX Input 4 Volume
2229 */
2230#define WM2200_DSP1LMIX_VOL4_MASK 0x00FE /* DSP1LMIX_VOL4 - [7:1] */
2231#define WM2200_DSP1LMIX_VOL4_SHIFT 1 /* DSP1LMIX_VOL4 - [7:1] */
2232#define WM2200_DSP1LMIX_VOL4_WIDTH 7 /* DSP1LMIX_VOL4 - [7:1] */
2233
2234/*
2235 * R1656 (0x678) - DSP1RMIX Input 1 Source
2236 */
2237#define WM2200_DSP1RMIX_SRC1_MASK 0x007F /* DSP1RMIX_SRC1 - [6:0] */
2238#define WM2200_DSP1RMIX_SRC1_SHIFT 0 /* DSP1RMIX_SRC1 - [6:0] */
2239#define WM2200_DSP1RMIX_SRC1_WIDTH 7 /* DSP1RMIX_SRC1 - [6:0] */
2240
2241/*
2242 * R1657 (0x679) - DSP1RMIX Input 1 Volume
2243 */
2244#define WM2200_DSP1RMIX_VOL1_MASK 0x00FE /* DSP1RMIX_VOL1 - [7:1] */
2245#define WM2200_DSP1RMIX_VOL1_SHIFT 1 /* DSP1RMIX_VOL1 - [7:1] */
2246#define WM2200_DSP1RMIX_VOL1_WIDTH 7 /* DSP1RMIX_VOL1 - [7:1] */
2247
2248/*
2249 * R1658 (0x67A) - DSP1RMIX Input 2 Source
2250 */
2251#define WM2200_DSP1RMIX_SRC2_MASK 0x007F /* DSP1RMIX_SRC2 - [6:0] */
2252#define WM2200_DSP1RMIX_SRC2_SHIFT 0 /* DSP1RMIX_SRC2 - [6:0] */
2253#define WM2200_DSP1RMIX_SRC2_WIDTH 7 /* DSP1RMIX_SRC2 - [6:0] */
2254
2255/*
2256 * R1659 (0x67B) - DSP1RMIX Input 2 Volume
2257 */
2258#define WM2200_DSP1RMIX_VOL2_MASK 0x00FE /* DSP1RMIX_VOL2 - [7:1] */
2259#define WM2200_DSP1RMIX_VOL2_SHIFT 1 /* DSP1RMIX_VOL2 - [7:1] */
2260#define WM2200_DSP1RMIX_VOL2_WIDTH 7 /* DSP1RMIX_VOL2 - [7:1] */
2261
2262/*
2263 * R1660 (0x67C) - DSP1RMIX Input 3 Source
2264 */
2265#define WM2200_DSP1RMIX_SRC3_MASK 0x007F /* DSP1RMIX_SRC3 - [6:0] */
2266#define WM2200_DSP1RMIX_SRC3_SHIFT 0 /* DSP1RMIX_SRC3 - [6:0] */
2267#define WM2200_DSP1RMIX_SRC3_WIDTH 7 /* DSP1RMIX_SRC3 - [6:0] */
2268
2269/*
2270 * R1661 (0x67D) - DSP1RMIX Input 3 Volume
2271 */
2272#define WM2200_DSP1RMIX_VOL3_MASK 0x00FE /* DSP1RMIX_VOL3 - [7:1] */
2273#define WM2200_DSP1RMIX_VOL3_SHIFT 1 /* DSP1RMIX_VOL3 - [7:1] */
2274#define WM2200_DSP1RMIX_VOL3_WIDTH 7 /* DSP1RMIX_VOL3 - [7:1] */
2275
2276/*
2277 * R1662 (0x67E) - DSP1RMIX Input 4 Source
2278 */
2279#define WM2200_DSP1RMIX_SRC4_MASK 0x007F /* DSP1RMIX_SRC4 - [6:0] */
2280#define WM2200_DSP1RMIX_SRC4_SHIFT 0 /* DSP1RMIX_SRC4 - [6:0] */
2281#define WM2200_DSP1RMIX_SRC4_WIDTH 7 /* DSP1RMIX_SRC4 - [6:0] */
2282
2283/*
2284 * R1663 (0x67F) - DSP1RMIX Input 4 Volume
2285 */
2286#define WM2200_DSP1RMIX_VOL4_MASK 0x00FE /* DSP1RMIX_VOL4 - [7:1] */
2287#define WM2200_DSP1RMIX_VOL4_SHIFT 1 /* DSP1RMIX_VOL4 - [7:1] */
2288#define WM2200_DSP1RMIX_VOL4_WIDTH 7 /* DSP1RMIX_VOL4 - [7:1] */
2289
2290/*
2291 * R1664 (0x680) - DSP1AUX1MIX Input 1 Source
2292 */
2293#define WM2200_DSP1AUX1MIX_SRC1_MASK 0x007F /* DSP1AUX1MIX_SRC1 - [6:0] */
2294#define WM2200_DSP1AUX1MIX_SRC1_SHIFT 0 /* DSP1AUX1MIX_SRC1 - [6:0] */
2295#define WM2200_DSP1AUX1MIX_SRC1_WIDTH 7 /* DSP1AUX1MIX_SRC1 - [6:0] */
2296
2297/*
2298 * R1665 (0x681) - DSP1AUX2MIX Input 1 Source
2299 */
2300#define WM2200_DSP1AUX2MIX_SRC1_MASK 0x007F /* DSP1AUX2MIX_SRC1 - [6:0] */
2301#define WM2200_DSP1AUX2MIX_SRC1_SHIFT 0 /* DSP1AUX2MIX_SRC1 - [6:0] */
2302#define WM2200_DSP1AUX2MIX_SRC1_WIDTH 7 /* DSP1AUX2MIX_SRC1 - [6:0] */
2303
2304/*
2305 * R1666 (0x682) - DSP1AUX3MIX Input 1 Source
2306 */
2307#define WM2200_DSP1AUX3MIX_SRC1_MASK 0x007F /* DSP1AUX3MIX_SRC1 - [6:0] */
2308#define WM2200_DSP1AUX3MIX_SRC1_SHIFT 0 /* DSP1AUX3MIX_SRC1 - [6:0] */
2309#define WM2200_DSP1AUX3MIX_SRC1_WIDTH 7 /* DSP1AUX3MIX_SRC1 - [6:0] */
2310
2311/*
2312 * R1667 (0x683) - DSP1AUX4MIX Input 1 Source
2313 */
2314#define WM2200_DSP1AUX4MIX_SRC1_MASK 0x007F /* DSP1AUX4MIX_SRC1 - [6:0] */
2315#define WM2200_DSP1AUX4MIX_SRC1_SHIFT 0 /* DSP1AUX4MIX_SRC1 - [6:0] */
2316#define WM2200_DSP1AUX4MIX_SRC1_WIDTH 7 /* DSP1AUX4MIX_SRC1 - [6:0] */
2317
2318/*
2319 * R1668 (0x684) - DSP1AUX5MIX Input 1 Source
2320 */
2321#define WM2200_DSP1AUX5MIX_SRC1_MASK 0x007F /* DSP1AUX5MIX_SRC1 - [6:0] */
2322#define WM2200_DSP1AUX5MIX_SRC1_SHIFT 0 /* DSP1AUX5MIX_SRC1 - [6:0] */
2323#define WM2200_DSP1AUX5MIX_SRC1_WIDTH 7 /* DSP1AUX5MIX_SRC1 - [6:0] */
2324
2325/*
2326 * R1669 (0x685) - DSP1AUX6MIX Input 1 Source
2327 */
2328#define WM2200_DSP1AUX6MIX_SRC1_MASK 0x007F /* DSP1AUX6MIX_SRC1 - [6:0] */
2329#define WM2200_DSP1AUX6MIX_SRC1_SHIFT 0 /* DSP1AUX6MIX_SRC1 - [6:0] */
2330#define WM2200_DSP1AUX6MIX_SRC1_WIDTH 7 /* DSP1AUX6MIX_SRC1 - [6:0] */
2331
2332/*
2333 * R1670 (0x686) - DSP2LMIX Input 1 Source
2334 */
2335#define WM2200_DSP2LMIX_SRC1_MASK 0x007F /* DSP2LMIX_SRC1 - [6:0] */
2336#define WM2200_DSP2LMIX_SRC1_SHIFT 0 /* DSP2LMIX_SRC1 - [6:0] */
2337#define WM2200_DSP2LMIX_SRC1_WIDTH 7 /* DSP2LMIX_SRC1 - [6:0] */
2338
2339/*
2340 * R1671 (0x687) - DSP2LMIX Input 1 Volume
2341 */
2342#define WM2200_DSP2LMIX_VOL1_MASK 0x00FE /* DSP2LMIX_VOL1 - [7:1] */
2343#define WM2200_DSP2LMIX_VOL1_SHIFT 1 /* DSP2LMIX_VOL1 - [7:1] */
2344#define WM2200_DSP2LMIX_VOL1_WIDTH 7 /* DSP2LMIX_VOL1 - [7:1] */
2345
2346/*
2347 * R1672 (0x688) - DSP2LMIX Input 2 Source
2348 */
2349#define WM2200_DSP2LMIX_SRC2_MASK 0x007F /* DSP2LMIX_SRC2 - [6:0] */
2350#define WM2200_DSP2LMIX_SRC2_SHIFT 0 /* DSP2LMIX_SRC2 - [6:0] */
2351#define WM2200_DSP2LMIX_SRC2_WIDTH 7 /* DSP2LMIX_SRC2 - [6:0] */
2352
2353/*
2354 * R1673 (0x689) - DSP2LMIX Input 2 Volume
2355 */
2356#define WM2200_DSP2LMIX_VOL2_MASK 0x00FE /* DSP2LMIX_VOL2 - [7:1] */
2357#define WM2200_DSP2LMIX_VOL2_SHIFT 1 /* DSP2LMIX_VOL2 - [7:1] */
2358#define WM2200_DSP2LMIX_VOL2_WIDTH 7 /* DSP2LMIX_VOL2 - [7:1] */
2359
2360/*
2361 * R1674 (0x68A) - DSP2LMIX Input 3 Source
2362 */
2363#define WM2200_DSP2LMIX_SRC3_MASK 0x007F /* DSP2LMIX_SRC3 - [6:0] */
2364#define WM2200_DSP2LMIX_SRC3_SHIFT 0 /* DSP2LMIX_SRC3 - [6:0] */
2365#define WM2200_DSP2LMIX_SRC3_WIDTH 7 /* DSP2LMIX_SRC3 - [6:0] */
2366
2367/*
2368 * R1675 (0x68B) - DSP2LMIX Input 3 Volume
2369 */
2370#define WM2200_DSP2LMIX_VOL3_MASK 0x00FE /* DSP2LMIX_VOL3 - [7:1] */
2371#define WM2200_DSP2LMIX_VOL3_SHIFT 1 /* DSP2LMIX_VOL3 - [7:1] */
2372#define WM2200_DSP2LMIX_VOL3_WIDTH 7 /* DSP2LMIX_VOL3 - [7:1] */
2373
2374/*
2375 * R1676 (0x68C) - DSP2LMIX Input 4 Source
2376 */
2377#define WM2200_DSP2LMIX_SRC4_MASK 0x007F /* DSP2LMIX_SRC4 - [6:0] */
2378#define WM2200_DSP2LMIX_SRC4_SHIFT 0 /* DSP2LMIX_SRC4 - [6:0] */
2379#define WM2200_DSP2LMIX_SRC4_WIDTH 7 /* DSP2LMIX_SRC4 - [6:0] */
2380
2381/*
2382 * R1677 (0x68D) - DSP2LMIX Input 4 Volume
2383 */
2384#define WM2200_DSP2LMIX_VOL4_MASK 0x00FE /* DSP2LMIX_VOL4 - [7:1] */
2385#define WM2200_DSP2LMIX_VOL4_SHIFT 1 /* DSP2LMIX_VOL4 - [7:1] */
2386#define WM2200_DSP2LMIX_VOL4_WIDTH 7 /* DSP2LMIX_VOL4 - [7:1] */
2387
2388/*
2389 * R1678 (0x68E) - DSP2RMIX Input 1 Source
2390 */
2391#define WM2200_DSP2RMIX_SRC1_MASK 0x007F /* DSP2RMIX_SRC1 - [6:0] */
2392#define WM2200_DSP2RMIX_SRC1_SHIFT 0 /* DSP2RMIX_SRC1 - [6:0] */
2393#define WM2200_DSP2RMIX_SRC1_WIDTH 7 /* DSP2RMIX_SRC1 - [6:0] */
2394
2395/*
2396 * R1679 (0x68F) - DSP2RMIX Input 1 Volume
2397 */
2398#define WM2200_DSP2RMIX_VOL1_MASK 0x00FE /* DSP2RMIX_VOL1 - [7:1] */
2399#define WM2200_DSP2RMIX_VOL1_SHIFT 1 /* DSP2RMIX_VOL1 - [7:1] */
2400#define WM2200_DSP2RMIX_VOL1_WIDTH 7 /* DSP2RMIX_VOL1 - [7:1] */
2401
2402/*
2403 * R1680 (0x690) - DSP2RMIX Input 2 Source
2404 */
2405#define WM2200_DSP2RMIX_SRC2_MASK 0x007F /* DSP2RMIX_SRC2 - [6:0] */
2406#define WM2200_DSP2RMIX_SRC2_SHIFT 0 /* DSP2RMIX_SRC2 - [6:0] */
2407#define WM2200_DSP2RMIX_SRC2_WIDTH 7 /* DSP2RMIX_SRC2 - [6:0] */
2408
2409/*
2410 * R1681 (0x691) - DSP2RMIX Input 2 Volume
2411 */
2412#define WM2200_DSP2RMIX_VOL2_MASK 0x00FE /* DSP2RMIX_VOL2 - [7:1] */
2413#define WM2200_DSP2RMIX_VOL2_SHIFT 1 /* DSP2RMIX_VOL2 - [7:1] */
2414#define WM2200_DSP2RMIX_VOL2_WIDTH 7 /* DSP2RMIX_VOL2 - [7:1] */
2415
2416/*
2417 * R1682 (0x692) - DSP2RMIX Input 3 Source
2418 */
2419#define WM2200_DSP2RMIX_SRC3_MASK 0x007F /* DSP2RMIX_SRC3 - [6:0] */
2420#define WM2200_DSP2RMIX_SRC3_SHIFT 0 /* DSP2RMIX_SRC3 - [6:0] */
2421#define WM2200_DSP2RMIX_SRC3_WIDTH 7 /* DSP2RMIX_SRC3 - [6:0] */
2422
2423/*
2424 * R1683 (0x693) - DSP2RMIX Input 3 Volume
2425 */
2426#define WM2200_DSP2RMIX_VOL3_MASK 0x00FE /* DSP2RMIX_VOL3 - [7:1] */
2427#define WM2200_DSP2RMIX_VOL3_SHIFT 1 /* DSP2RMIX_VOL3 - [7:1] */
2428#define WM2200_DSP2RMIX_VOL3_WIDTH 7 /* DSP2RMIX_VOL3 - [7:1] */
2429
2430/*
2431 * R1684 (0x694) - DSP2RMIX Input 4 Source
2432 */
2433#define WM2200_DSP2RMIX_SRC4_MASK 0x007F /* DSP2RMIX_SRC4 - [6:0] */
2434#define WM2200_DSP2RMIX_SRC4_SHIFT 0 /* DSP2RMIX_SRC4 - [6:0] */
2435#define WM2200_DSP2RMIX_SRC4_WIDTH 7 /* DSP2RMIX_SRC4 - [6:0] */
2436
2437/*
2438 * R1685 (0x695) - DSP2RMIX Input 4 Volume
2439 */
2440#define WM2200_DSP2RMIX_VOL4_MASK 0x00FE /* DSP2RMIX_VOL4 - [7:1] */
2441#define WM2200_DSP2RMIX_VOL4_SHIFT 1 /* DSP2RMIX_VOL4 - [7:1] */
2442#define WM2200_DSP2RMIX_VOL4_WIDTH 7 /* DSP2RMIX_VOL4 - [7:1] */
2443
2444/*
2445 * R1686 (0x696) - DSP2AUX1MIX Input 1 Source
2446 */
2447#define WM2200_DSP2AUX1MIX_SRC1_MASK 0x007F /* DSP2AUX1MIX_SRC1 - [6:0] */
2448#define WM2200_DSP2AUX1MIX_SRC1_SHIFT 0 /* DSP2AUX1MIX_SRC1 - [6:0] */
2449#define WM2200_DSP2AUX1MIX_SRC1_WIDTH 7 /* DSP2AUX1MIX_SRC1 - [6:0] */
2450
2451/*
2452 * R1687 (0x697) - DSP2AUX2MIX Input 1 Source
2453 */
2454#define WM2200_DSP2AUX2MIX_SRC1_MASK 0x007F /* DSP2AUX2MIX_SRC1 - [6:0] */
2455#define WM2200_DSP2AUX2MIX_SRC1_SHIFT 0 /* DSP2AUX2MIX_SRC1 - [6:0] */
2456#define WM2200_DSP2AUX2MIX_SRC1_WIDTH 7 /* DSP2AUX2MIX_SRC1 - [6:0] */
2457
2458/*
2459 * R1688 (0x698) - DSP2AUX3MIX Input 1 Source
2460 */
2461#define WM2200_DSP2AUX3MIX_SRC1_MASK 0x007F /* DSP2AUX3MIX_SRC1 - [6:0] */
2462#define WM2200_DSP2AUX3MIX_SRC1_SHIFT 0 /* DSP2AUX3MIX_SRC1 - [6:0] */
2463#define WM2200_DSP2AUX3MIX_SRC1_WIDTH 7 /* DSP2AUX3MIX_SRC1 - [6:0] */
2464
2465/*
2466 * R1689 (0x699) - DSP2AUX4MIX Input 1 Source
2467 */
2468#define WM2200_DSP2AUX4MIX_SRC1_MASK 0x007F /* DSP2AUX4MIX_SRC1 - [6:0] */
2469#define WM2200_DSP2AUX4MIX_SRC1_SHIFT 0 /* DSP2AUX4MIX_SRC1 - [6:0] */
2470#define WM2200_DSP2AUX4MIX_SRC1_WIDTH 7 /* DSP2AUX4MIX_SRC1 - [6:0] */
2471
2472/*
2473 * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source
2474 */
2475#define WM2200_DSP2AUX5MIX_SRC1_MASK 0x007F /* DSP2AUX5MIX_SRC1 - [6:0] */
2476#define WM2200_DSP2AUX5MIX_SRC1_SHIFT 0 /* DSP2AUX5MIX_SRC1 - [6:0] */
2477#define WM2200_DSP2AUX5MIX_SRC1_WIDTH 7 /* DSP2AUX5MIX_SRC1 - [6:0] */
2478
2479/*
2480 * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source
2481 */
2482#define WM2200_DSP2AUX6MIX_SRC1_MASK 0x007F /* DSP2AUX6MIX_SRC1 - [6:0] */
2483#define WM2200_DSP2AUX6MIX_SRC1_SHIFT 0 /* DSP2AUX6MIX_SRC1 - [6:0] */
2484#define WM2200_DSP2AUX6MIX_SRC1_WIDTH 7 /* DSP2AUX6MIX_SRC1 - [6:0] */
2485
2486/*
2487 * R1792 (0x700) - GPIO CTRL 1
2488 */
2489#define WM2200_GP1_DIR 0x8000 /* GP1_DIR */
2490#define WM2200_GP1_DIR_MASK 0x8000 /* GP1_DIR */
2491#define WM2200_GP1_DIR_SHIFT 15 /* GP1_DIR */
2492#define WM2200_GP1_DIR_WIDTH 1 /* GP1_DIR */
2493#define WM2200_GP1_PU 0x4000 /* GP1_PU */
2494#define WM2200_GP1_PU_MASK 0x4000 /* GP1_PU */
2495#define WM2200_GP1_PU_SHIFT 14 /* GP1_PU */
2496#define WM2200_GP1_PU_WIDTH 1 /* GP1_PU */
2497#define WM2200_GP1_PD 0x2000 /* GP1_PD */
2498#define WM2200_GP1_PD_MASK 0x2000 /* GP1_PD */
2499#define WM2200_GP1_PD_SHIFT 13 /* GP1_PD */
2500#define WM2200_GP1_PD_WIDTH 1 /* GP1_PD */
2501#define WM2200_GP1_POL 0x0400 /* GP1_POL */
2502#define WM2200_GP1_POL_MASK 0x0400 /* GP1_POL */
2503#define WM2200_GP1_POL_SHIFT 10 /* GP1_POL */
2504#define WM2200_GP1_POL_WIDTH 1 /* GP1_POL */
2505#define WM2200_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
2506#define WM2200_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
2507#define WM2200_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
2508#define WM2200_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
2509#define WM2200_GP1_DB 0x0100 /* GP1_DB */
2510#define WM2200_GP1_DB_MASK 0x0100 /* GP1_DB */
2511#define WM2200_GP1_DB_SHIFT 8 /* GP1_DB */
2512#define WM2200_GP1_DB_WIDTH 1 /* GP1_DB */
2513#define WM2200_GP1_LVL 0x0040 /* GP1_LVL */
2514#define WM2200_GP1_LVL_MASK 0x0040 /* GP1_LVL */
2515#define WM2200_GP1_LVL_SHIFT 6 /* GP1_LVL */
2516#define WM2200_GP1_LVL_WIDTH 1 /* GP1_LVL */
2517#define WM2200_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
2518#define WM2200_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
2519#define WM2200_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
2520
2521/*
2522 * R1793 (0x701) - GPIO CTRL 2
2523 */
2524#define WM2200_GP2_DIR 0x8000 /* GP2_DIR */
2525#define WM2200_GP2_DIR_MASK 0x8000 /* GP2_DIR */
2526#define WM2200_GP2_DIR_SHIFT 15 /* GP2_DIR */
2527#define WM2200_GP2_DIR_WIDTH 1 /* GP2_DIR */
2528#define WM2200_GP2_PU 0x4000 /* GP2_PU */
2529#define WM2200_GP2_PU_MASK 0x4000 /* GP2_PU */
2530#define WM2200_GP2_PU_SHIFT 14 /* GP2_PU */
2531#define WM2200_GP2_PU_WIDTH 1 /* GP2_PU */
2532#define WM2200_GP2_PD 0x2000 /* GP2_PD */
2533#define WM2200_GP2_PD_MASK 0x2000 /* GP2_PD */
2534#define WM2200_GP2_PD_SHIFT 13 /* GP2_PD */
2535#define WM2200_GP2_PD_WIDTH 1 /* GP2_PD */
2536#define WM2200_GP2_POL 0x0400 /* GP2_POL */
2537#define WM2200_GP2_POL_MASK 0x0400 /* GP2_POL */
2538#define WM2200_GP2_POL_SHIFT 10 /* GP2_POL */
2539#define WM2200_GP2_POL_WIDTH 1 /* GP2_POL */
2540#define WM2200_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
2541#define WM2200_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
2542#define WM2200_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
2543#define WM2200_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
2544#define WM2200_GP2_DB 0x0100 /* GP2_DB */
2545#define WM2200_GP2_DB_MASK 0x0100 /* GP2_DB */
2546#define WM2200_GP2_DB_SHIFT 8 /* GP2_DB */
2547#define WM2200_GP2_DB_WIDTH 1 /* GP2_DB */
2548#define WM2200_GP2_LVL 0x0040 /* GP2_LVL */
2549#define WM2200_GP2_LVL_MASK 0x0040 /* GP2_LVL */
2550#define WM2200_GP2_LVL_SHIFT 6 /* GP2_LVL */
2551#define WM2200_GP2_LVL_WIDTH 1 /* GP2_LVL */
2552#define WM2200_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
2553#define WM2200_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
2554#define WM2200_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
2555
2556/*
2557 * R1794 (0x702) - GPIO CTRL 3
2558 */
2559#define WM2200_GP3_DIR 0x8000 /* GP3_DIR */
2560#define WM2200_GP3_DIR_MASK 0x8000 /* GP3_DIR */
2561#define WM2200_GP3_DIR_SHIFT 15 /* GP3_DIR */
2562#define WM2200_GP3_DIR_WIDTH 1 /* GP3_DIR */
2563#define WM2200_GP3_PU 0x4000 /* GP3_PU */
2564#define WM2200_GP3_PU_MASK 0x4000 /* GP3_PU */
2565#define WM2200_GP3_PU_SHIFT 14 /* GP3_PU */
2566#define WM2200_GP3_PU_WIDTH 1 /* GP3_PU */
2567#define WM2200_GP3_PD 0x2000 /* GP3_PD */
2568#define WM2200_GP3_PD_MASK 0x2000 /* GP3_PD */
2569#define WM2200_GP3_PD_SHIFT 13 /* GP3_PD */
2570#define WM2200_GP3_PD_WIDTH 1 /* GP3_PD */
2571#define WM2200_GP3_POL 0x0400 /* GP3_POL */
2572#define WM2200_GP3_POL_MASK 0x0400 /* GP3_POL */
2573#define WM2200_GP3_POL_SHIFT 10 /* GP3_POL */
2574#define WM2200_GP3_POL_WIDTH 1 /* GP3_POL */
2575#define WM2200_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
2576#define WM2200_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
2577#define WM2200_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
2578#define WM2200_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
2579#define WM2200_GP3_DB 0x0100 /* GP3_DB */
2580#define WM2200_GP3_DB_MASK 0x0100 /* GP3_DB */
2581#define WM2200_GP3_DB_SHIFT 8 /* GP3_DB */
2582#define WM2200_GP3_DB_WIDTH 1 /* GP3_DB */
2583#define WM2200_GP3_LVL 0x0040 /* GP3_LVL */
2584#define WM2200_GP3_LVL_MASK 0x0040 /* GP3_LVL */
2585#define WM2200_GP3_LVL_SHIFT 6 /* GP3_LVL */
2586#define WM2200_GP3_LVL_WIDTH 1 /* GP3_LVL */
2587#define WM2200_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
2588#define WM2200_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
2589#define WM2200_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
2590
2591/*
2592 * R1795 (0x703) - GPIO CTRL 4
2593 */
2594#define WM2200_GP4_DIR 0x8000 /* GP4_DIR */
2595#define WM2200_GP4_DIR_MASK 0x8000 /* GP4_DIR */
2596#define WM2200_GP4_DIR_SHIFT 15 /* GP4_DIR */
2597#define WM2200_GP4_DIR_WIDTH 1 /* GP4_DIR */
2598#define WM2200_GP4_PU 0x4000 /* GP4_PU */
2599#define WM2200_GP4_PU_MASK 0x4000 /* GP4_PU */
2600#define WM2200_GP4_PU_SHIFT 14 /* GP4_PU */
2601#define WM2200_GP4_PU_WIDTH 1 /* GP4_PU */
2602#define WM2200_GP4_PD 0x2000 /* GP4_PD */
2603#define WM2200_GP4_PD_MASK 0x2000 /* GP4_PD */
2604#define WM2200_GP4_PD_SHIFT 13 /* GP4_PD */
2605#define WM2200_GP4_PD_WIDTH 1 /* GP4_PD */
2606#define WM2200_GP4_POL 0x0400 /* GP4_POL */
2607#define WM2200_GP4_POL_MASK 0x0400 /* GP4_POL */
2608#define WM2200_GP4_POL_SHIFT 10 /* GP4_POL */
2609#define WM2200_GP4_POL_WIDTH 1 /* GP4_POL */
2610#define WM2200_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
2611#define WM2200_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
2612#define WM2200_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
2613#define WM2200_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
2614#define WM2200_GP4_DB 0x0100 /* GP4_DB */
2615#define WM2200_GP4_DB_MASK 0x0100 /* GP4_DB */
2616#define WM2200_GP4_DB_SHIFT 8 /* GP4_DB */
2617#define WM2200_GP4_DB_WIDTH 1 /* GP4_DB */
2618#define WM2200_GP4_LVL 0x0040 /* GP4_LVL */
2619#define WM2200_GP4_LVL_MASK 0x0040 /* GP4_LVL */
2620#define WM2200_GP4_LVL_SHIFT 6 /* GP4_LVL */
2621#define WM2200_GP4_LVL_WIDTH 1 /* GP4_LVL */
2622#define WM2200_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
2623#define WM2200_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
2624#define WM2200_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
2625
2626/*
2627 * R1799 (0x707) - ADPS1 IRQ0
2628 */
2629#define WM2200_DSP_IRQ1 0x0002 /* DSP_IRQ1 */
2630#define WM2200_DSP_IRQ1_MASK 0x0002 /* DSP_IRQ1 */
2631#define WM2200_DSP_IRQ1_SHIFT 1 /* DSP_IRQ1 */
2632#define WM2200_DSP_IRQ1_WIDTH 1 /* DSP_IRQ1 */
2633#define WM2200_DSP_IRQ0 0x0001 /* DSP_IRQ0 */
2634#define WM2200_DSP_IRQ0_MASK 0x0001 /* DSP_IRQ0 */
2635#define WM2200_DSP_IRQ0_SHIFT 0 /* DSP_IRQ0 */
2636#define WM2200_DSP_IRQ0_WIDTH 1 /* DSP_IRQ0 */
2637
2638/*
2639 * R1800 (0x708) - ADPS1 IRQ1
2640 */
2641#define WM2200_DSP_IRQ3 0x0002 /* DSP_IRQ3 */
2642#define WM2200_DSP_IRQ3_MASK 0x0002 /* DSP_IRQ3 */
2643#define WM2200_DSP_IRQ3_SHIFT 1 /* DSP_IRQ3 */
2644#define WM2200_DSP_IRQ3_WIDTH 1 /* DSP_IRQ3 */
2645#define WM2200_DSP_IRQ2 0x0001 /* DSP_IRQ2 */
2646#define WM2200_DSP_IRQ2_MASK 0x0001 /* DSP_IRQ2 */
2647#define WM2200_DSP_IRQ2_SHIFT 0 /* DSP_IRQ2 */
2648#define WM2200_DSP_IRQ2_WIDTH 1 /* DSP_IRQ2 */
2649
2650/*
2651 * R1801 (0x709) - Misc Pad Ctrl 1
2652 */
2653#define WM2200_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
2654#define WM2200_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
2655#define WM2200_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
2656#define WM2200_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
2657#define WM2200_MCLK2_PD 0x2000 /* MCLK2_PD */
2658#define WM2200_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
2659#define WM2200_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
2660#define WM2200_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
2661#define WM2200_MCLK1_PD 0x1000 /* MCLK1_PD */
2662#define WM2200_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
2663#define WM2200_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
2664#define WM2200_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
2665#define WM2200_DACLRCLK1_PU 0x0400 /* DACLRCLK1_PU */
2666#define WM2200_DACLRCLK1_PU_MASK 0x0400 /* DACLRCLK1_PU */
2667#define WM2200_DACLRCLK1_PU_SHIFT 10 /* DACLRCLK1_PU */
2668#define WM2200_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
2669#define WM2200_DACLRCLK1_PD 0x0200 /* DACLRCLK1_PD */
2670#define WM2200_DACLRCLK1_PD_MASK 0x0200 /* DACLRCLK1_PD */
2671#define WM2200_DACLRCLK1_PD_SHIFT 9 /* DACLRCLK1_PD */
2672#define WM2200_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
2673#define WM2200_BCLK1_PU 0x0100 /* BCLK1_PU */
2674#define WM2200_BCLK1_PU_MASK 0x0100 /* BCLK1_PU */
2675#define WM2200_BCLK1_PU_SHIFT 8 /* BCLK1_PU */
2676#define WM2200_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
2677#define WM2200_BCLK1_PD 0x0080 /* BCLK1_PD */
2678#define WM2200_BCLK1_PD_MASK 0x0080 /* BCLK1_PD */
2679#define WM2200_BCLK1_PD_SHIFT 7 /* BCLK1_PD */
2680#define WM2200_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
2681#define WM2200_DACDAT1_PU 0x0040 /* DACDAT1_PU */
2682#define WM2200_DACDAT1_PU_MASK 0x0040 /* DACDAT1_PU */
2683#define WM2200_DACDAT1_PU_SHIFT 6 /* DACDAT1_PU */
2684#define WM2200_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
2685#define WM2200_DACDAT1_PD 0x0020 /* DACDAT1_PD */
2686#define WM2200_DACDAT1_PD_MASK 0x0020 /* DACDAT1_PD */
2687#define WM2200_DACDAT1_PD_SHIFT 5 /* DACDAT1_PD */
2688#define WM2200_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
2689#define WM2200_DMICDAT3_PD 0x0010 /* DMICDAT3_PD */
2690#define WM2200_DMICDAT3_PD_MASK 0x0010 /* DMICDAT3_PD */
2691#define WM2200_DMICDAT3_PD_SHIFT 4 /* DMICDAT3_PD */
2692#define WM2200_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
2693#define WM2200_DMICDAT2_PD 0x0008 /* DMICDAT2_PD */
2694#define WM2200_DMICDAT2_PD_MASK 0x0008 /* DMICDAT2_PD */
2695#define WM2200_DMICDAT2_PD_SHIFT 3 /* DMICDAT2_PD */
2696#define WM2200_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
2697#define WM2200_DMICDAT1_PD 0x0004 /* DMICDAT1_PD */
2698#define WM2200_DMICDAT1_PD_MASK 0x0004 /* DMICDAT1_PD */
2699#define WM2200_DMICDAT1_PD_SHIFT 2 /* DMICDAT1_PD */
2700#define WM2200_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
2701#define WM2200_RSTB_PU 0x0002 /* RSTB_PU */
2702#define WM2200_RSTB_PU_MASK 0x0002 /* RSTB_PU */
2703#define WM2200_RSTB_PU_SHIFT 1 /* RSTB_PU */
2704#define WM2200_RSTB_PU_WIDTH 1 /* RSTB_PU */
2705#define WM2200_ADDR_PD 0x0001 /* ADDR_PD */
2706#define WM2200_ADDR_PD_MASK 0x0001 /* ADDR_PD */
2707#define WM2200_ADDR_PD_SHIFT 0 /* ADDR_PD */
2708#define WM2200_ADDR_PD_WIDTH 1 /* ADDR_PD */
2709
2710/*
2711 * R2048 (0x800) - Interrupt Status 1
2712 */
2713#define WM2200_DSP_IRQ0_EINT 0x0080 /* DSP_IRQ0_EINT */
2714#define WM2200_DSP_IRQ0_EINT_MASK 0x0080 /* DSP_IRQ0_EINT */
2715#define WM2200_DSP_IRQ0_EINT_SHIFT 7 /* DSP_IRQ0_EINT */
2716#define WM2200_DSP_IRQ0_EINT_WIDTH 1 /* DSP_IRQ0_EINT */
2717#define WM2200_DSP_IRQ1_EINT 0x0040 /* DSP_IRQ1_EINT */
2718#define WM2200_DSP_IRQ1_EINT_MASK 0x0040 /* DSP_IRQ1_EINT */
2719#define WM2200_DSP_IRQ1_EINT_SHIFT 6 /* DSP_IRQ1_EINT */
2720#define WM2200_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
2721#define WM2200_DSP_IRQ2_EINT 0x0020 /* DSP_IRQ2_EINT */
2722#define WM2200_DSP_IRQ2_EINT_MASK 0x0020 /* DSP_IRQ2_EINT */
2723#define WM2200_DSP_IRQ2_EINT_SHIFT 5 /* DSP_IRQ2_EINT */
2724#define WM2200_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
2725#define WM2200_DSP_IRQ3_EINT 0x0010 /* DSP_IRQ3_EINT */
2726#define WM2200_DSP_IRQ3_EINT_MASK 0x0010 /* DSP_IRQ3_EINT */
2727#define WM2200_DSP_IRQ3_EINT_SHIFT 4 /* DSP_IRQ3_EINT */
2728#define WM2200_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
2729#define WM2200_GP4_EINT 0x0008 /* GP4_EINT */
2730#define WM2200_GP4_EINT_MASK 0x0008 /* GP4_EINT */
2731#define WM2200_GP4_EINT_SHIFT 3 /* GP4_EINT */
2732#define WM2200_GP4_EINT_WIDTH 1 /* GP4_EINT */
2733#define WM2200_GP3_EINT 0x0004 /* GP3_EINT */
2734#define WM2200_GP3_EINT_MASK 0x0004 /* GP3_EINT */
2735#define WM2200_GP3_EINT_SHIFT 2 /* GP3_EINT */
2736#define WM2200_GP3_EINT_WIDTH 1 /* GP3_EINT */
2737#define WM2200_GP2_EINT 0x0002 /* GP2_EINT */
2738#define WM2200_GP2_EINT_MASK 0x0002 /* GP2_EINT */
2739#define WM2200_GP2_EINT_SHIFT 1 /* GP2_EINT */
2740#define WM2200_GP2_EINT_WIDTH 1 /* GP2_EINT */
2741#define WM2200_GP1_EINT 0x0001 /* GP1_EINT */
2742#define WM2200_GP1_EINT_MASK 0x0001 /* GP1_EINT */
2743#define WM2200_GP1_EINT_SHIFT 0 /* GP1_EINT */
2744#define WM2200_GP1_EINT_WIDTH 1 /* GP1_EINT */
2745
2746/*
2747 * R2049 (0x801) - Interrupt Status 1 Mask
2748 */
2749#define WM2200_IM_DSP_IRQ0_EINT 0x0080 /* IM_DSP_IRQ0_EINT */
2750#define WM2200_IM_DSP_IRQ0_EINT_MASK 0x0080 /* IM_DSP_IRQ0_EINT */
2751#define WM2200_IM_DSP_IRQ0_EINT_SHIFT 7 /* IM_DSP_IRQ0_EINT */
2752#define WM2200_IM_DSP_IRQ0_EINT_WIDTH 1 /* IM_DSP_IRQ0_EINT */
2753#define WM2200_IM_DSP_IRQ1_EINT 0x0040 /* IM_DSP_IRQ1_EINT */
2754#define WM2200_IM_DSP_IRQ1_EINT_MASK 0x0040 /* IM_DSP_IRQ1_EINT */
2755#define WM2200_IM_DSP_IRQ1_EINT_SHIFT 6 /* IM_DSP_IRQ1_EINT */
2756#define WM2200_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
2757#define WM2200_IM_DSP_IRQ2_EINT 0x0020 /* IM_DSP_IRQ2_EINT */
2758#define WM2200_IM_DSP_IRQ2_EINT_MASK 0x0020 /* IM_DSP_IRQ2_EINT */
2759#define WM2200_IM_DSP_IRQ2_EINT_SHIFT 5 /* IM_DSP_IRQ2_EINT */
2760#define WM2200_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
2761#define WM2200_IM_DSP_IRQ3_EINT 0x0010 /* IM_DSP_IRQ3_EINT */
2762#define WM2200_IM_DSP_IRQ3_EINT_MASK 0x0010 /* IM_DSP_IRQ3_EINT */
2763#define WM2200_IM_DSP_IRQ3_EINT_SHIFT 4 /* IM_DSP_IRQ3_EINT */
2764#define WM2200_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
2765#define WM2200_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
2766#define WM2200_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
2767#define WM2200_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
2768#define WM2200_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
2769#define WM2200_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
2770#define WM2200_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
2771#define WM2200_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
2772#define WM2200_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
2773#define WM2200_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
2774#define WM2200_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
2775#define WM2200_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
2776#define WM2200_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
2777#define WM2200_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
2778#define WM2200_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
2779#define WM2200_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
2780#define WM2200_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
2781
2782/*
2783 * R2050 (0x802) - Interrupt Status 2
2784 */
2785#define WM2200_WSEQ_BUSY_EINT 0x0100 /* WSEQ_BUSY_EINT */
2786#define WM2200_WSEQ_BUSY_EINT_MASK 0x0100 /* WSEQ_BUSY_EINT */
2787#define WM2200_WSEQ_BUSY_EINT_SHIFT 8 /* WSEQ_BUSY_EINT */
2788#define WM2200_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
2789#define WM2200_FLL_LOCK_EINT 0x0002 /* FLL_LOCK_EINT */
2790#define WM2200_FLL_LOCK_EINT_MASK 0x0002 /* FLL_LOCK_EINT */
2791#define WM2200_FLL_LOCK_EINT_SHIFT 1 /* FLL_LOCK_EINT */
2792#define WM2200_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
2793#define WM2200_CLKGEN_EINT 0x0001 /* CLKGEN_EINT */
2794#define WM2200_CLKGEN_EINT_MASK 0x0001 /* CLKGEN_EINT */
2795#define WM2200_CLKGEN_EINT_SHIFT 0 /* CLKGEN_EINT */
2796#define WM2200_CLKGEN_EINT_WIDTH 1 /* CLKGEN_EINT */
2797
2798/*
2799 * R2051 (0x803) - Interrupt Raw Status 2
2800 */
2801#define WM2200_WSEQ_BUSY_STS 0x0100 /* WSEQ_BUSY_STS */
2802#define WM2200_WSEQ_BUSY_STS_MASK 0x0100 /* WSEQ_BUSY_STS */
2803#define WM2200_WSEQ_BUSY_STS_SHIFT 8 /* WSEQ_BUSY_STS */
2804#define WM2200_WSEQ_BUSY_STS_WIDTH 1 /* WSEQ_BUSY_STS */
2805#define WM2200_FLL_LOCK_STS 0x0002 /* FLL_LOCK_STS */
2806#define WM2200_FLL_LOCK_STS_MASK 0x0002 /* FLL_LOCK_STS */
2807#define WM2200_FLL_LOCK_STS_SHIFT 1 /* FLL_LOCK_STS */
2808#define WM2200_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
2809#define WM2200_CLKGEN_STS 0x0001 /* CLKGEN_STS */
2810#define WM2200_CLKGEN_STS_MASK 0x0001 /* CLKGEN_STS */
2811#define WM2200_CLKGEN_STS_SHIFT 0 /* CLKGEN_STS */
2812#define WM2200_CLKGEN_STS_WIDTH 1 /* CLKGEN_STS */
2813
2814/*
2815 * R2052 (0x804) - Interrupt Status 2 Mask
2816 */
2817#define WM2200_IM_WSEQ_BUSY_EINT 0x0100 /* IM_WSEQ_BUSY_EINT */
2818#define WM2200_IM_WSEQ_BUSY_EINT_MASK 0x0100 /* IM_WSEQ_BUSY_EINT */
2819#define WM2200_IM_WSEQ_BUSY_EINT_SHIFT 8 /* IM_WSEQ_BUSY_EINT */
2820#define WM2200_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
2821#define WM2200_IM_FLL_LOCK_EINT 0x0002 /* IM_FLL_LOCK_EINT */
2822#define WM2200_IM_FLL_LOCK_EINT_MASK 0x0002 /* IM_FLL_LOCK_EINT */
2823#define WM2200_IM_FLL_LOCK_EINT_SHIFT 1 /* IM_FLL_LOCK_EINT */
2824#define WM2200_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
2825#define WM2200_IM_CLKGEN_EINT 0x0001 /* IM_CLKGEN_EINT */
2826#define WM2200_IM_CLKGEN_EINT_MASK 0x0001 /* IM_CLKGEN_EINT */
2827#define WM2200_IM_CLKGEN_EINT_SHIFT 0 /* IM_CLKGEN_EINT */
2828#define WM2200_IM_CLKGEN_EINT_WIDTH 1 /* IM_CLKGEN_EINT */
2829
2830/*
2831 * R2056 (0x808) - Interrupt Control
2832 */
2833#define WM2200_IM_IRQ 0x0001 /* IM_IRQ */
2834#define WM2200_IM_IRQ_MASK 0x0001 /* IM_IRQ */
2835#define WM2200_IM_IRQ_SHIFT 0 /* IM_IRQ */
2836#define WM2200_IM_IRQ_WIDTH 1 /* IM_IRQ */
2837
2838/*
2839 * R2304 (0x900) - EQL_1
2840 */
2841#define WM2200_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */
2842#define WM2200_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */
2843#define WM2200_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */
2844#define WM2200_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */
2845#define WM2200_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */
2846#define WM2200_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */
2847#define WM2200_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */
2848#define WM2200_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */
2849#define WM2200_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */
2850#define WM2200_EQL_ENA 0x0001 /* EQL_ENA */
2851#define WM2200_EQL_ENA_MASK 0x0001 /* EQL_ENA */
2852#define WM2200_EQL_ENA_SHIFT 0 /* EQL_ENA */
2853#define WM2200_EQL_ENA_WIDTH 1 /* EQL_ENA */
2854
2855/*
2856 * R2305 (0x901) - EQL_2
2857 */
2858#define WM2200_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */
2859#define WM2200_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */
2860#define WM2200_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */
2861#define WM2200_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */
2862#define WM2200_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */
2863#define WM2200_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */
2864
2865/*
2866 * R2306 (0x902) - EQL_3
2867 */
2868#define WM2200_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */
2869#define WM2200_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */
2870#define WM2200_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */
2871
2872/*
2873 * R2307 (0x903) - EQL_4
2874 */
2875#define WM2200_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */
2876#define WM2200_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */
2877#define WM2200_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */
2878
2879/*
2880 * R2308 (0x904) - EQL_5
2881 */
2882#define WM2200_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */
2883#define WM2200_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */
2884#define WM2200_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */
2885
2886/*
2887 * R2309 (0x905) - EQL_6
2888 */
2889#define WM2200_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */
2890#define WM2200_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */
2891#define WM2200_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */
2892
2893/*
2894 * R2310 (0x906) - EQL_7
2895 */
2896#define WM2200_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */
2897#define WM2200_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */
2898#define WM2200_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */
2899
2900/*
2901 * R2311 (0x907) - EQL_8
2902 */
2903#define WM2200_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */
2904#define WM2200_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */
2905#define WM2200_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */
2906
2907/*
2908 * R2312 (0x908) - EQL_9
2909 */
2910#define WM2200_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */
2911#define WM2200_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */
2912#define WM2200_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */
2913
2914/*
2915 * R2313 (0x909) - EQL_10
2916 */
2917#define WM2200_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */
2918#define WM2200_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */
2919#define WM2200_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */
2920
2921/*
2922 * R2314 (0x90A) - EQL_11
2923 */
2924#define WM2200_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */
2925#define WM2200_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */
2926#define WM2200_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */
2927
2928/*
2929 * R2315 (0x90B) - EQL_12
2930 */
2931#define WM2200_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */
2932#define WM2200_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */
2933#define WM2200_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */
2934
2935/*
2936 * R2316 (0x90C) - EQL_13
2937 */
2938#define WM2200_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */
2939#define WM2200_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */
2940#define WM2200_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */
2941
2942/*
2943 * R2317 (0x90D) - EQL_14
2944 */
2945#define WM2200_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */
2946#define WM2200_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */
2947#define WM2200_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */
2948
2949/*
2950 * R2318 (0x90E) - EQL_15
2951 */
2952#define WM2200_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */
2953#define WM2200_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */
2954#define WM2200_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */
2955
2956/*
2957 * R2319 (0x90F) - EQL_16
2958 */
2959#define WM2200_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */
2960#define WM2200_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */
2961#define WM2200_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */
2962
2963/*
2964 * R2320 (0x910) - EQL_17
2965 */
2966#define WM2200_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */
2967#define WM2200_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */
2968#define WM2200_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */
2969
2970/*
2971 * R2321 (0x911) - EQL_18
2972 */
2973#define WM2200_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */
2974#define WM2200_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */
2975#define WM2200_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */
2976
2977/*
2978 * R2322 (0x912) - EQL_19
2979 */
2980#define WM2200_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */
2981#define WM2200_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */
2982#define WM2200_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */
2983
2984/*
2985 * R2323 (0x913) - EQL_20
2986 */
2987#define WM2200_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */
2988#define WM2200_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */
2989#define WM2200_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */
2990
2991/*
2992 * R2326 (0x916) - EQR_1
2993 */
2994#define WM2200_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */
2995#define WM2200_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */
2996#define WM2200_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */
2997#define WM2200_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */
2998#define WM2200_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */
2999#define WM2200_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */
3000#define WM2200_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */
3001#define WM2200_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */
3002#define WM2200_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */
3003#define WM2200_EQR_ENA 0x0001 /* EQR_ENA */
3004#define WM2200_EQR_ENA_MASK 0x0001 /* EQR_ENA */
3005#define WM2200_EQR_ENA_SHIFT 0 /* EQR_ENA */
3006#define WM2200_EQR_ENA_WIDTH 1 /* EQR_ENA */
3007
3008/*
3009 * R2327 (0x917) - EQR_2
3010 */
3011#define WM2200_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */
3012#define WM2200_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */
3013#define WM2200_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */
3014#define WM2200_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */
3015#define WM2200_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */
3016#define WM2200_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */
3017
3018/*
3019 * R2328 (0x918) - EQR_3
3020 */
3021#define WM2200_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */
3022#define WM2200_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */
3023#define WM2200_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */
3024
3025/*
3026 * R2329 (0x919) - EQR_4
3027 */
3028#define WM2200_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */
3029#define WM2200_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */
3030#define WM2200_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */
3031
3032/*
3033 * R2330 (0x91A) - EQR_5
3034 */
3035#define WM2200_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */
3036#define WM2200_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */
3037#define WM2200_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */
3038
3039/*
3040 * R2331 (0x91B) - EQR_6
3041 */
3042#define WM2200_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */
3043#define WM2200_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */
3044#define WM2200_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */
3045
3046/*
3047 * R2332 (0x91C) - EQR_7
3048 */
3049#define WM2200_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */
3050#define WM2200_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */
3051#define WM2200_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */
3052
3053/*
3054 * R2333 (0x91D) - EQR_8
3055 */
3056#define WM2200_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */
3057#define WM2200_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */
3058#define WM2200_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */
3059
3060/*
3061 * R2334 (0x91E) - EQR_9
3062 */
3063#define WM2200_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */
3064#define WM2200_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */
3065#define WM2200_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */
3066
3067/*
3068 * R2335 (0x91F) - EQR_10
3069 */
3070#define WM2200_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */
3071#define WM2200_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */
3072#define WM2200_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */
3073
3074/*
3075 * R2336 (0x920) - EQR_11
3076 */
3077#define WM2200_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */
3078#define WM2200_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */
3079#define WM2200_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */
3080
3081/*
3082 * R2337 (0x921) - EQR_12
3083 */
3084#define WM2200_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */
3085#define WM2200_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */
3086#define WM2200_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */
3087
3088/*
3089 * R2338 (0x922) - EQR_13
3090 */
3091#define WM2200_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */
3092#define WM2200_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */
3093#define WM2200_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */
3094
3095/*
3096 * R2339 (0x923) - EQR_14
3097 */
3098#define WM2200_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */
3099#define WM2200_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */
3100#define WM2200_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */
3101
3102/*
3103 * R2340 (0x924) - EQR_15
3104 */
3105#define WM2200_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */
3106#define WM2200_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */
3107#define WM2200_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */
3108
3109/*
3110 * R2341 (0x925) - EQR_16
3111 */
3112#define WM2200_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */
3113#define WM2200_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */
3114#define WM2200_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */
3115
3116/*
3117 * R2342 (0x926) - EQR_17
3118 */
3119#define WM2200_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */
3120#define WM2200_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */
3121#define WM2200_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */
3122
3123/*
3124 * R2343 (0x927) - EQR_18
3125 */
3126#define WM2200_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */
3127#define WM2200_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */
3128#define WM2200_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */
3129
3130/*
3131 * R2344 (0x928) - EQR_19
3132 */
3133#define WM2200_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */
3134#define WM2200_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */
3135#define WM2200_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */
3136
3137/*
3138 * R2345 (0x929) - EQR_20
3139 */
3140#define WM2200_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */
3141#define WM2200_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */
3142#define WM2200_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */
3143
3144/*
3145 * R2366 (0x93E) - HPLPF1_1
3146 */
3147#define WM2200_LHPF1_MODE 0x0002 /* LHPF1_MODE */
3148#define WM2200_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
3149#define WM2200_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
3150#define WM2200_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
3151#define WM2200_LHPF1_ENA 0x0001 /* LHPF1_ENA */
3152#define WM2200_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
3153#define WM2200_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
3154#define WM2200_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
3155
3156/*
3157 * R2367 (0x93F) - HPLPF1_2
3158 */
3159#define WM2200_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
3160#define WM2200_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
3161#define WM2200_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
3162
3163/*
3164 * R2370 (0x942) - HPLPF2_1
3165 */
3166#define WM2200_LHPF2_MODE 0x0002 /* LHPF2_MODE */
3167#define WM2200_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
3168#define WM2200_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
3169#define WM2200_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
3170#define WM2200_LHPF2_ENA 0x0001 /* LHPF2_ENA */
3171#define WM2200_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
3172#define WM2200_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
3173#define WM2200_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
3174
3175/*
3176 * R2371 (0x943) - HPLPF2_2
3177 */
3178#define WM2200_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
3179#define WM2200_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
3180#define WM2200_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
3181
3182/*
3183 * R2560 (0xA00) - DSP1 Control 1
3184 */
3185#define WM2200_DSP1_RW_SEQUENCE_ENA 0x0001 /* DSP1_RW_SEQUENCE_ENA */
3186#define WM2200_DSP1_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP1_RW_SEQUENCE_ENA */
3187#define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT 0 /* DSP1_RW_SEQUENCE_ENA */
3188#define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH 1 /* DSP1_RW_SEQUENCE_ENA */
3189
3190/*
3191 * R2562 (0xA02) - DSP1 Control 2
3192 */
3193#define WM2200_DSP1_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_PM - [15:8] */
3194#define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT 8 /* DSP1_PAGE_BASE_PM - [15:8] */
3195#define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH 8 /* DSP1_PAGE_BASE_PM - [15:8] */
3196
3197/*
3198 * R2563 (0xA03) - DSP1 Control 3
3199 */
3200#define WM2200_DSP1_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_DM - [15:8] */
3201#define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT 8 /* DSP1_PAGE_BASE_DM - [15:8] */
3202#define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH 8 /* DSP1_PAGE_BASE_DM - [15:8] */
3203
3204/*
3205 * R2564 (0xA04) - DSP1 Control 4
3206 */
3207#define WM2200_DSP1_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_ZM - [15:8] */
3208#define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
3209#define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
3210
3211/*
3212 * R2566 (0xA06) - DSP1 Control 5
3213 */
3214#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3215#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3216#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3217
3218/*
3219 * R2567 (0xA07) - DSP1 Control 6
3220 */
3221#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3222#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3223#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3224
3225/*
3226 * R2568 (0xA08) - DSP1 Control 7
3227 */
3228#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3229#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3230#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3231
3232/*
3233 * R2569 (0xA09) - DSP1 Control 8
3234 */
3235#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3236#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3237#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3238
3239/*
3240 * R2570 (0xA0A) - DSP1 Control 9
3241 */
3242#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3243#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3244#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3245
3246/*
3247 * R2571 (0xA0B) - DSP1 Control 10
3248 */
3249#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3250#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3251#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3252
3253/*
3254 * R2572 (0xA0C) - DSP1 Control 11
3255 */
3256#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3257#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3258#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3259
3260/*
3261 * R2573 (0xA0D) - DSP1 Control 12
3262 */
3263#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3264#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3265#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3266
3267/*
3268 * R2575 (0xA0F) - DSP1 Control 13
3269 */
3270#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3271#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3272#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3273
3274/*
3275 * R2576 (0xA10) - DSP1 Control 14
3276 */
3277#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3278#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3279#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3280
3281/*
3282 * R2577 (0xA11) - DSP1 Control 15
3283 */
3284#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3285#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3286#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3287
3288/*
3289 * R2578 (0xA12) - DSP1 Control 16
3290 */
3291#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3292#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3293#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3294
3295/*
3296 * R2579 (0xA13) - DSP1 Control 17
3297 */
3298#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3299#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3300#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3301
3302/*
3303 * R2580 (0xA14) - DSP1 Control 18
3304 */
3305#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3306#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3307#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3308
3309/*
3310 * R2582 (0xA16) - DSP1 Control 19
3311 */
3312#define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3313#define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3314#define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3315
3316/*
3317 * R2583 (0xA17) - DSP1 Control 20
3318 */
3319#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3320#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3321#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3322
3323/*
3324 * R2584 (0xA18) - DSP1 Control 21
3325 */
3326#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3327#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3328#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3329
3330/*
3331 * R2586 (0xA1A) - DSP1 Control 22
3332 */
3333#define WM2200_DSP1_DM_SIZE_MASK 0xFFFF /* DSP1_DM_SIZE - [15:0] */
3334#define WM2200_DSP1_DM_SIZE_SHIFT 0 /* DSP1_DM_SIZE - [15:0] */
3335#define WM2200_DSP1_DM_SIZE_WIDTH 16 /* DSP1_DM_SIZE - [15:0] */
3336
3337/*
3338 * R2587 (0xA1B) - DSP1 Control 23
3339 */
3340#define WM2200_DSP1_PM_SIZE_MASK 0xFFFF /* DSP1_PM_SIZE - [15:0] */
3341#define WM2200_DSP1_PM_SIZE_SHIFT 0 /* DSP1_PM_SIZE - [15:0] */
3342#define WM2200_DSP1_PM_SIZE_WIDTH 16 /* DSP1_PM_SIZE - [15:0] */
3343
3344/*
3345 * R2588 (0xA1C) - DSP1 Control 24
3346 */
3347#define WM2200_DSP1_ZM_SIZE_MASK 0xFFFF /* DSP1_ZM_SIZE - [15:0] */
3348#define WM2200_DSP1_ZM_SIZE_SHIFT 0 /* DSP1_ZM_SIZE - [15:0] */
3349#define WM2200_DSP1_ZM_SIZE_WIDTH 16 /* DSP1_ZM_SIZE - [15:0] */
3350
3351/*
3352 * R2590 (0xA1E) - DSP1 Control 25
3353 */
3354#define WM2200_DSP1_PING_FULL 0x8000 /* DSP1_PING_FULL */
3355#define WM2200_DSP1_PING_FULL_MASK 0x8000 /* DSP1_PING_FULL */
3356#define WM2200_DSP1_PING_FULL_SHIFT 15 /* DSP1_PING_FULL */
3357#define WM2200_DSP1_PING_FULL_WIDTH 1 /* DSP1_PING_FULL */
3358#define WM2200_DSP1_PONG_FULL 0x4000 /* DSP1_PONG_FULL */
3359#define WM2200_DSP1_PONG_FULL_MASK 0x4000 /* DSP1_PONG_FULL */
3360#define WM2200_DSP1_PONG_FULL_SHIFT 14 /* DSP1_PONG_FULL */
3361#define WM2200_DSP1_PONG_FULL_WIDTH 1 /* DSP1_PONG_FULL */
3362#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3363#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3364#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3365
3366/*
3367 * R2592 (0xA20) - DSP1 Control 26
3368 */
3369#define WM2200_DSP1_SCRATCH_0_MASK 0xFFFF /* DSP1_SCRATCH_0 - [15:0] */
3370#define WM2200_DSP1_SCRATCH_0_SHIFT 0 /* DSP1_SCRATCH_0 - [15:0] */
3371#define WM2200_DSP1_SCRATCH_0_WIDTH 16 /* DSP1_SCRATCH_0 - [15:0] */
3372
3373/*
3374 * R2593 (0xA21) - DSP1 Control 27
3375 */
3376#define WM2200_DSP1_SCRATCH_1_MASK 0xFFFF /* DSP1_SCRATCH_1 - [15:0] */
3377#define WM2200_DSP1_SCRATCH_1_SHIFT 0 /* DSP1_SCRATCH_1 - [15:0] */
3378#define WM2200_DSP1_SCRATCH_1_WIDTH 16 /* DSP1_SCRATCH_1 - [15:0] */
3379
3380/*
3381 * R2594 (0xA22) - DSP1 Control 28
3382 */
3383#define WM2200_DSP1_SCRATCH_2_MASK 0xFFFF /* DSP1_SCRATCH_2 - [15:0] */
3384#define WM2200_DSP1_SCRATCH_2_SHIFT 0 /* DSP1_SCRATCH_2 - [15:0] */
3385#define WM2200_DSP1_SCRATCH_2_WIDTH 16 /* DSP1_SCRATCH_2 - [15:0] */
3386
3387/*
3388 * R2595 (0xA23) - DSP1 Control 29
3389 */
3390#define WM2200_DSP1_SCRATCH_3_MASK 0xFFFF /* DSP1_SCRATCH_3 - [15:0] */
3391#define WM2200_DSP1_SCRATCH_3_SHIFT 0 /* DSP1_SCRATCH_3 - [15:0] */
3392#define WM2200_DSP1_SCRATCH_3_WIDTH 16 /* DSP1_SCRATCH_3 - [15:0] */
3393
3394/*
3395 * R2596 (0xA24) - DSP1 Control 30
3396 */
3397#define WM2200_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */
3398#define WM2200_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */
3399#define WM2200_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */
3400#define WM2200_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */
3401#define WM2200_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */
3402#define WM2200_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */
3403#define WM2200_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */
3404#define WM2200_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */
3405#define WM2200_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */
3406#define WM2200_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */
3407#define WM2200_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */
3408#define WM2200_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */
3409#define WM2200_DSP1_START 0x0001 /* DSP1_START */
3410#define WM2200_DSP1_START_MASK 0x0001 /* DSP1_START */
3411#define WM2200_DSP1_START_SHIFT 0 /* DSP1_START */
3412#define WM2200_DSP1_START_WIDTH 1 /* DSP1_START */
3413
3414/*
3415 * R2598 (0xA26) - DSP1 Control 31
3416 */
3417#define WM2200_DSP1_CLK_RATE_MASK 0x0018 /* DSP1_CLK_RATE - [4:3] */
3418#define WM2200_DSP1_CLK_RATE_SHIFT 3 /* DSP1_CLK_RATE - [4:3] */
3419#define WM2200_DSP1_CLK_RATE_WIDTH 2 /* DSP1_CLK_RATE - [4:3] */
3420#define WM2200_DSP1_CLK_AVAIL 0x0004 /* DSP1_CLK_AVAIL */
3421#define WM2200_DSP1_CLK_AVAIL_MASK 0x0004 /* DSP1_CLK_AVAIL */
3422#define WM2200_DSP1_CLK_AVAIL_SHIFT 2 /* DSP1_CLK_AVAIL */
3423#define WM2200_DSP1_CLK_AVAIL_WIDTH 1 /* DSP1_CLK_AVAIL */
3424#define WM2200_DSP1_CLK_REQ_MASK 0x0003 /* DSP1_CLK_REQ - [1:0] */
3425#define WM2200_DSP1_CLK_REQ_SHIFT 0 /* DSP1_CLK_REQ - [1:0] */
3426#define WM2200_DSP1_CLK_REQ_WIDTH 2 /* DSP1_CLK_REQ - [1:0] */
3427
3428/*
3429 * R2816 (0xB00) - DSP2 Control 1
3430 */
3431#define WM2200_DSP2_RW_SEQUENCE_ENA 0x0001 /* DSP2_RW_SEQUENCE_ENA */
3432#define WM2200_DSP2_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP2_RW_SEQUENCE_ENA */
3433#define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT 0 /* DSP2_RW_SEQUENCE_ENA */
3434#define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH 1 /* DSP2_RW_SEQUENCE_ENA */
3435
3436/*
3437 * R2818 (0xB02) - DSP2 Control 2
3438 */
3439#define WM2200_DSP2_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_PM - [15:8] */
3440#define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT 8 /* DSP2_PAGE_BASE_PM - [15:8] */
3441#define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH 8 /* DSP2_PAGE_BASE_PM - [15:8] */
3442
3443/*
3444 * R2819 (0xB03) - DSP2 Control 3
3445 */
3446#define WM2200_DSP2_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_DM - [15:8] */
3447#define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT 8 /* DSP2_PAGE_BASE_DM - [15:8] */
3448#define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH 8 /* DSP2_PAGE_BASE_DM - [15:8] */
3449
3450/*
3451 * R2820 (0xB04) - DSP2 Control 4
3452 */
3453#define WM2200_DSP2_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_ZM - [15:8] */
3454#define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
3455#define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
3456
3457/*
3458 * R2822 (0xB06) - DSP2 Control 5
3459 */
3460#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3461#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3462#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3463
3464/*
3465 * R2823 (0xB07) - DSP2 Control 6
3466 */
3467#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3468#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3469#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3470
3471/*
3472 * R2824 (0xB08) - DSP2 Control 7
3473 */
3474#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3475#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3476#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3477
3478/*
3479 * R2825 (0xB09) - DSP2 Control 8
3480 */
3481#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3482#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3483#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3484
3485/*
3486 * R2826 (0xB0A) - DSP2 Control 9
3487 */
3488#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3489#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3490#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3491
3492/*
3493 * R2827 (0xB0B) - DSP2 Control 10
3494 */
3495#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3496#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3497#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3498
3499/*
3500 * R2828 (0xB0C) - DSP2 Control 11
3501 */
3502#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3503#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3504#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3505
3506/*
3507 * R2829 (0xB0D) - DSP2 Control 12
3508 */
3509#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3510#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3511#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3512
3513/*
3514 * R2831 (0xB0F) - DSP2 Control 13
3515 */
3516#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3517#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3518#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3519
3520/*
3521 * R2832 (0xB10) - DSP2 Control 14
3522 */
3523#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3524#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3525#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3526
3527/*
3528 * R2833 (0xB11) - DSP2 Control 15
3529 */
3530#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3531#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3532#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3533
3534/*
3535 * R2834 (0xB12) - DSP2 Control 16
3536 */
3537#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3538#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3539#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3540
3541/*
3542 * R2835 (0xB13) - DSP2 Control 17
3543 */
3544#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3545#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3546#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3547
3548/*
3549 * R2836 (0xB14) - DSP2 Control 18
3550 */
3551#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3552#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3553#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3554
3555/*
3556 * R2838 (0xB16) - DSP2 Control 19
3557 */
3558#define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3559#define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3560#define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3561
3562/*
3563 * R2839 (0xB17) - DSP2 Control 20
3564 */
3565#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3566#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3567#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3568
3569/*
3570 * R2840 (0xB18) - DSP2 Control 21
3571 */
3572#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3573#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3574#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3575
3576/*
3577 * R2842 (0xB1A) - DSP2 Control 22
3578 */
3579#define WM2200_DSP2_DM_SIZE_MASK 0xFFFF /* DSP2_DM_SIZE - [15:0] */
3580#define WM2200_DSP2_DM_SIZE_SHIFT 0 /* DSP2_DM_SIZE - [15:0] */
3581#define WM2200_DSP2_DM_SIZE_WIDTH 16 /* DSP2_DM_SIZE - [15:0] */
3582
3583/*
3584 * R2843 (0xB1B) - DSP2 Control 23
3585 */
3586#define WM2200_DSP2_PM_SIZE_MASK 0xFFFF /* DSP2_PM_SIZE - [15:0] */
3587#define WM2200_DSP2_PM_SIZE_SHIFT 0 /* DSP2_PM_SIZE - [15:0] */
3588#define WM2200_DSP2_PM_SIZE_WIDTH 16 /* DSP2_PM_SIZE - [15:0] */
3589
3590/*
3591 * R2844 (0xB1C) - DSP2 Control 24
3592 */
3593#define WM2200_DSP2_ZM_SIZE_MASK 0xFFFF /* DSP2_ZM_SIZE - [15:0] */
3594#define WM2200_DSP2_ZM_SIZE_SHIFT 0 /* DSP2_ZM_SIZE - [15:0] */
3595#define WM2200_DSP2_ZM_SIZE_WIDTH 16 /* DSP2_ZM_SIZE - [15:0] */
3596
3597/*
3598 * R2846 (0xB1E) - DSP2 Control 25
3599 */
3600#define WM2200_DSP2_PING_FULL 0x8000 /* DSP2_PING_FULL */
3601#define WM2200_DSP2_PING_FULL_MASK 0x8000 /* DSP2_PING_FULL */
3602#define WM2200_DSP2_PING_FULL_SHIFT 15 /* DSP2_PING_FULL */
3603#define WM2200_DSP2_PING_FULL_WIDTH 1 /* DSP2_PING_FULL */
3604#define WM2200_DSP2_PONG_FULL 0x4000 /* DSP2_PONG_FULL */
3605#define WM2200_DSP2_PONG_FULL_MASK 0x4000 /* DSP2_PONG_FULL */
3606#define WM2200_DSP2_PONG_FULL_SHIFT 14 /* DSP2_PONG_FULL */
3607#define WM2200_DSP2_PONG_FULL_WIDTH 1 /* DSP2_PONG_FULL */
3608#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3609#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3610#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3611
3612/*
3613 * R2848 (0xB20) - DSP2 Control 26
3614 */
3615#define WM2200_DSP2_SCRATCH_0_MASK 0xFFFF /* DSP2_SCRATCH_0 - [15:0] */
3616#define WM2200_DSP2_SCRATCH_0_SHIFT 0 /* DSP2_SCRATCH_0 - [15:0] */
3617#define WM2200_DSP2_SCRATCH_0_WIDTH 16 /* DSP2_SCRATCH_0 - [15:0] */
3618
3619/*
3620 * R2849 (0xB21) - DSP2 Control 27
3621 */
3622#define WM2200_DSP2_SCRATCH_1_MASK 0xFFFF /* DSP2_SCRATCH_1 - [15:0] */
3623#define WM2200_DSP2_SCRATCH_1_SHIFT 0 /* DSP2_SCRATCH_1 - [15:0] */
3624#define WM2200_DSP2_SCRATCH_1_WIDTH 16 /* DSP2_SCRATCH_1 - [15:0] */
3625
3626/*
3627 * R2850 (0xB22) - DSP2 Control 28
3628 */
3629#define WM2200_DSP2_SCRATCH_2_MASK 0xFFFF /* DSP2_SCRATCH_2 - [15:0] */
3630#define WM2200_DSP2_SCRATCH_2_SHIFT 0 /* DSP2_SCRATCH_2 - [15:0] */
3631#define WM2200_DSP2_SCRATCH_2_WIDTH 16 /* DSP2_SCRATCH_2 - [15:0] */
3632
3633/*
3634 * R2851 (0xB23) - DSP2 Control 29
3635 */
3636#define WM2200_DSP2_SCRATCH_3_MASK 0xFFFF /* DSP2_SCRATCH_3 - [15:0] */
3637#define WM2200_DSP2_SCRATCH_3_SHIFT 0 /* DSP2_SCRATCH_3 - [15:0] */
3638#define WM2200_DSP2_SCRATCH_3_WIDTH 16 /* DSP2_SCRATCH_3 - [15:0] */
3639
3640/*
3641 * R2852 (0xB24) - DSP2 Control 30
3642 */
3643#define WM2200_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */
3644#define WM2200_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */
3645#define WM2200_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */
3646#define WM2200_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */
3647#define WM2200_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */
3648#define WM2200_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */
3649#define WM2200_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */
3650#define WM2200_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */
3651#define WM2200_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */
3652#define WM2200_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */
3653#define WM2200_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */
3654#define WM2200_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */
3655#define WM2200_DSP2_START 0x0001 /* DSP2_START */
3656#define WM2200_DSP2_START_MASK 0x0001 /* DSP2_START */
3657#define WM2200_DSP2_START_SHIFT 0 /* DSP2_START */
3658#define WM2200_DSP2_START_WIDTH 1 /* DSP2_START */
3659
3660/*
3661 * R2854 (0xB26) - DSP2 Control 31
3662 */
3663#define WM2200_DSP2_CLK_RATE_MASK 0x0018 /* DSP2_CLK_RATE - [4:3] */
3664#define WM2200_DSP2_CLK_RATE_SHIFT 3 /* DSP2_CLK_RATE - [4:3] */
3665#define WM2200_DSP2_CLK_RATE_WIDTH 2 /* DSP2_CLK_RATE - [4:3] */
3666#define WM2200_DSP2_CLK_AVAIL 0x0004 /* DSP2_CLK_AVAIL */
3667#define WM2200_DSP2_CLK_AVAIL_MASK 0x0004 /* DSP2_CLK_AVAIL */
3668#define WM2200_DSP2_CLK_AVAIL_SHIFT 2 /* DSP2_CLK_AVAIL */
3669#define WM2200_DSP2_CLK_AVAIL_WIDTH 1 /* DSP2_CLK_AVAIL */
3670#define WM2200_DSP2_CLK_REQ_MASK 0x0003 /* DSP2_CLK_REQ - [1:0] */
3671#define WM2200_DSP2_CLK_REQ_SHIFT 0 /* DSP2_CLK_REQ - [1:0] */
3672#define WM2200_DSP2_CLK_REQ_WIDTH 2 /* DSP2_CLK_REQ - [1:0] */
3673
3674#endif
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 89f2af77b1c3..b9c185ce64e4 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -18,6 +18,7 @@
18#include <linux/gcd.h> 18#include <linux/gcd.h>
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/pm_runtime.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/regulator/fixed.h> 23#include <linux/regulator/fixed.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -50,13 +51,11 @@ struct wm5100_fll {
50 51
51/* codec private data */ 52/* codec private data */
52struct wm5100_priv { 53struct wm5100_priv {
54 struct device *dev;
53 struct regmap *regmap; 55 struct regmap *regmap;
54 struct snd_soc_codec *codec; 56 struct snd_soc_codec *codec;
55 57
56 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; 58 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
57 struct regulator *cpvdd;
58 struct regulator *dbvdd2;
59 struct regulator *dbvdd3;
60 59
61 int rev; 60 int rev;
62 61
@@ -73,6 +72,7 @@ struct wm5100_priv {
73 bool jack_detecting; 72 bool jack_detecting;
74 bool jack_mic; 73 bool jack_mic;
75 int jack_mode; 74 int jack_mode;
75 int jack_flips;
76 76
77 struct wm5100_fll fll[2]; 77 struct wm5100_fll fll[2];
78 78
@@ -709,6 +709,8 @@ WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
709 709
710WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), 710WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
711WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), 711WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
712SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5,
713 WM5100_DRCL_ENA | WM5100_DRCR_ENA),
712 714
713WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), 715WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
714WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), 716WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
@@ -776,127 +778,48 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
776 return 0; 778 return 0;
777} 779}
778 780
779static int wm5100_cp_ev(struct snd_soc_dapm_widget *w, 781static void wm5100_log_status3(struct wm5100_priv *wm5100, int val)
780 struct snd_kcontrol *kcontrol,
781 int event)
782{
783 struct snd_soc_codec *codec = w->codec;
784 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
785 int ret;
786
787 switch (event) {
788 case SND_SOC_DAPM_PRE_PMU:
789 ret = regulator_enable(wm5100->cpvdd);
790 if (ret != 0) {
791 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
792 ret);
793 return ret;
794 }
795 return ret;
796
797 case SND_SOC_DAPM_POST_PMD:
798 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
799 if (ret != 0) {
800 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
801 ret);
802 return ret;
803 }
804 return ret;
805
806 default:
807 BUG();
808 return 0;
809 }
810}
811
812static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
813 struct snd_kcontrol *kcontrol,
814 int event)
815{
816 struct snd_soc_codec *codec = w->codec;
817 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
818 struct regulator *regulator;
819 int ret;
820
821 switch (w->shift) {
822 case 2:
823 regulator = wm5100->dbvdd2;
824 break;
825 case 3:
826 regulator = wm5100->dbvdd3;
827 break;
828 default:
829 BUG();
830 return 0;
831 }
832
833 switch (event) {
834 case SND_SOC_DAPM_PRE_PMU:
835 ret = regulator_enable(regulator);
836 if (ret != 0) {
837 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
838 w->shift, ret);
839 return ret;
840 }
841 return ret;
842
843 case SND_SOC_DAPM_POST_PMD:
844 ret = regulator_disable(regulator);
845 if (ret != 0) {
846 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
847 w->shift, ret);
848 return ret;
849 }
850 return ret;
851
852 default:
853 BUG();
854 return 0;
855 }
856}
857
858static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
859{ 782{
860 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) 783 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
861 dev_crit(codec->dev, "Speaker shutdown warning\n"); 784 dev_crit(wm5100->dev, "Speaker shutdown warning\n");
862 if (val & WM5100_SPK_SHUTDOWN_EINT) 785 if (val & WM5100_SPK_SHUTDOWN_EINT)
863 dev_crit(codec->dev, "Speaker shutdown\n"); 786 dev_crit(wm5100->dev, "Speaker shutdown\n");
864 if (val & WM5100_CLKGEN_ERR_EINT) 787 if (val & WM5100_CLKGEN_ERR_EINT)
865 dev_crit(codec->dev, "SYSCLK underclocked\n"); 788 dev_crit(wm5100->dev, "SYSCLK underclocked\n");
866 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT) 789 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
867 dev_crit(codec->dev, "ASYNCCLK underclocked\n"); 790 dev_crit(wm5100->dev, "ASYNCCLK underclocked\n");
868} 791}
869 792
870static void wm5100_log_status4(struct snd_soc_codec *codec, int val) 793static void wm5100_log_status4(struct wm5100_priv *wm5100, int val)
871{ 794{
872 if (val & WM5100_AIF3_ERR_EINT) 795 if (val & WM5100_AIF3_ERR_EINT)
873 dev_err(codec->dev, "AIF3 configuration error\n"); 796 dev_err(wm5100->dev, "AIF3 configuration error\n");
874 if (val & WM5100_AIF2_ERR_EINT) 797 if (val & WM5100_AIF2_ERR_EINT)
875 dev_err(codec->dev, "AIF2 configuration error\n"); 798 dev_err(wm5100->dev, "AIF2 configuration error\n");
876 if (val & WM5100_AIF1_ERR_EINT) 799 if (val & WM5100_AIF1_ERR_EINT)
877 dev_err(codec->dev, "AIF1 configuration error\n"); 800 dev_err(wm5100->dev, "AIF1 configuration error\n");
878 if (val & WM5100_CTRLIF_ERR_EINT) 801 if (val & WM5100_CTRLIF_ERR_EINT)
879 dev_err(codec->dev, "Control interface error\n"); 802 dev_err(wm5100->dev, "Control interface error\n");
880 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT) 803 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
881 dev_err(codec->dev, "ISRC2 underclocked\n"); 804 dev_err(wm5100->dev, "ISRC2 underclocked\n");
882 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT) 805 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
883 dev_err(codec->dev, "ISRC1 underclocked\n"); 806 dev_err(wm5100->dev, "ISRC1 underclocked\n");
884 if (val & WM5100_FX_UNDERCLOCKED_EINT) 807 if (val & WM5100_FX_UNDERCLOCKED_EINT)
885 dev_err(codec->dev, "FX underclocked\n"); 808 dev_err(wm5100->dev, "FX underclocked\n");
886 if (val & WM5100_AIF3_UNDERCLOCKED_EINT) 809 if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
887 dev_err(codec->dev, "AIF3 underclocked\n"); 810 dev_err(wm5100->dev, "AIF3 underclocked\n");
888 if (val & WM5100_AIF2_UNDERCLOCKED_EINT) 811 if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
889 dev_err(codec->dev, "AIF2 underclocked\n"); 812 dev_err(wm5100->dev, "AIF2 underclocked\n");
890 if (val & WM5100_AIF1_UNDERCLOCKED_EINT) 813 if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
891 dev_err(codec->dev, "AIF1 underclocked\n"); 814 dev_err(wm5100->dev, "AIF1 underclocked\n");
892 if (val & WM5100_ASRC_UNDERCLOCKED_EINT) 815 if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
893 dev_err(codec->dev, "ASRC underclocked\n"); 816 dev_err(wm5100->dev, "ASRC underclocked\n");
894 if (val & WM5100_DAC_UNDERCLOCKED_EINT) 817 if (val & WM5100_DAC_UNDERCLOCKED_EINT)
895 dev_err(codec->dev, "DAC underclocked\n"); 818 dev_err(wm5100->dev, "DAC underclocked\n");
896 if (val & WM5100_ADC_UNDERCLOCKED_EINT) 819 if (val & WM5100_ADC_UNDERCLOCKED_EINT)
897 dev_err(codec->dev, "ADC underclocked\n"); 820 dev_err(wm5100->dev, "ADC underclocked\n");
898 if (val & WM5100_MIXER_UNDERCLOCKED_EINT) 821 if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
899 dev_err(codec->dev, "Mixer underclocked\n"); 822 dev_err(wm5100->dev, "Mixer underclocked\n");
900} 823}
901 824
902static int wm5100_post_ev(struct snd_soc_dapm_widget *w, 825static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
@@ -904,16 +827,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
904 int event) 827 int event)
905{ 828{
906 struct snd_soc_codec *codec = w->codec; 829 struct snd_soc_codec *codec = w->codec;
830 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
907 int ret; 831 int ret;
908 832
909 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3); 833 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
910 ret &= WM5100_SPK_SHUTDOWN_WARN_STS | 834 ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
911 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS | 835 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
912 WM5100_CLKGEN_ERR_ASYNC_STS; 836 WM5100_CLKGEN_ERR_ASYNC_STS;
913 wm5100_log_status3(codec, ret); 837 wm5100_log_status3(wm5100, ret);
914 838
915 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4); 839 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
916 wm5100_log_status4(codec, ret); 840 wm5100_log_status4(wm5100, ret);
917 841
918 return 0; 842 return 0;
919} 843}
@@ -924,18 +848,16 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
924SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, 848SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
925 0, NULL, 0), 849 0, NULL, 0),
926 850
851SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
852SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
853SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
854
927SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, 855SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
928 wm5100_cp_ev, 856 NULL, 0),
929 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
930SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, 857SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
931 NULL, 0), 858 NULL, 0),
932SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, 859SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
933 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev, 860 WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0),
934 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
935SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
937SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
939 861
940SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, 862SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
941 0, NULL, 0), 863 0, NULL, 0),
@@ -1146,6 +1068,9 @@ SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1146}; 1068};
1147 1069
1148static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { 1070static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1071 { "CP1", NULL, "CPVDD" },
1072 { "CP2 Active", NULL, "CPVDD" },
1073
1149 { "IN1L", NULL, "SYSCLK" }, 1074 { "IN1L", NULL, "SYSCLK" },
1150 { "IN1R", NULL, "SYSCLK" }, 1075 { "IN1R", NULL, "SYSCLK" },
1151 { "IN2L", NULL, "SYSCLK" }, 1076 { "IN2L", NULL, "SYSCLK" },
@@ -1308,10 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1308 { "PWM2", NULL, "PWM2 Driver" }, 1233 { "PWM2", NULL, "PWM2 Driver" },
1309}; 1234};
1310 1235
1311static struct { 1236static const __devinitdata struct reg_default wm5100_reva_patches[] = {
1312 int reg;
1313 int val;
1314} wm5100_reva_patches[] = {
1315 { WM5100_AUDIO_IF_1_10, 0 }, 1237 { WM5100_AUDIO_IF_1_10, 0 },
1316 { WM5100_AUDIO_IF_1_11, 1 }, 1238 { WM5100_AUDIO_IF_1_11, 1 },
1317 { WM5100_AUDIO_IF_1_12, 2 }, 1239 { WM5100_AUDIO_IF_1_12, 2 },
@@ -1343,80 +1265,6 @@ static struct {
1343 { WM5100_AUDIO_IF_3_19, 1 }, 1265 { WM5100_AUDIO_IF_3_19, 1 },
1344}; 1266};
1345 1267
1346static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1347 enum snd_soc_bias_level level)
1348{
1349 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1350 int ret, i;
1351
1352 switch (level) {
1353 case SND_SOC_BIAS_ON:
1354 break;
1355
1356 case SND_SOC_BIAS_PREPARE:
1357 break;
1358
1359 case SND_SOC_BIAS_STANDBY:
1360 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1361 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1362 wm5100->core_supplies);
1363 if (ret != 0) {
1364 dev_err(codec->dev,
1365 "Failed to enable supplies: %d\n",
1366 ret);
1367 return ret;
1368 }
1369
1370 if (wm5100->pdata.ldo_ena) {
1371 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1372 1);
1373 msleep(2);
1374 }
1375
1376 regcache_cache_only(wm5100->regmap, false);
1377
1378 switch (wm5100->rev) {
1379 case 0:
1380 regcache_cache_bypass(wm5100->regmap, true);
1381 snd_soc_write(codec, 0x11, 0x3);
1382 snd_soc_write(codec, 0x203, 0xc);
1383 snd_soc_write(codec, 0x206, 0);
1384 snd_soc_write(codec, 0x207, 0xf0);
1385 snd_soc_write(codec, 0x208, 0x3c);
1386 snd_soc_write(codec, 0x209, 0);
1387 snd_soc_write(codec, 0x211, 0x20d8);
1388 snd_soc_write(codec, 0x11, 0);
1389
1390 for (i = 0;
1391 i < ARRAY_SIZE(wm5100_reva_patches);
1392 i++)
1393 snd_soc_write(codec,
1394 wm5100_reva_patches[i].reg,
1395 wm5100_reva_patches[i].val);
1396 regcache_cache_bypass(wm5100->regmap, false);
1397 break;
1398 default:
1399 break;
1400 }
1401
1402 regcache_sync(wm5100->regmap);
1403 }
1404 break;
1405
1406 case SND_SOC_BIAS_OFF:
1407 regcache_cache_only(wm5100->regmap, true);
1408 regcache_mark_dirty(wm5100->regmap);
1409 if (wm5100->pdata.ldo_ena)
1410 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1411 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1412 wm5100->core_supplies);
1413 break;
1414 }
1415 codec->dapm.bias_level = level;
1416
1417 return 0;
1418}
1419
1420static int wm5100_dai_to_base(struct snd_soc_dai *dai) 1268static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1421{ 1269{
1422 switch (dai->id) { 1270 switch (dai->id) {
@@ -1944,6 +1792,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1944 1792
1945 if (!Fout) { 1793 if (!Fout) {
1946 dev_dbg(codec->dev, "FLL%d disabled", fll_id); 1794 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1795 if (fll->fout)
1796 pm_runtime_put(codec->dev);
1947 fll->fout = 0; 1797 fll->fout = 0;
1948 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); 1798 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1949 return 0; 1799 return 0;
@@ -1988,6 +1838,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1988 /* Clear any pending completions */ 1838 /* Clear any pending completions */
1989 try_wait_for_completion(&fll->lock); 1839 try_wait_for_completion(&fll->lock);
1990 1840
1841 pm_runtime_get_sync(codec->dev);
1842
1991 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); 1843 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1992 1844
1993 if (i2c->irq) 1845 if (i2c->irq)
@@ -2022,6 +1874,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2022 } 1874 }
2023 if (i == timeout) { 1875 if (i == timeout) {
2024 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); 1876 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
1877 pm_runtime_put(codec->dev);
2025 return -ETIMEDOUT; 1878 return -ETIMEDOUT;
2026 } 1879 }
2027 1880
@@ -2124,55 +1977,73 @@ static int wm5100_dig_vu[] = {
2124 WM5100_DAC_DIGITAL_VOLUME_6R, 1977 WM5100_DAC_DIGITAL_VOLUME_6R,
2125}; 1978};
2126 1979
2127static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode) 1980static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
2128{ 1981{
2129 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2130 struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode]; 1982 struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
2131 1983
2132 BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)); 1984 BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
2133 1985
2134 gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); 1986 gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
2135 snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1, 1987 regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1,
2136 WM5100_ACCDET_BIAS_SRC_MASK | 1988 WM5100_ACCDET_BIAS_SRC_MASK |
2137 WM5100_ACCDET_SRC, 1989 WM5100_ACCDET_SRC,
2138 (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | 1990 (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
2139 mode->micd_src << WM5100_ACCDET_SRC_SHIFT); 1991 mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
2140 snd_soc_update_bits(codec, WM5100_MISC_CONTROL, 1992 regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL,
2141 WM5100_HPCOM_SRC, 1993 WM5100_HPCOM_SRC,
2142 mode->micd_src << WM5100_HPCOM_SRC_SHIFT); 1994 mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
2143 1995
2144 wm5100->jack_mode = the_mode; 1996 wm5100->jack_mode = the_mode;
2145 1997
2146 dev_dbg(codec->dev, "Set microphone polarity to %d\n", 1998 dev_dbg(wm5100->dev, "Set microphone polarity to %d\n",
2147 wm5100->jack_mode); 1999 wm5100->jack_mode);
2148} 2000}
2149 2001
2150static void wm5100_micd_irq(struct snd_soc_codec *codec) 2002static void wm5100_report_headphone(struct wm5100_priv *wm5100)
2151{ 2003{
2152 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); 2004 dev_dbg(wm5100->dev, "Headphone detected\n");
2153 int val; 2005 wm5100->jack_detecting = false;
2006 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2007 SND_JACK_HEADPHONE);
2008
2009 /* Increase the detection rate a bit for responsiveness. */
2010 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2011 WM5100_ACCDET_RATE_MASK,
2012 7 << WM5100_ACCDET_RATE_SHIFT);
2013}
2154 2014
2155 val = snd_soc_read(codec, WM5100_MIC_DETECT_3); 2015static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2016{
2017 unsigned int val;
2018 int ret;
2156 2019
2157 dev_dbg(codec->dev, "Microphone event: %x\n", val); 2020 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
2021 if (ret != 0) {
2022 dev_err(wm5100->dev, "Failed to read micropone status: %d\n",
2023 ret);
2024 return;
2025 }
2026
2027 dev_dbg(wm5100->dev, "Microphone event: %x\n", val);
2158 2028
2159 if (!(val & WM5100_ACCDET_VALID)) { 2029 if (!(val & WM5100_ACCDET_VALID)) {
2160 dev_warn(codec->dev, "Microphone detection state invalid\n"); 2030 dev_warn(wm5100->dev, "Microphone detection state invalid\n");
2161 return; 2031 return;
2162 } 2032 }
2163 2033
2164 /* No accessory, reset everything and report removal */ 2034 /* No accessory, reset everything and report removal */
2165 if (!(val & WM5100_ACCDET_STS)) { 2035 if (!(val & WM5100_ACCDET_STS)) {
2166 dev_dbg(codec->dev, "Jack removal detected\n"); 2036 dev_dbg(wm5100->dev, "Jack removal detected\n");
2167 wm5100->jack_mic = false; 2037 wm5100->jack_mic = false;
2168 wm5100->jack_detecting = true; 2038 wm5100->jack_detecting = true;
2039 wm5100->jack_flips = 0;
2169 snd_soc_jack_report(wm5100->jack, 0, 2040 snd_soc_jack_report(wm5100->jack, 0,
2170 SND_JACK_LINEOUT | SND_JACK_HEADSET | 2041 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2171 SND_JACK_BTN_0); 2042 SND_JACK_BTN_0);
2172 2043
2173 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, 2044 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2174 WM5100_ACCDET_RATE_MASK, 2045 WM5100_ACCDET_RATE_MASK,
2175 WM5100_ACCDET_RATE_MASK); 2046 WM5100_ACCDET_RATE_MASK);
2176 return; 2047 return;
2177 } 2048 }
2178 2049
@@ -2182,7 +2053,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
2182 */ 2053 */
2183 if (val & 0x400) { 2054 if (val & 0x400) {
2184 if (wm5100->jack_detecting) { 2055 if (wm5100->jack_detecting) {
2185 dev_dbg(codec->dev, "Microphone detected\n"); 2056 dev_dbg(wm5100->dev, "Microphone detected\n");
2186 wm5100->jack_mic = true; 2057 wm5100->jack_mic = true;
2187 wm5100->jack_detecting = false; 2058 wm5100->jack_detecting = false;
2188 snd_soc_jack_report(wm5100->jack, 2059 snd_soc_jack_report(wm5100->jack,
@@ -2191,11 +2062,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
2191 2062
2192 /* Increase poll rate to give better responsiveness 2063 /* Increase poll rate to give better responsiveness
2193 * for buttons */ 2064 * for buttons */
2194 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, 2065 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2195 WM5100_ACCDET_RATE_MASK, 2066 WM5100_ACCDET_RATE_MASK,
2196 5 << WM5100_ACCDET_RATE_SHIFT); 2067 5 << WM5100_ACCDET_RATE_SHIFT);
2197 } else { 2068 } else {
2198 dev_dbg(codec->dev, "Mic button up\n"); 2069 dev_dbg(wm5100->dev, "Mic button up\n");
2199 snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0); 2070 snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
2200 } 2071 }
2201 2072
@@ -2205,10 +2076,16 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
2205 /* If we detected a lower impedence during initial startup 2076 /* If we detected a lower impedence during initial startup
2206 * then we probably have the wrong polarity, flip it. Don't 2077 * then we probably have the wrong polarity, flip it. Don't
2207 * do this for the lowest impedences to speed up detection of 2078 * do this for the lowest impedences to speed up detection of
2208 * plain headphones. 2079 * plain headphones and give up if neither polarity looks
2080 * sensible.
2209 */ 2081 */
2210 if (wm5100->jack_detecting && (val & 0x3f8)) { 2082 if (wm5100->jack_detecting && (val & 0x3f8)) {
2211 wm5100_set_detect_mode(codec, !wm5100->jack_mode); 2083 wm5100->jack_flips++;
2084
2085 if (wm5100->jack_flips > 1)
2086 wm5100_report_headphone(wm5100);
2087 else
2088 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
2212 2089
2213 return; 2090 return;
2214 } 2091 }
@@ -2218,21 +2095,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
2218 */ 2095 */
2219 if (val & 0x3fc) { 2096 if (val & 0x3fc) {
2220 if (wm5100->jack_mic) { 2097 if (wm5100->jack_mic) {
2221 dev_dbg(codec->dev, "Mic button detected\n"); 2098 dev_dbg(wm5100->dev, "Mic button detected\n");
2222 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, 2099 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2223 SND_JACK_BTN_0); 2100 SND_JACK_BTN_0);
2224 } else if (wm5100->jack_detecting) { 2101 } else if (wm5100->jack_detecting) {
2225 dev_dbg(codec->dev, "Headphone detected\n"); 2102 wm5100_report_headphone(wm5100);
2226 wm5100->jack_detecting = false;
2227 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2228 SND_JACK_HEADPHONE);
2229
2230 /* Increase the detection rate a bit for
2231 * responsiveness.
2232 */
2233 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2234 WM5100_ACCDET_RATE_MASK,
2235 7 << WM5100_ACCDET_RATE_SHIFT);
2236 } 2103 }
2237 } 2104 }
2238} 2105}
@@ -2244,8 +2111,9 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2244 if (jack) { 2111 if (jack) {
2245 wm5100->jack = jack; 2112 wm5100->jack = jack;
2246 wm5100->jack_detecting = true; 2113 wm5100->jack_detecting = true;
2114 wm5100->jack_flips = 0;
2247 2115
2248 wm5100_set_detect_mode(codec, 0); 2116 wm5100_set_detect_mode(wm5100, 0);
2249 2117
2250 /* Slowest detection rate, gives debounce for initial 2118 /* Slowest detection rate, gives debounce for initial
2251 * detection */ 2119 * detection */
@@ -2284,52 +2152,70 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2284 2152
2285static irqreturn_t wm5100_irq(int irq, void *data) 2153static irqreturn_t wm5100_irq(int irq, void *data)
2286{ 2154{
2287 struct snd_soc_codec *codec = data; 2155 struct wm5100_priv *wm5100 = data;
2288 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2289 irqreturn_t status = IRQ_NONE; 2156 irqreturn_t status = IRQ_NONE;
2290 int irq_val; 2157 unsigned int irq_val, mask_val;
2158 int ret;
2291 2159
2292 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3); 2160 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val);
2293 if (irq_val < 0) { 2161 if (ret < 0) {
2294 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n", 2162 dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n",
2295 irq_val); 2163 ret);
2296 irq_val = 0; 2164 irq_val = 0;
2297 } 2165 }
2298 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2299 2166
2300 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val); 2167 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK,
2168 &mask_val);
2169 if (ret < 0) {
2170 dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n",
2171 ret);
2172 mask_val = 0xffff;
2173 }
2174
2175 irq_val &= ~mask_val;
2176
2177 regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val);
2301 2178
2302 if (irq_val) 2179 if (irq_val)
2303 status = IRQ_HANDLED; 2180 status = IRQ_HANDLED;
2304 2181
2305 wm5100_log_status3(codec, irq_val); 2182 wm5100_log_status3(wm5100, irq_val);
2306 2183
2307 if (irq_val & WM5100_FLL1_LOCK_EINT) { 2184 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2308 dev_dbg(codec->dev, "FLL1 locked\n"); 2185 dev_dbg(wm5100->dev, "FLL1 locked\n");
2309 complete(&wm5100->fll[0].lock); 2186 complete(&wm5100->fll[0].lock);
2310 } 2187 }
2311 if (irq_val & WM5100_FLL2_LOCK_EINT) { 2188 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2312 dev_dbg(codec->dev, "FLL2 locked\n"); 2189 dev_dbg(wm5100->dev, "FLL2 locked\n");
2313 complete(&wm5100->fll[1].lock); 2190 complete(&wm5100->fll[1].lock);
2314 } 2191 }
2315 2192
2316 if (irq_val & WM5100_ACCDET_EINT) 2193 if (irq_val & WM5100_ACCDET_EINT)
2317 wm5100_micd_irq(codec); 2194 wm5100_micd_irq(wm5100);
2318 2195
2319 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4); 2196 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val);
2320 if (irq_val < 0) { 2197 if (ret < 0) {
2321 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n", 2198 dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n",
2322 irq_val); 2199 ret);
2323 irq_val = 0; 2200 irq_val = 0;
2324 } 2201 }
2325 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK); 2202
2203 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK,
2204 &mask_val);
2205 if (ret < 0) {
2206 dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n",
2207 ret);
2208 mask_val = 0xffff;
2209 }
2210
2211 irq_val &= ~mask_val;
2326 2212
2327 if (irq_val) 2213 if (irq_val)
2328 status = IRQ_HANDLED; 2214 status = IRQ_HANDLED;
2329 2215
2330 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val); 2216 regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val);
2331 2217
2332 wm5100_log_status4(codec, irq_val); 2218 wm5100_log_status4(wm5100, irq_val);
2333 2219
2334 return status; 2220 return status;
2335} 2221}
@@ -2454,7 +2340,7 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2454{ 2340{
2455 struct i2c_client *i2c = to_i2c_client(codec->dev); 2341 struct i2c_client *i2c = to_i2c_client(codec->dev);
2456 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); 2342 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2457 int ret, i, irq_flags; 2343 int ret, i;
2458 2344
2459 wm5100->codec = codec; 2345 wm5100->codec = codec;
2460 codec->control_data = wm5100->regmap; 2346 codec->control_data = wm5100->regmap;
@@ -2465,9 +2351,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2465 return ret; 2351 return ret;
2466 } 2352 }
2467 2353
2468 regcache_cache_only(wm5100->regmap, true);
2469
2470
2471 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) 2354 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2472 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, 2355 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2473 WM5100_OUT_VU); 2356 WM5100_OUT_VU);
@@ -2478,60 +2361,10 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2478 2361
2479 /* TODO: check if we're symmetric */ 2362 /* TODO: check if we're symmetric */
2480 2363
2481 if (i2c->irq) { 2364 if (i2c->irq)
2482 if (wm5100->pdata.irq_flags)
2483 irq_flags = wm5100->pdata.irq_flags;
2484 else
2485 irq_flags = IRQF_TRIGGER_LOW;
2486
2487 irq_flags |= IRQF_ONESHOT;
2488
2489 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2490 ret = request_threaded_irq(i2c->irq, NULL,
2491 wm5100_edge_irq,
2492 irq_flags, "wm5100", codec);
2493 else
2494 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2495 irq_flags, "wm5100", codec);
2496
2497 if (ret != 0) {
2498 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2499 i2c->irq, ret);
2500 } else {
2501 /* Enable default interrupts */
2502 snd_soc_update_bits(codec,
2503 WM5100_INTERRUPT_STATUS_3_MASK,
2504 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2505 WM5100_IM_SPK_SHUTDOWN_EINT |
2506 WM5100_IM_ASRC2_LOCK_EINT |
2507 WM5100_IM_ASRC1_LOCK_EINT |
2508 WM5100_IM_FLL2_LOCK_EINT |
2509 WM5100_IM_FLL1_LOCK_EINT |
2510 WM5100_CLKGEN_ERR_EINT |
2511 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2512
2513 snd_soc_update_bits(codec,
2514 WM5100_INTERRUPT_STATUS_4_MASK,
2515 WM5100_AIF3_ERR_EINT |
2516 WM5100_AIF2_ERR_EINT |
2517 WM5100_AIF1_ERR_EINT |
2518 WM5100_CTRLIF_ERR_EINT |
2519 WM5100_ISRC2_UNDERCLOCKED_EINT |
2520 WM5100_ISRC1_UNDERCLOCKED_EINT |
2521 WM5100_FX_UNDERCLOCKED_EINT |
2522 WM5100_AIF3_UNDERCLOCKED_EINT |
2523 WM5100_AIF2_UNDERCLOCKED_EINT |
2524 WM5100_AIF1_UNDERCLOCKED_EINT |
2525 WM5100_ASRC_UNDERCLOCKED_EINT |
2526 WM5100_DAC_UNDERCLOCKED_EINT |
2527 WM5100_ADC_UNDERCLOCKED_EINT |
2528 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2529 }
2530 } else {
2531 snd_soc_dapm_new_controls(&codec->dapm, 2365 snd_soc_dapm_new_controls(&codec->dapm,
2532 wm5100_dapm_widgets_noirq, 2366 wm5100_dapm_widgets_noirq,
2533 ARRAY_SIZE(wm5100_dapm_widgets_noirq)); 2367 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2534 }
2535 2368
2536 if (wm5100->pdata.hp_pol) { 2369 if (wm5100->pdata.hp_pol) {
2537 ret = gpio_request_one(wm5100->pdata.hp_pol, 2370 ret = gpio_request_one(wm5100->pdata.hp_pol,
@@ -2543,19 +2376,9 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2543 } 2376 }
2544 } 2377 }
2545 2378
2546 /* We'll get woken up again when the system has something useful
2547 * for us to do.
2548 */
2549 if (wm5100->pdata.ldo_ena)
2550 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2551 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2552 wm5100->core_supplies);
2553
2554 return 0; 2379 return 0;
2555 2380
2556err_gpio: 2381err_gpio:
2557 if (i2c->irq)
2558 free_irq(i2c->irq, codec);
2559 2382
2560 return ret; 2383 return ret;
2561} 2384}
@@ -2563,14 +2386,11 @@ err_gpio:
2563static int wm5100_remove(struct snd_soc_codec *codec) 2386static int wm5100_remove(struct snd_soc_codec *codec)
2564{ 2387{
2565 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); 2388 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2566 struct i2c_client *i2c = to_i2c_client(codec->dev);
2567 2389
2568 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2569 if (wm5100->pdata.hp_pol) { 2390 if (wm5100->pdata.hp_pol) {
2570 gpio_free(wm5100->pdata.hp_pol); 2391 gpio_free(wm5100->pdata.hp_pol);
2571 } 2392 }
2572 if (i2c->irq) 2393
2573 free_irq(i2c->irq, codec);
2574 return 0; 2394 return 0;
2575} 2395}
2576 2396
@@ -2587,7 +2407,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2587 2407
2588 .set_sysclk = wm5100_set_sysclk, 2408 .set_sysclk = wm5100_set_sysclk,
2589 .set_pll = wm5100_set_fll, 2409 .set_pll = wm5100_set_fll,
2590 .set_bias_level = wm5100_set_bias_level,
2591 .idle_bias_off = 1, 2410 .idle_bias_off = 1,
2592 .reg_cache_size = WM5100_MAX_REGISTER, 2411 .reg_cache_size = WM5100_MAX_REGISTER,
2593 .volatile_register = wm5100_soc_volatile, 2412 .volatile_register = wm5100_soc_volatile,
@@ -2626,13 +2445,15 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2626 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); 2445 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2627 struct wm5100_priv *wm5100; 2446 struct wm5100_priv *wm5100;
2628 unsigned int reg; 2447 unsigned int reg;
2629 int ret, i; 2448 int ret, i, irq_flags;
2630 2449
2631 wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv), 2450 wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
2632 GFP_KERNEL); 2451 GFP_KERNEL);
2633 if (wm5100 == NULL) 2452 if (wm5100 == NULL)
2634 return -ENOMEM; 2453 return -ENOMEM;
2635 2454
2455 wm5100->dev = &i2c->dev;
2456
2636 wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); 2457 wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap);
2637 if (IS_ERR(wm5100->regmap)) { 2458 if (IS_ERR(wm5100->regmap)) {
2638 ret = PTR_ERR(wm5100->regmap); 2459 ret = PTR_ERR(wm5100->regmap);
@@ -2652,41 +2473,21 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2652 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) 2473 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2653 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; 2474 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2654 2475
2655 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), 2476 ret = devm_regulator_bulk_get(&i2c->dev,
2656 wm5100->core_supplies); 2477 ARRAY_SIZE(wm5100->core_supplies),
2478 wm5100->core_supplies);
2657 if (ret != 0) { 2479 if (ret != 0) {
2658 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", 2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2659 ret); 2481 ret);
2660 goto err_regmap; 2482 goto err_regmap;
2661 } 2483 }
2662 2484
2663 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2664 if (IS_ERR(wm5100->cpvdd)) {
2665 ret = PTR_ERR(wm5100->cpvdd);
2666 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2667 goto err_core;
2668 }
2669
2670 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2671 if (IS_ERR(wm5100->dbvdd2)) {
2672 ret = PTR_ERR(wm5100->dbvdd2);
2673 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2674 goto err_cpvdd;
2675 }
2676
2677 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2678 if (IS_ERR(wm5100->dbvdd3)) {
2679 ret = PTR_ERR(wm5100->dbvdd3);
2680 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2681 goto err_dbvdd2;
2682 }
2683
2684 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), 2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2685 wm5100->core_supplies); 2486 wm5100->core_supplies);
2686 if (ret != 0) { 2487 if (ret != 0) {
2687 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", 2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2688 ret); 2489 ret);
2689 goto err_dbvdd3; 2490 goto err_regmap;
2690 } 2491 }
2691 2492
2692 if (wm5100->pdata.ldo_ena) { 2493 if (wm5100->pdata.ldo_ena) {
@@ -2712,7 +2513,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2712 2513
2713 ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg); 2514 ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
2714 if (ret < 0) { 2515 if (ret < 0) {
2715 dev_err(&i2c->dev, "Failed to read ID register\n"); 2516 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2716 goto err_reset; 2517 goto err_reset;
2717 } 2518 }
2718 switch (reg) { 2519 switch (reg) {
@@ -2741,6 +2542,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2741 goto err_reset; 2542 goto err_reset;
2742 } 2543 }
2743 2544
2545 switch (wm5100->rev) {
2546 case 0:
2547 ret = regmap_register_patch(wm5100->regmap,
2548 wm5100_reva_patches,
2549 ARRAY_SIZE(wm5100_reva_patches));
2550 if (ret != 0) {
2551 dev_err(&i2c->dev, "Failed to register patches: %d\n",
2552 ret);
2553 goto err_reset;
2554 }
2555 break;
2556 default:
2557 break;
2558 }
2559
2560
2744 wm5100_init_gpio(i2c); 2561 wm5100_init_gpio(i2c);
2745 2562
2746 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { 2563 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
@@ -2761,6 +2578,62 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2761 WM5100_IN1_DMIC_SUP_SHIFT)); 2578 WM5100_IN1_DMIC_SUP_SHIFT));
2762 } 2579 }
2763 2580
2581 if (i2c->irq) {
2582 if (wm5100->pdata.irq_flags)
2583 irq_flags = wm5100->pdata.irq_flags;
2584 else
2585 irq_flags = IRQF_TRIGGER_LOW;
2586
2587 irq_flags |= IRQF_ONESHOT;
2588
2589 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2590 ret = request_threaded_irq(i2c->irq, NULL,
2591 wm5100_edge_irq, irq_flags,
2592 "wm5100", wm5100);
2593 else
2594 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2595 irq_flags, "wm5100",
2596 wm5100);
2597
2598 if (ret != 0) {
2599 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2600 i2c->irq, ret);
2601 } else {
2602 /* Enable default interrupts */
2603 regmap_update_bits(wm5100->regmap,
2604 WM5100_INTERRUPT_STATUS_3_MASK,
2605 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2606 WM5100_IM_SPK_SHUTDOWN_EINT |
2607 WM5100_IM_ASRC2_LOCK_EINT |
2608 WM5100_IM_ASRC1_LOCK_EINT |
2609 WM5100_IM_FLL2_LOCK_EINT |
2610 WM5100_IM_FLL1_LOCK_EINT |
2611 WM5100_CLKGEN_ERR_EINT |
2612 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2613
2614 regmap_update_bits(wm5100->regmap,
2615 WM5100_INTERRUPT_STATUS_4_MASK,
2616 WM5100_AIF3_ERR_EINT |
2617 WM5100_AIF2_ERR_EINT |
2618 WM5100_AIF1_ERR_EINT |
2619 WM5100_CTRLIF_ERR_EINT |
2620 WM5100_ISRC2_UNDERCLOCKED_EINT |
2621 WM5100_ISRC1_UNDERCLOCKED_EINT |
2622 WM5100_FX_UNDERCLOCKED_EINT |
2623 WM5100_AIF3_UNDERCLOCKED_EINT |
2624 WM5100_AIF2_UNDERCLOCKED_EINT |
2625 WM5100_AIF1_UNDERCLOCKED_EINT |
2626 WM5100_ASRC_UNDERCLOCKED_EINT |
2627 WM5100_DAC_UNDERCLOCKED_EINT |
2628 WM5100_ADC_UNDERCLOCKED_EINT |
2629 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2630 }
2631 }
2632
2633 pm_runtime_set_active(&i2c->dev);
2634 pm_runtime_enable(&i2c->dev);
2635 pm_request_idle(&i2c->dev);
2636
2764 ret = snd_soc_register_codec(&i2c->dev, 2637 ret = snd_soc_register_codec(&i2c->dev,
2765 &soc_codec_dev_wm5100, wm5100_dai, 2638 &soc_codec_dev_wm5100, wm5100_dai,
2766 ARRAY_SIZE(wm5100_dai)); 2639 ARRAY_SIZE(wm5100_dai));
@@ -2772,9 +2645,11 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2772 return ret; 2645 return ret;
2773 2646
2774err_reset: 2647err_reset:
2648 if (i2c->irq)
2649 free_irq(i2c->irq, wm5100);
2775 wm5100_free_gpio(i2c); 2650 wm5100_free_gpio(i2c);
2776 if (wm5100->pdata.reset) { 2651 if (wm5100->pdata.reset) {
2777 gpio_set_value_cansleep(wm5100->pdata.reset, 1); 2652 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
2778 gpio_free(wm5100->pdata.reset); 2653 gpio_free(wm5100->pdata.reset);
2779 } 2654 }
2780err_ldo: 2655err_ldo:
@@ -2785,45 +2660,78 @@ err_ldo:
2785err_enable: 2660err_enable:
2786 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2787 wm5100->core_supplies); 2662 wm5100->core_supplies);
2788err_dbvdd3:
2789 regulator_put(wm5100->dbvdd3);
2790err_dbvdd2:
2791 regulator_put(wm5100->dbvdd2);
2792err_cpvdd:
2793 regulator_put(wm5100->cpvdd);
2794err_core:
2795 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2796 wm5100->core_supplies);
2797err_regmap: 2663err_regmap:
2798 regmap_exit(wm5100->regmap); 2664 regmap_exit(wm5100->regmap);
2799err: 2665err:
2800 return ret; 2666 return ret;
2801} 2667}
2802 2668
2803static __devexit int wm5100_i2c_remove(struct i2c_client *client) 2669static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
2804{ 2670{
2805 struct wm5100_priv *wm5100 = i2c_get_clientdata(client); 2671 struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
2806 2672
2807 snd_soc_unregister_codec(&client->dev); 2673 snd_soc_unregister_codec(&i2c->dev);
2808 wm5100_free_gpio(client); 2674 if (i2c->irq)
2675 free_irq(i2c->irq, wm5100);
2676 wm5100_free_gpio(i2c);
2809 if (wm5100->pdata.reset) { 2677 if (wm5100->pdata.reset) {
2810 gpio_set_value_cansleep(wm5100->pdata.reset, 1); 2678 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
2811 gpio_free(wm5100->pdata.reset); 2679 gpio_free(wm5100->pdata.reset);
2812 } 2680 }
2813 if (wm5100->pdata.ldo_ena) { 2681 if (wm5100->pdata.ldo_ena) {
2814 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2682 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2815 gpio_free(wm5100->pdata.ldo_ena); 2683 gpio_free(wm5100->pdata.ldo_ena);
2816 } 2684 }
2817 regulator_put(wm5100->dbvdd3);
2818 regulator_put(wm5100->dbvdd2);
2819 regulator_put(wm5100->cpvdd);
2820 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2821 wm5100->core_supplies);
2822 regmap_exit(wm5100->regmap); 2685 regmap_exit(wm5100->regmap);
2823 2686
2824 return 0; 2687 return 0;
2825} 2688}
2826 2689
2690#ifdef CONFIG_PM_RUNTIME
2691static int wm5100_runtime_suspend(struct device *dev)
2692{
2693 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2694
2695 regcache_cache_only(wm5100->regmap, true);
2696 regcache_mark_dirty(wm5100->regmap);
2697 if (wm5100->pdata.ldo_ena)
2698 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2699 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2700 wm5100->core_supplies);
2701
2702 return 0;
2703}
2704
2705static int wm5100_runtime_resume(struct device *dev)
2706{
2707 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2708 int ret;
2709
2710 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2711 wm5100->core_supplies);
2712 if (ret != 0) {
2713 dev_err(dev, "Failed to enable supplies: %d\n",
2714 ret);
2715 return ret;
2716 }
2717
2718 if (wm5100->pdata.ldo_ena) {
2719 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
2720 msleep(2);
2721 }
2722
2723 regcache_cache_only(wm5100->regmap, false);
2724 regcache_sync(wm5100->regmap);
2725
2726 return 0;
2727}
2728#endif
2729
2730static struct dev_pm_ops wm5100_pm = {
2731 SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume,
2732 NULL)
2733};
2734
2827static const struct i2c_device_id wm5100_i2c_id[] = { 2735static const struct i2c_device_id wm5100_i2c_id[] = {
2828 { "wm5100", 0 }, 2736 { "wm5100", 0 },
2829 { } 2737 { }
@@ -2834,6 +2742,7 @@ static struct i2c_driver wm5100_i2c_driver = {
2834 .driver = { 2742 .driver = {
2835 .name = "wm5100", 2743 .name = "wm5100",
2836 .owner = THIS_MODULE, 2744 .owner = THIS_MODULE,
2745 .pm = &wm5100_pm,
2837 }, 2746 },
2838 .probe = wm5100_i2c_probe, 2747 .probe = wm5100_i2c_probe,
2839 .remove = __devexit_p(wm5100_i2c_remove), 2748 .remove = __devexit_p(wm5100_i2c_remove),
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 8821af70e660..a32caa72bd7d 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
23#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
24#include <linux/of_device.h> 25#include <linux/of_device.h>
@@ -41,7 +42,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
41 42
42/* codec private data */ 43/* codec private data */
43struct wm8731_priv { 44struct wm8731_priv {
44 enum snd_soc_control_type control_type; 45 struct regmap *regmap;
45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 46 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
46 unsigned int sysclk; 47 unsigned int sysclk;
47 int sysclk_type; 48 int sysclk_type;
@@ -52,16 +53,30 @@ struct wm8731_priv {
52 53
53/* 54/*
54 * wm8731 register cache 55 * wm8731 register cache
55 * We can't read the WM8731 register space when we are
56 * using 2 wire for device control, so we cache them instead.
57 * There is no point in caching the reset register
58 */ 56 */
59static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 57static const struct reg_default wm8731_reg_defaults[] = {
60 0x0097, 0x0097, 0x0079, 0x0079, 58 { 0, 0x0097 },
61 0x000a, 0x0008, 0x009f, 0x000a, 59 { 1, 0x0097 },
62 0x0000, 0x0000 60 { 2, 0x0079 },
61 { 3, 0x0079 },
62 { 4, 0x000a },
63 { 5, 0x0008 },
64 { 6, 0x009f },
65 { 7, 0x000a },
66 { 8, 0x0000 },
67 { 9, 0x0000 },
63}; 68};
64 69
70static bool wm8731_volatile(struct device *dev, unsigned int reg)
71{
72 return reg == WM8731_RESET;
73}
74
75static bool wm8731_writeable(struct device *dev, unsigned int reg)
76{
77 return reg <= WM8731_RESET;
78}
79
65#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) 80#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
66 81
67static const char *wm8731_input_select[] = {"Line In", "Mic"}; 82static const char *wm8731_input_select[] = {"Line In", "Mic"};
@@ -441,7 +456,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
441 if (ret != 0) 456 if (ret != 0)
442 return ret; 457 return ret;
443 458
444 snd_soc_cache_sync(codec); 459 regcache_sync(wm8731->regmap);
445 } 460 }
446 461
447 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 462 /* Clear PWROFF, gate CLKOUT, everything else as-is */
@@ -452,7 +467,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
452 snd_soc_write(codec, WM8731_PWR, 0xffff); 467 snd_soc_write(codec, WM8731_PWR, 0xffff);
453 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 468 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies); 469 wm8731->supplies);
455 codec->cache_sync = 1; 470 regcache_mark_dirty(wm8731->regmap);
456 break; 471 break;
457 } 472 }
458 codec->dapm.bias_level = level; 473 codec->dapm.bias_level = level;
@@ -513,7 +528,8 @@ static int wm8731_probe(struct snd_soc_codec *codec)
513 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 528 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
514 int ret = 0, i; 529 int ret = 0, i;
515 530
516 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type); 531 codec->control_data = wm8731->regmap;
532 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
517 if (ret < 0) { 533 if (ret < 0) {
518 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 534 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
519 return ret; 535 return ret;
@@ -585,9 +601,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
585 .suspend = wm8731_suspend, 601 .suspend = wm8731_suspend,
586 .resume = wm8731_resume, 602 .resume = wm8731_resume,
587 .set_bias_level = wm8731_set_bias_level, 603 .set_bias_level = wm8731_set_bias_level,
588 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
589 .reg_word_size = sizeof(u16),
590 .reg_cache_default = wm8731_reg,
591 .dapm_widgets = wm8731_dapm_widgets, 604 .dapm_widgets = wm8731_dapm_widgets,
592 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), 605 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
593 .dapm_routes = wm8731_intercon, 606 .dapm_routes = wm8731_intercon,
@@ -603,6 +616,19 @@ static const struct of_device_id wm8731_of_match[] = {
603 616
604MODULE_DEVICE_TABLE(of, wm8731_of_match); 617MODULE_DEVICE_TABLE(of, wm8731_of_match);
605 618
619static const struct regmap_config wm8731_regmap = {
620 .reg_bits = 7,
621 .val_bits = 9,
622
623 .max_register = WM8731_RESET,
624 .volatile_reg = wm8731_volatile,
625 .writeable_reg = wm8731_writeable,
626
627 .cache_type = REGCACHE_RBTREE,
628 .reg_defaults = wm8731_reg_defaults,
629 .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults),
630};
631
606#if defined(CONFIG_SPI_MASTER) 632#if defined(CONFIG_SPI_MASTER)
607static int __devinit wm8731_spi_probe(struct spi_device *spi) 633static int __devinit wm8731_spi_probe(struct spi_device *spi)
608{ 634{
@@ -613,20 +639,39 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
613 if (wm8731 == NULL) 639 if (wm8731 == NULL)
614 return -ENOMEM; 640 return -ENOMEM;
615 641
616 wm8731->control_type = SND_SOC_SPI; 642 wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap);
643 if (IS_ERR(wm8731->regmap)) {
644 ret = PTR_ERR(wm8731->regmap);
645 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
646 ret);
647 goto err;
648 }
649
617 spi_set_drvdata(spi, wm8731); 650 spi_set_drvdata(spi, wm8731);
618 651
619 ret = snd_soc_register_codec(&spi->dev, 652 ret = snd_soc_register_codec(&spi->dev,
620 &soc_codec_dev_wm8731, &wm8731_dai, 1); 653 &soc_codec_dev_wm8731, &wm8731_dai, 1);
621 if (ret < 0) 654 if (ret != 0) {
622 kfree(wm8731); 655 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
656 goto err_regmap;
657 }
658
659 return 0;
660
661err_regmap:
662 regmap_exit(wm8731->regmap);
663err:
664 kfree(wm8731);
623 return ret; 665 return ret;
624} 666}
625 667
626static int __devexit wm8731_spi_remove(struct spi_device *spi) 668static int __devexit wm8731_spi_remove(struct spi_device *spi)
627{ 669{
670 struct wm8731_priv *wm8731 = spi_get_drvdata(spi);
671
628 snd_soc_unregister_codec(&spi->dev); 672 snd_soc_unregister_codec(&spi->dev);
629 kfree(spi_get_drvdata(spi)); 673 regmap_exit(wm8731->regmap);
674 kfree(wm8731);
630 return 0; 675 return 0;
631} 676}
632 677
@@ -652,20 +697,38 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
652 if (wm8731 == NULL) 697 if (wm8731 == NULL)
653 return -ENOMEM; 698 return -ENOMEM;
654 699
700 wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap);
701 if (IS_ERR(wm8731->regmap)) {
702 ret = PTR_ERR(wm8731->regmap);
703 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
704 ret);
705 goto err;
706 }
707
655 i2c_set_clientdata(i2c, wm8731); 708 i2c_set_clientdata(i2c, wm8731);
656 wm8731->control_type = SND_SOC_I2C;
657 709
658 ret = snd_soc_register_codec(&i2c->dev, 710 ret = snd_soc_register_codec(&i2c->dev,
659 &soc_codec_dev_wm8731, &wm8731_dai, 1); 711 &soc_codec_dev_wm8731, &wm8731_dai, 1);
660 if (ret < 0) 712 if (ret != 0) {
661 kfree(wm8731); 713 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
714 goto err_regmap;
715 }
716
717 return 0;
718
719err_regmap:
720 regmap_exit(wm8731->regmap);
721err:
722 kfree(wm8731);
662 return ret; 723 return ret;
663} 724}
664 725
665static __devexit int wm8731_i2c_remove(struct i2c_client *client) 726static __devexit int wm8731_i2c_remove(struct i2c_client *client)
666{ 727{
728 struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
667 snd_soc_unregister_codec(&client->dev); 729 snd_soc_unregister_codec(&client->dev);
668 kfree(i2c_get_clientdata(client)); 730 regmap_exit(wm8731->regmap);
731 kfree(wm8731);
669 return 0; 732 return 0;
670} 733}
671 734
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index ff95e62c56b9..4fe9d191e277 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -599,7 +599,7 @@ static int wm8737_probe(struct snd_soc_codec *codec)
599 /* Bias level configuration will have done an extra enable */ 599 /* Bias level configuration will have done an extra enable */
600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
601 601
602 snd_soc_add_controls(codec, wm8737_snd_controls, 602 snd_soc_add_codec_controls(codec, wm8737_snd_controls,
603 ARRAY_SIZE(wm8737_snd_controls)); 603 ARRAY_SIZE(wm8737_snd_controls));
604 wm8737_add_widgets(codec); 604 wm8737_add_widgets(codec);
605 605
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b114c19f530a..e27e7b62b365 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -39,6 +39,7 @@
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/of_device.h> 41#include <linux/of_device.h>
42#include <linux/regmap.h>
42#include <linux/spi/spi.h> 43#include <linux/spi/spi.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
44#include <sound/core.h> 45#include <sound/core.h>
@@ -65,28 +66,86 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
65 * We can't read the WM8753 register space when we 66 * We can't read the WM8753 register space when we
66 * are using 2 wire for device control, so we cache them instead. 67 * are using 2 wire for device control, so we cache them instead.
67 */ 68 */
68static const u16 wm8753_reg[] = { 69static const struct reg_default wm8753_reg_defaults[] = {
69 0x0000, 0x0008, 0x0000, 0x000a, 70 { 0x00, 0x0000 },
70 0x000a, 0x0033, 0x0000, 0x0007, 71 { 0x01, 0x0008 },
71 0x00ff, 0x00ff, 0x000f, 0x000f, 72 { 0x02, 0x0000 },
72 0x007b, 0x0000, 0x0032, 0x0000, 73 { 0x03, 0x000a },
73 0x00c3, 0x00c3, 0x00c0, 0x0000, 74 { 0x04, 0x000a },
74 0x0000, 0x0000, 0x0000, 0x0000, 75 { 0x05, 0x0033 },
75 0x0000, 0x0000, 0x0000, 0x0000, 76 { 0x06, 0x0000 },
76 0x0000, 0x0000, 0x0000, 0x0000, 77 { 0x07, 0x0007 },
77 0x0055, 0x0005, 0x0050, 0x0055, 78 { 0x08, 0x00ff },
78 0x0050, 0x0055, 0x0050, 0x0055, 79 { 0x09, 0x00ff },
79 0x0079, 0x0079, 0x0079, 0x0079, 80 { 0x0a, 0x000f },
80 0x0079, 0x0000, 0x0000, 0x0000, 81 { 0x0b, 0x000f },
81 0x0000, 0x0097, 0x0097, 0x0000, 82 { 0x0c, 0x007b },
82 0x0004, 0x0000, 0x0083, 0x0024, 83 { 0x0d, 0x0000 },
83 0x01ba, 0x0000, 0x0083, 0x0024, 84 { 0x0e, 0x0032 },
84 0x01ba, 0x0000, 0x0000, 0x0000 85 { 0x0f, 0x0000 },
86 { 0x10, 0x00c3 },
87 { 0x11, 0x00c3 },
88 { 0x12, 0x00c0 },
89 { 0x13, 0x0000 },
90 { 0x14, 0x0000 },
91 { 0x15, 0x0000 },
92 { 0x16, 0x0000 },
93 { 0x17, 0x0000 },
94 { 0x18, 0x0000 },
95 { 0x19, 0x0000 },
96 { 0x1a, 0x0000 },
97 { 0x1b, 0x0000 },
98 { 0x1c, 0x0000 },
99 { 0x1d, 0x0000 },
100 { 0x1e, 0x0000 },
101 { 0x1f, 0x0000 },
102 { 0x20, 0x0055 },
103 { 0x21, 0x0005 },
104 { 0x22, 0x0050 },
105 { 0x23, 0x0055 },
106 { 0x24, 0x0050 },
107 { 0x25, 0x0055 },
108 { 0x26, 0x0050 },
109 { 0x27, 0x0055 },
110 { 0x28, 0x0079 },
111 { 0x29, 0x0079 },
112 { 0x2a, 0x0079 },
113 { 0x2b, 0x0079 },
114 { 0x2c, 0x0079 },
115 { 0x2d, 0x0000 },
116 { 0x2e, 0x0000 },
117 { 0x2f, 0x0000 },
118 { 0x30, 0x0000 },
119 { 0x31, 0x0097 },
120 { 0x32, 0x0097 },
121 { 0x33, 0x0000 },
122 { 0x34, 0x0004 },
123 { 0x35, 0x0000 },
124 { 0x36, 0x0083 },
125 { 0x37, 0x0024 },
126 { 0x38, 0x01ba },
127 { 0x39, 0x0000 },
128 { 0x3a, 0x0083 },
129 { 0x3b, 0x0024 },
130 { 0x3c, 0x01ba },
131 { 0x3d, 0x0000 },
132 { 0x3e, 0x0000 },
133 { 0x3f, 0x0000 },
85}; 134};
86 135
136static bool wm8753_volatile(struct device *dev, unsigned int reg)
137{
138 return reg == WM8753_RESET;
139}
140
141static bool wm8753_writeable(struct device *dev, unsigned int reg)
142{
143 return reg <= WM8753_ADCTL2;
144}
145
87/* codec private data */ 146/* codec private data */
88struct wm8753_priv { 147struct wm8753_priv {
89 enum snd_soc_control_type control_type; 148 struct regmap *regmap;
90 unsigned int sysclk; 149 unsigned int sysclk;
91 unsigned int pcmclk; 150 unsigned int pcmclk;
92 151
@@ -1383,25 +1442,15 @@ static void wm8753_work(struct work_struct *work)
1383static int wm8753_suspend(struct snd_soc_codec *codec) 1442static int wm8753_suspend(struct snd_soc_codec *codec)
1384{ 1443{
1385 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1444 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1445 codec->cache_sync = 1;
1386 return 0; 1446 return 0;
1387} 1447}
1388 1448
1389static int wm8753_resume(struct snd_soc_codec *codec) 1449static int wm8753_resume(struct snd_soc_codec *codec)
1390{ 1450{
1391 u16 *reg_cache = codec->reg_cache; 1451 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1392 int i;
1393
1394 /* Sync reg_cache with the hardware */
1395 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1396 if (i == WM8753_RESET)
1397 continue;
1398
1399 /* No point in writing hardware default values back */
1400 if (reg_cache[i] == wm8753_reg[i])
1401 continue;
1402 1452
1403 snd_soc_write(codec, i, reg_cache[i]); 1453 regcache_sync(wm8753->regmap);
1404 }
1405 1454
1406 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1455 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1407 1456
@@ -1423,7 +1472,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1423 1472
1424 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); 1473 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
1425 1474
1426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); 1475 codec->control_data = wm8753->regmap;
1476 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
1427 if (ret < 0) { 1477 if (ret < 0) {
1428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1478 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1429 return ret; 1479 return ret;
@@ -1473,9 +1523,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1473 .suspend = wm8753_suspend, 1523 .suspend = wm8753_suspend,
1474 .resume = wm8753_resume, 1524 .resume = wm8753_resume,
1475 .set_bias_level = wm8753_set_bias_level, 1525 .set_bias_level = wm8753_set_bias_level,
1476 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
1477 .reg_word_size = sizeof(u16),
1478 .reg_cache_default = wm8753_reg,
1479 1526
1480 .controls = wm8753_snd_controls, 1527 .controls = wm8753_snd_controls,
1481 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1528 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
@@ -1491,30 +1538,62 @@ static const struct of_device_id wm8753_of_match[] = {
1491}; 1538};
1492MODULE_DEVICE_TABLE(of, wm8753_of_match); 1539MODULE_DEVICE_TABLE(of, wm8753_of_match);
1493 1540
1541static const struct regmap_config wm8753_regmap = {
1542 .reg_bits = 7,
1543 .val_bits = 9,
1544
1545 .max_register = WM8753_ADCTL2,
1546 .writeable_reg = wm8753_writeable,
1547 .volatile_reg = wm8753_volatile,
1548
1549 .cache_type = REGCACHE_RBTREE,
1550 .reg_defaults = wm8753_reg_defaults,
1551 .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults),
1552};
1553
1494#if defined(CONFIG_SPI_MASTER) 1554#if defined(CONFIG_SPI_MASTER)
1495static int __devinit wm8753_spi_probe(struct spi_device *spi) 1555static int __devinit wm8753_spi_probe(struct spi_device *spi)
1496{ 1556{
1497 struct wm8753_priv *wm8753; 1557 struct wm8753_priv *wm8753;
1498 int ret; 1558 int ret;
1499 1559
1500 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1560 wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv),
1561 GFP_KERNEL);
1501 if (wm8753 == NULL) 1562 if (wm8753 == NULL)
1502 return -ENOMEM; 1563 return -ENOMEM;
1503 1564
1504 wm8753->control_type = SND_SOC_SPI;
1505 spi_set_drvdata(spi, wm8753); 1565 spi_set_drvdata(spi, wm8753);
1506 1566
1507 ret = snd_soc_register_codec(&spi->dev, 1567 wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
1508 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1568 if (IS_ERR(wm8753->regmap)) {
1509 if (ret < 0) 1569 ret = PTR_ERR(wm8753->regmap);
1510 kfree(wm8753); 1570 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1571 ret);
1572 goto err;
1573 }
1574
1575 ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
1576 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1577 if (ret != 0) {
1578 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
1579 goto err_regmap;
1580 }
1581
1582 return 0;
1583
1584err_regmap:
1585 regmap_exit(wm8753->regmap);
1586err:
1511 return ret; 1587 return ret;
1512} 1588}
1513 1589
1514static int __devexit wm8753_spi_remove(struct spi_device *spi) 1590static int __devexit wm8753_spi_remove(struct spi_device *spi)
1515{ 1591{
1592 struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
1593
1516 snd_soc_unregister_codec(&spi->dev); 1594 snd_soc_unregister_codec(&spi->dev);
1517 kfree(spi_get_drvdata(spi)); 1595 regmap_exit(wm8753->regmap);
1596 kfree(wm8753);
1518 return 0; 1597 return 0;
1519} 1598}
1520 1599
@@ -1536,24 +1615,42 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1536 struct wm8753_priv *wm8753; 1615 struct wm8753_priv *wm8753;
1537 int ret; 1616 int ret;
1538 1617
1539 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1618 wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv),
1619 GFP_KERNEL);
1540 if (wm8753 == NULL) 1620 if (wm8753 == NULL)
1541 return -ENOMEM; 1621 return -ENOMEM;
1542 1622
1543 i2c_set_clientdata(i2c, wm8753); 1623 i2c_set_clientdata(i2c, wm8753);
1544 wm8753->control_type = SND_SOC_I2C;
1545 1624
1546 ret = snd_soc_register_codec(&i2c->dev, 1625 wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
1547 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1626 if (IS_ERR(wm8753->regmap)) {
1548 if (ret < 0) 1627 ret = PTR_ERR(wm8753->regmap);
1549 kfree(wm8753); 1628 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1629 ret);
1630 goto err;
1631 }
1632
1633 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
1634 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1635 if (ret != 0) {
1636 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1637 goto err_regmap;
1638 }
1639
1640 return 0;
1641
1642err_regmap:
1643 regmap_exit(wm8753->regmap);
1644err:
1550 return ret; 1645 return ret;
1551} 1646}
1552 1647
1553static __devexit int wm8753_i2c_remove(struct i2c_client *client) 1648static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1554{ 1649{
1650 struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
1651
1555 snd_soc_unregister_codec(&client->dev); 1652 snd_soc_unregister_codec(&client->dev);
1556 kfree(i2c_get_clientdata(client)); 1653 regmap_exit(wm8753->regmap);
1557 return 0; 1654 return 0;
1558} 1655}
1559 1656
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19374a9e5ba6..a5127b4ff9e1 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -580,8 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec)
580 wm8770 = snd_soc_codec_get_drvdata(codec); 580 wm8770 = snd_soc_codec_get_drvdata(codec);
581 wm8770->codec = codec; 581 wm8770->codec = codec;
582 582
583 codec->dapm.idle_bias_off = 1;
584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); 583 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
586 if (ret < 0) { 584 if (ret < 0) {
587 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 585 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -643,7 +641,7 @@ static int wm8770_probe(struct snd_soc_codec *codec)
643 /* mute all DACs */ 641 /* mute all DACs */
644 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); 642 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
645 643
646 snd_soc_add_controls(codec, wm8770_snd_controls, 644 snd_soc_add_codec_controls(codec, wm8770_snd_controls,
647 ARRAY_SIZE(wm8770_snd_controls)); 645 ARRAY_SIZE(wm8770_snd_controls));
648 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, 646 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
649 ARRAY_SIZE(wm8770_dapm_widgets)); 647 ARRAY_SIZE(wm8770_dapm_widgets));
@@ -679,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
679 .suspend = wm8770_suspend, 677 .suspend = wm8770_suspend,
680 .resume = wm8770_resume, 678 .resume = wm8770_resume,
681 .set_bias_level = wm8770_set_bias_level, 679 .set_bias_level = wm8770_set_bias_level,
680 .idle_bias_off = true,
682 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), 681 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
683 .reg_word_size = sizeof (u16), 682 .reg_word_size = sizeof (u16),
684 .reg_cache_default = wm8770_reg_defs 683 .reg_cache_default = wm8770_reg_defs
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 33e97d1d8f46..a19db5a0a17a 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -30,6 +30,11 @@
30 30
31#include "wm8776.h" 31#include "wm8776.h"
32 32
33enum wm8776_chip_type {
34 WM8775 = 1,
35 WM8776,
36};
37
33/* codec private data */ 38/* codec private data */
34struct wm8776_priv { 39struct wm8776_priv {
35 enum snd_soc_control_type control_type; 40 enum snd_soc_control_type control_type;
@@ -512,7 +517,8 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
512} 517}
513 518
514static const struct i2c_device_id wm8776_i2c_id[] = { 519static const struct i2c_device_id wm8776_i2c_id[] = {
515 { "wm8776", 0 }, 520 { "wm8775", WM8775 },
521 { "wm8776", WM8776 },
516 { } 522 { }
517}; 523};
518MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); 524MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index d54a3ca5e19e..6bd1b767b138 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -18,6 +18,7 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_device.h> 19#include <linux/of_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/regmap.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
@@ -35,45 +36,33 @@ static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
35 "DVDD" 36 "DVDD"
36}; 37};
37 38
38static const u8 wm8804_reg_defs[] = { 39static const struct reg_default wm8804_reg_defaults[] = {
39 0x05, /* R0 - RST/DEVID1 */ 40 { 3, 0x21 }, /* R3 - PLL1 */
40 0x88, /* R1 - DEVID2 */ 41 { 4, 0xFD }, /* R4 - PLL2 */
41 0x04, /* R2 - DEVREV */ 42 { 5, 0x36 }, /* R5 - PLL3 */
42 0x21, /* R3 - PLL1 */ 43 { 6, 0x07 }, /* R6 - PLL4 */
43 0xFD, /* R4 - PLL2 */ 44 { 7, 0x16 }, /* R7 - PLL5 */
44 0x36, /* R5 - PLL3 */ 45 { 8, 0x18 }, /* R8 - PLL6 */
45 0x07, /* R6 - PLL4 */ 46 { 9, 0xFF }, /* R9 - SPDMODE */
46 0x16, /* R7 - PLL5 */ 47 { 10, 0x00 }, /* R10 - INTMASK */
47 0x18, /* R8 - PLL6 */ 48 { 18, 0x00 }, /* R18 - SPDTX1 */
48 0xFF, /* R9 - SPDMODE */ 49 { 19, 0x00 }, /* R19 - SPDTX2 */
49 0x00, /* R10 - INTMASK */ 50 { 20, 0x00 }, /* R20 - SPDTX3 */
50 0x00, /* R11 - INTSTAT */ 51 { 21, 0x71 }, /* R21 - SPDTX4 */
51 0x00, /* R12 - SPDSTAT */ 52 { 22, 0x0B }, /* R22 - SPDTX5 */
52 0x00, /* R13 - RXCHAN1 */ 53 { 23, 0x70 }, /* R23 - GPO0 */
53 0x00, /* R14 - RXCHAN2 */ 54 { 24, 0x57 }, /* R24 - GPO1 */
54 0x00, /* R15 - RXCHAN3 */ 55 { 26, 0x42 }, /* R26 - GPO2 */
55 0x00, /* R16 - RXCHAN4 */ 56 { 27, 0x06 }, /* R27 - AIFTX */
56 0x00, /* R17 - RXCHAN5 */ 57 { 28, 0x06 }, /* R28 - AIFRX */
57 0x00, /* R18 - SPDTX1 */ 58 { 29, 0x80 }, /* R29 - SPDRX1 */
58 0x00, /* R19 - SPDTX2 */ 59 { 30, 0x07 }, /* R30 - PWRDN */
59 0x00, /* R20 - SPDTX3 */
60 0x71, /* R21 - SPDTX4 */
61 0x0B, /* R22 - SPDTX5 */
62 0x70, /* R23 - GPO0 */
63 0x57, /* R24 - GPO1 */
64 0x00, /* R25 */
65 0x42, /* R26 - GPO2 */
66 0x06, /* R27 - AIFTX */
67 0x06, /* R28 - AIFRX */
68 0x80, /* R29 - SPDRX1 */
69 0x07, /* R30 - PWRDN */
70}; 60};
71 61
72struct wm8804_priv { 62struct wm8804_priv {
73 enum snd_soc_control_type control_type; 63 struct regmap *regmap;
74 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; 64 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; 65 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
76 struct snd_soc_codec *codec;
77}; 66};
78 67
79static int txsrc_get(struct snd_kcontrol *kcontrol, 68static int txsrc_get(struct snd_kcontrol *kcontrol,
@@ -94,7 +83,7 @@ static int wm8804_regulator_event_##n(struct notifier_block *nb, \
94 struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \ 83 struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
95 disable_nb[n]); \ 84 disable_nb[n]); \
96 if (event & REGULATOR_EVENT_DISABLE) { \ 85 if (event & REGULATOR_EVENT_DISABLE) { \
97 wm8804->codec->cache_sync = 1; \ 86 regcache_mark_dirty(wm8804->regmap); \
98 } \ 87 } \
99 return 0; \ 88 return 0; \
100} 89}
@@ -176,7 +165,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
176 return 0; 165 return 0;
177} 166}
178 167
179static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg) 168static bool wm8804_volatile(struct device *dev, unsigned int reg)
180{ 169{
181 switch (reg) { 170 switch (reg) {
182 case WM8804_RST_DEVID1: 171 case WM8804_RST_DEVID1:
@@ -189,12 +178,10 @@ static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
189 case WM8804_RXCHAN3: 178 case WM8804_RXCHAN3:
190 case WM8804_RXCHAN4: 179 case WM8804_RXCHAN4:
191 case WM8804_RXCHAN5: 180 case WM8804_RXCHAN5:
192 return 1; 181 return true;
193 default: 182 default:
194 break; 183 return false;
195 } 184 }
196
197 return 0;
198} 185}
199 186
200static int wm8804_reset(struct snd_soc_codec *codec) 187static int wm8804_reset(struct snd_soc_codec *codec)
@@ -482,24 +469,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
482 return 0; 469 return 0;
483} 470}
484 471
485static void wm8804_sync_cache(struct snd_soc_codec *codec)
486{
487 short i;
488 u8 *cache;
489
490 if (!codec->cache_sync)
491 return;
492
493 codec->cache_only = 0;
494 cache = codec->reg_cache;
495 for (i = 0; i < codec->driver->reg_cache_size; i++) {
496 if (i == WM8804_RST_DEVID1 || cache[i] == wm8804_reg_defs[i])
497 continue;
498 snd_soc_write(codec, i, cache[i]);
499 }
500 codec->cache_sync = 0;
501}
502
503static int wm8804_set_bias_level(struct snd_soc_codec *codec, 472static int wm8804_set_bias_level(struct snd_soc_codec *codec,
504 enum snd_soc_bias_level level) 473 enum snd_soc_bias_level level)
505{ 474{
@@ -524,7 +493,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
524 ret); 493 ret);
525 return ret; 494 return ret;
526 } 495 }
527 wm8804_sync_cache(codec); 496 regcache_sync(wm8804->regmap);
528 } 497 }
529 /* power down the OSC and the PLL */ 498 /* power down the OSC and the PLL */
530 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9); 499 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
@@ -579,11 +548,10 @@ static int wm8804_probe(struct snd_soc_codec *codec)
579 int i, id1, id2, ret; 548 int i, id1, id2, ret;
580 549
581 wm8804 = snd_soc_codec_get_drvdata(codec); 550 wm8804 = snd_soc_codec_get_drvdata(codec);
582 wm8804->codec = codec;
583 551
584 codec->dapm.idle_bias_off = 1; 552 codec->control_data = wm8804->regmap;
585 553
586 ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); 554 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
587 if (ret < 0) { 555 if (ret < 0) {
588 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 556 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
589 return ret; 557 return ret;
@@ -636,8 +604,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
636 604
637 id2 = (id2 << 8) | id1; 605 id2 = (id2 << 8) | id1;
638 606
639 if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8) 607 if (id2 != 0x8805) {
640 | wm8804_reg_defs[WM8804_RST_DEVID1])) {
641 dev_err(codec->dev, "Invalid device ID: %#x\n", id2); 608 dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
642 ret = -EINVAL; 609 ret = -EINVAL;
643 goto err_reg_enable; 610 goto err_reg_enable;
@@ -710,10 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
710 .suspend = wm8804_suspend, 677 .suspend = wm8804_suspend,
711 .resume = wm8804_resume, 678 .resume = wm8804_resume,
712 .set_bias_level = wm8804_set_bias_level, 679 .set_bias_level = wm8804_set_bias_level,
713 .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs), 680 .idle_bias_off = true,
714 .reg_word_size = sizeof(u8),
715 .reg_cache_default = wm8804_reg_defs,
716 .volatile_register = wm8804_volatile,
717 681
718 .controls = wm8804_snd_controls, 682 .controls = wm8804_snd_controls,
719 .num_controls = ARRAY_SIZE(wm8804_snd_controls), 683 .num_controls = ARRAY_SIZE(wm8804_snd_controls),
@@ -725,30 +689,47 @@ static const struct of_device_id wm8804_of_match[] = {
725}; 689};
726MODULE_DEVICE_TABLE(of, wm8804_of_match); 690MODULE_DEVICE_TABLE(of, wm8804_of_match);
727 691
692static struct regmap_config wm8804_regmap_config = {
693 .reg_bits = 8,
694 .val_bits = 8,
695
696 .max_register = WM8804_MAX_REGISTER,
697 .volatile_reg = wm8804_volatile,
698
699 .cache_type = REGCACHE_RBTREE,
700 .reg_defaults = wm8804_reg_defaults,
701 .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
702};
703
728#if defined(CONFIG_SPI_MASTER) 704#if defined(CONFIG_SPI_MASTER)
729static int __devinit wm8804_spi_probe(struct spi_device *spi) 705static int __devinit wm8804_spi_probe(struct spi_device *spi)
730{ 706{
731 struct wm8804_priv *wm8804; 707 struct wm8804_priv *wm8804;
732 int ret; 708 int ret;
733 709
734 wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); 710 wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL);
735 if (!wm8804) 711 if (!wm8804)
736 return -ENOMEM; 712 return -ENOMEM;
737 713
738 wm8804->control_type = SND_SOC_SPI; 714 wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config);
715 if (IS_ERR(wm8804->regmap)) {
716 ret = PTR_ERR(wm8804->regmap);
717 return ret;
718 }
719
739 spi_set_drvdata(spi, wm8804); 720 spi_set_drvdata(spi, wm8804);
740 721
741 ret = snd_soc_register_codec(&spi->dev, 722 ret = snd_soc_register_codec(&spi->dev,
742 &soc_codec_dev_wm8804, &wm8804_dai, 1); 723 &soc_codec_dev_wm8804, &wm8804_dai, 1);
743 if (ret < 0) 724
744 kfree(wm8804);
745 return ret; 725 return ret;
746} 726}
747 727
748static int __devexit wm8804_spi_remove(struct spi_device *spi) 728static int __devexit wm8804_spi_remove(struct spi_device *spi)
749{ 729{
730 struct wm8804_priv *wm8804 = spi_get_drvdata(spi);
750 snd_soc_unregister_codec(&spi->dev); 731 snd_soc_unregister_codec(&spi->dev);
751 kfree(spi_get_drvdata(spi)); 732 regmap_exit(wm8804->regmap);
752 return 0; 733 return 0;
753} 734}
754 735
@@ -770,24 +751,37 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
770 struct wm8804_priv *wm8804; 751 struct wm8804_priv *wm8804;
771 int ret; 752 int ret;
772 753
773 wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); 754 wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL);
774 if (!wm8804) 755 if (!wm8804)
775 return -ENOMEM; 756 return -ENOMEM;
776 757
777 wm8804->control_type = SND_SOC_I2C; 758 wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config);
759 if (IS_ERR(wm8804->regmap)) {
760 ret = PTR_ERR(wm8804->regmap);
761 return ret;
762 }
763
778 i2c_set_clientdata(i2c, wm8804); 764 i2c_set_clientdata(i2c, wm8804);
779 765
780 ret = snd_soc_register_codec(&i2c->dev, 766 ret = snd_soc_register_codec(&i2c->dev,
781 &soc_codec_dev_wm8804, &wm8804_dai, 1); 767 &soc_codec_dev_wm8804, &wm8804_dai, 1);
782 if (ret < 0) 768 if (ret != 0)
783 kfree(wm8804); 769 goto err;
770
771 return 0;
772
773err:
774 regmap_exit(wm8804->regmap);
784 return ret; 775 return ret;
785} 776}
786 777
787static __devexit int wm8804_i2c_remove(struct i2c_client *client) 778static __devexit int wm8804_i2c_remove(struct i2c_client *i2c)
788{ 779{
789 snd_soc_unregister_codec(&client->dev); 780 struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c);
790 kfree(i2c_get_clientdata(client)); 781
782 snd_soc_unregister_codec(&i2c->dev);
783 regmap_exit(wm8804->regmap);
784
791 return 0; 785 return 0;
792} 786}
793 787
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f31c754c8865..65d525d74c54 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -17,6 +17,7 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/regmap.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
@@ -47,6 +48,7 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
47 48
48/* codec private data */ 49/* codec private data */
49struct wm8904_priv { 50struct wm8904_priv {
51 struct regmap *regmap;
50 52
51 enum wm8904_type devtype; 53 enum wm8904_type devtype;
52 54
@@ -86,517 +88,230 @@ struct wm8904_priv {
86 int dcs_state[WM8904_NUM_DCS_CHANNELS]; 88 int dcs_state[WM8904_NUM_DCS_CHANNELS];
87}; 89};
88 90
89static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = { 91static const struct reg_default wm8904_reg_defaults[] = {
90 0x8904, /* R0 - SW Reset and ID */ 92 { 4, 0x0018 }, /* R4 - Bias Control 0 */
91 0x0000, /* R1 - Revision */ 93 { 5, 0x0000 }, /* R5 - VMID Control 0 */
92 0x0000, /* R2 */ 94 { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
93 0x0000, /* R3 */ 95 { 7, 0x0000 }, /* R7 - Mic Bias Control 1 */
94 0x0018, /* R4 - Bias Control 0 */ 96 { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
95 0x0000, /* R5 - VMID Control 0 */ 97 { 9, 0x9696 }, /* R9 - mic Filter Control */
96 0x0000, /* R6 - Mic Bias Control 0 */ 98 { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
97 0x0000, /* R7 - Mic Bias Control 1 */ 99 { 12, 0x0000 }, /* R12 - Power Management 0 */
98 0x0001, /* R8 - Analogue DAC 0 */ 100 { 14, 0x0000 }, /* R14 - Power Management 2 */
99 0x9696, /* R9 - mic Filter Control */ 101 { 15, 0x0000 }, /* R15 - Power Management 3 */
100 0x0001, /* R10 - Analogue ADC 0 */ 102 { 18, 0x0000 }, /* R18 - Power Management 6 */
101 0x0000, /* R11 */ 103 { 19, 0x945E }, /* R20 - Clock Rates 0 */
102 0x0000, /* R12 - Power Management 0 */ 104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */
103 0x0000, /* R13 */ 105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */
104 0x0000, /* R14 - Power Management 2 */ 106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
105 0x0000, /* R15 - Power Management 3 */ 107 { 25, 0x000A }, /* R25 - Audio Interface 1 */
106 0x0000, /* R16 */ 108 { 26, 0x00E4 }, /* R26 - Audio Interface 2 */
107 0x0000, /* R17 */ 109 { 27, 0x0040 }, /* R27 - Audio Interface 3 */
108 0x0000, /* R18 - Power Management 6 */ 110 { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
109 0x0000, /* R19 */ 111 { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
110 0x945E, /* R20 - Clock Rates 0 */ 112 { 32, 0x0000 }, /* R32 - DAC Digital 0 */
111 0x0C05, /* R21 - Clock Rates 1 */ 113 { 33, 0x0008 }, /* R33 - DAC Digital 1 */
112 0x0006, /* R22 - Clock Rates 2 */ 114 { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
113 0x0000, /* R23 */ 115 { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
114 0x0050, /* R24 - Audio Interface 0 */ 116 { 38, 0x0010 }, /* R38 - ADC Digital 0 */
115 0x000A, /* R25 - Audio Interface 1 */ 117 { 39, 0x0000 }, /* R39 - Digital Microphone 0 */
116 0x00E4, /* R26 - Audio Interface 2 */ 118 { 40, 0x01AF }, /* R40 - DRC 0 */
117 0x0040, /* R27 - Audio Interface 3 */ 119 { 41, 0x3248 }, /* R41 - DRC 1 */
118 0x0000, /* R28 */ 120 { 42, 0x0000 }, /* R42 - DRC 2 */
119 0x0000, /* R29 */ 121 { 43, 0x0000 }, /* R43 - DRC 3 */
120 0x00C0, /* R30 - DAC Digital Volume Left */ 122 { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
121 0x00C0, /* R31 - DAC Digital Volume Right */ 123 { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
122 0x0000, /* R32 - DAC Digital 0 */ 124 { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
123 0x0008, /* R33 - DAC Digital 1 */ 125 { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
124 0x0000, /* R34 */ 126 { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
125 0x0000, /* R35 */ 127 { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
126 0x00C0, /* R36 - ADC Digital Volume Left */ 128 { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
127 0x00C0, /* R37 - ADC Digital Volume Right */ 129 { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
128 0x0010, /* R38 - ADC Digital 0 */ 130 { 61, 0x0000 }, /* R61 - Analogue OUT12 ZC */
129 0x0000, /* R39 - Digital Microphone 0 */ 131 { 67, 0x0000 }, /* R67 - DC Servo 0 */
130 0x01AF, /* R40 - DRC 0 */ 132 { 69, 0xAAAA }, /* R69 - DC Servo 2 */
131 0x3248, /* R41 - DRC 1 */ 133 { 71, 0xAAAA }, /* R71 - DC Servo 4 */
132 0x0000, /* R42 - DRC 2 */ 134 { 72, 0xAAAA }, /* R72 - DC Servo 5 */
133 0x0000, /* R43 - DRC 3 */ 135 { 90, 0x0000 }, /* R90 - Analogue HP 0 */
134 0x0085, /* R44 - Analogue Left Input 0 */ 136 { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
135 0x0085, /* R45 - Analogue Right Input 0 */ 137 { 98, 0x0000 }, /* R98 - Charge Pump 0 */
136 0x0044, /* R46 - Analogue Left Input 1 */ 138 { 104, 0x0004 }, /* R104 - Class W 0 */
137 0x0044, /* R47 - Analogue Right Input 1 */ 139 { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
138 0x0000, /* R48 */ 140 { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
139 0x0000, /* R49 */ 141 { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
140 0x0000, /* R50 */ 142 { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
141 0x0000, /* R51 */ 143 { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
142 0x0000, /* R52 */ 144 { 116, 0x0000 }, /* R116 - FLL Control 1 */
143 0x0000, /* R53 */ 145 { 117, 0x0007 }, /* R117 - FLL Control 2 */
144 0x0000, /* R54 */ 146 { 118, 0x0000 }, /* R118 - FLL Control 3 */
145 0x0000, /* R55 */ 147 { 119, 0x2EE0 }, /* R119 - FLL Control 4 */
146 0x0000, /* R56 */ 148 { 120, 0x0004 }, /* R120 - FLL Control 5 */
147 0x002D, /* R57 - Analogue OUT1 Left */ 149 { 121, 0x0014 }, /* R121 - GPIO Control 1 */
148 0x002D, /* R58 - Analogue OUT1 Right */ 150 { 122, 0x0010 }, /* R122 - GPIO Control 2 */
149 0x0039, /* R59 - Analogue OUT2 Left */ 151 { 123, 0x0010 }, /* R123 - GPIO Control 3 */
150 0x0039, /* R60 - Analogue OUT2 Right */ 152 { 124, 0x0000 }, /* R124 - GPIO Control 4 */
151 0x0000, /* R61 - Analogue OUT12 ZC */ 153 { 126, 0x0000 }, /* R126 - Digital Pulls */
152 0x0000, /* R62 */ 154 { 128, 0xFFFF }, /* R128 - Interrupt Status Mask */
153 0x0000, /* R63 */ 155 { 129, 0x0000 }, /* R129 - Interrupt Polarity */
154 0x0000, /* R64 */ 156 { 130, 0x0000 }, /* R130 - Interrupt Debounce */
155 0x0000, /* R65 */ 157 { 134, 0x0000 }, /* R134 - EQ1 */
156 0x0000, /* R66 */ 158 { 135, 0x000C }, /* R135 - EQ2 */
157 0x0000, /* R67 - DC Servo 0 */ 159 { 136, 0x000C }, /* R136 - EQ3 */
158 0x0000, /* R68 - DC Servo 1 */ 160 { 137, 0x000C }, /* R137 - EQ4 */
159 0xAAAA, /* R69 - DC Servo 2 */ 161 { 138, 0x000C }, /* R138 - EQ5 */
160 0x0000, /* R70 */ 162 { 139, 0x000C }, /* R139 - EQ6 */
161 0xAAAA, /* R71 - DC Servo 4 */ 163 { 140, 0x0FCA }, /* R140 - EQ7 */
162 0xAAAA, /* R72 - DC Servo 5 */ 164 { 141, 0x0400 }, /* R141 - EQ8 */
163 0x0000, /* R73 - DC Servo 6 */ 165 { 142, 0x00D8 }, /* R142 - EQ9 */
164 0x0000, /* R74 - DC Servo 7 */ 166 { 143, 0x1EB5 }, /* R143 - EQ10 */
165 0x0000, /* R75 - DC Servo 8 */ 167 { 144, 0xF145 }, /* R144 - EQ11 */
166 0x0000, /* R76 - DC Servo 9 */ 168 { 145, 0x0B75 }, /* R145 - EQ12 */
167 0x0000, /* R77 - DC Servo Readback 0 */ 169 { 146, 0x01C5 }, /* R146 - EQ13 */
168 0x0000, /* R78 */ 170 { 147, 0x1C58 }, /* R147 - EQ14 */
169 0x0000, /* R79 */ 171 { 148, 0xF373 }, /* R148 - EQ15 */
170 0x0000, /* R80 */ 172 { 149, 0x0A54 }, /* R149 - EQ16 */
171 0x0000, /* R81 */ 173 { 150, 0x0558 }, /* R150 - EQ17 */
172 0x0000, /* R82 */ 174 { 151, 0x168E }, /* R151 - EQ18 */
173 0x0000, /* R83 */ 175 { 152, 0xF829 }, /* R152 - EQ19 */
174 0x0000, /* R84 */ 176 { 153, 0x07AD }, /* R153 - EQ20 */
175 0x0000, /* R85 */ 177 { 154, 0x1103 }, /* R154 - EQ21 */
176 0x0000, /* R86 */ 178 { 155, 0x0564 }, /* R155 - EQ22 */
177 0x0000, /* R87 */ 179 { 156, 0x0559 }, /* R156 - EQ23 */
178 0x0000, /* R88 */ 180 { 157, 0x4000 }, /* R157 - EQ24 */
179 0x0000, /* R89 */ 181 { 161, 0x0000 }, /* R161 - Control Interface Test 1 */
180 0x0000, /* R90 - Analogue HP 0 */ 182 { 204, 0x0000 }, /* R204 - Analogue Output Bias 0 */
181 0x0000, /* R91 */ 183 { 247, 0x0000 }, /* R247 - FLL NCO Test 0 */
182 0x0000, /* R92 */ 184 { 248, 0x0019 }, /* R248 - FLL NCO Test 1 */
183 0x0000, /* R93 */
184 0x0000, /* R94 - Analogue Lineout 0 */
185 0x0000, /* R95 */
186 0x0000, /* R96 */
187 0x0000, /* R97 */
188 0x0000, /* R98 - Charge Pump 0 */
189 0x0000, /* R99 */
190 0x0000, /* R100 */
191 0x0000, /* R101 */
192 0x0000, /* R102 */
193 0x0000, /* R103 */
194 0x0004, /* R104 - Class W 0 */
195 0x0000, /* R105 */
196 0x0000, /* R106 */
197 0x0000, /* R107 */
198 0x0000, /* R108 - Write Sequencer 0 */
199 0x0000, /* R109 - Write Sequencer 1 */
200 0x0000, /* R110 - Write Sequencer 2 */
201 0x0000, /* R111 - Write Sequencer 3 */
202 0x0000, /* R112 - Write Sequencer 4 */
203 0x0000, /* R113 */
204 0x0000, /* R114 */
205 0x0000, /* R115 */
206 0x0000, /* R116 - FLL Control 1 */
207 0x0007, /* R117 - FLL Control 2 */
208 0x0000, /* R118 - FLL Control 3 */
209 0x2EE0, /* R119 - FLL Control 4 */
210 0x0004, /* R120 - FLL Control 5 */
211 0x0014, /* R121 - GPIO Control 1 */
212 0x0010, /* R122 - GPIO Control 2 */
213 0x0010, /* R123 - GPIO Control 3 */
214 0x0000, /* R124 - GPIO Control 4 */
215 0x0000, /* R125 */
216 0x0000, /* R126 - Digital Pulls */
217 0x0000, /* R127 - Interrupt Status */
218 0xFFFF, /* R128 - Interrupt Status Mask */
219 0x0000, /* R129 - Interrupt Polarity */
220 0x0000, /* R130 - Interrupt Debounce */
221 0x0000, /* R131 */
222 0x0000, /* R132 */
223 0x0000, /* R133 */
224 0x0000, /* R134 - EQ1 */
225 0x000C, /* R135 - EQ2 */
226 0x000C, /* R136 - EQ3 */
227 0x000C, /* R137 - EQ4 */
228 0x000C, /* R138 - EQ5 */
229 0x000C, /* R139 - EQ6 */
230 0x0FCA, /* R140 - EQ7 */
231 0x0400, /* R141 - EQ8 */
232 0x00D8, /* R142 - EQ9 */
233 0x1EB5, /* R143 - EQ10 */
234 0xF145, /* R144 - EQ11 */
235 0x0B75, /* R145 - EQ12 */
236 0x01C5, /* R146 - EQ13 */
237 0x1C58, /* R147 - EQ14 */
238 0xF373, /* R148 - EQ15 */
239 0x0A54, /* R149 - EQ16 */
240 0x0558, /* R150 - EQ17 */
241 0x168E, /* R151 - EQ18 */
242 0xF829, /* R152 - EQ19 */
243 0x07AD, /* R153 - EQ20 */
244 0x1103, /* R154 - EQ21 */
245 0x0564, /* R155 - EQ22 */
246 0x0559, /* R156 - EQ23 */
247 0x4000, /* R157 - EQ24 */
248 0x0000, /* R158 */
249 0x0000, /* R159 */
250 0x0000, /* R160 */
251 0x0000, /* R161 - Control Interface Test 1 */
252 0x0000, /* R162 */
253 0x0000, /* R163 */
254 0x0000, /* R164 */
255 0x0000, /* R165 */
256 0x0000, /* R166 */
257 0x0000, /* R167 */
258 0x0000, /* R168 */
259 0x0000, /* R169 */
260 0x0000, /* R170 */
261 0x0000, /* R171 */
262 0x0000, /* R172 */
263 0x0000, /* R173 */
264 0x0000, /* R174 */
265 0x0000, /* R175 */
266 0x0000, /* R176 */
267 0x0000, /* R177 */
268 0x0000, /* R178 */
269 0x0000, /* R179 */
270 0x0000, /* R180 */
271 0x0000, /* R181 */
272 0x0000, /* R182 */
273 0x0000, /* R183 */
274 0x0000, /* R184 */
275 0x0000, /* R185 */
276 0x0000, /* R186 */
277 0x0000, /* R187 */
278 0x0000, /* R188 */
279 0x0000, /* R189 */
280 0x0000, /* R190 */
281 0x0000, /* R191 */
282 0x0000, /* R192 */
283 0x0000, /* R193 */
284 0x0000, /* R194 */
285 0x0000, /* R195 */
286 0x0000, /* R196 */
287 0x0000, /* R197 */
288 0x0000, /* R198 */
289 0x0000, /* R199 */
290 0x0000, /* R200 */
291 0x0000, /* R201 */
292 0x0000, /* R202 */
293 0x0000, /* R203 */
294 0x0000, /* R204 - Analogue Output Bias 0 */
295 0x0000, /* R205 */
296 0x0000, /* R206 */
297 0x0000, /* R207 */
298 0x0000, /* R208 */
299 0x0000, /* R209 */
300 0x0000, /* R210 */
301 0x0000, /* R211 */
302 0x0000, /* R212 */
303 0x0000, /* R213 */
304 0x0000, /* R214 */
305 0x0000, /* R215 */
306 0x0000, /* R216 */
307 0x0000, /* R217 */
308 0x0000, /* R218 */
309 0x0000, /* R219 */
310 0x0000, /* R220 */
311 0x0000, /* R221 */
312 0x0000, /* R222 */
313 0x0000, /* R223 */
314 0x0000, /* R224 */
315 0x0000, /* R225 */
316 0x0000, /* R226 */
317 0x0000, /* R227 */
318 0x0000, /* R228 */
319 0x0000, /* R229 */
320 0x0000, /* R230 */
321 0x0000, /* R231 */
322 0x0000, /* R232 */
323 0x0000, /* R233 */
324 0x0000, /* R234 */
325 0x0000, /* R235 */
326 0x0000, /* R236 */
327 0x0000, /* R237 */
328 0x0000, /* R238 */
329 0x0000, /* R239 */
330 0x0000, /* R240 */
331 0x0000, /* R241 */
332 0x0000, /* R242 */
333 0x0000, /* R243 */
334 0x0000, /* R244 */
335 0x0000, /* R245 */
336 0x0000, /* R246 */
337 0x0000, /* R247 - FLL NCO Test 0 */
338 0x0019, /* R248 - FLL NCO Test 1 */
339}; 185};
340 186
341static struct { 187static bool wm8904_volatile_register(struct device *dev, unsigned int reg)
342 int readable; 188{
343 int writable; 189 switch (reg) {
344 int vol; 190 case WM8904_SW_RESET_AND_ID:
345} wm8904_access[] = { 191 case WM8904_REVISION:
346 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */ 192 case WM8904_DC_SERVO_1:
347 { 0x0000, 0x0000, 0 }, /* R1 - Revision */ 193 case WM8904_DC_SERVO_6:
348 { 0x0000, 0x0000, 0 }, /* R2 */ 194 case WM8904_DC_SERVO_7:
349 { 0x0000, 0x0000, 0 }, /* R3 */ 195 case WM8904_DC_SERVO_8:
350 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */ 196 case WM8904_DC_SERVO_9:
351 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */ 197 case WM8904_DC_SERVO_READBACK_0:
352 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */ 198 case WM8904_INTERRUPT_STATUS:
353 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */ 199 return true;
354 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */ 200 default:
355 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */ 201 return false;
356 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */ 202 }
357 { 0x0000, 0x0000, 0 }, /* R11 */ 203}
358 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
359 { 0x0000, 0x0000, 0 }, /* R13 */
360 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
361 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
362 { 0x0000, 0x0000, 0 }, /* R16 */
363 { 0x0000, 0x0000, 0 }, /* R17 */
364 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
365 { 0x0000, 0x0000, 0 }, /* R19 */
366 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
367 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
368 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
369 { 0x0000, 0x0000, 0 }, /* R23 */
370 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
371 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
372 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
373 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
374 { 0x0000, 0x0000, 0 }, /* R28 */
375 { 0x0000, 0x0000, 0 }, /* R29 */
376 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
377 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
378 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
379 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
380 { 0x0000, 0x0000, 0 }, /* R34 */
381 { 0x0000, 0x0000, 0 }, /* R35 */
382 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
383 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
384 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
385 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
386 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
387 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
388 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
389 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
390 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
391 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
392 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
393 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
394 { 0x0000, 0x0000, 0 }, /* R48 */
395 { 0x0000, 0x0000, 0 }, /* R49 */
396 { 0x0000, 0x0000, 0 }, /* R50 */
397 { 0x0000, 0x0000, 0 }, /* R51 */
398 { 0x0000, 0x0000, 0 }, /* R52 */
399 { 0x0000, 0x0000, 0 }, /* R53 */
400 { 0x0000, 0x0000, 0 }, /* R54 */
401 { 0x0000, 0x0000, 0 }, /* R55 */
402 { 0x0000, 0x0000, 0 }, /* R56 */
403 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
404 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
405 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
406 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
407 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
408 { 0x0000, 0x0000, 0 }, /* R62 */
409 { 0x0000, 0x0000, 0 }, /* R63 */
410 { 0x0000, 0x0000, 0 }, /* R64 */
411 { 0x0000, 0x0000, 0 }, /* R65 */
412 { 0x0000, 0x0000, 0 }, /* R66 */
413 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
414 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
415 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
416 { 0x0000, 0x0000, 0 }, /* R70 */
417 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
418 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
419 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
420 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
421 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
422 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
423 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
424 { 0x0000, 0x0000, 0 }, /* R78 */
425 { 0x0000, 0x0000, 0 }, /* R79 */
426 { 0x0000, 0x0000, 0 }, /* R80 */
427 { 0x0000, 0x0000, 0 }, /* R81 */
428 { 0x0000, 0x0000, 0 }, /* R82 */
429 { 0x0000, 0x0000, 0 }, /* R83 */
430 { 0x0000, 0x0000, 0 }, /* R84 */
431 { 0x0000, 0x0000, 0 }, /* R85 */
432 { 0x0000, 0x0000, 0 }, /* R86 */
433 { 0x0000, 0x0000, 0 }, /* R87 */
434 { 0x0000, 0x0000, 0 }, /* R88 */
435 { 0x0000, 0x0000, 0 }, /* R89 */
436 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
437 { 0x0000, 0x0000, 0 }, /* R91 */
438 { 0x0000, 0x0000, 0 }, /* R92 */
439 { 0x0000, 0x0000, 0 }, /* R93 */
440 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
441 { 0x0000, 0x0000, 0 }, /* R95 */
442 { 0x0000, 0x0000, 0 }, /* R96 */
443 { 0x0000, 0x0000, 0 }, /* R97 */
444 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
445 { 0x0000, 0x0000, 0 }, /* R99 */
446 { 0x0000, 0x0000, 0 }, /* R100 */
447 { 0x0000, 0x0000, 0 }, /* R101 */
448 { 0x0000, 0x0000, 0 }, /* R102 */
449 { 0x0000, 0x0000, 0 }, /* R103 */
450 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
451 { 0x0000, 0x0000, 0 }, /* R105 */
452 { 0x0000, 0x0000, 0 }, /* R106 */
453 { 0x0000, 0x0000, 0 }, /* R107 */
454 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
455 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
456 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
457 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
458 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
459 { 0x0000, 0x0000, 0 }, /* R113 */
460 { 0x0000, 0x0000, 0 }, /* R114 */
461 { 0x0000, 0x0000, 0 }, /* R115 */
462 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
463 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
464 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
465 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
466 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
467 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
468 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
469 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
470 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
471 { 0x0000, 0x0000, 0 }, /* R125 */
472 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
473 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
474 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
475 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
476 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
477 { 0x0000, 0x0000, 0 }, /* R131 */
478 { 0x0000, 0x0000, 0 }, /* R132 */
479 { 0x0000, 0x0000, 0 }, /* R133 */
480 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
481 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
482 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
483 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
484 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
485 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
486 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
487 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
488 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
489 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
490 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
491 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
504 { 0x0000, 0x0000, 0 }, /* R158 */
505 { 0x0000, 0x0000, 0 }, /* R159 */
506 { 0x0000, 0x0000, 0 }, /* R160 */
507 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
508 { 0x0000, 0x0000, 0 }, /* R162 */
509 { 0x0000, 0x0000, 0 }, /* R163 */
510 { 0x0000, 0x0000, 0 }, /* R164 */
511 { 0x0000, 0x0000, 0 }, /* R165 */
512 { 0x0000, 0x0000, 0 }, /* R166 */
513 { 0x0000, 0x0000, 0 }, /* R167 */
514 { 0x0000, 0x0000, 0 }, /* R168 */
515 { 0x0000, 0x0000, 0 }, /* R169 */
516 { 0x0000, 0x0000, 0 }, /* R170 */
517 { 0x0000, 0x0000, 0 }, /* R171 */
518 { 0x0000, 0x0000, 0 }, /* R172 */
519 { 0x0000, 0x0000, 0 }, /* R173 */
520 { 0x0000, 0x0000, 0 }, /* R174 */
521 { 0x0000, 0x0000, 0 }, /* R175 */
522 { 0x0000, 0x0000, 0 }, /* R176 */
523 { 0x0000, 0x0000, 0 }, /* R177 */
524 { 0x0000, 0x0000, 0 }, /* R178 */
525 { 0x0000, 0x0000, 0 }, /* R179 */
526 { 0x0000, 0x0000, 0 }, /* R180 */
527 { 0x0000, 0x0000, 0 }, /* R181 */
528 { 0x0000, 0x0000, 0 }, /* R182 */
529 { 0x0000, 0x0000, 0 }, /* R183 */
530 { 0x0000, 0x0000, 0 }, /* R184 */
531 { 0x0000, 0x0000, 0 }, /* R185 */
532 { 0x0000, 0x0000, 0 }, /* R186 */
533 { 0x0000, 0x0000, 0 }, /* R187 */
534 { 0x0000, 0x0000, 0 }, /* R188 */
535 { 0x0000, 0x0000, 0 }, /* R189 */
536 { 0x0000, 0x0000, 0 }, /* R190 */
537 { 0x0000, 0x0000, 0 }, /* R191 */
538 { 0x0000, 0x0000, 0 }, /* R192 */
539 { 0x0000, 0x0000, 0 }, /* R193 */
540 { 0x0000, 0x0000, 0 }, /* R194 */
541 { 0x0000, 0x0000, 0 }, /* R195 */
542 { 0x0000, 0x0000, 0 }, /* R196 */
543 { 0x0000, 0x0000, 0 }, /* R197 */
544 { 0x0000, 0x0000, 0 }, /* R198 */
545 { 0x0000, 0x0000, 0 }, /* R199 */
546 { 0x0000, 0x0000, 0 }, /* R200 */
547 { 0x0000, 0x0000, 0 }, /* R201 */
548 { 0x0000, 0x0000, 0 }, /* R202 */
549 { 0x0000, 0x0000, 0 }, /* R203 */
550 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
551 { 0x0000, 0x0000, 0 }, /* R205 */
552 { 0x0000, 0x0000, 0 }, /* R206 */
553 { 0x0000, 0x0000, 0 }, /* R207 */
554 { 0x0000, 0x0000, 0 }, /* R208 */
555 { 0x0000, 0x0000, 0 }, /* R209 */
556 { 0x0000, 0x0000, 0 }, /* R210 */
557 { 0x0000, 0x0000, 0 }, /* R211 */
558 { 0x0000, 0x0000, 0 }, /* R212 */
559 { 0x0000, 0x0000, 0 }, /* R213 */
560 { 0x0000, 0x0000, 0 }, /* R214 */
561 { 0x0000, 0x0000, 0 }, /* R215 */
562 { 0x0000, 0x0000, 0 }, /* R216 */
563 { 0x0000, 0x0000, 0 }, /* R217 */
564 { 0x0000, 0x0000, 0 }, /* R218 */
565 { 0x0000, 0x0000, 0 }, /* R219 */
566 { 0x0000, 0x0000, 0 }, /* R220 */
567 { 0x0000, 0x0000, 0 }, /* R221 */
568 { 0x0000, 0x0000, 0 }, /* R222 */
569 { 0x0000, 0x0000, 0 }, /* R223 */
570 { 0x0000, 0x0000, 0 }, /* R224 */
571 { 0x0000, 0x0000, 0 }, /* R225 */
572 { 0x0000, 0x0000, 0 }, /* R226 */
573 { 0x0000, 0x0000, 0 }, /* R227 */
574 { 0x0000, 0x0000, 0 }, /* R228 */
575 { 0x0000, 0x0000, 0 }, /* R229 */
576 { 0x0000, 0x0000, 0 }, /* R230 */
577 { 0x0000, 0x0000, 0 }, /* R231 */
578 { 0x0000, 0x0000, 0 }, /* R232 */
579 { 0x0000, 0x0000, 0 }, /* R233 */
580 { 0x0000, 0x0000, 0 }, /* R234 */
581 { 0x0000, 0x0000, 0 }, /* R235 */
582 { 0x0000, 0x0000, 0 }, /* R236 */
583 { 0x0000, 0x0000, 0 }, /* R237 */
584 { 0x0000, 0x0000, 0 }, /* R238 */
585 { 0x0000, 0x0000, 0 }, /* R239 */
586 { 0x0000, 0x0000, 0 }, /* R240 */
587 { 0x0000, 0x0000, 0 }, /* R241 */
588 { 0x0000, 0x0000, 0 }, /* R242 */
589 { 0x0000, 0x0000, 0 }, /* R243 */
590 { 0x0000, 0x0000, 0 }, /* R244 */
591 { 0x0000, 0x0000, 0 }, /* R245 */
592 { 0x0000, 0x0000, 0 }, /* R246 */
593 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
594 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
595};
596 204
597static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg) 205static bool wm8904_readable_register(struct device *dev, unsigned int reg)
598{ 206{
599 return wm8904_access[reg].vol; 207 switch (reg) {
208 case WM8904_SW_RESET_AND_ID:
209 case WM8904_REVISION:
210 case WM8904_BIAS_CONTROL_0:
211 case WM8904_VMID_CONTROL_0:
212 case WM8904_MIC_BIAS_CONTROL_0:
213 case WM8904_MIC_BIAS_CONTROL_1:
214 case WM8904_ANALOGUE_DAC_0:
215 case WM8904_MIC_FILTER_CONTROL:
216 case WM8904_ANALOGUE_ADC_0:
217 case WM8904_POWER_MANAGEMENT_0:
218 case WM8904_POWER_MANAGEMENT_2:
219 case WM8904_POWER_MANAGEMENT_3:
220 case WM8904_POWER_MANAGEMENT_6:
221 case WM8904_CLOCK_RATES_0:
222 case WM8904_CLOCK_RATES_1:
223 case WM8904_CLOCK_RATES_2:
224 case WM8904_AUDIO_INTERFACE_0:
225 case WM8904_AUDIO_INTERFACE_1:
226 case WM8904_AUDIO_INTERFACE_2:
227 case WM8904_AUDIO_INTERFACE_3:
228 case WM8904_DAC_DIGITAL_VOLUME_LEFT:
229 case WM8904_DAC_DIGITAL_VOLUME_RIGHT:
230 case WM8904_DAC_DIGITAL_0:
231 case WM8904_DAC_DIGITAL_1:
232 case WM8904_ADC_DIGITAL_VOLUME_LEFT:
233 case WM8904_ADC_DIGITAL_VOLUME_RIGHT:
234 case WM8904_ADC_DIGITAL_0:
235 case WM8904_DIGITAL_MICROPHONE_0:
236 case WM8904_DRC_0:
237 case WM8904_DRC_1:
238 case WM8904_DRC_2:
239 case WM8904_DRC_3:
240 case WM8904_ANALOGUE_LEFT_INPUT_0:
241 case WM8904_ANALOGUE_RIGHT_INPUT_0:
242 case WM8904_ANALOGUE_LEFT_INPUT_1:
243 case WM8904_ANALOGUE_RIGHT_INPUT_1:
244 case WM8904_ANALOGUE_OUT1_LEFT:
245 case WM8904_ANALOGUE_OUT1_RIGHT:
246 case WM8904_ANALOGUE_OUT2_LEFT:
247 case WM8904_ANALOGUE_OUT2_RIGHT:
248 case WM8904_ANALOGUE_OUT12_ZC:
249 case WM8904_DC_SERVO_0:
250 case WM8904_DC_SERVO_1:
251 case WM8904_DC_SERVO_2:
252 case WM8904_DC_SERVO_4:
253 case WM8904_DC_SERVO_5:
254 case WM8904_DC_SERVO_6:
255 case WM8904_DC_SERVO_7:
256 case WM8904_DC_SERVO_8:
257 case WM8904_DC_SERVO_9:
258 case WM8904_DC_SERVO_READBACK_0:
259 case WM8904_ANALOGUE_HP_0:
260 case WM8904_ANALOGUE_LINEOUT_0:
261 case WM8904_CHARGE_PUMP_0:
262 case WM8904_CLASS_W_0:
263 case WM8904_WRITE_SEQUENCER_0:
264 case WM8904_WRITE_SEQUENCER_1:
265 case WM8904_WRITE_SEQUENCER_2:
266 case WM8904_WRITE_SEQUENCER_3:
267 case WM8904_WRITE_SEQUENCER_4:
268 case WM8904_FLL_CONTROL_1:
269 case WM8904_FLL_CONTROL_2:
270 case WM8904_FLL_CONTROL_3:
271 case WM8904_FLL_CONTROL_4:
272 case WM8904_FLL_CONTROL_5:
273 case WM8904_GPIO_CONTROL_1:
274 case WM8904_GPIO_CONTROL_2:
275 case WM8904_GPIO_CONTROL_3:
276 case WM8904_GPIO_CONTROL_4:
277 case WM8904_DIGITAL_PULLS:
278 case WM8904_INTERRUPT_STATUS:
279 case WM8904_INTERRUPT_STATUS_MASK:
280 case WM8904_INTERRUPT_POLARITY:
281 case WM8904_INTERRUPT_DEBOUNCE:
282 case WM8904_EQ1:
283 case WM8904_EQ2:
284 case WM8904_EQ3:
285 case WM8904_EQ4:
286 case WM8904_EQ5:
287 case WM8904_EQ6:
288 case WM8904_EQ7:
289 case WM8904_EQ8:
290 case WM8904_EQ9:
291 case WM8904_EQ10:
292 case WM8904_EQ11:
293 case WM8904_EQ12:
294 case WM8904_EQ13:
295 case WM8904_EQ14:
296 case WM8904_EQ15:
297 case WM8904_EQ16:
298 case WM8904_EQ17:
299 case WM8904_EQ18:
300 case WM8904_EQ19:
301 case WM8904_EQ20:
302 case WM8904_EQ21:
303 case WM8904_EQ22:
304 case WM8904_EQ23:
305 case WM8904_EQ24:
306 case WM8904_CONTROL_INTERFACE_TEST_1:
307 case WM8904_ADC_TEST_0:
308 case WM8904_ANALOGUE_OUTPUT_BIAS_0:
309 case WM8904_FLL_NCO_TEST_0:
310 case WM8904_FLL_NCO_TEST_1:
311 return true;
312 default:
313 return true;
314 }
600} 315}
601 316
602static int wm8904_reset(struct snd_soc_codec *codec) 317static int wm8904_reset(struct snd_soc_codec *codec)
@@ -855,6 +570,29 @@ static const char *hpf_mode_text[] = {
855static const struct soc_enum hpf_mode = 570static const struct soc_enum hpf_mode =
856 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); 571 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
857 572
573static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
575{
576 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
577 unsigned int val;
578 int ret;
579
580 ret = snd_soc_put_volsw(kcontrol, ucontrol);
581 if (ret < 0)
582 return ret;
583
584 if (ucontrol->value.integer.value[0])
585 val = 0;
586 else
587 val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5;
588
589 snd_soc_update_bits(codec, WM8904_ADC_TEST_0,
590 WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5,
591 val);
592
593 return ret;
594}
595
858static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { 596static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
859SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, 597SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
860 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), 598 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
@@ -871,7 +609,12 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
871SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 609SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
872SOC_ENUM("High Pass Filter Mode", hpf_mode), 610SOC_ENUM("High Pass Filter Mode", hpf_mode),
873 611
874SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0), 612{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
613 .name = "ADC 128x OSR Switch",
614 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
615 .put = wm8904_adc_osr_put,
616 .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
617},
875}; 618};
876 619
877static const char *drc_path_text[] = { 620static const char *drc_path_text[] = {
@@ -1433,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1433 1176
1434 switch (wm8904->devtype) { 1177 switch (wm8904->devtype) {
1435 case WM8904: 1178 case WM8904:
1436 snd_soc_add_controls(codec, wm8904_adc_snd_controls, 1179 snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
1437 ARRAY_SIZE(wm8904_adc_snd_controls)); 1180 ARRAY_SIZE(wm8904_adc_snd_controls));
1438 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1181 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1439 ARRAY_SIZE(wm8904_dac_snd_controls)); 1182 ARRAY_SIZE(wm8904_dac_snd_controls));
1440 snd_soc_add_controls(codec, wm8904_snd_controls, 1183 snd_soc_add_codec_controls(codec, wm8904_snd_controls,
1441 ARRAY_SIZE(wm8904_snd_controls)); 1184 ARRAY_SIZE(wm8904_snd_controls));
1442 1185
1443 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, 1186 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
@@ -1458,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1458 break; 1201 break;
1459 1202
1460 case WM8912: 1203 case WM8912:
1461 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1204 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1462 ARRAY_SIZE(wm8904_dac_snd_controls)); 1205 ARRAY_SIZE(wm8904_dac_snd_controls));
1463 1206
1464 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, 1207 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
@@ -2088,32 +1831,6 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2088 return 0; 1831 return 0;
2089} 1832}
2090 1833
2091static void wm8904_sync_cache(struct snd_soc_codec *codec)
2092{
2093 u16 *reg_cache = codec->reg_cache;
2094 int i;
2095
2096 if (!codec->cache_sync)
2097 return;
2098
2099 codec->cache_only = 0;
2100
2101 /* Sync back cached values if they're different from the
2102 * hardware default.
2103 */
2104 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2105 if (!wm8904_access[i].writable)
2106 continue;
2107
2108 if (reg_cache[i] == wm8904_reg[i])
2109 continue;
2110
2111 snd_soc_write(codec, i, reg_cache[i]);
2112 }
2113
2114 codec->cache_sync = 0;
2115}
2116
2117static int wm8904_set_bias_level(struct snd_soc_codec *codec, 1834static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2118 enum snd_soc_bias_level level) 1835 enum snd_soc_bias_level level)
2119{ 1836{
@@ -2146,7 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2146 return ret; 1863 return ret;
2147 } 1864 }
2148 1865
2149 wm8904_sync_cache(codec); 1866 regcache_sync(wm8904->regmap);
2150 1867
2151 /* Enable bias */ 1868 /* Enable bias */
2152 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, 1869 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2303,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2303 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2020 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2304 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2021 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2305 2022
2306 ret = snd_soc_add_controls(codec, &control, 1); 2023 ret = snd_soc_add_codec_controls(codec, &control, 1);
2307 if (ret != 0) 2024 if (ret != 0)
2308 dev_err(codec->dev, 2025 dev_err(codec->dev,
2309 "Failed to add ReTune Mobile control: %d\n", ret); 2026 "Failed to add ReTune Mobile control: %d\n", ret);
@@ -2316,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2316 int ret, i; 2033 int ret, i;
2317 2034
2318 if (!pdata) { 2035 if (!pdata) {
2319 snd_soc_add_controls(codec, wm8904_eq_controls, 2036 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2320 ARRAY_SIZE(wm8904_eq_controls)); 2037 ARRAY_SIZE(wm8904_eq_controls));
2321 return; 2038 return;
2322 } 2039 }
@@ -2344,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2344 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2061 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2345 wm8904->drc_enum.texts = wm8904->drc_texts; 2062 wm8904->drc_enum.texts = wm8904->drc_texts;
2346 2063
2347 ret = snd_soc_add_controls(codec, &control, 1); 2064 ret = snd_soc_add_codec_controls(codec, &control, 1);
2348 if (ret != 0) 2065 if (ret != 0)
2349 dev_err(codec->dev, 2066 dev_err(codec->dev,
2350 "Failed to add DRC mode control: %d\n", ret); 2067 "Failed to add DRC mode control: %d\n", ret);
@@ -2358,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2358 if (pdata->num_retune_mobile_cfgs) 2075 if (pdata->num_retune_mobile_cfgs)
2359 wm8904_handle_retune_mobile_pdata(codec); 2076 wm8904_handle_retune_mobile_pdata(codec);
2360 else 2077 else
2361 snd_soc_add_controls(codec, wm8904_eq_controls, 2078 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2362 ARRAY_SIZE(wm8904_eq_controls)); 2079 ARRAY_SIZE(wm8904_eq_controls));
2363} 2080}
2364 2081
@@ -2371,7 +2088,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2371 int ret, i; 2088 int ret, i;
2372 2089
2373 codec->cache_sync = 1; 2090 codec->cache_sync = 1;
2374 codec->dapm.idle_bias_off = 1; 2091 codec->control_data = wm8904->regmap;
2375 2092
2376 switch (wm8904->devtype) { 2093 switch (wm8904->devtype) {
2377 case WM8904: 2094 case WM8904:
@@ -2385,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2385 return -EINVAL; 2102 return -EINVAL;
2386 } 2103 }
2387 2104
2388 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 2105 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
2389 if (ret != 0) { 2106 if (ret != 0) {
2390 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2107 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2391 return ret; 2108 return ret;
@@ -2413,7 +2130,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2413 dev_err(codec->dev, "Failed to read ID register\n"); 2130 dev_err(codec->dev, "Failed to read ID register\n");
2414 goto err_enable; 2131 goto err_enable;
2415 } 2132 }
2416 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { 2133 if (ret != 0x8904) {
2417 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); 2134 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2418 ret = -EINVAL; 2135 ret = -EINVAL;
2419 goto err_enable; 2136 goto err_enable;
@@ -2519,38 +2236,62 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2519 .suspend = wm8904_suspend, 2236 .suspend = wm8904_suspend,
2520 .resume = wm8904_resume, 2237 .resume = wm8904_resume,
2521 .set_bias_level = wm8904_set_bias_level, 2238 .set_bias_level = wm8904_set_bias_level,
2522 .reg_cache_size = ARRAY_SIZE(wm8904_reg), 2239 .idle_bias_off = true,
2523 .reg_word_size = sizeof(u16), 2240};
2524 .reg_cache_default = wm8904_reg, 2241
2525 .volatile_register = wm8904_volatile_register, 2242static const struct regmap_config wm8904_regmap = {
2243 .reg_bits = 8,
2244 .val_bits = 16,
2245
2246 .max_register = WM8904_MAX_REGISTER,
2247 .volatile_reg = wm8904_volatile_register,
2248 .readable_reg = wm8904_readable_register,
2249
2250 .cache_type = REGCACHE_RBTREE,
2251 .reg_defaults = wm8904_reg_defaults,
2252 .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
2526}; 2253};
2527 2254
2528#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2529static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2255static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2530 const struct i2c_device_id *id) 2256 const struct i2c_device_id *id)
2531{ 2257{
2532 struct wm8904_priv *wm8904; 2258 struct wm8904_priv *wm8904;
2533 int ret; 2259 int ret;
2534 2260
2535 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); 2261 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
2262 GFP_KERNEL);
2536 if (wm8904 == NULL) 2263 if (wm8904 == NULL)
2537 return -ENOMEM; 2264 return -ENOMEM;
2538 2265
2266 wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap);
2267 if (IS_ERR(wm8904->regmap)) {
2268 ret = PTR_ERR(wm8904->regmap);
2269 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2270 ret);
2271 return ret;
2272 }
2273
2539 wm8904->devtype = id->driver_data; 2274 wm8904->devtype = id->driver_data;
2540 i2c_set_clientdata(i2c, wm8904); 2275 i2c_set_clientdata(i2c, wm8904);
2541 wm8904->pdata = i2c->dev.platform_data; 2276 wm8904->pdata = i2c->dev.platform_data;
2542 2277
2543 ret = snd_soc_register_codec(&i2c->dev, 2278 ret = snd_soc_register_codec(&i2c->dev,
2544 &soc_codec_dev_wm8904, &wm8904_dai, 1); 2279 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2545 if (ret < 0) 2280 if (ret != 0)
2546 kfree(wm8904); 2281 goto err;
2282
2283 return 0;
2284
2285err:
2286 regmap_exit(wm8904->regmap);
2547 return ret; 2287 return ret;
2548} 2288}
2549 2289
2550static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2290static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2551{ 2291{
2292 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2552 snd_soc_unregister_codec(&client->dev); 2293 snd_soc_unregister_codec(&client->dev);
2553 kfree(i2c_get_clientdata(client)); 2294 regmap_exit(wm8904->regmap);
2554 return 0; 2295 return 0;
2555} 2296}
2556 2297
@@ -2571,27 +2312,22 @@ static struct i2c_driver wm8904_i2c_driver = {
2571 .remove = __devexit_p(wm8904_i2c_remove), 2312 .remove = __devexit_p(wm8904_i2c_remove),
2572 .id_table = wm8904_i2c_id, 2313 .id_table = wm8904_i2c_id,
2573}; 2314};
2574#endif
2575 2315
2576static int __init wm8904_modinit(void) 2316static int __init wm8904_modinit(void)
2577{ 2317{
2578 int ret = 0; 2318 int ret = 0;
2579#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2580 ret = i2c_add_driver(&wm8904_i2c_driver); 2319 ret = i2c_add_driver(&wm8904_i2c_driver);
2581 if (ret != 0) { 2320 if (ret != 0) {
2582 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", 2321 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2583 ret); 2322 ret);
2584 } 2323 }
2585#endif
2586 return ret; 2324 return ret;
2587} 2325}
2588module_init(wm8904_modinit); 2326module_init(wm8904_modinit);
2589 2327
2590static void __exit wm8904_exit(void) 2328static void __exit wm8904_exit(void)
2591{ 2329{
2592#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2593 i2c_del_driver(&wm8904_i2c_driver); 2330 i2c_del_driver(&wm8904_i2c_driver);
2594#endif
2595} 2331}
2596module_exit(wm8904_exit); 2332module_exit(wm8904_exit);
2597 2333
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index 9e8c84188ba7..c29a0e8131ca 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -123,6 +123,7 @@
123#define WM8904_EQ23 0x9C 123#define WM8904_EQ23 0x9C
124#define WM8904_EQ24 0x9D 124#define WM8904_EQ24 0x9D
125#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1 125#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
126#define WM8904_ADC_TEST_0 0xC6
126#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC 127#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
127#define WM8904_FLL_NCO_TEST_0 0xF7 128#define WM8904_FLL_NCO_TEST_0 0xF7
128#define WM8904_FLL_NCO_TEST_1 0xF8 129#define WM8904_FLL_NCO_TEST_1 0xF8
@@ -1557,6 +1558,16 @@
1557#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */ 1558#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
1558 1559
1559/* 1560/*
1561 * R198 (0xC6) - ADC Test 0
1562 */
1563#define WM8904_ADC_128_OSR_TST_MODE 0x0004 /* ADC_128_OSR_TST_MODE */
1564#define WM8904_ADC_128_OSR_TST_MODE_SHIFT 2 /* ADC_128_OSR_TST_MODE */
1565#define WM8904_ADC_128_OSR_TST_MODE_WIDTH 1 /* ADC_128_OSR_TST_MODE */
1566#define WM8904_ADC_BIASX1P5 0x0001 /* ADC_BIASX1P5 */
1567#define WM8904_ADC_BIASX1P5_SHIFT 0 /* ADC_BIASX1P5 */
1568#define WM8904_ADC_BIASX1P5_WIDTH 1 /* ADC_BIASX1P5 */
1569
1570/*
1560 * R204 (0xCC) - Analogue Output Bias 0 1571 * R204 (0xCC) - Analogue Output Bias 0
1561 */ 1572 */
1562#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */ 1573#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 14039ea2f3e4..d2883affea3b 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -717,7 +717,7 @@ static int wm8940_probe(struct snd_soc_codec *codec)
717 return ret; 717 return ret;
718 } 718 }
719 719
720 ret = snd_soc_add_controls(codec, wm8940_snd_controls, 720 ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
721 ARRAY_SIZE(wm8940_snd_controls)); 721 ARRAY_SIZE(wm8940_snd_controls));
722 if (ret) 722 if (ret)
723 return ret; 723 return ret;
@@ -743,14 +743,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
743 .volatile_register = wm8940_volatile_register, 743 .volatile_register = wm8940_volatile_register,
744}; 744};
745 745
746#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
747static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, 746static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
748 const struct i2c_device_id *id) 747 const struct i2c_device_id *id)
749{ 748{
750 struct wm8940_priv *wm8940; 749 struct wm8940_priv *wm8940;
751 int ret; 750 int ret;
752 751
753 wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL); 752 wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv),
753 GFP_KERNEL);
754 if (wm8940 == NULL) 754 if (wm8940 == NULL)
755 return -ENOMEM; 755 return -ENOMEM;
756 756
@@ -759,15 +759,14 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
759 759
760 ret = snd_soc_register_codec(&i2c->dev, 760 ret = snd_soc_register_codec(&i2c->dev,
761 &soc_codec_dev_wm8940, &wm8940_dai, 1); 761 &soc_codec_dev_wm8940, &wm8940_dai, 1);
762 if (ret < 0) 762
763 kfree(wm8940);
764 return ret; 763 return ret;
765} 764}
766 765
767static __devexit int wm8940_i2c_remove(struct i2c_client *client) 766static __devexit int wm8940_i2c_remove(struct i2c_client *client)
768{ 767{
769 snd_soc_unregister_codec(&client->dev); 768 snd_soc_unregister_codec(&client->dev);
770 kfree(i2c_get_clientdata(client)); 769
771 return 0; 770 return 0;
772} 771}
773 772
@@ -786,27 +785,22 @@ static struct i2c_driver wm8940_i2c_driver = {
786 .remove = __devexit_p(wm8940_i2c_remove), 785 .remove = __devexit_p(wm8940_i2c_remove),
787 .id_table = wm8940_i2c_id, 786 .id_table = wm8940_i2c_id,
788}; 787};
789#endif
790 788
791static int __init wm8940_modinit(void) 789static int __init wm8940_modinit(void)
792{ 790{
793 int ret = 0; 791 int ret = 0;
794#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
795 ret = i2c_add_driver(&wm8940_i2c_driver); 792 ret = i2c_add_driver(&wm8940_i2c_driver);
796 if (ret != 0) { 793 if (ret != 0) {
797 printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", 794 printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
798 ret); 795 ret);
799 } 796 }
800#endif
801 return ret; 797 return ret;
802} 798}
803module_init(wm8940_modinit); 799module_init(wm8940_modinit);
804 800
805static void __exit wm8940_exit(void) 801static void __exit wm8940_exit(void)
806{ 802{
807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
808 i2c_del_driver(&wm8940_i2c_driver); 803 i2c_del_driver(&wm8940_i2c_driver);
809#endif
810} 804}
811module_exit(wm8940_exit); 805module_exit(wm8940_exit);
812 806
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 924548182d58..61fe97433e73 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regmap.h>
19#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
@@ -38,7 +39,7 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
38 39
39/* codec private data */ 40/* codec private data */
40struct wm8955_priv { 41struct wm8955_priv {
41 enum snd_soc_control_type control_type; 42 struct regmap *regmap;
42 43
43 unsigned int mclk_rate; 44 unsigned int mclk_rate;
44 45
@@ -48,69 +49,85 @@ struct wm8955_priv {
48 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; 49 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
49}; 50};
50 51
51static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { 52static const struct reg_default wm8955_reg_defaults[] = {
52 0x0000, /* R0 */ 53 { 2, 0x0079 }, /* R2 - LOUT1 volume */
53 0x0000, /* R1 */ 54 { 3, 0x0079 }, /* R3 - ROUT1 volume */
54 0x0079, /* R2 - LOUT1 volume */ 55 { 5, 0x0008 }, /* R5 - DAC Control */
55 0x0079, /* R3 - ROUT1 volume */ 56 { 7, 0x000A }, /* R7 - Audio Interface */
56 0x0000, /* R4 */ 57 { 8, 0x0000 }, /* R8 - Sample Rate */
57 0x0008, /* R5 - DAC Control */ 58 { 10, 0x00FF }, /* R10 - Left DAC volume */
58 0x0000, /* R6 */ 59 { 11, 0x00FF }, /* R11 - Right DAC volume */
59 0x000A, /* R7 - Audio Interface */ 60 { 12, 0x000F }, /* R12 - Bass control */
60 0x0000, /* R8 - Sample Rate */ 61 { 13, 0x000F }, /* R13 - Treble control */
61 0x0000, /* R9 */ 62 { 23, 0x00C1 }, /* R23 - Additional control (1) */
62 0x00FF, /* R10 - Left DAC volume */ 63 { 24, 0x0000 }, /* R24 - Additional control (2) */
63 0x00FF, /* R11 - Right DAC volume */ 64 { 25, 0x0000 }, /* R25 - Power Management (1) */
64 0x000F, /* R12 - Bass control */ 65 { 26, 0x0000 }, /* R26 - Power Management (2) */
65 0x000F, /* R13 - Treble control */ 66 { 27, 0x0000 }, /* R27 - Additional Control (3) */
66 0x0000, /* R14 */ 67 { 34, 0x0050 }, /* R34 - Left out Mix (1) */
67 0x0000, /* R15 - Reset */ 68 { 35, 0x0050 }, /* R35 - Left out Mix (2) */
68 0x0000, /* R16 */ 69 { 36, 0x0050 }, /* R36 - Right out Mix (1) */
69 0x0000, /* R17 */ 70 { 37, 0x0050 }, /* R37 - Right Out Mix (2) */
70 0x0000, /* R18 */ 71 { 38, 0x0050 }, /* R38 - Mono out Mix (1) */
71 0x0000, /* R19 */ 72 { 39, 0x0050 }, /* R39 - Mono out Mix (2) */
72 0x0000, /* R20 */ 73 { 40, 0x0079 }, /* R40 - LOUT2 volume */
73 0x0000, /* R21 */ 74 { 41, 0x0079 }, /* R41 - ROUT2 volume */
74 0x0000, /* R22 */ 75 { 42, 0x0079 }, /* R42 - MONOOUT volume */
75 0x00C1, /* R23 - Additional control (1) */ 76 { 43, 0x0000 }, /* R43 - Clocking / PLL */
76 0x0000, /* R24 - Additional control (2) */ 77 { 44, 0x0103 }, /* R44 - PLL Control 1 */
77 0x0000, /* R25 - Power Management (1) */ 78 { 45, 0x0024 }, /* R45 - PLL Control 2 */
78 0x0000, /* R26 - Power Management (2) */ 79 { 46, 0x01BA }, /* R46 - PLL Control 3 */
79 0x0000, /* R27 - Additional Control (3) */ 80 { 59, 0x0000 }, /* R59 - PLL Control 4 */
80 0x0000, /* R28 */
81 0x0000, /* R29 */
82 0x0000, /* R30 */
83 0x0000, /* R31 */
84 0x0000, /* R32 */
85 0x0000, /* R33 */
86 0x0050, /* R34 - Left out Mix (1) */
87 0x0050, /* R35 - Left out Mix (2) */
88 0x0050, /* R36 - Right out Mix (1) */
89 0x0050, /* R37 - Right Out Mix (2) */
90 0x0050, /* R38 - Mono out Mix (1) */
91 0x0050, /* R39 - Mono out Mix (2) */
92 0x0079, /* R40 - LOUT2 volume */
93 0x0079, /* R41 - ROUT2 volume */
94 0x0079, /* R42 - MONOOUT volume */
95 0x0000, /* R43 - Clocking / PLL */
96 0x0103, /* R44 - PLL Control 1 */
97 0x0024, /* R45 - PLL Control 2 */
98 0x01BA, /* R46 - PLL Control 3 */
99 0x0000, /* R47 */
100 0x0000, /* R48 */
101 0x0000, /* R49 */
102 0x0000, /* R50 */
103 0x0000, /* R51 */
104 0x0000, /* R52 */
105 0x0000, /* R53 */
106 0x0000, /* R54 */
107 0x0000, /* R55 */
108 0x0000, /* R56 */
109 0x0000, /* R57 */
110 0x0000, /* R58 */
111 0x0000, /* R59 - PLL Control 4 */
112}; 81};
113 82
83static bool wm8955_writeable(struct device *dev, unsigned int reg)
84{
85 switch (reg) {
86 case WM8955_LOUT1_VOLUME:
87 case WM8955_ROUT1_VOLUME:
88 case WM8955_DAC_CONTROL:
89 case WM8955_AUDIO_INTERFACE:
90 case WM8955_SAMPLE_RATE:
91 case WM8955_LEFT_DAC_VOLUME:
92 case WM8955_RIGHT_DAC_VOLUME:
93 case WM8955_BASS_CONTROL:
94 case WM8955_TREBLE_CONTROL:
95 case WM8955_RESET:
96 case WM8955_ADDITIONAL_CONTROL_1:
97 case WM8955_ADDITIONAL_CONTROL_2:
98 case WM8955_POWER_MANAGEMENT_1:
99 case WM8955_POWER_MANAGEMENT_2:
100 case WM8955_ADDITIONAL_CONTROL_3:
101 case WM8955_LEFT_OUT_MIX_1:
102 case WM8955_LEFT_OUT_MIX_2:
103 case WM8955_RIGHT_OUT_MIX_1:
104 case WM8955_RIGHT_OUT_MIX_2:
105 case WM8955_MONO_OUT_MIX_1:
106 case WM8955_MONO_OUT_MIX_2:
107 case WM8955_LOUT2_VOLUME:
108 case WM8955_ROUT2_VOLUME:
109 case WM8955_MONOOUT_VOLUME:
110 case WM8955_CLOCKING_PLL:
111 case WM8955_PLL_CONTROL_1:
112 case WM8955_PLL_CONTROL_2:
113 case WM8955_PLL_CONTROL_3:
114 case WM8955_PLL_CONTROL_4:
115 return true;
116 default:
117 return false;
118 }
119}
120
121static bool wm8955_volatile(struct device *dev, unsigned int reg)
122{
123 switch (reg) {
124 case WM8955_RESET:
125 return true;
126 default:
127 return false;
128 }
129}
130
114static int wm8955_reset(struct snd_soc_codec *codec) 131static int wm8955_reset(struct snd_soc_codec *codec)
115{ 132{
116 return snd_soc_write(codec, WM8955_RESET, 0); 133 return snd_soc_write(codec, WM8955_RESET, 0);
@@ -527,7 +544,7 @@ SND_SOC_DAPM_OUTPUT("MONOOUT"),
527SND_SOC_DAPM_OUTPUT("OUT3"), 544SND_SOC_DAPM_OUTPUT("OUT3"),
528}; 545};
529 546
530static const struct snd_soc_dapm_route wm8955_intercon[] = { 547static const struct snd_soc_dapm_route wm8955_dapm_routes[] = {
531 { "DACL", NULL, "SYSCLK" }, 548 { "DACL", NULL, "SYSCLK" },
532 { "DACR", NULL, "SYSCLK" }, 549 { "DACR", NULL, "SYSCLK" },
533 550
@@ -572,21 +589,6 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
572 { "OUT3", NULL, "OUT3 PGA" }, 589 { "OUT3", NULL, "OUT3 PGA" },
573}; 590};
574 591
575static int wm8955_add_widgets(struct snd_soc_codec *codec)
576{
577 struct snd_soc_dapm_context *dapm = &codec->dapm;
578
579 snd_soc_add_controls(codec, wm8955_snd_controls,
580 ARRAY_SIZE(wm8955_snd_controls));
581
582 snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
583 ARRAY_SIZE(wm8955_dapm_widgets));
584 snd_soc_dapm_add_routes(dapm, wm8955_intercon,
585 ARRAY_SIZE(wm8955_intercon));
586
587 return 0;
588}
589
590static int wm8955_hw_params(struct snd_pcm_substream *substream, 592static int wm8955_hw_params(struct snd_pcm_substream *substream,
591 struct snd_pcm_hw_params *params, 593 struct snd_pcm_hw_params *params,
592 struct snd_soc_dai *dai) 594 struct snd_soc_dai *dai)
@@ -765,8 +767,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
765 enum snd_soc_bias_level level) 767 enum snd_soc_bias_level level)
766{ 768{
767 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 769 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
768 u16 *reg_cache = codec->reg_cache; 770 int ret;
769 int ret, i;
770 771
771 switch (level) { 772 switch (level) {
772 case SND_SOC_BIAS_ON: 773 case SND_SOC_BIAS_ON:
@@ -795,18 +796,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
795 return ret; 796 return ret;
796 } 797 }
797 798
798 /* Sync back cached values if they're 799 regcache_sync(wm8955->regmap);
799 * different from the hardware default.
800 */
801 for (i = 0; i < codec->driver->reg_cache_size; i++) {
802 if (i == WM8955_RESET)
803 continue;
804
805 if (reg_cache[i] == wm8955_reg[i])
806 continue;
807
808 snd_soc_write(codec, i, reg_cache[i]);
809 }
810 800
811 /* Enable VREF and VMID */ 801 /* Enable VREF and VMID */
812 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, 802 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
@@ -880,8 +870,12 @@ static struct snd_soc_dai_driver wm8955_dai = {
880#ifdef CONFIG_PM 870#ifdef CONFIG_PM
881static int wm8955_suspend(struct snd_soc_codec *codec) 871static int wm8955_suspend(struct snd_soc_codec *codec)
882{ 872{
873 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
874
883 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); 875 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
884 876
877 regcache_mark_dirty(wm8955->regmap);
878
885 return 0; 879 return 0;
886} 880}
887 881
@@ -900,10 +894,11 @@ static int wm8955_probe(struct snd_soc_codec *codec)
900{ 894{
901 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 895 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
902 struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); 896 struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
903 u16 *reg_cache = codec->reg_cache;
904 int ret, i; 897 int ret, i;
905 898
906 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); 899 codec->control_data = wm8955->regmap;
900
901 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
907 if (ret != 0) { 902 if (ret != 0) {
908 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 903 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
909 return ret; 904 return ret;
@@ -958,12 +953,12 @@ static int wm8955_probe(struct snd_soc_codec *codec)
958 /* Set platform data values */ 953 /* Set platform data values */
959 if (pdata) { 954 if (pdata) {
960 if (pdata->out2_speaker) 955 if (pdata->out2_speaker)
961 reg_cache[WM8955_ADDITIONAL_CONTROL_2] 956 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2,
962 |= WM8955_ROUT2INV; 957 WM8955_ROUT2INV, WM8955_ROUT2INV);
963 958
964 if (pdata->monoin_diff) 959 if (pdata->monoin_diff)
965 reg_cache[WM8955_MONO_OUT_MIX_1] 960 snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1,
966 |= WM8955_DMEN; 961 WM8955_DMEN, WM8955_DMEN);
967 } 962 }
968 963
969 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 964 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -971,7 +966,6 @@ static int wm8955_probe(struct snd_soc_codec *codec)
971 /* Bias level configuration will have done an extra enable */ 966 /* Bias level configuration will have done an extra enable */
972 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 967 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
973 968
974 wm8955_add_widgets(codec);
975 return 0; 969 return 0;
976 970
977err_enable: 971err_enable:
@@ -996,36 +990,68 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
996 .suspend = wm8955_suspend, 990 .suspend = wm8955_suspend,
997 .resume = wm8955_resume, 991 .resume = wm8955_resume,
998 .set_bias_level = wm8955_set_bias_level, 992 .set_bias_level = wm8955_set_bias_level,
999 .reg_cache_size = ARRAY_SIZE(wm8955_reg), 993
1000 .reg_word_size = sizeof(u16), 994 .controls = wm8955_snd_controls,
1001 .reg_cache_default = wm8955_reg, 995 .num_controls = ARRAY_SIZE(wm8955_snd_controls),
996 .dapm_widgets = wm8955_dapm_widgets,
997 .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets),
998 .dapm_routes = wm8955_dapm_routes,
999 .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes),
1000};
1001
1002static const struct regmap_config wm8955_regmap = {
1003 .reg_bits = 7,
1004 .val_bits = 9,
1005
1006 .max_register = WM8955_MAX_REGISTER,
1007 .volatile_reg = wm8955_volatile,
1008 .writeable_reg = wm8955_writeable,
1009
1010 .cache_type = REGCACHE_RBTREE,
1011 .reg_defaults = wm8955_reg_defaults,
1012 .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults),
1002}; 1013};
1003 1014
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1005static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, 1015static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1006 const struct i2c_device_id *id) 1016 const struct i2c_device_id *id)
1007{ 1017{
1008 struct wm8955_priv *wm8955; 1018 struct wm8955_priv *wm8955;
1009 int ret; 1019 int ret;
1010 1020
1011 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); 1021 wm8955 = devm_kzalloc(&i2c->dev, sizeof(struct wm8955_priv),
1022 GFP_KERNEL);
1012 if (wm8955 == NULL) 1023 if (wm8955 == NULL)
1013 return -ENOMEM; 1024 return -ENOMEM;
1014 1025
1026 wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap);
1027 if (IS_ERR(wm8955->regmap)) {
1028 ret = PTR_ERR(wm8955->regmap);
1029 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1030 ret);
1031 return ret;
1032 }
1033
1015 i2c_set_clientdata(i2c, wm8955); 1034 i2c_set_clientdata(i2c, wm8955);
1016 wm8955->control_type = SND_SOC_I2C;
1017 1035
1018 ret = snd_soc_register_codec(&i2c->dev, 1036 ret = snd_soc_register_codec(&i2c->dev,
1019 &soc_codec_dev_wm8955, &wm8955_dai, 1); 1037 &soc_codec_dev_wm8955, &wm8955_dai, 1);
1020 if (ret < 0) 1038 if (ret != 0)
1021 kfree(wm8955); 1039 goto err;
1040
1041 return ret;
1042
1043err:
1044 regmap_exit(wm8955->regmap);
1022 return ret; 1045 return ret;
1023} 1046}
1024 1047
1025static __devexit int wm8955_i2c_remove(struct i2c_client *client) 1048static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1026{ 1049{
1050 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1051
1027 snd_soc_unregister_codec(&client->dev); 1052 snd_soc_unregister_codec(&client->dev);
1028 kfree(i2c_get_clientdata(client)); 1053 regmap_exit(wm8955->regmap);
1054
1029 return 0; 1055 return 0;
1030} 1056}
1031 1057
@@ -1044,27 +1070,22 @@ static struct i2c_driver wm8955_i2c_driver = {
1044 .remove = __devexit_p(wm8955_i2c_remove), 1070 .remove = __devexit_p(wm8955_i2c_remove),
1045 .id_table = wm8955_i2c_id, 1071 .id_table = wm8955_i2c_id,
1046}; 1072};
1047#endif
1048 1073
1049static int __init wm8955_modinit(void) 1074static int __init wm8955_modinit(void)
1050{ 1075{
1051 int ret = 0; 1076 int ret = 0;
1052#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1053 ret = i2c_add_driver(&wm8955_i2c_driver); 1077 ret = i2c_add_driver(&wm8955_i2c_driver);
1054 if (ret != 0) { 1078 if (ret != 0) {
1055 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", 1079 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1056 ret); 1080 ret);
1057 } 1081 }
1058#endif
1059 return ret; 1082 return ret;
1060} 1083}
1061module_init(wm8955_modinit); 1084module_init(wm8955_modinit);
1062 1085
1063static void __exit wm8955_exit(void) 1086static void __exit wm8955_exit(void)
1064{ 1087{
1065#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1066 i2c_del_driver(&wm8955_i2c_driver); 1088 i2c_del_driver(&wm8955_i2c_driver);
1067#endif
1068} 1089}
1069module_exit(wm8955_exit); 1090module_exit(wm8955_exit);
1070 1091
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 40ac888faf3d..1332692ef81b 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -920,11 +920,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
920 920
921 wm8994->dsp_active = -1; 921 wm8994->dsp_active = -1;
922 922
923 snd_soc_add_controls(codec, wm8958_mbc_snd_controls, 923 snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls,
924 ARRAY_SIZE(wm8958_mbc_snd_controls)); 924 ARRAY_SIZE(wm8958_mbc_snd_controls));
925 snd_soc_add_controls(codec, wm8958_vss_snd_controls, 925 snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls,
926 ARRAY_SIZE(wm8958_vss_snd_controls)); 926 ARRAY_SIZE(wm8958_vss_snd_controls));
927 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, 927 snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls,
928 ARRAY_SIZE(wm8958_enh_eq_snd_controls)); 928 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
929 929
930 930
@@ -958,7 +958,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs; 958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
959 wm8994->mbc_enum.texts = wm8994->mbc_texts; 959 wm8994->mbc_enum.texts = wm8994->mbc_texts;
960 960
961 ret = snd_soc_add_controls(wm8994->codec, control, 1); 961 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
962 if (ret != 0) 962 if (ret != 0)
963 dev_err(wm8994->codec->dev, 963 dev_err(wm8994->codec->dev,
964 "Failed to add MBC mode controls: %d\n", ret); 964 "Failed to add MBC mode controls: %d\n", ret);
@@ -986,7 +986,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
986 wm8994->vss_enum.max = pdata->num_vss_cfgs; 986 wm8994->vss_enum.max = pdata->num_vss_cfgs;
987 wm8994->vss_enum.texts = wm8994->vss_texts; 987 wm8994->vss_enum.texts = wm8994->vss_texts;
988 988
989 ret = snd_soc_add_controls(wm8994->codec, control, 1); 989 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
990 if (ret != 0) 990 if (ret != 0)
991 dev_err(wm8994->codec->dev, 991 dev_err(wm8994->codec->dev,
992 "Failed to add VSS mode controls: %d\n", ret); 992 "Failed to add VSS mode controls: %d\n", ret);
@@ -1015,7 +1015,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1015 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; 1015 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1016 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; 1016 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1017 1017
1018 ret = snd_soc_add_controls(wm8994->codec, control, 1); 1018 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
1019 if (ret != 0) 1019 if (ret != 0)
1020 dev_err(wm8994->codec->dev, 1020 dev_err(wm8994->codec->dev,
1021 "Failed to add VSS HPFmode controls: %d\n", 1021 "Failed to add VSS HPFmode controls: %d\n",
@@ -1045,7 +1045,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1045 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; 1045 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1046 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; 1046 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1047 1047
1048 ret = snd_soc_add_controls(wm8994->codec, control, 1); 1048 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
1049 if (ret != 0) 1049 if (ret != 0)
1050 dev_err(wm8994->codec->dev, 1050 dev_err(wm8994->codec->dev,
1051 "Failed to add enhanced EQ controls: %d\n", 1051 "Failed to add enhanced EQ controls: %d\n",
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e5caae32e541..840d72086d04 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -940,7 +940,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
940 snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); 940 snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
941 snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); 941 snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
942 942
943 snd_soc_add_controls(codec, wm8960_snd_controls, 943 snd_soc_add_codec_controls(codec, wm8960_snd_controls,
944 ARRAY_SIZE(wm8960_snd_controls)); 944 ARRAY_SIZE(wm8960_snd_controls));
945 wm8960_add_widgets(codec); 945 wm8960_add_widgets(codec);
946 946
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 4f20c72a0f1d..05ea7c274093 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,7 +1022,7 @@ static int wm8961_probe(struct snd_soc_codec *codec)
1022 1022
1023 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1023 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1024 1024
1025 snd_soc_add_controls(codec, wm8961_snd_controls, 1025 snd_soc_add_codec_controls(codec, wm8961_snd_controls,
1026 ARRAY_SIZE(wm8961_snd_controls)); 1026 ARRAY_SIZE(wm8961_snd_controls));
1027 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, 1027 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
1028 ARRAY_SIZE(wm8961_dapm_widgets)); 1028 ARRAY_SIZE(wm8961_dapm_widgets));
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 0ac228b7dc04..15d467ff91b4 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -20,6 +20,7 @@
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/pm_runtime.h>
23#include <linux/regmap.h> 24#include <linux/regmap.h>
24#include <linux/regulator/consumer.h> 25#include <linux/regulator/consumer.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
@@ -115,11 +116,11 @@ static struct reg_default wm8962_reg[] = {
115 { 1, 0x049F }, /* R1 - Right Input volume */ 116 { 1, 0x049F }, /* R1 - Right Input volume */
116 { 2, 0x0000 }, /* R2 - HPOUTL volume */ 117 { 2, 0x0000 }, /* R2 - HPOUTL volume */
117 { 3, 0x0000 }, /* R3 - HPOUTR volume */ 118 { 3, 0x0000 }, /* R3 - HPOUTR volume */
118 { 4, 0x0020 }, /* R4 - Clocking1 */ 119
119 { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ 120 { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */
120 { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ 121 { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */
121 { 7, 0x000A }, /* R7 - Audio Interface 0 */ 122 { 7, 0x000A }, /* R7 - Audio Interface 0 */
122 { 8, 0x01E4 }, /* R8 - Clocking2 */ 123
123 { 9, 0x0300 }, /* R9 - Audio Interface 1 */ 124 { 9, 0x0300 }, /* R9 - Audio Interface 1 */
124 { 10, 0x00C0 }, /* R10 - Left DAC volume */ 125 { 10, 0x00C0 }, /* R10 - Left DAC volume */
125 { 11, 0x00C0 }, /* R11 - Right DAC volume */ 126 { 11, 0x00C0 }, /* R11 - Right DAC volume */
@@ -128,7 +129,7 @@ static struct reg_default wm8962_reg[] = {
128 { 15, 0x6243 }, /* R15 - Software Reset */ 129 { 15, 0x6243 }, /* R15 - Software Reset */
129 130
130 { 17, 0x007B }, /* R17 - ALC1 */ 131 { 17, 0x007B }, /* R17 - ALC1 */
131 { 18, 0x0000 }, /* R18 - ALC2 */ 132
132 { 19, 0x1C32 }, /* R19 - ALC3 */ 133 { 19, 0x1C32 }, /* R19 - ALC3 */
133 { 20, 0x3200 }, /* R20 - Noise Gate */ 134 { 20, 0x3200 }, /* R20 - Noise Gate */
134 { 21, 0x00C0 }, /* R21 - Left ADC volume */ 135 { 21, 0x00C0 }, /* R21 - Left ADC volume */
@@ -152,10 +153,6 @@ static struct reg_default wm8962_reg[] = {
152 { 40, 0x0000 }, /* R40 - SPKOUTL volume */ 153 { 40, 0x0000 }, /* R40 - SPKOUTL volume */
153 { 41, 0x0000 }, /* R41 - SPKOUTR volume */ 154 { 41, 0x0000 }, /* R41 - SPKOUTR volume */
154 155
155 { 47, 0x0000 }, /* R47 - Thermal Shutdown Status */
156 { 48, 0x8027 }, /* R48 - Additional Control (4) */
157 { 49, 0x0010 }, /* R49 - Class D Control 1 */
158
159 { 51, 0x0003 }, /* R51 - Class D Control 2 */ 156 { 51, 0x0003 }, /* R51 - Class D Control 2 */
160 157
161 { 56, 0x0506 }, /* R56 - Clocking 4 */ 158 { 56, 0x0506 }, /* R56 - Clocking 4 */
@@ -167,8 +164,6 @@ static struct reg_default wm8962_reg[] = {
167 164
168 { 64, 0x0810 }, /* R64 - DC Servo 4 */ 165 { 64, 0x0810 }, /* R64 - DC Servo 4 */
169 166
170 { 66, 0x0000 }, /* R66 - DC Servo 6 */
171
172 { 68, 0x001B }, /* R68 - Analogue PGA Bias */ 167 { 68, 0x001B }, /* R68 - Analogue PGA Bias */
173 { 69, 0x0000 }, /* R69 - Analogue HP 0 */ 168 { 69, 0x0000 }, /* R69 - Analogue HP 0 */
174 169
@@ -207,8 +202,6 @@ static struct reg_default wm8962_reg[] = {
207 { 126, 0x000D }, /* R126 - Analogue Clocking3 */ 202 { 126, 0x000D }, /* R126 - Analogue Clocking3 */
208 { 127, 0x0000 }, /* R127 - PLL Software Reset */ 203 { 127, 0x0000 }, /* R127 - PLL Software Reset */
209 204
210 { 129, 0x0000 }, /* R129 - PLL2 */
211
212 { 131, 0x0000 }, /* R131 - PLL 4 */ 205 { 131, 0x0000 }, /* R131 - PLL 4 */
213 206
214 { 136, 0x0067 }, /* R136 - PLL 9 */ 207 { 136, 0x0067 }, /* R136 - PLL 9 */
@@ -303,9 +296,6 @@ static struct reg_default wm8962_reg[] = {
303 { 516, 0x8100 }, /* R516 - GPIO 5 */ 296 { 516, 0x8100 }, /* R516 - GPIO 5 */
304 { 517, 0x8100 }, /* R517 - GPIO 6 */ 297 { 517, 0x8100 }, /* R517 - GPIO 6 */
305 298
306 { 560, 0x0000 }, /* R560 - Interrupt Status 1 */
307 { 561, 0x0000 }, /* R561 - Interrupt Status 2 */
308
309 { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */ 299 { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */
310 { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */ 300 { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */
311 301
@@ -317,8 +307,6 @@ static struct reg_default wm8962_reg[] = {
317 307
318 { 768, 0x1C00 }, /* R768 - DSP2 Power Management */ 308 { 768, 0x1C00 }, /* R768 - DSP2 Power Management */
319 309
320 { 1037, 0x0000 }, /* R1037 - DSP2_ExecControl */
321
322 { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ 310 { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
323 311
324 { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */ 312 { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */
@@ -797,1167 +785,660 @@ static struct reg_default wm8962_reg[] = {
797 { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */ 785 { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */
798}; 786};
799 787
800static const struct wm8962_reg_access {
801 u16 read;
802 u16 write;
803 u16 vol;
804} wm8962_reg_access[WM8962_MAX_REGISTER + 1] = {
805 [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */
806 [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1 - Right Input volume */
807 [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */
808 [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */
809 [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */
810 [5] = { 0x007F, 0x007F, 0x0000 }, /* R5 - ADC & DAC Control 1 */
811 [6] = { 0x37ED, 0x37ED, 0x0000 }, /* R6 - ADC & DAC Control 2 */
812 [7] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R7 - Audio Interface 0 */
813 [8] = { 0x0FEF, 0x0FEF, 0xFFFF }, /* R8 - Clocking2 */
814 [9] = { 0x0B9F, 0x039F, 0x0000 }, /* R9 - Audio Interface 1 */
815 [10] = { 0x00FF, 0x01FF, 0x0000 }, /* R10 - Left DAC volume */
816 [11] = { 0x00FF, 0x01FF, 0x0000 }, /* R11 - Right DAC volume */
817 [14] = { 0x07FF, 0x07FF, 0x0000 }, /* R14 - Audio Interface 2 */
818 [15] = { 0xFFFF, 0xFFFF, 0xFFFF }, /* R15 - Software Reset */
819 [17] = { 0x07FF, 0x07FF, 0x0000 }, /* R17 - ALC1 */
820 [18] = { 0xF8FF, 0x00FF, 0xFFFF }, /* R18 - ALC2 */
821 [19] = { 0x1DFF, 0x1DFF, 0x0000 }, /* R19 - ALC3 */
822 [20] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20 - Noise Gate */
823 [21] = { 0x00FF, 0x01FF, 0x0000 }, /* R21 - Left ADC volume */
824 [22] = { 0x00FF, 0x01FF, 0x0000 }, /* R22 - Right ADC volume */
825 [23] = { 0x0161, 0x0161, 0x0000 }, /* R23 - Additional control(1) */
826 [24] = { 0x0008, 0x0008, 0x0000 }, /* R24 - Additional control(2) */
827 [25] = { 0x07FE, 0x07FE, 0x0000 }, /* R25 - Pwr Mgmt (1) */
828 [26] = { 0x01FB, 0x01FB, 0x0000 }, /* R26 - Pwr Mgmt (2) */
829 [27] = { 0x0017, 0x0017, 0x0000 }, /* R27 - Additional Control (3) */
830 [28] = { 0x001C, 0x001C, 0x0000 }, /* R28 - Anti-pop */
831
832 [30] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R30 - Clocking 3 */
833 [31] = { 0x000F, 0x000F, 0x0000 }, /* R31 - Input mixer control (1) */
834 [32] = { 0x01FF, 0x01FF, 0x0000 }, /* R32 - Left input mixer volume */
835 [33] = { 0x01FF, 0x01FF, 0x0000 }, /* R33 - Right input mixer volume */
836 [34] = { 0x003F, 0x003F, 0x0000 }, /* R34 - Input mixer control (2) */
837 [35] = { 0x003F, 0x003F, 0x0000 }, /* R35 - Input bias control */
838 [37] = { 0x001F, 0x001F, 0x0000 }, /* R37 - Left input PGA control */
839 [38] = { 0x001F, 0x001F, 0x0000 }, /* R38 - Right input PGA control */
840 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
841 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
842
843 [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */
844 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
845 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
846 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
847 [56] = { 0x001E, 0x001E, 0x0000 }, /* R56 - Clocking 4 */
848 [57] = { 0x02FC, 0x02FC, 0x0000 }, /* R57 - DAC DSP Mixing (1) */
849 [58] = { 0x00FC, 0x00FC, 0x0000 }, /* R58 - DAC DSP Mixing (2) */
850 [60] = { 0x00CC, 0x00CC, 0x0000 }, /* R60 - DC Servo 0 */
851 [61] = { 0x00DD, 0x00DD, 0x0000 }, /* R61 - DC Servo 1 */
852 [64] = { 0x3F80, 0x3F80, 0x0000 }, /* R64 - DC Servo 4 */
853 [66] = { 0x0780, 0x0000, 0xFFFF }, /* R66 - DC Servo 6 */
854 [68] = { 0x0007, 0x0007, 0x0000 }, /* R68 - Analogue PGA Bias */
855 [69] = { 0x00FF, 0x00FF, 0x0000 }, /* R69 - Analogue HP 0 */
856 [71] = { 0x01FF, 0x01FF, 0x0000 }, /* R71 - Analogue HP 2 */
857 [72] = { 0x0001, 0x0001, 0x0000 }, /* R72 - Charge Pump 1 */
858 [82] = { 0x0001, 0x0001, 0x0000 }, /* R82 - Charge Pump B */
859 [87] = { 0x00A0, 0x00A0, 0x0000 }, /* R87 - Write Sequencer Control 1 */
860 [90] = { 0x007F, 0x01FF, 0x0000 }, /* R90 - Write Sequencer Control 2 */
861 [93] = { 0x03F9, 0x0000, 0x0000 }, /* R93 - Write Sequencer Control 3 */
862 [94] = { 0x0070, 0x0070, 0x0000 }, /* R94 - Control Interface */
863 [99] = { 0x000F, 0x000F, 0x0000 }, /* R99 - Mixer Enables */
864 [100] = { 0x00BF, 0x00BF, 0x0000 }, /* R100 - Headphone Mixer (1) */
865 [101] = { 0x00BF, 0x00BF, 0x0000 }, /* R101 - Headphone Mixer (2) */
866 [102] = { 0x01FF, 0x01FF, 0x0000 }, /* R102 - Headphone Mixer (3) */
867 [103] = { 0x01FF, 0x01FF, 0x0000 }, /* R103 - Headphone Mixer (4) */
868 [105] = { 0x00BF, 0x00BF, 0x0000 }, /* R105 - Speaker Mixer (1) */
869 [106] = { 0x00BF, 0x00BF, 0x0000 }, /* R106 - Speaker Mixer (2) */
870 [107] = { 0x01FF, 0x01FF, 0x0000 }, /* R107 - Speaker Mixer (3) */
871 [108] = { 0x01FF, 0x01FF, 0x0000 }, /* R108 - Speaker Mixer (4) */
872 [109] = { 0x00F0, 0x00F0, 0x0000 }, /* R109 - Speaker Mixer (5) */
873 [110] = { 0x00F7, 0x00F7, 0x0000 }, /* R110 - Beep Generator (1) */
874 [115] = { 0x001F, 0x001F, 0x0000 }, /* R115 - Oscillator Trim (3) */
875 [116] = { 0x001F, 0x001F, 0x0000 }, /* R116 - Oscillator Trim (4) */
876 [119] = { 0x00FF, 0x00FF, 0x0000 }, /* R119 - Oscillator Trim (7) */
877 [124] = { 0x0079, 0x0079, 0x0000 }, /* R124 - Analogue Clocking1 */
878 [125] = { 0x00DF, 0x00DF, 0x0000 }, /* R125 - Analogue Clocking2 */
879 [126] = { 0x000D, 0x000D, 0x0000 }, /* R126 - Analogue Clocking3 */
880 [127] = { 0x0000, 0xFFFF, 0x0000 }, /* R127 - PLL Software Reset */
881 [129] = { 0x00B0, 0x00B0, 0x0000 }, /* R129 - PLL2 */
882 [131] = { 0x0003, 0x0003, 0x0000 }, /* R131 - PLL 4 */
883 [136] = { 0x005F, 0x005F, 0x0000 }, /* R136 - PLL 9 */
884 [137] = { 0x00FF, 0x00FF, 0x0000 }, /* R137 - PLL 10 */
885 [138] = { 0x00FF, 0x00FF, 0x0000 }, /* R138 - PLL 11 */
886 [139] = { 0x00FF, 0x00FF, 0x0000 }, /* R139 - PLL 12 */
887 [140] = { 0x005F, 0x005F, 0x0000 }, /* R140 - PLL 13 */
888 [141] = { 0x00FF, 0x00FF, 0x0000 }, /* R141 - PLL 14 */
889 [142] = { 0x00FF, 0x00FF, 0x0000 }, /* R142 - PLL 15 */
890 [143] = { 0x00FF, 0x00FF, 0x0000 }, /* R143 - PLL 16 */
891 [155] = { 0x0067, 0x0067, 0x0000 }, /* R155 - FLL Control (1) */
892 [156] = { 0x01FB, 0x01FB, 0x0000 }, /* R156 - FLL Control (2) */
893 [157] = { 0x0007, 0x0007, 0x0000 }, /* R157 - FLL Control (3) */
894 [159] = { 0x007F, 0x007F, 0x0000 }, /* R159 - FLL Control (5) */
895 [160] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R160 - FLL Control (6) */
896 [161] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R161 - FLL Control (7) */
897 [162] = { 0x03FF, 0x03FF, 0x0000 }, /* R162 - FLL Control (8) */
898 [252] = { 0x0005, 0x0005, 0x0000 }, /* R252 - General test 1 */
899 [256] = { 0x000F, 0x000F, 0x0000 }, /* R256 - DF1 */
900 [257] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R257 - DF2 */
901 [258] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R258 - DF3 */
902 [259] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R259 - DF4 */
903 [260] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R260 - DF5 */
904 [261] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R261 - DF6 */
905 [262] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R262 - DF7 */
906 [264] = { 0x0003, 0x0003, 0x0000 }, /* R264 - LHPF1 */
907 [265] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R265 - LHPF2 */
908 [268] = { 0x0077, 0x0077, 0x0000 }, /* R268 - THREED1 */
909 [269] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R269 - THREED2 */
910 [270] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R270 - THREED3 */
911 [271] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R271 - THREED4 */
912 [276] = { 0x7FFF, 0x7FFF, 0x0000 }, /* R276 - DRC 1 */
913 [277] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R277 - DRC 2 */
914 [278] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R278 - DRC 3 */
915 [279] = { 0x07FF, 0x07FF, 0x0000 }, /* R279 - DRC 4 */
916 [280] = { 0x03FF, 0x03FF, 0x0000 }, /* R280 - DRC 5 */
917 [285] = { 0x0003, 0x0003, 0x0000 }, /* R285 - Tloopback */
918 [335] = { 0x0007, 0x0007, 0x0000 }, /* R335 - EQ1 */
919 [336] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R336 - EQ2 */
920 [337] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R337 - EQ3 */
921 [338] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R338 - EQ4 */
922 [339] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R339 - EQ5 */
923 [340] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R340 - EQ6 */
924 [341] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R341 - EQ7 */
925 [342] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R342 - EQ8 */
926 [343] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R343 - EQ9 */
927 [344] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R344 - EQ10 */
928 [345] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R345 - EQ11 */
929 [346] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R346 - EQ12 */
930 [347] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R347 - EQ13 */
931 [348] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R348 - EQ14 */
932 [349] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R349 - EQ15 */
933 [350] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R350 - EQ16 */
934 [351] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R351 - EQ17 */
935 [352] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R352 - EQ18 */
936 [353] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R353 - EQ19 */
937 [354] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R354 - EQ20 */
938 [355] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R355 - EQ21 */
939 [356] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R356 - EQ22 */
940 [357] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R357 - EQ23 */
941 [358] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R358 - EQ24 */
942 [359] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R359 - EQ25 */
943 [360] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R360 - EQ26 */
944 [361] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R361 - EQ27 */
945 [362] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R362 - EQ28 */
946 [363] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R363 - EQ29 */
947 [364] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R364 - EQ30 */
948 [365] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R365 - EQ31 */
949 [366] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R366 - EQ32 */
950 [367] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R367 - EQ33 */
951 [368] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R368 - EQ34 */
952 [369] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R369 - EQ35 */
953 [370] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R370 - EQ36 */
954 [371] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R371 - EQ37 */
955 [372] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R372 - EQ38 */
956 [373] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R373 - EQ39 */
957 [374] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R374 - EQ40 */
958 [375] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R375 - EQ41 */
959 [513] = { 0x045F, 0x045F, 0x0000 }, /* R513 - GPIO 2 */
960 [514] = { 0x045F, 0x045F, 0x0000 }, /* R514 - GPIO 3 */
961 [516] = { 0xE75F, 0xE75F, 0x0000 }, /* R516 - GPIO 5 */
962 [517] = { 0xE75F, 0xE75F, 0x0000 }, /* R517 - GPIO 6 */
963 [560] = { 0x0030, 0x0030, 0xFFFF }, /* R560 - Interrupt Status 1 */
964 [561] = { 0xFFED, 0xFFED, 0xFFFF }, /* R561 - Interrupt Status 2 */
965 [568] = { 0x0030, 0x0030, 0x0000 }, /* R568 - Interrupt Status 1 Mask */
966 [569] = { 0xFFED, 0xFFED, 0x0000 }, /* R569 - Interrupt Status 2 Mask */
967 [576] = { 0x0001, 0x0001, 0x0000 }, /* R576 - Interrupt Control */
968 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
969 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
970 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
971 [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */
972 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
973 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
974 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
975 [4099] = { 0x010F, 0x010F, 0x0000 }, /* R4099 - Write Sequencer 3 */
976 [4100] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4100 - Write Sequencer 4 */
977 [4101] = { 0x00FF, 0x00FF, 0x0000 }, /* R4101 - Write Sequencer 5 */
978 [4102] = { 0x070F, 0x070F, 0x0000 }, /* R4102 - Write Sequencer 6 */
979 [4103] = { 0x010F, 0x010F, 0x0000 }, /* R4103 - Write Sequencer 7 */
980 [4104] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4104 - Write Sequencer 8 */
981 [4105] = { 0x00FF, 0x00FF, 0x0000 }, /* R4105 - Write Sequencer 9 */
982 [4106] = { 0x070F, 0x070F, 0x0000 }, /* R4106 - Write Sequencer 10 */
983 [4107] = { 0x010F, 0x010F, 0x0000 }, /* R4107 - Write Sequencer 11 */
984 [4108] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4108 - Write Sequencer 12 */
985 [4109] = { 0x00FF, 0x00FF, 0x0000 }, /* R4109 - Write Sequencer 13 */
986 [4110] = { 0x070F, 0x070F, 0x0000 }, /* R4110 - Write Sequencer 14 */
987 [4111] = { 0x010F, 0x010F, 0x0000 }, /* R4111 - Write Sequencer 15 */
988 [4112] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4112 - Write Sequencer 16 */
989 [4113] = { 0x00FF, 0x00FF, 0x0000 }, /* R4113 - Write Sequencer 17 */
990 [4114] = { 0x070F, 0x070F, 0x0000 }, /* R4114 - Write Sequencer 18 */
991 [4115] = { 0x010F, 0x010F, 0x0000 }, /* R4115 - Write Sequencer 19 */
992 [4116] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4116 - Write Sequencer 20 */
993 [4117] = { 0x00FF, 0x00FF, 0x0000 }, /* R4117 - Write Sequencer 21 */
994 [4118] = { 0x070F, 0x070F, 0x0000 }, /* R4118 - Write Sequencer 22 */
995 [4119] = { 0x010F, 0x010F, 0x0000 }, /* R4119 - Write Sequencer 23 */
996 [4120] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4120 - Write Sequencer 24 */
997 [4121] = { 0x00FF, 0x00FF, 0x0000 }, /* R4121 - Write Sequencer 25 */
998 [4122] = { 0x070F, 0x070F, 0x0000 }, /* R4122 - Write Sequencer 26 */
999 [4123] = { 0x010F, 0x010F, 0x0000 }, /* R4123 - Write Sequencer 27 */
1000 [4124] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4124 - Write Sequencer 28 */
1001 [4125] = { 0x00FF, 0x00FF, 0x0000 }, /* R4125 - Write Sequencer 29 */
1002 [4126] = { 0x070F, 0x070F, 0x0000 }, /* R4126 - Write Sequencer 30 */
1003 [4127] = { 0x010F, 0x010F, 0x0000 }, /* R4127 - Write Sequencer 31 */
1004 [4128] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4128 - Write Sequencer 32 */
1005 [4129] = { 0x00FF, 0x00FF, 0x0000 }, /* R4129 - Write Sequencer 33 */
1006 [4130] = { 0x070F, 0x070F, 0x0000 }, /* R4130 - Write Sequencer 34 */
1007 [4131] = { 0x010F, 0x010F, 0x0000 }, /* R4131 - Write Sequencer 35 */
1008 [4132] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4132 - Write Sequencer 36 */
1009 [4133] = { 0x00FF, 0x00FF, 0x0000 }, /* R4133 - Write Sequencer 37 */
1010 [4134] = { 0x070F, 0x070F, 0x0000 }, /* R4134 - Write Sequencer 38 */
1011 [4135] = { 0x010F, 0x010F, 0x0000 }, /* R4135 - Write Sequencer 39 */
1012 [4136] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4136 - Write Sequencer 40 */
1013 [4137] = { 0x00FF, 0x00FF, 0x0000 }, /* R4137 - Write Sequencer 41 */
1014 [4138] = { 0x070F, 0x070F, 0x0000 }, /* R4138 - Write Sequencer 42 */
1015 [4139] = { 0x010F, 0x010F, 0x0000 }, /* R4139 - Write Sequencer 43 */
1016 [4140] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4140 - Write Sequencer 44 */
1017 [4141] = { 0x00FF, 0x00FF, 0x0000 }, /* R4141 - Write Sequencer 45 */
1018 [4142] = { 0x070F, 0x070F, 0x0000 }, /* R4142 - Write Sequencer 46 */
1019 [4143] = { 0x010F, 0x010F, 0x0000 }, /* R4143 - Write Sequencer 47 */
1020 [4144] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4144 - Write Sequencer 48 */
1021 [4145] = { 0x00FF, 0x00FF, 0x0000 }, /* R4145 - Write Sequencer 49 */
1022 [4146] = { 0x070F, 0x070F, 0x0000 }, /* R4146 - Write Sequencer 50 */
1023 [4147] = { 0x010F, 0x010F, 0x0000 }, /* R4147 - Write Sequencer 51 */
1024 [4148] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4148 - Write Sequencer 52 */
1025 [4149] = { 0x00FF, 0x00FF, 0x0000 }, /* R4149 - Write Sequencer 53 */
1026 [4150] = { 0x070F, 0x070F, 0x0000 }, /* R4150 - Write Sequencer 54 */
1027 [4151] = { 0x010F, 0x010F, 0x0000 }, /* R4151 - Write Sequencer 55 */
1028 [4152] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4152 - Write Sequencer 56 */
1029 [4153] = { 0x00FF, 0x00FF, 0x0000 }, /* R4153 - Write Sequencer 57 */
1030 [4154] = { 0x070F, 0x070F, 0x0000 }, /* R4154 - Write Sequencer 58 */
1031 [4155] = { 0x010F, 0x010F, 0x0000 }, /* R4155 - Write Sequencer 59 */
1032 [4156] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4156 - Write Sequencer 60 */
1033 [4157] = { 0x00FF, 0x00FF, 0x0000 }, /* R4157 - Write Sequencer 61 */
1034 [4158] = { 0x070F, 0x070F, 0x0000 }, /* R4158 - Write Sequencer 62 */
1035 [4159] = { 0x010F, 0x010F, 0x0000 }, /* R4159 - Write Sequencer 63 */
1036 [4160] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4160 - Write Sequencer 64 */
1037 [4161] = { 0x00FF, 0x00FF, 0x0000 }, /* R4161 - Write Sequencer 65 */
1038 [4162] = { 0x070F, 0x070F, 0x0000 }, /* R4162 - Write Sequencer 66 */
1039 [4163] = { 0x010F, 0x010F, 0x0000 }, /* R4163 - Write Sequencer 67 */
1040 [4164] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4164 - Write Sequencer 68 */
1041 [4165] = { 0x00FF, 0x00FF, 0x0000 }, /* R4165 - Write Sequencer 69 */
1042 [4166] = { 0x070F, 0x070F, 0x0000 }, /* R4166 - Write Sequencer 70 */
1043 [4167] = { 0x010F, 0x010F, 0x0000 }, /* R4167 - Write Sequencer 71 */
1044 [4168] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4168 - Write Sequencer 72 */
1045 [4169] = { 0x00FF, 0x00FF, 0x0000 }, /* R4169 - Write Sequencer 73 */
1046 [4170] = { 0x070F, 0x070F, 0x0000 }, /* R4170 - Write Sequencer 74 */
1047 [4171] = { 0x010F, 0x010F, 0x0000 }, /* R4171 - Write Sequencer 75 */
1048 [4172] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4172 - Write Sequencer 76 */
1049 [4173] = { 0x00FF, 0x00FF, 0x0000 }, /* R4173 - Write Sequencer 77 */
1050 [4174] = { 0x070F, 0x070F, 0x0000 }, /* R4174 - Write Sequencer 78 */
1051 [4175] = { 0x010F, 0x010F, 0x0000 }, /* R4175 - Write Sequencer 79 */
1052 [4176] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4176 - Write Sequencer 80 */
1053 [4177] = { 0x00FF, 0x00FF, 0x0000 }, /* R4177 - Write Sequencer 81 */
1054 [4178] = { 0x070F, 0x070F, 0x0000 }, /* R4178 - Write Sequencer 82 */
1055 [4179] = { 0x010F, 0x010F, 0x0000 }, /* R4179 - Write Sequencer 83 */
1056 [4180] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4180 - Write Sequencer 84 */
1057 [4181] = { 0x00FF, 0x00FF, 0x0000 }, /* R4181 - Write Sequencer 85 */
1058 [4182] = { 0x070F, 0x070F, 0x0000 }, /* R4182 - Write Sequencer 86 */
1059 [4183] = { 0x010F, 0x010F, 0x0000 }, /* R4183 - Write Sequencer 87 */
1060 [4184] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4184 - Write Sequencer 88 */
1061 [4185] = { 0x00FF, 0x00FF, 0x0000 }, /* R4185 - Write Sequencer 89 */
1062 [4186] = { 0x070F, 0x070F, 0x0000 }, /* R4186 - Write Sequencer 90 */
1063 [4187] = { 0x010F, 0x010F, 0x0000 }, /* R4187 - Write Sequencer 91 */
1064 [4188] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4188 - Write Sequencer 92 */
1065 [4189] = { 0x00FF, 0x00FF, 0x0000 }, /* R4189 - Write Sequencer 93 */
1066 [4190] = { 0x070F, 0x070F, 0x0000 }, /* R4190 - Write Sequencer 94 */
1067 [4191] = { 0x010F, 0x010F, 0x0000 }, /* R4191 - Write Sequencer 95 */
1068 [4192] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4192 - Write Sequencer 96 */
1069 [4193] = { 0x00FF, 0x00FF, 0x0000 }, /* R4193 - Write Sequencer 97 */
1070 [4194] = { 0x070F, 0x070F, 0x0000 }, /* R4194 - Write Sequencer 98 */
1071 [4195] = { 0x010F, 0x010F, 0x0000 }, /* R4195 - Write Sequencer 99 */
1072 [4196] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4196 - Write Sequencer 100 */
1073 [4197] = { 0x00FF, 0x00FF, 0x0000 }, /* R4197 - Write Sequencer 101 */
1074 [4198] = { 0x070F, 0x070F, 0x0000 }, /* R4198 - Write Sequencer 102 */
1075 [4199] = { 0x010F, 0x010F, 0x0000 }, /* R4199 - Write Sequencer 103 */
1076 [4200] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4200 - Write Sequencer 104 */
1077 [4201] = { 0x00FF, 0x00FF, 0x0000 }, /* R4201 - Write Sequencer 105 */
1078 [4202] = { 0x070F, 0x070F, 0x0000 }, /* R4202 - Write Sequencer 106 */
1079 [4203] = { 0x010F, 0x010F, 0x0000 }, /* R4203 - Write Sequencer 107 */
1080 [4204] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4204 - Write Sequencer 108 */
1081 [4205] = { 0x00FF, 0x00FF, 0x0000 }, /* R4205 - Write Sequencer 109 */
1082 [4206] = { 0x070F, 0x070F, 0x0000 }, /* R4206 - Write Sequencer 110 */
1083 [4207] = { 0x010F, 0x010F, 0x0000 }, /* R4207 - Write Sequencer 111 */
1084 [4208] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4208 - Write Sequencer 112 */
1085 [4209] = { 0x00FF, 0x00FF, 0x0000 }, /* R4209 - Write Sequencer 113 */
1086 [4210] = { 0x070F, 0x070F, 0x0000 }, /* R4210 - Write Sequencer 114 */
1087 [4211] = { 0x010F, 0x010F, 0x0000 }, /* R4211 - Write Sequencer 115 */
1088 [4212] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4212 - Write Sequencer 116 */
1089 [4213] = { 0x00FF, 0x00FF, 0x0000 }, /* R4213 - Write Sequencer 117 */
1090 [4214] = { 0x070F, 0x070F, 0x0000 }, /* R4214 - Write Sequencer 118 */
1091 [4215] = { 0x010F, 0x010F, 0x0000 }, /* R4215 - Write Sequencer 119 */
1092 [4216] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4216 - Write Sequencer 120 */
1093 [4217] = { 0x00FF, 0x00FF, 0x0000 }, /* R4217 - Write Sequencer 121 */
1094 [4218] = { 0x070F, 0x070F, 0x0000 }, /* R4218 - Write Sequencer 122 */
1095 [4219] = { 0x010F, 0x010F, 0x0000 }, /* R4219 - Write Sequencer 123 */
1096 [4220] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4220 - Write Sequencer 124 */
1097 [4221] = { 0x00FF, 0x00FF, 0x0000 }, /* R4221 - Write Sequencer 125 */
1098 [4222] = { 0x070F, 0x070F, 0x0000 }, /* R4222 - Write Sequencer 126 */
1099 [4223] = { 0x010F, 0x010F, 0x0000 }, /* R4223 - Write Sequencer 127 */
1100 [4224] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4224 - Write Sequencer 128 */
1101 [4225] = { 0x00FF, 0x00FF, 0x0000 }, /* R4225 - Write Sequencer 129 */
1102 [4226] = { 0x070F, 0x070F, 0x0000 }, /* R4226 - Write Sequencer 130 */
1103 [4227] = { 0x010F, 0x010F, 0x0000 }, /* R4227 - Write Sequencer 131 */
1104 [4228] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4228 - Write Sequencer 132 */
1105 [4229] = { 0x00FF, 0x00FF, 0x0000 }, /* R4229 - Write Sequencer 133 */
1106 [4230] = { 0x070F, 0x070F, 0x0000 }, /* R4230 - Write Sequencer 134 */
1107 [4231] = { 0x010F, 0x010F, 0x0000 }, /* R4231 - Write Sequencer 135 */
1108 [4232] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4232 - Write Sequencer 136 */
1109 [4233] = { 0x00FF, 0x00FF, 0x0000 }, /* R4233 - Write Sequencer 137 */
1110 [4234] = { 0x070F, 0x070F, 0x0000 }, /* R4234 - Write Sequencer 138 */
1111 [4235] = { 0x010F, 0x010F, 0x0000 }, /* R4235 - Write Sequencer 139 */
1112 [4236] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4236 - Write Sequencer 140 */
1113 [4237] = { 0x00FF, 0x00FF, 0x0000 }, /* R4237 - Write Sequencer 141 */
1114 [4238] = { 0x070F, 0x070F, 0x0000 }, /* R4238 - Write Sequencer 142 */
1115 [4239] = { 0x010F, 0x010F, 0x0000 }, /* R4239 - Write Sequencer 143 */
1116 [4240] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4240 - Write Sequencer 144 */
1117 [4241] = { 0x00FF, 0x00FF, 0x0000 }, /* R4241 - Write Sequencer 145 */
1118 [4242] = { 0x070F, 0x070F, 0x0000 }, /* R4242 - Write Sequencer 146 */
1119 [4243] = { 0x010F, 0x010F, 0x0000 }, /* R4243 - Write Sequencer 147 */
1120 [4244] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4244 - Write Sequencer 148 */
1121 [4245] = { 0x00FF, 0x00FF, 0x0000 }, /* R4245 - Write Sequencer 149 */
1122 [4246] = { 0x070F, 0x070F, 0x0000 }, /* R4246 - Write Sequencer 150 */
1123 [4247] = { 0x010F, 0x010F, 0x0000 }, /* R4247 - Write Sequencer 151 */
1124 [4248] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4248 - Write Sequencer 152 */
1125 [4249] = { 0x00FF, 0x00FF, 0x0000 }, /* R4249 - Write Sequencer 153 */
1126 [4250] = { 0x070F, 0x070F, 0x0000 }, /* R4250 - Write Sequencer 154 */
1127 [4251] = { 0x010F, 0x010F, 0x0000 }, /* R4251 - Write Sequencer 155 */
1128 [4252] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4252 - Write Sequencer 156 */
1129 [4253] = { 0x00FF, 0x00FF, 0x0000 }, /* R4253 - Write Sequencer 157 */
1130 [4254] = { 0x070F, 0x070F, 0x0000 }, /* R4254 - Write Sequencer 158 */
1131 [4255] = { 0x010F, 0x010F, 0x0000 }, /* R4255 - Write Sequencer 159 */
1132 [4256] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4256 - Write Sequencer 160 */
1133 [4257] = { 0x00FF, 0x00FF, 0x0000 }, /* R4257 - Write Sequencer 161 */
1134 [4258] = { 0x070F, 0x070F, 0x0000 }, /* R4258 - Write Sequencer 162 */
1135 [4259] = { 0x010F, 0x010F, 0x0000 }, /* R4259 - Write Sequencer 163 */
1136 [4260] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4260 - Write Sequencer 164 */
1137 [4261] = { 0x00FF, 0x00FF, 0x0000 }, /* R4261 - Write Sequencer 165 */
1138 [4262] = { 0x070F, 0x070F, 0x0000 }, /* R4262 - Write Sequencer 166 */
1139 [4263] = { 0x010F, 0x010F, 0x0000 }, /* R4263 - Write Sequencer 167 */
1140 [4264] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4264 - Write Sequencer 168 */
1141 [4265] = { 0x00FF, 0x00FF, 0x0000 }, /* R4265 - Write Sequencer 169 */
1142 [4266] = { 0x070F, 0x070F, 0x0000 }, /* R4266 - Write Sequencer 170 */
1143 [4267] = { 0x010F, 0x010F, 0x0000 }, /* R4267 - Write Sequencer 171 */
1144 [4268] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4268 - Write Sequencer 172 */
1145 [4269] = { 0x00FF, 0x00FF, 0x0000 }, /* R4269 - Write Sequencer 173 */
1146 [4270] = { 0x070F, 0x070F, 0x0000 }, /* R4270 - Write Sequencer 174 */
1147 [4271] = { 0x010F, 0x010F, 0x0000 }, /* R4271 - Write Sequencer 175 */
1148 [4272] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4272 - Write Sequencer 176 */
1149 [4273] = { 0x00FF, 0x00FF, 0x0000 }, /* R4273 - Write Sequencer 177 */
1150 [4274] = { 0x070F, 0x070F, 0x0000 }, /* R4274 - Write Sequencer 178 */
1151 [4275] = { 0x010F, 0x010F, 0x0000 }, /* R4275 - Write Sequencer 179 */
1152 [4276] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4276 - Write Sequencer 180 */
1153 [4277] = { 0x00FF, 0x00FF, 0x0000 }, /* R4277 - Write Sequencer 181 */
1154 [4278] = { 0x070F, 0x070F, 0x0000 }, /* R4278 - Write Sequencer 182 */
1155 [4279] = { 0x010F, 0x010F, 0x0000 }, /* R4279 - Write Sequencer 183 */
1156 [4280] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4280 - Write Sequencer 184 */
1157 [4281] = { 0x00FF, 0x00FF, 0x0000 }, /* R4281 - Write Sequencer 185 */
1158 [4282] = { 0x070F, 0x070F, 0x0000 }, /* R4282 - Write Sequencer 186 */
1159 [4283] = { 0x010F, 0x010F, 0x0000 }, /* R4283 - Write Sequencer 187 */
1160 [4284] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4284 - Write Sequencer 188 */
1161 [4285] = { 0x00FF, 0x00FF, 0x0000 }, /* R4285 - Write Sequencer 189 */
1162 [4286] = { 0x070F, 0x070F, 0x0000 }, /* R4286 - Write Sequencer 190 */
1163 [4287] = { 0x010F, 0x010F, 0x0000 }, /* R4287 - Write Sequencer 191 */
1164 [4288] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4288 - Write Sequencer 192 */
1165 [4289] = { 0x00FF, 0x00FF, 0x0000 }, /* R4289 - Write Sequencer 193 */
1166 [4290] = { 0x070F, 0x070F, 0x0000 }, /* R4290 - Write Sequencer 194 */
1167 [4291] = { 0x010F, 0x010F, 0x0000 }, /* R4291 - Write Sequencer 195 */
1168 [4292] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4292 - Write Sequencer 196 */
1169 [4293] = { 0x00FF, 0x00FF, 0x0000 }, /* R4293 - Write Sequencer 197 */
1170 [4294] = { 0x070F, 0x070F, 0x0000 }, /* R4294 - Write Sequencer 198 */
1171 [4295] = { 0x010F, 0x010F, 0x0000 }, /* R4295 - Write Sequencer 199 */
1172 [4296] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4296 - Write Sequencer 200 */
1173 [4297] = { 0x00FF, 0x00FF, 0x0000 }, /* R4297 - Write Sequencer 201 */
1174 [4298] = { 0x070F, 0x070F, 0x0000 }, /* R4298 - Write Sequencer 202 */
1175 [4299] = { 0x010F, 0x010F, 0x0000 }, /* R4299 - Write Sequencer 203 */
1176 [4300] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4300 - Write Sequencer 204 */
1177 [4301] = { 0x00FF, 0x00FF, 0x0000 }, /* R4301 - Write Sequencer 205 */
1178 [4302] = { 0x070F, 0x070F, 0x0000 }, /* R4302 - Write Sequencer 206 */
1179 [4303] = { 0x010F, 0x010F, 0x0000 }, /* R4303 - Write Sequencer 207 */
1180 [4304] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4304 - Write Sequencer 208 */
1181 [4305] = { 0x00FF, 0x00FF, 0x0000 }, /* R4305 - Write Sequencer 209 */
1182 [4306] = { 0x070F, 0x070F, 0x0000 }, /* R4306 - Write Sequencer 210 */
1183 [4307] = { 0x010F, 0x010F, 0x0000 }, /* R4307 - Write Sequencer 211 */
1184 [4308] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4308 - Write Sequencer 212 */
1185 [4309] = { 0x00FF, 0x00FF, 0x0000 }, /* R4309 - Write Sequencer 213 */
1186 [4310] = { 0x070F, 0x070F, 0x0000 }, /* R4310 - Write Sequencer 214 */
1187 [4311] = { 0x010F, 0x010F, 0x0000 }, /* R4311 - Write Sequencer 215 */
1188 [4312] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4312 - Write Sequencer 216 */
1189 [4313] = { 0x00FF, 0x00FF, 0x0000 }, /* R4313 - Write Sequencer 217 */
1190 [4314] = { 0x070F, 0x070F, 0x0000 }, /* R4314 - Write Sequencer 218 */
1191 [4315] = { 0x010F, 0x010F, 0x0000 }, /* R4315 - Write Sequencer 219 */
1192 [4316] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4316 - Write Sequencer 220 */
1193 [4317] = { 0x00FF, 0x00FF, 0x0000 }, /* R4317 - Write Sequencer 221 */
1194 [4318] = { 0x070F, 0x070F, 0x0000 }, /* R4318 - Write Sequencer 222 */
1195 [4319] = { 0x010F, 0x010F, 0x0000 }, /* R4319 - Write Sequencer 223 */
1196 [4320] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4320 - Write Sequencer 224 */
1197 [4321] = { 0x00FF, 0x00FF, 0x0000 }, /* R4321 - Write Sequencer 225 */
1198 [4322] = { 0x070F, 0x070F, 0x0000 }, /* R4322 - Write Sequencer 226 */
1199 [4323] = { 0x010F, 0x010F, 0x0000 }, /* R4323 - Write Sequencer 227 */
1200 [4324] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4324 - Write Sequencer 228 */
1201 [4325] = { 0x00FF, 0x00FF, 0x0000 }, /* R4325 - Write Sequencer 229 */
1202 [4326] = { 0x070F, 0x070F, 0x0000 }, /* R4326 - Write Sequencer 230 */
1203 [4327] = { 0x010F, 0x010F, 0x0000 }, /* R4327 - Write Sequencer 231 */
1204 [4328] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4328 - Write Sequencer 232 */
1205 [4329] = { 0x00FF, 0x00FF, 0x0000 }, /* R4329 - Write Sequencer 233 */
1206 [4330] = { 0x070F, 0x070F, 0x0000 }, /* R4330 - Write Sequencer 234 */
1207 [4331] = { 0x010F, 0x010F, 0x0000 }, /* R4331 - Write Sequencer 235 */
1208 [4332] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4332 - Write Sequencer 236 */
1209 [4333] = { 0x00FF, 0x00FF, 0x0000 }, /* R4333 - Write Sequencer 237 */
1210 [4334] = { 0x070F, 0x070F, 0x0000 }, /* R4334 - Write Sequencer 238 */
1211 [4335] = { 0x010F, 0x010F, 0x0000 }, /* R4335 - Write Sequencer 239 */
1212 [4336] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4336 - Write Sequencer 240 */
1213 [4337] = { 0x00FF, 0x00FF, 0x0000 }, /* R4337 - Write Sequencer 241 */
1214 [4338] = { 0x070F, 0x070F, 0x0000 }, /* R4338 - Write Sequencer 242 */
1215 [4339] = { 0x010F, 0x010F, 0x0000 }, /* R4339 - Write Sequencer 243 */
1216 [4340] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4340 - Write Sequencer 244 */
1217 [4341] = { 0x00FF, 0x00FF, 0x0000 }, /* R4341 - Write Sequencer 245 */
1218 [4342] = { 0x070F, 0x070F, 0x0000 }, /* R4342 - Write Sequencer 246 */
1219 [4343] = { 0x010F, 0x010F, 0x0000 }, /* R4343 - Write Sequencer 247 */
1220 [4344] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4344 - Write Sequencer 248 */
1221 [4345] = { 0x00FF, 0x00FF, 0x0000 }, /* R4345 - Write Sequencer 249 */
1222 [4346] = { 0x070F, 0x070F, 0x0000 }, /* R4346 - Write Sequencer 250 */
1223 [4347] = { 0x010F, 0x010F, 0x0000 }, /* R4347 - Write Sequencer 251 */
1224 [4348] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4348 - Write Sequencer 252 */
1225 [4349] = { 0x00FF, 0x00FF, 0x0000 }, /* R4349 - Write Sequencer 253 */
1226 [4350] = { 0x070F, 0x070F, 0x0000 }, /* R4350 - Write Sequencer 254 */
1227 [4351] = { 0x010F, 0x010F, 0x0000 }, /* R4351 - Write Sequencer 255 */
1228 [4352] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4352 - Write Sequencer 256 */
1229 [4353] = { 0x00FF, 0x00FF, 0x0000 }, /* R4353 - Write Sequencer 257 */
1230 [4354] = { 0x070F, 0x070F, 0x0000 }, /* R4354 - Write Sequencer 258 */
1231 [4355] = { 0x010F, 0x010F, 0x0000 }, /* R4355 - Write Sequencer 259 */
1232 [4356] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4356 - Write Sequencer 260 */
1233 [4357] = { 0x00FF, 0x00FF, 0x0000 }, /* R4357 - Write Sequencer 261 */
1234 [4358] = { 0x070F, 0x070F, 0x0000 }, /* R4358 - Write Sequencer 262 */
1235 [4359] = { 0x010F, 0x010F, 0x0000 }, /* R4359 - Write Sequencer 263 */
1236 [4360] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4360 - Write Sequencer 264 */
1237 [4361] = { 0x00FF, 0x00FF, 0x0000 }, /* R4361 - Write Sequencer 265 */
1238 [4362] = { 0x070F, 0x070F, 0x0000 }, /* R4362 - Write Sequencer 266 */
1239 [4363] = { 0x010F, 0x010F, 0x0000 }, /* R4363 - Write Sequencer 267 */
1240 [4364] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4364 - Write Sequencer 268 */
1241 [4365] = { 0x00FF, 0x00FF, 0x0000 }, /* R4365 - Write Sequencer 269 */
1242 [4366] = { 0x070F, 0x070F, 0x0000 }, /* R4366 - Write Sequencer 270 */
1243 [4367] = { 0x010F, 0x010F, 0x0000 }, /* R4367 - Write Sequencer 271 */
1244 [4368] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4368 - Write Sequencer 272 */
1245 [4369] = { 0x00FF, 0x00FF, 0x0000 }, /* R4369 - Write Sequencer 273 */
1246 [4370] = { 0x070F, 0x070F, 0x0000 }, /* R4370 - Write Sequencer 274 */
1247 [4371] = { 0x010F, 0x010F, 0x0000 }, /* R4371 - Write Sequencer 275 */
1248 [4372] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4372 - Write Sequencer 276 */
1249 [4373] = { 0x00FF, 0x00FF, 0x0000 }, /* R4373 - Write Sequencer 277 */
1250 [4374] = { 0x070F, 0x070F, 0x0000 }, /* R4374 - Write Sequencer 278 */
1251 [4375] = { 0x010F, 0x010F, 0x0000 }, /* R4375 - Write Sequencer 279 */
1252 [4376] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4376 - Write Sequencer 280 */
1253 [4377] = { 0x00FF, 0x00FF, 0x0000 }, /* R4377 - Write Sequencer 281 */
1254 [4378] = { 0x070F, 0x070F, 0x0000 }, /* R4378 - Write Sequencer 282 */
1255 [4379] = { 0x010F, 0x010F, 0x0000 }, /* R4379 - Write Sequencer 283 */
1256 [4380] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4380 - Write Sequencer 284 */
1257 [4381] = { 0x00FF, 0x00FF, 0x0000 }, /* R4381 - Write Sequencer 285 */
1258 [4382] = { 0x070F, 0x070F, 0x0000 }, /* R4382 - Write Sequencer 286 */
1259 [4383] = { 0x010F, 0x010F, 0x0000 }, /* R4383 - Write Sequencer 287 */
1260 [4384] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4384 - Write Sequencer 288 */
1261 [4385] = { 0x00FF, 0x00FF, 0x0000 }, /* R4385 - Write Sequencer 289 */
1262 [4386] = { 0x070F, 0x070F, 0x0000 }, /* R4386 - Write Sequencer 290 */
1263 [4387] = { 0x010F, 0x010F, 0x0000 }, /* R4387 - Write Sequencer 291 */
1264 [4388] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4388 - Write Sequencer 292 */
1265 [4389] = { 0x00FF, 0x00FF, 0x0000 }, /* R4389 - Write Sequencer 293 */
1266 [4390] = { 0x070F, 0x070F, 0x0000 }, /* R4390 - Write Sequencer 294 */
1267 [4391] = { 0x010F, 0x010F, 0x0000 }, /* R4391 - Write Sequencer 295 */
1268 [4392] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4392 - Write Sequencer 296 */
1269 [4393] = { 0x00FF, 0x00FF, 0x0000 }, /* R4393 - Write Sequencer 297 */
1270 [4394] = { 0x070F, 0x070F, 0x0000 }, /* R4394 - Write Sequencer 298 */
1271 [4395] = { 0x010F, 0x010F, 0x0000 }, /* R4395 - Write Sequencer 299 */
1272 [4396] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4396 - Write Sequencer 300 */
1273 [4397] = { 0x00FF, 0x00FF, 0x0000 }, /* R4397 - Write Sequencer 301 */
1274 [4398] = { 0x070F, 0x070F, 0x0000 }, /* R4398 - Write Sequencer 302 */
1275 [4399] = { 0x010F, 0x010F, 0x0000 }, /* R4399 - Write Sequencer 303 */
1276 [4400] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4400 - Write Sequencer 304 */
1277 [4401] = { 0x00FF, 0x00FF, 0x0000 }, /* R4401 - Write Sequencer 305 */
1278 [4402] = { 0x070F, 0x070F, 0x0000 }, /* R4402 - Write Sequencer 306 */
1279 [4403] = { 0x010F, 0x010F, 0x0000 }, /* R4403 - Write Sequencer 307 */
1280 [4404] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4404 - Write Sequencer 308 */
1281 [4405] = { 0x00FF, 0x00FF, 0x0000 }, /* R4405 - Write Sequencer 309 */
1282 [4406] = { 0x070F, 0x070F, 0x0000 }, /* R4406 - Write Sequencer 310 */
1283 [4407] = { 0x010F, 0x010F, 0x0000 }, /* R4407 - Write Sequencer 311 */
1284 [4408] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4408 - Write Sequencer 312 */
1285 [4409] = { 0x00FF, 0x00FF, 0x0000 }, /* R4409 - Write Sequencer 313 */
1286 [4410] = { 0x070F, 0x070F, 0x0000 }, /* R4410 - Write Sequencer 314 */
1287 [4411] = { 0x010F, 0x010F, 0x0000 }, /* R4411 - Write Sequencer 315 */
1288 [4412] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4412 - Write Sequencer 316 */
1289 [4413] = { 0x00FF, 0x00FF, 0x0000 }, /* R4413 - Write Sequencer 317 */
1290 [4414] = { 0x070F, 0x070F, 0x0000 }, /* R4414 - Write Sequencer 318 */
1291 [4415] = { 0x010F, 0x010F, 0x0000 }, /* R4415 - Write Sequencer 319 */
1292 [4416] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4416 - Write Sequencer 320 */
1293 [4417] = { 0x00FF, 0x00FF, 0x0000 }, /* R4417 - Write Sequencer 321 */
1294 [4418] = { 0x070F, 0x070F, 0x0000 }, /* R4418 - Write Sequencer 322 */
1295 [4419] = { 0x010F, 0x010F, 0x0000 }, /* R4419 - Write Sequencer 323 */
1296 [4420] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4420 - Write Sequencer 324 */
1297 [4421] = { 0x00FF, 0x00FF, 0x0000 }, /* R4421 - Write Sequencer 325 */
1298 [4422] = { 0x070F, 0x070F, 0x0000 }, /* R4422 - Write Sequencer 326 */
1299 [4423] = { 0x010F, 0x010F, 0x0000 }, /* R4423 - Write Sequencer 327 */
1300 [4424] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4424 - Write Sequencer 328 */
1301 [4425] = { 0x00FF, 0x00FF, 0x0000 }, /* R4425 - Write Sequencer 329 */
1302 [4426] = { 0x070F, 0x070F, 0x0000 }, /* R4426 - Write Sequencer 330 */
1303 [4427] = { 0x010F, 0x010F, 0x0000 }, /* R4427 - Write Sequencer 331 */
1304 [4428] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4428 - Write Sequencer 332 */
1305 [4429] = { 0x00FF, 0x00FF, 0x0000 }, /* R4429 - Write Sequencer 333 */
1306 [4430] = { 0x070F, 0x070F, 0x0000 }, /* R4430 - Write Sequencer 334 */
1307 [4431] = { 0x010F, 0x010F, 0x0000 }, /* R4431 - Write Sequencer 335 */
1308 [4432] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4432 - Write Sequencer 336 */
1309 [4433] = { 0x00FF, 0x00FF, 0x0000 }, /* R4433 - Write Sequencer 337 */
1310 [4434] = { 0x070F, 0x070F, 0x0000 }, /* R4434 - Write Sequencer 338 */
1311 [4435] = { 0x010F, 0x010F, 0x0000 }, /* R4435 - Write Sequencer 339 */
1312 [4436] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4436 - Write Sequencer 340 */
1313 [4437] = { 0x00FF, 0x00FF, 0x0000 }, /* R4437 - Write Sequencer 341 */
1314 [4438] = { 0x070F, 0x070F, 0x0000 }, /* R4438 - Write Sequencer 342 */
1315 [4439] = { 0x010F, 0x010F, 0x0000 }, /* R4439 - Write Sequencer 343 */
1316 [4440] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4440 - Write Sequencer 344 */
1317 [4441] = { 0x00FF, 0x00FF, 0x0000 }, /* R4441 - Write Sequencer 345 */
1318 [4442] = { 0x070F, 0x070F, 0x0000 }, /* R4442 - Write Sequencer 346 */
1319 [4443] = { 0x010F, 0x010F, 0x0000 }, /* R4443 - Write Sequencer 347 */
1320 [4444] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4444 - Write Sequencer 348 */
1321 [4445] = { 0x00FF, 0x00FF, 0x0000 }, /* R4445 - Write Sequencer 349 */
1322 [4446] = { 0x070F, 0x070F, 0x0000 }, /* R4446 - Write Sequencer 350 */
1323 [4447] = { 0x010F, 0x010F, 0x0000 }, /* R4447 - Write Sequencer 351 */
1324 [4448] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4448 - Write Sequencer 352 */
1325 [4449] = { 0x00FF, 0x00FF, 0x0000 }, /* R4449 - Write Sequencer 353 */
1326 [4450] = { 0x070F, 0x070F, 0x0000 }, /* R4450 - Write Sequencer 354 */
1327 [4451] = { 0x010F, 0x010F, 0x0000 }, /* R4451 - Write Sequencer 355 */
1328 [4452] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4452 - Write Sequencer 356 */
1329 [4453] = { 0x00FF, 0x00FF, 0x0000 }, /* R4453 - Write Sequencer 357 */
1330 [4454] = { 0x070F, 0x070F, 0x0000 }, /* R4454 - Write Sequencer 358 */
1331 [4455] = { 0x010F, 0x010F, 0x0000 }, /* R4455 - Write Sequencer 359 */
1332 [4456] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4456 - Write Sequencer 360 */
1333 [4457] = { 0x00FF, 0x00FF, 0x0000 }, /* R4457 - Write Sequencer 361 */
1334 [4458] = { 0x070F, 0x070F, 0x0000 }, /* R4458 - Write Sequencer 362 */
1335 [4459] = { 0x010F, 0x010F, 0x0000 }, /* R4459 - Write Sequencer 363 */
1336 [4460] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4460 - Write Sequencer 364 */
1337 [4461] = { 0x00FF, 0x00FF, 0x0000 }, /* R4461 - Write Sequencer 365 */
1338 [4462] = { 0x070F, 0x070F, 0x0000 }, /* R4462 - Write Sequencer 366 */
1339 [4463] = { 0x010F, 0x010F, 0x0000 }, /* R4463 - Write Sequencer 367 */
1340 [4464] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4464 - Write Sequencer 368 */
1341 [4465] = { 0x00FF, 0x00FF, 0x0000 }, /* R4465 - Write Sequencer 369 */
1342 [4466] = { 0x070F, 0x070F, 0x0000 }, /* R4466 - Write Sequencer 370 */
1343 [4467] = { 0x010F, 0x010F, 0x0000 }, /* R4467 - Write Sequencer 371 */
1344 [4468] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4468 - Write Sequencer 372 */
1345 [4469] = { 0x00FF, 0x00FF, 0x0000 }, /* R4469 - Write Sequencer 373 */
1346 [4470] = { 0x070F, 0x070F, 0x0000 }, /* R4470 - Write Sequencer 374 */
1347 [4471] = { 0x010F, 0x010F, 0x0000 }, /* R4471 - Write Sequencer 375 */
1348 [4472] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4472 - Write Sequencer 376 */
1349 [4473] = { 0x00FF, 0x00FF, 0x0000 }, /* R4473 - Write Sequencer 377 */
1350 [4474] = { 0x070F, 0x070F, 0x0000 }, /* R4474 - Write Sequencer 378 */
1351 [4475] = { 0x010F, 0x010F, 0x0000 }, /* R4475 - Write Sequencer 379 */
1352 [4476] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4476 - Write Sequencer 380 */
1353 [4477] = { 0x00FF, 0x00FF, 0x0000 }, /* R4477 - Write Sequencer 381 */
1354 [4478] = { 0x070F, 0x070F, 0x0000 }, /* R4478 - Write Sequencer 382 */
1355 [4479] = { 0x010F, 0x010F, 0x0000 }, /* R4479 - Write Sequencer 383 */
1356 [4480] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4480 - Write Sequencer 384 */
1357 [4481] = { 0x00FF, 0x00FF, 0x0000 }, /* R4481 - Write Sequencer 385 */
1358 [4482] = { 0x070F, 0x070F, 0x0000 }, /* R4482 - Write Sequencer 386 */
1359 [4483] = { 0x010F, 0x010F, 0x0000 }, /* R4483 - Write Sequencer 387 */
1360 [4484] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4484 - Write Sequencer 388 */
1361 [4485] = { 0x00FF, 0x00FF, 0x0000 }, /* R4485 - Write Sequencer 389 */
1362 [4486] = { 0x070F, 0x070F, 0x0000 }, /* R4486 - Write Sequencer 390 */
1363 [4487] = { 0x010F, 0x010F, 0x0000 }, /* R4487 - Write Sequencer 391 */
1364 [4488] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4488 - Write Sequencer 392 */
1365 [4489] = { 0x00FF, 0x00FF, 0x0000 }, /* R4489 - Write Sequencer 393 */
1366 [4490] = { 0x070F, 0x070F, 0x0000 }, /* R4490 - Write Sequencer 394 */
1367 [4491] = { 0x010F, 0x010F, 0x0000 }, /* R4491 - Write Sequencer 395 */
1368 [4492] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4492 - Write Sequencer 396 */
1369 [4493] = { 0x00FF, 0x00FF, 0x0000 }, /* R4493 - Write Sequencer 397 */
1370 [4494] = { 0x070F, 0x070F, 0x0000 }, /* R4494 - Write Sequencer 398 */
1371 [4495] = { 0x010F, 0x010F, 0x0000 }, /* R4495 - Write Sequencer 399 */
1372 [4496] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4496 - Write Sequencer 400 */
1373 [4497] = { 0x00FF, 0x00FF, 0x0000 }, /* R4497 - Write Sequencer 401 */
1374 [4498] = { 0x070F, 0x070F, 0x0000 }, /* R4498 - Write Sequencer 402 */
1375 [4499] = { 0x010F, 0x010F, 0x0000 }, /* R4499 - Write Sequencer 403 */
1376 [4500] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4500 - Write Sequencer 404 */
1377 [4501] = { 0x00FF, 0x00FF, 0x0000 }, /* R4501 - Write Sequencer 405 */
1378 [4502] = { 0x070F, 0x070F, 0x0000 }, /* R4502 - Write Sequencer 406 */
1379 [4503] = { 0x010F, 0x010F, 0x0000 }, /* R4503 - Write Sequencer 407 */
1380 [4504] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4504 - Write Sequencer 408 */
1381 [4505] = { 0x00FF, 0x00FF, 0x0000 }, /* R4505 - Write Sequencer 409 */
1382 [4506] = { 0x070F, 0x070F, 0x0000 }, /* R4506 - Write Sequencer 410 */
1383 [4507] = { 0x010F, 0x010F, 0x0000 }, /* R4507 - Write Sequencer 411 */
1384 [4508] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4508 - Write Sequencer 412 */
1385 [4509] = { 0x00FF, 0x00FF, 0x0000 }, /* R4509 - Write Sequencer 413 */
1386 [4510] = { 0x070F, 0x070F, 0x0000 }, /* R4510 - Write Sequencer 414 */
1387 [4511] = { 0x010F, 0x010F, 0x0000 }, /* R4511 - Write Sequencer 415 */
1388 [4512] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4512 - Write Sequencer 416 */
1389 [4513] = { 0x00FF, 0x00FF, 0x0000 }, /* R4513 - Write Sequencer 417 */
1390 [4514] = { 0x070F, 0x070F, 0x0000 }, /* R4514 - Write Sequencer 418 */
1391 [4515] = { 0x010F, 0x010F, 0x0000 }, /* R4515 - Write Sequencer 419 */
1392 [4516] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4516 - Write Sequencer 420 */
1393 [4517] = { 0x00FF, 0x00FF, 0x0000 }, /* R4517 - Write Sequencer 421 */
1394 [4518] = { 0x070F, 0x070F, 0x0000 }, /* R4518 - Write Sequencer 422 */
1395 [4519] = { 0x010F, 0x010F, 0x0000 }, /* R4519 - Write Sequencer 423 */
1396 [4520] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4520 - Write Sequencer 424 */
1397 [4521] = { 0x00FF, 0x00FF, 0x0000 }, /* R4521 - Write Sequencer 425 */
1398 [4522] = { 0x070F, 0x070F, 0x0000 }, /* R4522 - Write Sequencer 426 */
1399 [4523] = { 0x010F, 0x010F, 0x0000 }, /* R4523 - Write Sequencer 427 */
1400 [4524] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4524 - Write Sequencer 428 */
1401 [4525] = { 0x00FF, 0x00FF, 0x0000 }, /* R4525 - Write Sequencer 429 */
1402 [4526] = { 0x070F, 0x070F, 0x0000 }, /* R4526 - Write Sequencer 430 */
1403 [4527] = { 0x010F, 0x010F, 0x0000 }, /* R4527 - Write Sequencer 431 */
1404 [4528] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4528 - Write Sequencer 432 */
1405 [4529] = { 0x00FF, 0x00FF, 0x0000 }, /* R4529 - Write Sequencer 433 */
1406 [4530] = { 0x070F, 0x070F, 0x0000 }, /* R4530 - Write Sequencer 434 */
1407 [4531] = { 0x010F, 0x010F, 0x0000 }, /* R4531 - Write Sequencer 435 */
1408 [4532] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4532 - Write Sequencer 436 */
1409 [4533] = { 0x00FF, 0x00FF, 0x0000 }, /* R4533 - Write Sequencer 437 */
1410 [4534] = { 0x070F, 0x070F, 0x0000 }, /* R4534 - Write Sequencer 438 */
1411 [4535] = { 0x010F, 0x010F, 0x0000 }, /* R4535 - Write Sequencer 439 */
1412 [4536] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4536 - Write Sequencer 440 */
1413 [4537] = { 0x00FF, 0x00FF, 0x0000 }, /* R4537 - Write Sequencer 441 */
1414 [4538] = { 0x070F, 0x070F, 0x0000 }, /* R4538 - Write Sequencer 442 */
1415 [4539] = { 0x010F, 0x010F, 0x0000 }, /* R4539 - Write Sequencer 443 */
1416 [4540] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4540 - Write Sequencer 444 */
1417 [4541] = { 0x00FF, 0x00FF, 0x0000 }, /* R4541 - Write Sequencer 445 */
1418 [4542] = { 0x070F, 0x070F, 0x0000 }, /* R4542 - Write Sequencer 446 */
1419 [4543] = { 0x010F, 0x010F, 0x0000 }, /* R4543 - Write Sequencer 447 */
1420 [4544] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4544 - Write Sequencer 448 */
1421 [4545] = { 0x00FF, 0x00FF, 0x0000 }, /* R4545 - Write Sequencer 449 */
1422 [4546] = { 0x070F, 0x070F, 0x0000 }, /* R4546 - Write Sequencer 450 */
1423 [4547] = { 0x010F, 0x010F, 0x0000 }, /* R4547 - Write Sequencer 451 */
1424 [4548] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4548 - Write Sequencer 452 */
1425 [4549] = { 0x00FF, 0x00FF, 0x0000 }, /* R4549 - Write Sequencer 453 */
1426 [4550] = { 0x070F, 0x070F, 0x0000 }, /* R4550 - Write Sequencer 454 */
1427 [4551] = { 0x010F, 0x010F, 0x0000 }, /* R4551 - Write Sequencer 455 */
1428 [4552] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4552 - Write Sequencer 456 */
1429 [4553] = { 0x00FF, 0x00FF, 0x0000 }, /* R4553 - Write Sequencer 457 */
1430 [4554] = { 0x070F, 0x070F, 0x0000 }, /* R4554 - Write Sequencer 458 */
1431 [4555] = { 0x010F, 0x010F, 0x0000 }, /* R4555 - Write Sequencer 459 */
1432 [4556] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4556 - Write Sequencer 460 */
1433 [4557] = { 0x00FF, 0x00FF, 0x0000 }, /* R4557 - Write Sequencer 461 */
1434 [4558] = { 0x070F, 0x070F, 0x0000 }, /* R4558 - Write Sequencer 462 */
1435 [4559] = { 0x010F, 0x010F, 0x0000 }, /* R4559 - Write Sequencer 463 */
1436 [4560] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4560 - Write Sequencer 464 */
1437 [4561] = { 0x00FF, 0x00FF, 0x0000 }, /* R4561 - Write Sequencer 465 */
1438 [4562] = { 0x070F, 0x070F, 0x0000 }, /* R4562 - Write Sequencer 466 */
1439 [4563] = { 0x010F, 0x010F, 0x0000 }, /* R4563 - Write Sequencer 467 */
1440 [4564] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4564 - Write Sequencer 468 */
1441 [4565] = { 0x00FF, 0x00FF, 0x0000 }, /* R4565 - Write Sequencer 469 */
1442 [4566] = { 0x070F, 0x070F, 0x0000 }, /* R4566 - Write Sequencer 470 */
1443 [4567] = { 0x010F, 0x010F, 0x0000 }, /* R4567 - Write Sequencer 471 */
1444 [4568] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4568 - Write Sequencer 472 */
1445 [4569] = { 0x00FF, 0x00FF, 0x0000 }, /* R4569 - Write Sequencer 473 */
1446 [4570] = { 0x070F, 0x070F, 0x0000 }, /* R4570 - Write Sequencer 474 */
1447 [4571] = { 0x010F, 0x010F, 0x0000 }, /* R4571 - Write Sequencer 475 */
1448 [4572] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4572 - Write Sequencer 476 */
1449 [4573] = { 0x00FF, 0x00FF, 0x0000 }, /* R4573 - Write Sequencer 477 */
1450 [4574] = { 0x070F, 0x070F, 0x0000 }, /* R4574 - Write Sequencer 478 */
1451 [4575] = { 0x010F, 0x010F, 0x0000 }, /* R4575 - Write Sequencer 479 */
1452 [4576] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4576 - Write Sequencer 480 */
1453 [4577] = { 0x00FF, 0x00FF, 0x0000 }, /* R4577 - Write Sequencer 481 */
1454 [4578] = { 0x070F, 0x070F, 0x0000 }, /* R4578 - Write Sequencer 482 */
1455 [4579] = { 0x010F, 0x010F, 0x0000 }, /* R4579 - Write Sequencer 483 */
1456 [4580] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4580 - Write Sequencer 484 */
1457 [4581] = { 0x00FF, 0x00FF, 0x0000 }, /* R4581 - Write Sequencer 485 */
1458 [4582] = { 0x070F, 0x070F, 0x0000 }, /* R4582 - Write Sequencer 486 */
1459 [4583] = { 0x010F, 0x010F, 0x0000 }, /* R4583 - Write Sequencer 487 */
1460 [4584] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4584 - Write Sequencer 488 */
1461 [4585] = { 0x00FF, 0x00FF, 0x0000 }, /* R4585 - Write Sequencer 489 */
1462 [4586] = { 0x070F, 0x070F, 0x0000 }, /* R4586 - Write Sequencer 490 */
1463 [4587] = { 0x010F, 0x010F, 0x0000 }, /* R4587 - Write Sequencer 491 */
1464 [4588] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4588 - Write Sequencer 492 */
1465 [4589] = { 0x00FF, 0x00FF, 0x0000 }, /* R4589 - Write Sequencer 493 */
1466 [4590] = { 0x070F, 0x070F, 0x0000 }, /* R4590 - Write Sequencer 494 */
1467 [4591] = { 0x010F, 0x010F, 0x0000 }, /* R4591 - Write Sequencer 495 */
1468 [4592] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4592 - Write Sequencer 496 */
1469 [4593] = { 0x00FF, 0x00FF, 0x0000 }, /* R4593 - Write Sequencer 497 */
1470 [4594] = { 0x070F, 0x070F, 0x0000 }, /* R4594 - Write Sequencer 498 */
1471 [4595] = { 0x010F, 0x010F, 0x0000 }, /* R4595 - Write Sequencer 499 */
1472 [4596] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4596 - Write Sequencer 500 */
1473 [4597] = { 0x00FF, 0x00FF, 0x0000 }, /* R4597 - Write Sequencer 501 */
1474 [4598] = { 0x070F, 0x070F, 0x0000 }, /* R4598 - Write Sequencer 502 */
1475 [4599] = { 0x010F, 0x010F, 0x0000 }, /* R4599 - Write Sequencer 503 */
1476 [4600] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4600 - Write Sequencer 504 */
1477 [4601] = { 0x00FF, 0x00FF, 0x0000 }, /* R4601 - Write Sequencer 505 */
1478 [4602] = { 0x070F, 0x070F, 0x0000 }, /* R4602 - Write Sequencer 506 */
1479 [4603] = { 0x010F, 0x010F, 0x0000 }, /* R4603 - Write Sequencer 507 */
1480 [4604] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4604 - Write Sequencer 508 */
1481 [4605] = { 0x00FF, 0x00FF, 0x0000 }, /* R4605 - Write Sequencer 509 */
1482 [4606] = { 0x070F, 0x070F, 0x0000 }, /* R4606 - Write Sequencer 510 */
1483 [4607] = { 0x010F, 0x010F, 0x0000 }, /* R4607 - Write Sequencer 511 */
1484 [8192] = { 0x03FF, 0x03FF, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
1485 [9216] = { 0x003F, 0x003F, 0x0000 }, /* R9216 - DSP2 Address RAM 2 */
1486 [9217] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */
1487 [9218] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */
1488 [12288] = { 0x00FF, 0x00FF, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */
1489 [12289] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */
1490 [13312] = { 0x00FF, 0x00FF, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */
1491 [13313] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */
1492 [14336] = { 0x00FF, 0x00FF, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */
1493 [14337] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */
1494 [15360] = { 0x07FF, 0x07FF, 0x0000 }, /* R15360 - DSP2 Coeff RAM 0 */
1495 [16384] = { 0x00FF, 0x00FF, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
1496 [16385] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
1497 [16386] = { 0x00FF, 0x00FF, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
1498 [16387] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
1499 [16388] = { 0x00FF, 0x00FF, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */
1500 [16389] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */
1501 [16896] = { 0x00FF, 0x00FF, 0x0000 }, /* R16896 - HDBASS_AI_1 */
1502 [16897] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16897 - HDBASS_AI_0 */
1503 [16898] = { 0x00FF, 0x00FF, 0x0000 }, /* R16898 - HDBASS_AR_1 */
1504 [16899] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16899 - HDBASS_AR_0 */
1505 [16900] = { 0x00FF, 0x00FF, 0x0000 }, /* R16900 - HDBASS_B_1 */
1506 [16901] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16901 - HDBASS_B_0 */
1507 [16902] = { 0x00FF, 0x00FF, 0x0000 }, /* R16902 - HDBASS_K_1 */
1508 [16903] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16903 - HDBASS_K_0 */
1509 [16904] = { 0x00FF, 0x00FF, 0x0000 }, /* R16904 - HDBASS_N1_1 */
1510 [16905] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16905 - HDBASS_N1_0 */
1511 [16906] = { 0x00FF, 0x00FF, 0x0000 }, /* R16906 - HDBASS_N2_1 */
1512 [16907] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16907 - HDBASS_N2_0 */
1513 [16908] = { 0x00FF, 0x00FF, 0x0000 }, /* R16908 - HDBASS_N3_1 */
1514 [16909] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16909 - HDBASS_N3_0 */
1515 [16910] = { 0x00FF, 0x00FF, 0x0000 }, /* R16910 - HDBASS_N4_1 */
1516 [16911] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16911 - HDBASS_N4_0 */
1517 [16912] = { 0x00FF, 0x00FF, 0x0000 }, /* R16912 - HDBASS_N5_1 */
1518 [16913] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16913 - HDBASS_N5_0 */
1519 [16914] = { 0x00FF, 0x00FF, 0x0000 }, /* R16914 - HDBASS_X1_1 */
1520 [16915] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16915 - HDBASS_X1_0 */
1521 [16916] = { 0x00FF, 0x00FF, 0x0000 }, /* R16916 - HDBASS_X2_1 */
1522 [16917] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16917 - HDBASS_X2_0 */
1523 [16918] = { 0x00FF, 0x00FF, 0x0000 }, /* R16918 - HDBASS_X3_1 */
1524 [16919] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16919 - HDBASS_X3_0 */
1525 [16920] = { 0x00FF, 0x00FF, 0x0000 }, /* R16920 - HDBASS_ATK_1 */
1526 [16921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16921 - HDBASS_ATK_0 */
1527 [16922] = { 0x00FF, 0x00FF, 0x0000 }, /* R16922 - HDBASS_DCY_1 */
1528 [16923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16923 - HDBASS_DCY_0 */
1529 [16924] = { 0x00FF, 0x00FF, 0x0000 }, /* R16924 - HDBASS_PG_1 */
1530 [16925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16925 - HDBASS_PG_0 */
1531 [17408] = { 0x00FF, 0x00FF, 0x0000 }, /* R17408 - HPF_C_1 */
1532 [17409] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17409 - HPF_C_0 */
1533 [17920] = { 0x00FF, 0x00FF, 0x0000 }, /* R17920 - ADCL_RETUNE_C1_1 */
1534 [17921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17921 - ADCL_RETUNE_C1_0 */
1535 [17922] = { 0x00FF, 0x00FF, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */
1536 [17923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */
1537 [17924] = { 0x00FF, 0x00FF, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */
1538 [17925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */
1539 [17926] = { 0x00FF, 0x00FF, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */
1540 [17927] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */
1541 [17928] = { 0x00FF, 0x00FF, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */
1542 [17929] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */
1543 [17930] = { 0x00FF, 0x00FF, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */
1544 [17931] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */
1545 [17932] = { 0x00FF, 0x00FF, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */
1546 [17933] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */
1547 [17934] = { 0x00FF, 0x00FF, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */
1548 [17935] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */
1549 [17936] = { 0x00FF, 0x00FF, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */
1550 [17937] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */
1551 [17938] = { 0x00FF, 0x00FF, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */
1552 [17939] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */
1553 [17940] = { 0x00FF, 0x00FF, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */
1554 [17941] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */
1555 [17942] = { 0x00FF, 0x00FF, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */
1556 [17943] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */
1557 [17944] = { 0x00FF, 0x00FF, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */
1558 [17945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */
1559 [17946] = { 0x00FF, 0x00FF, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */
1560 [17947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */
1561 [17948] = { 0x00FF, 0x00FF, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */
1562 [17949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */
1563 [17950] = { 0x00FF, 0x00FF, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */
1564 [17951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */
1565 [17952] = { 0x00FF, 0x00FF, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */
1566 [17953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */
1567 [17954] = { 0x00FF, 0x00FF, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */
1568 [17955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */
1569 [17956] = { 0x00FF, 0x00FF, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */
1570 [17957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */
1571 [17958] = { 0x00FF, 0x00FF, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */
1572 [17959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */
1573 [17960] = { 0x00FF, 0x00FF, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */
1574 [17961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */
1575 [17962] = { 0x00FF, 0x00FF, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */
1576 [17963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */
1577 [17964] = { 0x00FF, 0x00FF, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */
1578 [17965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */
1579 [17966] = { 0x00FF, 0x00FF, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */
1580 [17967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */
1581 [17968] = { 0x00FF, 0x00FF, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */
1582 [17969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */
1583 [17970] = { 0x00FF, 0x00FF, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */
1584 [17971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */
1585 [17972] = { 0x00FF, 0x00FF, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */
1586 [17973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */
1587 [17974] = { 0x00FF, 0x00FF, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */
1588 [17975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */
1589 [17976] = { 0x00FF, 0x00FF, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */
1590 [17977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */
1591 [17978] = { 0x00FF, 0x00FF, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */
1592 [17979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */
1593 [17980] = { 0x00FF, 0x00FF, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */
1594 [17981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */
1595 [17982] = { 0x00FF, 0x00FF, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */
1596 [17983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */
1597 [18432] = { 0x00FF, 0x00FF, 0x0000 }, /* R18432 - RETUNEADC_PG2_1 */
1598 [18433] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */
1599 [18434] = { 0x00FF, 0x00FF, 0x0000 }, /* R18434 - RETUNEADC_PG_1 */
1600 [18435] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */
1601 [18944] = { 0x00FF, 0x00FF, 0x0000 }, /* R18944 - ADCR_RETUNE_C1_1 */
1602 [18945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18945 - ADCR_RETUNE_C1_0 */
1603 [18946] = { 0x00FF, 0x00FF, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */
1604 [18947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */
1605 [18948] = { 0x00FF, 0x00FF, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */
1606 [18949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */
1607 [18950] = { 0x00FF, 0x00FF, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */
1608 [18951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */
1609 [18952] = { 0x00FF, 0x00FF, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */
1610 [18953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */
1611 [18954] = { 0x00FF, 0x00FF, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */
1612 [18955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */
1613 [18956] = { 0x00FF, 0x00FF, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */
1614 [18957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */
1615 [18958] = { 0x00FF, 0x00FF, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */
1616 [18959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */
1617 [18960] = { 0x00FF, 0x00FF, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */
1618 [18961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */
1619 [18962] = { 0x00FF, 0x00FF, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */
1620 [18963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */
1621 [18964] = { 0x00FF, 0x00FF, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */
1622 [18965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */
1623 [18966] = { 0x00FF, 0x00FF, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */
1624 [18967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */
1625 [18968] = { 0x00FF, 0x00FF, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */
1626 [18969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */
1627 [18970] = { 0x00FF, 0x00FF, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */
1628 [18971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */
1629 [18972] = { 0x00FF, 0x00FF, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */
1630 [18973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */
1631 [18974] = { 0x00FF, 0x00FF, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */
1632 [18975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */
1633 [18976] = { 0x00FF, 0x00FF, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */
1634 [18977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */
1635 [18978] = { 0x00FF, 0x00FF, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */
1636 [18979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */
1637 [18980] = { 0x00FF, 0x00FF, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */
1638 [18981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */
1639 [18982] = { 0x00FF, 0x00FF, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */
1640 [18983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */
1641 [18984] = { 0x00FF, 0x00FF, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */
1642 [18985] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */
1643 [18986] = { 0x00FF, 0x00FF, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */
1644 [18987] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */
1645 [18988] = { 0x00FF, 0x00FF, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */
1646 [18989] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */
1647 [18990] = { 0x00FF, 0x00FF, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */
1648 [18991] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */
1649 [18992] = { 0x00FF, 0x00FF, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */
1650 [18993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */
1651 [18994] = { 0x00FF, 0x00FF, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */
1652 [18995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */
1653 [18996] = { 0x00FF, 0x00FF, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */
1654 [18997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */
1655 [18998] = { 0x00FF, 0x00FF, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */
1656 [18999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */
1657 [19000] = { 0x00FF, 0x00FF, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */
1658 [19001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */
1659 [19002] = { 0x00FF, 0x00FF, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */
1660 [19003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */
1661 [19004] = { 0x00FF, 0x00FF, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */
1662 [19005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */
1663 [19006] = { 0x00FF, 0x00FF, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */
1664 [19007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */
1665 [19456] = { 0x00FF, 0x00FF, 0x0000 }, /* R19456 - DACL_RETUNE_C1_1 */
1666 [19457] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19457 - DACL_RETUNE_C1_0 */
1667 [19458] = { 0x00FF, 0x00FF, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */
1668 [19459] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */
1669 [19460] = { 0x00FF, 0x00FF, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */
1670 [19461] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */
1671 [19462] = { 0x00FF, 0x00FF, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */
1672 [19463] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */
1673 [19464] = { 0x00FF, 0x00FF, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */
1674 [19465] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */
1675 [19466] = { 0x00FF, 0x00FF, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */
1676 [19467] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */
1677 [19468] = { 0x00FF, 0x00FF, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */
1678 [19469] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */
1679 [19470] = { 0x00FF, 0x00FF, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */
1680 [19471] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */
1681 [19472] = { 0x00FF, 0x00FF, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */
1682 [19473] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */
1683 [19474] = { 0x00FF, 0x00FF, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */
1684 [19475] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */
1685 [19476] = { 0x00FF, 0x00FF, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */
1686 [19477] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */
1687 [19478] = { 0x00FF, 0x00FF, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */
1688 [19479] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */
1689 [19480] = { 0x00FF, 0x00FF, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */
1690 [19481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */
1691 [19482] = { 0x00FF, 0x00FF, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */
1692 [19483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */
1693 [19484] = { 0x00FF, 0x00FF, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */
1694 [19485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */
1695 [19486] = { 0x00FF, 0x00FF, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */
1696 [19487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */
1697 [19488] = { 0x00FF, 0x00FF, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */
1698 [19489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */
1699 [19490] = { 0x00FF, 0x00FF, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */
1700 [19491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */
1701 [19492] = { 0x00FF, 0x00FF, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */
1702 [19493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */
1703 [19494] = { 0x00FF, 0x00FF, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */
1704 [19495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */
1705 [19496] = { 0x00FF, 0x00FF, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */
1706 [19497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */
1707 [19498] = { 0x00FF, 0x00FF, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */
1708 [19499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */
1709 [19500] = { 0x00FF, 0x00FF, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */
1710 [19501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */
1711 [19502] = { 0x00FF, 0x00FF, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */
1712 [19503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */
1713 [19504] = { 0x00FF, 0x00FF, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */
1714 [19505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */
1715 [19506] = { 0x00FF, 0x00FF, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */
1716 [19507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */
1717 [19508] = { 0x00FF, 0x00FF, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */
1718 [19509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */
1719 [19510] = { 0x00FF, 0x00FF, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */
1720 [19511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */
1721 [19512] = { 0x00FF, 0x00FF, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */
1722 [19513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */
1723 [19514] = { 0x00FF, 0x00FF, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */
1724 [19515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */
1725 [19516] = { 0x00FF, 0x00FF, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */
1726 [19517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */
1727 [19518] = { 0x00FF, 0x00FF, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */
1728 [19519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */
1729 [19968] = { 0x00FF, 0x00FF, 0x0000 }, /* R19968 - RETUNEDAC_PG2_1 */
1730 [19969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */
1731 [19970] = { 0x00FF, 0x00FF, 0x0000 }, /* R19970 - RETUNEDAC_PG_1 */
1732 [19971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */
1733 [20480] = { 0x00FF, 0x00FF, 0x0000 }, /* R20480 - DACR_RETUNE_C1_1 */
1734 [20481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20481 - DACR_RETUNE_C1_0 */
1735 [20482] = { 0x00FF, 0x00FF, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */
1736 [20483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */
1737 [20484] = { 0x00FF, 0x00FF, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */
1738 [20485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */
1739 [20486] = { 0x00FF, 0x00FF, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */
1740 [20487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */
1741 [20488] = { 0x00FF, 0x00FF, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */
1742 [20489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */
1743 [20490] = { 0x00FF, 0x00FF, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */
1744 [20491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */
1745 [20492] = { 0x00FF, 0x00FF, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */
1746 [20493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */
1747 [20494] = { 0x00FF, 0x00FF, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */
1748 [20495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */
1749 [20496] = { 0x00FF, 0x00FF, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */
1750 [20497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */
1751 [20498] = { 0x00FF, 0x00FF, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */
1752 [20499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */
1753 [20500] = { 0x00FF, 0x00FF, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */
1754 [20501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */
1755 [20502] = { 0x00FF, 0x00FF, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */
1756 [20503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */
1757 [20504] = { 0x00FF, 0x00FF, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */
1758 [20505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */
1759 [20506] = { 0x00FF, 0x00FF, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */
1760 [20507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */
1761 [20508] = { 0x00FF, 0x00FF, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */
1762 [20509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */
1763 [20510] = { 0x00FF, 0x00FF, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */
1764 [20511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */
1765 [20512] = { 0x00FF, 0x00FF, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */
1766 [20513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */
1767 [20514] = { 0x00FF, 0x00FF, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */
1768 [20515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */
1769 [20516] = { 0x00FF, 0x00FF, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */
1770 [20517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */
1771 [20518] = { 0x00FF, 0x00FF, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */
1772 [20519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */
1773 [20520] = { 0x00FF, 0x00FF, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */
1774 [20521] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */
1775 [20522] = { 0x00FF, 0x00FF, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */
1776 [20523] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */
1777 [20524] = { 0x00FF, 0x00FF, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */
1778 [20525] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */
1779 [20526] = { 0x00FF, 0x00FF, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */
1780 [20527] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */
1781 [20528] = { 0x00FF, 0x00FF, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */
1782 [20529] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */
1783 [20530] = { 0x00FF, 0x00FF, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */
1784 [20531] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */
1785 [20532] = { 0x00FF, 0x00FF, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */
1786 [20533] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */
1787 [20534] = { 0x00FF, 0x00FF, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */
1788 [20535] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */
1789 [20536] = { 0x00FF, 0x00FF, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */
1790 [20537] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */
1791 [20538] = { 0x00FF, 0x00FF, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */
1792 [20539] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */
1793 [20540] = { 0x00FF, 0x00FF, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */
1794 [20541] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */
1795 [20542] = { 0x00FF, 0x00FF, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */
1796 [20543] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */
1797 [20992] = { 0x00FF, 0x00FF, 0x0000 }, /* R20992 - VSS_XHD2_1 */
1798 [20993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20993 - VSS_XHD2_0 */
1799 [20994] = { 0x00FF, 0x00FF, 0x0000 }, /* R20994 - VSS_XHD3_1 */
1800 [20995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20995 - VSS_XHD3_0 */
1801 [20996] = { 0x00FF, 0x00FF, 0x0000 }, /* R20996 - VSS_XHN1_1 */
1802 [20997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20997 - VSS_XHN1_0 */
1803 [20998] = { 0x00FF, 0x00FF, 0x0000 }, /* R20998 - VSS_XHN2_1 */
1804 [20999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20999 - VSS_XHN2_0 */
1805 [21000] = { 0x00FF, 0x00FF, 0x0000 }, /* R21000 - VSS_XHN3_1 */
1806 [21001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21001 - VSS_XHN3_0 */
1807 [21002] = { 0x00FF, 0x00FF, 0x0000 }, /* R21002 - VSS_XLA_1 */
1808 [21003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21003 - VSS_XLA_0 */
1809 [21004] = { 0x00FF, 0x00FF, 0x0000 }, /* R21004 - VSS_XLB_1 */
1810 [21005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21005 - VSS_XLB_0 */
1811 [21006] = { 0x00FF, 0x00FF, 0x0000 }, /* R21006 - VSS_XLG_1 */
1812 [21007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21007 - VSS_XLG_0 */
1813 [21008] = { 0x00FF, 0x00FF, 0x0000 }, /* R21008 - VSS_PG2_1 */
1814 [21009] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21009 - VSS_PG2_0 */
1815 [21010] = { 0x00FF, 0x00FF, 0x0000 }, /* R21010 - VSS_PG_1 */
1816 [21011] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21011 - VSS_PG_0 */
1817 [21012] = { 0x00FF, 0x00FF, 0x0000 }, /* R21012 - VSS_XTD1_1 */
1818 [21013] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21013 - VSS_XTD1_0 */
1819 [21014] = { 0x00FF, 0x00FF, 0x0000 }, /* R21014 - VSS_XTD2_1 */
1820 [21015] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21015 - VSS_XTD2_0 */
1821 [21016] = { 0x00FF, 0x00FF, 0x0000 }, /* R21016 - VSS_XTD3_1 */
1822 [21017] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21017 - VSS_XTD3_0 */
1823 [21018] = { 0x00FF, 0x00FF, 0x0000 }, /* R21018 - VSS_XTD4_1 */
1824 [21019] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21019 - VSS_XTD4_0 */
1825 [21020] = { 0x00FF, 0x00FF, 0x0000 }, /* R21020 - VSS_XTD5_1 */
1826 [21021] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21021 - VSS_XTD5_0 */
1827 [21022] = { 0x00FF, 0x00FF, 0x0000 }, /* R21022 - VSS_XTD6_1 */
1828 [21023] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21023 - VSS_XTD6_0 */
1829 [21024] = { 0x00FF, 0x00FF, 0x0000 }, /* R21024 - VSS_XTD7_1 */
1830 [21025] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21025 - VSS_XTD7_0 */
1831 [21026] = { 0x00FF, 0x00FF, 0x0000 }, /* R21026 - VSS_XTD8_1 */
1832 [21027] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21027 - VSS_XTD8_0 */
1833 [21028] = { 0x00FF, 0x00FF, 0x0000 }, /* R21028 - VSS_XTD9_1 */
1834 [21029] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21029 - VSS_XTD9_0 */
1835 [21030] = { 0x00FF, 0x00FF, 0x0000 }, /* R21030 - VSS_XTD10_1 */
1836 [21031] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21031 - VSS_XTD10_0 */
1837 [21032] = { 0x00FF, 0x00FF, 0x0000 }, /* R21032 - VSS_XTD11_1 */
1838 [21033] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21033 - VSS_XTD11_0 */
1839 [21034] = { 0x00FF, 0x00FF, 0x0000 }, /* R21034 - VSS_XTD12_1 */
1840 [21035] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21035 - VSS_XTD12_0 */
1841 [21036] = { 0x00FF, 0x00FF, 0x0000 }, /* R21036 - VSS_XTD13_1 */
1842 [21037] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21037 - VSS_XTD13_0 */
1843 [21038] = { 0x00FF, 0x00FF, 0x0000 }, /* R21038 - VSS_XTD14_1 */
1844 [21039] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21039 - VSS_XTD14_0 */
1845 [21040] = { 0x00FF, 0x00FF, 0x0000 }, /* R21040 - VSS_XTD15_1 */
1846 [21041] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21041 - VSS_XTD15_0 */
1847 [21042] = { 0x00FF, 0x00FF, 0x0000 }, /* R21042 - VSS_XTD16_1 */
1848 [21043] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21043 - VSS_XTD16_0 */
1849 [21044] = { 0x00FF, 0x00FF, 0x0000 }, /* R21044 - VSS_XTD17_1 */
1850 [21045] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21045 - VSS_XTD17_0 */
1851 [21046] = { 0x00FF, 0x00FF, 0x0000 }, /* R21046 - VSS_XTD18_1 */
1852 [21047] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21047 - VSS_XTD18_0 */
1853 [21048] = { 0x00FF, 0x00FF, 0x0000 }, /* R21048 - VSS_XTD19_1 */
1854 [21049] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21049 - VSS_XTD19_0 */
1855 [21050] = { 0x00FF, 0x00FF, 0x0000 }, /* R21050 - VSS_XTD20_1 */
1856 [21051] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21051 - VSS_XTD20_0 */
1857 [21052] = { 0x00FF, 0x00FF, 0x0000 }, /* R21052 - VSS_XTD21_1 */
1858 [21053] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21053 - VSS_XTD21_0 */
1859 [21054] = { 0x00FF, 0x00FF, 0x0000 }, /* R21054 - VSS_XTD22_1 */
1860 [21055] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21055 - VSS_XTD22_0 */
1861 [21056] = { 0x00FF, 0x00FF, 0x0000 }, /* R21056 - VSS_XTD23_1 */
1862 [21057] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21057 - VSS_XTD23_0 */
1863 [21058] = { 0x00FF, 0x00FF, 0x0000 }, /* R21058 - VSS_XTD24_1 */
1864 [21059] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21059 - VSS_XTD24_0 */
1865 [21060] = { 0x00FF, 0x00FF, 0x0000 }, /* R21060 - VSS_XTD25_1 */
1866 [21061] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21061 - VSS_XTD25_0 */
1867 [21062] = { 0x00FF, 0x00FF, 0x0000 }, /* R21062 - VSS_XTD26_1 */
1868 [21063] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21063 - VSS_XTD26_0 */
1869 [21064] = { 0x00FF, 0x00FF, 0x0000 }, /* R21064 - VSS_XTD27_1 */
1870 [21065] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21065 - VSS_XTD27_0 */
1871 [21066] = { 0x00FF, 0x00FF, 0x0000 }, /* R21066 - VSS_XTD28_1 */
1872 [21067] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21067 - VSS_XTD28_0 */
1873 [21068] = { 0x00FF, 0x00FF, 0x0000 }, /* R21068 - VSS_XTD29_1 */
1874 [21069] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21069 - VSS_XTD29_0 */
1875 [21070] = { 0x00FF, 0x00FF, 0x0000 }, /* R21070 - VSS_XTD30_1 */
1876 [21071] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21071 - VSS_XTD30_0 */
1877 [21072] = { 0x00FF, 0x00FF, 0x0000 }, /* R21072 - VSS_XTD31_1 */
1878 [21073] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21073 - VSS_XTD31_0 */
1879 [21074] = { 0x00FF, 0x00FF, 0x0000 }, /* R21074 - VSS_XTD32_1 */
1880 [21075] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21075 - VSS_XTD32_0 */
1881 [21076] = { 0x00FF, 0x00FF, 0x0000 }, /* R21076 - VSS_XTS1_1 */
1882 [21077] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21077 - VSS_XTS1_0 */
1883 [21078] = { 0x00FF, 0x00FF, 0x0000 }, /* R21078 - VSS_XTS2_1 */
1884 [21079] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21079 - VSS_XTS2_0 */
1885 [21080] = { 0x00FF, 0x00FF, 0x0000 }, /* R21080 - VSS_XTS3_1 */
1886 [21081] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21081 - VSS_XTS3_0 */
1887 [21082] = { 0x00FF, 0x00FF, 0x0000 }, /* R21082 - VSS_XTS4_1 */
1888 [21083] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21083 - VSS_XTS4_0 */
1889 [21084] = { 0x00FF, 0x00FF, 0x0000 }, /* R21084 - VSS_XTS5_1 */
1890 [21085] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21085 - VSS_XTS5_0 */
1891 [21086] = { 0x00FF, 0x00FF, 0x0000 }, /* R21086 - VSS_XTS6_1 */
1892 [21087] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21087 - VSS_XTS6_0 */
1893 [21088] = { 0x00FF, 0x00FF, 0x0000 }, /* R21088 - VSS_XTS7_1 */
1894 [21089] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21089 - VSS_XTS7_0 */
1895 [21090] = { 0x00FF, 0x00FF, 0x0000 }, /* R21090 - VSS_XTS8_1 */
1896 [21091] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21091 - VSS_XTS8_0 */
1897 [21092] = { 0x00FF, 0x00FF, 0x0000 }, /* R21092 - VSS_XTS9_1 */
1898 [21093] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21093 - VSS_XTS9_0 */
1899 [21094] = { 0x00FF, 0x00FF, 0x0000 }, /* R21094 - VSS_XTS10_1 */
1900 [21095] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21095 - VSS_XTS10_0 */
1901 [21096] = { 0x00FF, 0x00FF, 0x0000 }, /* R21096 - VSS_XTS11_1 */
1902 [21097] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21097 - VSS_XTS11_0 */
1903 [21098] = { 0x00FF, 0x00FF, 0x0000 }, /* R21098 - VSS_XTS12_1 */
1904 [21099] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21099 - VSS_XTS12_0 */
1905 [21100] = { 0x00FF, 0x00FF, 0x0000 }, /* R21100 - VSS_XTS13_1 */
1906 [21101] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21101 - VSS_XTS13_0 */
1907 [21102] = { 0x00FF, 0x00FF, 0x0000 }, /* R21102 - VSS_XTS14_1 */
1908 [21103] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21103 - VSS_XTS14_0 */
1909 [21104] = { 0x00FF, 0x00FF, 0x0000 }, /* R21104 - VSS_XTS15_1 */
1910 [21105] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21105 - VSS_XTS15_0 */
1911 [21106] = { 0x00FF, 0x00FF, 0x0000 }, /* R21106 - VSS_XTS16_1 */
1912 [21107] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21107 - VSS_XTS16_0 */
1913 [21108] = { 0x00FF, 0x00FF, 0x0000 }, /* R21108 - VSS_XTS17_1 */
1914 [21109] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21109 - VSS_XTS17_0 */
1915 [21110] = { 0x00FF, 0x00FF, 0x0000 }, /* R21110 - VSS_XTS18_1 */
1916 [21111] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21111 - VSS_XTS18_0 */
1917 [21112] = { 0x00FF, 0x00FF, 0x0000 }, /* R21112 - VSS_XTS19_1 */
1918 [21113] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21113 - VSS_XTS19_0 */
1919 [21114] = { 0x00FF, 0x00FF, 0x0000 }, /* R21114 - VSS_XTS20_1 */
1920 [21115] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21115 - VSS_XTS20_0 */
1921 [21116] = { 0x00FF, 0x00FF, 0x0000 }, /* R21116 - VSS_XTS21_1 */
1922 [21117] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21117 - VSS_XTS21_0 */
1923 [21118] = { 0x00FF, 0x00FF, 0x0000 }, /* R21118 - VSS_XTS22_1 */
1924 [21119] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21119 - VSS_XTS22_0 */
1925 [21120] = { 0x00FF, 0x00FF, 0x0000 }, /* R21120 - VSS_XTS23_1 */
1926 [21121] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21121 - VSS_XTS23_0 */
1927 [21122] = { 0x00FF, 0x00FF, 0x0000 }, /* R21122 - VSS_XTS24_1 */
1928 [21123] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21123 - VSS_XTS24_0 */
1929 [21124] = { 0x00FF, 0x00FF, 0x0000 }, /* R21124 - VSS_XTS25_1 */
1930 [21125] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21125 - VSS_XTS25_0 */
1931 [21126] = { 0x00FF, 0x00FF, 0x0000 }, /* R21126 - VSS_XTS26_1 */
1932 [21127] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21127 - VSS_XTS26_0 */
1933 [21128] = { 0x00FF, 0x00FF, 0x0000 }, /* R21128 - VSS_XTS27_1 */
1934 [21129] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21129 - VSS_XTS27_0 */
1935 [21130] = { 0x00FF, 0x00FF, 0x0000 }, /* R21130 - VSS_XTS28_1 */
1936 [21131] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21131 - VSS_XTS28_0 */
1937 [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */
1938 [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */
1939 [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */
1940 [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */
1941 [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */
1942 [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */
1943 [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */
1944 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
1945};
1946
1947static bool wm8962_volatile_register(struct device *dev, unsigned int reg) 788static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
1948{ 789{
1949 if (wm8962_reg_access[reg].vol) 790 switch (reg) {
1950 return 1; 791 case WM8962_CLOCKING1:
1951 else 792 case WM8962_CLOCKING2:
1952 return 0; 793 case WM8962_SOFTWARE_RESET:
794 case WM8962_ALC2:
795 case WM8962_THERMAL_SHUTDOWN_STATUS:
796 case WM8962_ADDITIONAL_CONTROL_4:
797 case WM8962_CLASS_D_CONTROL_1:
798 case WM8962_DC_SERVO_6:
799 case WM8962_INTERRUPT_STATUS_1:
800 case WM8962_INTERRUPT_STATUS_2:
801 case WM8962_DSP2_EXECCONTROL:
802 return true;
803 default:
804 return false;
805 }
1953} 806}
1954 807
1955static bool wm8962_readable_register(struct device *dev, unsigned int reg) 808static bool wm8962_readable_register(struct device *dev, unsigned int reg)
1956{ 809{
1957 if (wm8962_reg_access[reg].read) 810 switch (reg) {
1958 return 1; 811 case WM8962_LEFT_INPUT_VOLUME:
1959 else 812 case WM8962_RIGHT_INPUT_VOLUME:
1960 return 0; 813 case WM8962_HPOUTL_VOLUME:
814 case WM8962_HPOUTR_VOLUME:
815 case WM8962_CLOCKING1:
816 case WM8962_ADC_DAC_CONTROL_1:
817 case WM8962_ADC_DAC_CONTROL_2:
818 case WM8962_AUDIO_INTERFACE_0:
819 case WM8962_CLOCKING2:
820 case WM8962_AUDIO_INTERFACE_1:
821 case WM8962_LEFT_DAC_VOLUME:
822 case WM8962_RIGHT_DAC_VOLUME:
823 case WM8962_AUDIO_INTERFACE_2:
824 case WM8962_SOFTWARE_RESET:
825 case WM8962_ALC1:
826 case WM8962_ALC2:
827 case WM8962_ALC3:
828 case WM8962_NOISE_GATE:
829 case WM8962_LEFT_ADC_VOLUME:
830 case WM8962_RIGHT_ADC_VOLUME:
831 case WM8962_ADDITIONAL_CONTROL_1:
832 case WM8962_ADDITIONAL_CONTROL_2:
833 case WM8962_PWR_MGMT_1:
834 case WM8962_PWR_MGMT_2:
835 case WM8962_ADDITIONAL_CONTROL_3:
836 case WM8962_ANTI_POP:
837 case WM8962_CLOCKING_3:
838 case WM8962_INPUT_MIXER_CONTROL_1:
839 case WM8962_LEFT_INPUT_MIXER_VOLUME:
840 case WM8962_RIGHT_INPUT_MIXER_VOLUME:
841 case WM8962_INPUT_MIXER_CONTROL_2:
842 case WM8962_INPUT_BIAS_CONTROL:
843 case WM8962_LEFT_INPUT_PGA_CONTROL:
844 case WM8962_RIGHT_INPUT_PGA_CONTROL:
845 case WM8962_SPKOUTL_VOLUME:
846 case WM8962_SPKOUTR_VOLUME:
847 case WM8962_THERMAL_SHUTDOWN_STATUS:
848 case WM8962_ADDITIONAL_CONTROL_4:
849 case WM8962_CLASS_D_CONTROL_1:
850 case WM8962_CLASS_D_CONTROL_2:
851 case WM8962_CLOCKING_4:
852 case WM8962_DAC_DSP_MIXING_1:
853 case WM8962_DAC_DSP_MIXING_2:
854 case WM8962_DC_SERVO_0:
855 case WM8962_DC_SERVO_1:
856 case WM8962_DC_SERVO_4:
857 case WM8962_DC_SERVO_6:
858 case WM8962_ANALOGUE_PGA_BIAS:
859 case WM8962_ANALOGUE_HP_0:
860 case WM8962_ANALOGUE_HP_2:
861 case WM8962_CHARGE_PUMP_1:
862 case WM8962_CHARGE_PUMP_B:
863 case WM8962_WRITE_SEQUENCER_CONTROL_1:
864 case WM8962_WRITE_SEQUENCER_CONTROL_2:
865 case WM8962_WRITE_SEQUENCER_CONTROL_3:
866 case WM8962_CONTROL_INTERFACE:
867 case WM8962_MIXER_ENABLES:
868 case WM8962_HEADPHONE_MIXER_1:
869 case WM8962_HEADPHONE_MIXER_2:
870 case WM8962_HEADPHONE_MIXER_3:
871 case WM8962_HEADPHONE_MIXER_4:
872 case WM8962_SPEAKER_MIXER_1:
873 case WM8962_SPEAKER_MIXER_2:
874 case WM8962_SPEAKER_MIXER_3:
875 case WM8962_SPEAKER_MIXER_4:
876 case WM8962_SPEAKER_MIXER_5:
877 case WM8962_BEEP_GENERATOR_1:
878 case WM8962_OSCILLATOR_TRIM_3:
879 case WM8962_OSCILLATOR_TRIM_4:
880 case WM8962_OSCILLATOR_TRIM_7:
881 case WM8962_ANALOGUE_CLOCKING1:
882 case WM8962_ANALOGUE_CLOCKING2:
883 case WM8962_ANALOGUE_CLOCKING3:
884 case WM8962_PLL_SOFTWARE_RESET:
885 case WM8962_PLL2:
886 case WM8962_PLL_4:
887 case WM8962_PLL_9:
888 case WM8962_PLL_10:
889 case WM8962_PLL_11:
890 case WM8962_PLL_12:
891 case WM8962_PLL_13:
892 case WM8962_PLL_14:
893 case WM8962_PLL_15:
894 case WM8962_PLL_16:
895 case WM8962_FLL_CONTROL_1:
896 case WM8962_FLL_CONTROL_2:
897 case WM8962_FLL_CONTROL_3:
898 case WM8962_FLL_CONTROL_5:
899 case WM8962_FLL_CONTROL_6:
900 case WM8962_FLL_CONTROL_7:
901 case WM8962_FLL_CONTROL_8:
902 case WM8962_GENERAL_TEST_1:
903 case WM8962_DF1:
904 case WM8962_DF2:
905 case WM8962_DF3:
906 case WM8962_DF4:
907 case WM8962_DF5:
908 case WM8962_DF6:
909 case WM8962_DF7:
910 case WM8962_LHPF1:
911 case WM8962_LHPF2:
912 case WM8962_THREED1:
913 case WM8962_THREED2:
914 case WM8962_THREED3:
915 case WM8962_THREED4:
916 case WM8962_DRC_1:
917 case WM8962_DRC_2:
918 case WM8962_DRC_3:
919 case WM8962_DRC_4:
920 case WM8962_DRC_5:
921 case WM8962_TLOOPBACK:
922 case WM8962_EQ1:
923 case WM8962_EQ2:
924 case WM8962_EQ3:
925 case WM8962_EQ4:
926 case WM8962_EQ5:
927 case WM8962_EQ6:
928 case WM8962_EQ7:
929 case WM8962_EQ8:
930 case WM8962_EQ9:
931 case WM8962_EQ10:
932 case WM8962_EQ11:
933 case WM8962_EQ12:
934 case WM8962_EQ13:
935 case WM8962_EQ14:
936 case WM8962_EQ15:
937 case WM8962_EQ16:
938 case WM8962_EQ17:
939 case WM8962_EQ18:
940 case WM8962_EQ19:
941 case WM8962_EQ20:
942 case WM8962_EQ21:
943 case WM8962_EQ22:
944 case WM8962_EQ23:
945 case WM8962_EQ24:
946 case WM8962_EQ25:
947 case WM8962_EQ26:
948 case WM8962_EQ27:
949 case WM8962_EQ28:
950 case WM8962_EQ29:
951 case WM8962_EQ30:
952 case WM8962_EQ31:
953 case WM8962_EQ32:
954 case WM8962_EQ33:
955 case WM8962_EQ34:
956 case WM8962_EQ35:
957 case WM8962_EQ36:
958 case WM8962_EQ37:
959 case WM8962_EQ38:
960 case WM8962_EQ39:
961 case WM8962_EQ40:
962 case WM8962_EQ41:
963 case WM8962_GPIO_BASE:
964 case WM8962_GPIO_2:
965 case WM8962_GPIO_3:
966 case WM8962_GPIO_5:
967 case WM8962_GPIO_6:
968 case WM8962_INTERRUPT_STATUS_1:
969 case WM8962_INTERRUPT_STATUS_2:
970 case WM8962_INTERRUPT_STATUS_1_MASK:
971 case WM8962_INTERRUPT_STATUS_2_MASK:
972 case WM8962_INTERRUPT_CONTROL:
973 case WM8962_IRQ_DEBOUNCE:
974 case WM8962_MICINT_SOURCE_POL:
975 case WM8962_DSP2_POWER_MANAGEMENT:
976 case WM8962_DSP2_EXECCONTROL:
977 case WM8962_DSP2_INSTRUCTION_RAM_0:
978 case WM8962_DSP2_ADDRESS_RAM_2:
979 case WM8962_DSP2_ADDRESS_RAM_1:
980 case WM8962_DSP2_ADDRESS_RAM_0:
981 case WM8962_DSP2_DATA1_RAM_1:
982 case WM8962_DSP2_DATA1_RAM_0:
983 case WM8962_DSP2_DATA2_RAM_1:
984 case WM8962_DSP2_DATA2_RAM_0:
985 case WM8962_DSP2_DATA3_RAM_1:
986 case WM8962_DSP2_DATA3_RAM_0:
987 case WM8962_DSP2_COEFF_RAM_0:
988 case WM8962_RETUNEADC_SHARED_COEFF_1:
989 case WM8962_RETUNEADC_SHARED_COEFF_0:
990 case WM8962_RETUNEDAC_SHARED_COEFF_1:
991 case WM8962_RETUNEDAC_SHARED_COEFF_0:
992 case WM8962_SOUNDSTAGE_ENABLES_1:
993 case WM8962_SOUNDSTAGE_ENABLES_0:
994 case WM8962_HDBASS_AI_1:
995 case WM8962_HDBASS_AI_0:
996 case WM8962_HDBASS_AR_1:
997 case WM8962_HDBASS_AR_0:
998 case WM8962_HDBASS_B_1:
999 case WM8962_HDBASS_B_0:
1000 case WM8962_HDBASS_K_1:
1001 case WM8962_HDBASS_K_0:
1002 case WM8962_HDBASS_N1_1:
1003 case WM8962_HDBASS_N1_0:
1004 case WM8962_HDBASS_N2_1:
1005 case WM8962_HDBASS_N2_0:
1006 case WM8962_HDBASS_N3_1:
1007 case WM8962_HDBASS_N3_0:
1008 case WM8962_HDBASS_N4_1:
1009 case WM8962_HDBASS_N4_0:
1010 case WM8962_HDBASS_N5_1:
1011 case WM8962_HDBASS_N5_0:
1012 case WM8962_HDBASS_X1_1:
1013 case WM8962_HDBASS_X1_0:
1014 case WM8962_HDBASS_X2_1:
1015 case WM8962_HDBASS_X2_0:
1016 case WM8962_HDBASS_X3_1:
1017 case WM8962_HDBASS_X3_0:
1018 case WM8962_HDBASS_ATK_1:
1019 case WM8962_HDBASS_ATK_0:
1020 case WM8962_HDBASS_DCY_1:
1021 case WM8962_HDBASS_DCY_0:
1022 case WM8962_HDBASS_PG_1:
1023 case WM8962_HDBASS_PG_0:
1024 case WM8962_HPF_C_1:
1025 case WM8962_HPF_C_0:
1026 case WM8962_ADCL_RETUNE_C1_1:
1027 case WM8962_ADCL_RETUNE_C1_0:
1028 case WM8962_ADCL_RETUNE_C2_1:
1029 case WM8962_ADCL_RETUNE_C2_0:
1030 case WM8962_ADCL_RETUNE_C3_1:
1031 case WM8962_ADCL_RETUNE_C3_0:
1032 case WM8962_ADCL_RETUNE_C4_1:
1033 case WM8962_ADCL_RETUNE_C4_0:
1034 case WM8962_ADCL_RETUNE_C5_1:
1035 case WM8962_ADCL_RETUNE_C5_0:
1036 case WM8962_ADCL_RETUNE_C6_1:
1037 case WM8962_ADCL_RETUNE_C6_0:
1038 case WM8962_ADCL_RETUNE_C7_1:
1039 case WM8962_ADCL_RETUNE_C7_0:
1040 case WM8962_ADCL_RETUNE_C8_1:
1041 case WM8962_ADCL_RETUNE_C8_0:
1042 case WM8962_ADCL_RETUNE_C9_1:
1043 case WM8962_ADCL_RETUNE_C9_0:
1044 case WM8962_ADCL_RETUNE_C10_1:
1045 case WM8962_ADCL_RETUNE_C10_0:
1046 case WM8962_ADCL_RETUNE_C11_1:
1047 case WM8962_ADCL_RETUNE_C11_0:
1048 case WM8962_ADCL_RETUNE_C12_1:
1049 case WM8962_ADCL_RETUNE_C12_0:
1050 case WM8962_ADCL_RETUNE_C13_1:
1051 case WM8962_ADCL_RETUNE_C13_0:
1052 case WM8962_ADCL_RETUNE_C14_1:
1053 case WM8962_ADCL_RETUNE_C14_0:
1054 case WM8962_ADCL_RETUNE_C15_1:
1055 case WM8962_ADCL_RETUNE_C15_0:
1056 case WM8962_ADCL_RETUNE_C16_1:
1057 case WM8962_ADCL_RETUNE_C16_0:
1058 case WM8962_ADCL_RETUNE_C17_1:
1059 case WM8962_ADCL_RETUNE_C17_0:
1060 case WM8962_ADCL_RETUNE_C18_1:
1061 case WM8962_ADCL_RETUNE_C18_0:
1062 case WM8962_ADCL_RETUNE_C19_1:
1063 case WM8962_ADCL_RETUNE_C19_0:
1064 case WM8962_ADCL_RETUNE_C20_1:
1065 case WM8962_ADCL_RETUNE_C20_0:
1066 case WM8962_ADCL_RETUNE_C21_1:
1067 case WM8962_ADCL_RETUNE_C21_0:
1068 case WM8962_ADCL_RETUNE_C22_1:
1069 case WM8962_ADCL_RETUNE_C22_0:
1070 case WM8962_ADCL_RETUNE_C23_1:
1071 case WM8962_ADCL_RETUNE_C23_0:
1072 case WM8962_ADCL_RETUNE_C24_1:
1073 case WM8962_ADCL_RETUNE_C24_0:
1074 case WM8962_ADCL_RETUNE_C25_1:
1075 case WM8962_ADCL_RETUNE_C25_0:
1076 case WM8962_ADCL_RETUNE_C26_1:
1077 case WM8962_ADCL_RETUNE_C26_0:
1078 case WM8962_ADCL_RETUNE_C27_1:
1079 case WM8962_ADCL_RETUNE_C27_0:
1080 case WM8962_ADCL_RETUNE_C28_1:
1081 case WM8962_ADCL_RETUNE_C28_0:
1082 case WM8962_ADCL_RETUNE_C29_1:
1083 case WM8962_ADCL_RETUNE_C29_0:
1084 case WM8962_ADCL_RETUNE_C30_1:
1085 case WM8962_ADCL_RETUNE_C30_0:
1086 case WM8962_ADCL_RETUNE_C31_1:
1087 case WM8962_ADCL_RETUNE_C31_0:
1088 case WM8962_ADCL_RETUNE_C32_1:
1089 case WM8962_ADCL_RETUNE_C32_0:
1090 case WM8962_RETUNEADC_PG2_1:
1091 case WM8962_RETUNEADC_PG2_0:
1092 case WM8962_RETUNEADC_PG_1:
1093 case WM8962_RETUNEADC_PG_0:
1094 case WM8962_ADCR_RETUNE_C1_1:
1095 case WM8962_ADCR_RETUNE_C1_0:
1096 case WM8962_ADCR_RETUNE_C2_1:
1097 case WM8962_ADCR_RETUNE_C2_0:
1098 case WM8962_ADCR_RETUNE_C3_1:
1099 case WM8962_ADCR_RETUNE_C3_0:
1100 case WM8962_ADCR_RETUNE_C4_1:
1101 case WM8962_ADCR_RETUNE_C4_0:
1102 case WM8962_ADCR_RETUNE_C5_1:
1103 case WM8962_ADCR_RETUNE_C5_0:
1104 case WM8962_ADCR_RETUNE_C6_1:
1105 case WM8962_ADCR_RETUNE_C6_0:
1106 case WM8962_ADCR_RETUNE_C7_1:
1107 case WM8962_ADCR_RETUNE_C7_0:
1108 case WM8962_ADCR_RETUNE_C8_1:
1109 case WM8962_ADCR_RETUNE_C8_0:
1110 case WM8962_ADCR_RETUNE_C9_1:
1111 case WM8962_ADCR_RETUNE_C9_0:
1112 case WM8962_ADCR_RETUNE_C10_1:
1113 case WM8962_ADCR_RETUNE_C10_0:
1114 case WM8962_ADCR_RETUNE_C11_1:
1115 case WM8962_ADCR_RETUNE_C11_0:
1116 case WM8962_ADCR_RETUNE_C12_1:
1117 case WM8962_ADCR_RETUNE_C12_0:
1118 case WM8962_ADCR_RETUNE_C13_1:
1119 case WM8962_ADCR_RETUNE_C13_0:
1120 case WM8962_ADCR_RETUNE_C14_1:
1121 case WM8962_ADCR_RETUNE_C14_0:
1122 case WM8962_ADCR_RETUNE_C15_1:
1123 case WM8962_ADCR_RETUNE_C15_0:
1124 case WM8962_ADCR_RETUNE_C16_1:
1125 case WM8962_ADCR_RETUNE_C16_0:
1126 case WM8962_ADCR_RETUNE_C17_1:
1127 case WM8962_ADCR_RETUNE_C17_0:
1128 case WM8962_ADCR_RETUNE_C18_1:
1129 case WM8962_ADCR_RETUNE_C18_0:
1130 case WM8962_ADCR_RETUNE_C19_1:
1131 case WM8962_ADCR_RETUNE_C19_0:
1132 case WM8962_ADCR_RETUNE_C20_1:
1133 case WM8962_ADCR_RETUNE_C20_0:
1134 case WM8962_ADCR_RETUNE_C21_1:
1135 case WM8962_ADCR_RETUNE_C21_0:
1136 case WM8962_ADCR_RETUNE_C22_1:
1137 case WM8962_ADCR_RETUNE_C22_0:
1138 case WM8962_ADCR_RETUNE_C23_1:
1139 case WM8962_ADCR_RETUNE_C23_0:
1140 case WM8962_ADCR_RETUNE_C24_1:
1141 case WM8962_ADCR_RETUNE_C24_0:
1142 case WM8962_ADCR_RETUNE_C25_1:
1143 case WM8962_ADCR_RETUNE_C25_0:
1144 case WM8962_ADCR_RETUNE_C26_1:
1145 case WM8962_ADCR_RETUNE_C26_0:
1146 case WM8962_ADCR_RETUNE_C27_1:
1147 case WM8962_ADCR_RETUNE_C27_0:
1148 case WM8962_ADCR_RETUNE_C28_1:
1149 case WM8962_ADCR_RETUNE_C28_0:
1150 case WM8962_ADCR_RETUNE_C29_1:
1151 case WM8962_ADCR_RETUNE_C29_0:
1152 case WM8962_ADCR_RETUNE_C30_1:
1153 case WM8962_ADCR_RETUNE_C30_0:
1154 case WM8962_ADCR_RETUNE_C31_1:
1155 case WM8962_ADCR_RETUNE_C31_0:
1156 case WM8962_ADCR_RETUNE_C32_1:
1157 case WM8962_ADCR_RETUNE_C32_0:
1158 case WM8962_DACL_RETUNE_C1_1:
1159 case WM8962_DACL_RETUNE_C1_0:
1160 case WM8962_DACL_RETUNE_C2_1:
1161 case WM8962_DACL_RETUNE_C2_0:
1162 case WM8962_DACL_RETUNE_C3_1:
1163 case WM8962_DACL_RETUNE_C3_0:
1164 case WM8962_DACL_RETUNE_C4_1:
1165 case WM8962_DACL_RETUNE_C4_0:
1166 case WM8962_DACL_RETUNE_C5_1:
1167 case WM8962_DACL_RETUNE_C5_0:
1168 case WM8962_DACL_RETUNE_C6_1:
1169 case WM8962_DACL_RETUNE_C6_0:
1170 case WM8962_DACL_RETUNE_C7_1:
1171 case WM8962_DACL_RETUNE_C7_0:
1172 case WM8962_DACL_RETUNE_C8_1:
1173 case WM8962_DACL_RETUNE_C8_0:
1174 case WM8962_DACL_RETUNE_C9_1:
1175 case WM8962_DACL_RETUNE_C9_0:
1176 case WM8962_DACL_RETUNE_C10_1:
1177 case WM8962_DACL_RETUNE_C10_0:
1178 case WM8962_DACL_RETUNE_C11_1:
1179 case WM8962_DACL_RETUNE_C11_0:
1180 case WM8962_DACL_RETUNE_C12_1:
1181 case WM8962_DACL_RETUNE_C12_0:
1182 case WM8962_DACL_RETUNE_C13_1:
1183 case WM8962_DACL_RETUNE_C13_0:
1184 case WM8962_DACL_RETUNE_C14_1:
1185 case WM8962_DACL_RETUNE_C14_0:
1186 case WM8962_DACL_RETUNE_C15_1:
1187 case WM8962_DACL_RETUNE_C15_0:
1188 case WM8962_DACL_RETUNE_C16_1:
1189 case WM8962_DACL_RETUNE_C16_0:
1190 case WM8962_DACL_RETUNE_C17_1:
1191 case WM8962_DACL_RETUNE_C17_0:
1192 case WM8962_DACL_RETUNE_C18_1:
1193 case WM8962_DACL_RETUNE_C18_0:
1194 case WM8962_DACL_RETUNE_C19_1:
1195 case WM8962_DACL_RETUNE_C19_0:
1196 case WM8962_DACL_RETUNE_C20_1:
1197 case WM8962_DACL_RETUNE_C20_0:
1198 case WM8962_DACL_RETUNE_C21_1:
1199 case WM8962_DACL_RETUNE_C21_0:
1200 case WM8962_DACL_RETUNE_C22_1:
1201 case WM8962_DACL_RETUNE_C22_0:
1202 case WM8962_DACL_RETUNE_C23_1:
1203 case WM8962_DACL_RETUNE_C23_0:
1204 case WM8962_DACL_RETUNE_C24_1:
1205 case WM8962_DACL_RETUNE_C24_0:
1206 case WM8962_DACL_RETUNE_C25_1:
1207 case WM8962_DACL_RETUNE_C25_0:
1208 case WM8962_DACL_RETUNE_C26_1:
1209 case WM8962_DACL_RETUNE_C26_0:
1210 case WM8962_DACL_RETUNE_C27_1:
1211 case WM8962_DACL_RETUNE_C27_0:
1212 case WM8962_DACL_RETUNE_C28_1:
1213 case WM8962_DACL_RETUNE_C28_0:
1214 case WM8962_DACL_RETUNE_C29_1:
1215 case WM8962_DACL_RETUNE_C29_0:
1216 case WM8962_DACL_RETUNE_C30_1:
1217 case WM8962_DACL_RETUNE_C30_0:
1218 case WM8962_DACL_RETUNE_C31_1:
1219 case WM8962_DACL_RETUNE_C31_0:
1220 case WM8962_DACL_RETUNE_C32_1:
1221 case WM8962_DACL_RETUNE_C32_0:
1222 case WM8962_RETUNEDAC_PG2_1:
1223 case WM8962_RETUNEDAC_PG2_0:
1224 case WM8962_RETUNEDAC_PG_1:
1225 case WM8962_RETUNEDAC_PG_0:
1226 case WM8962_DACR_RETUNE_C1_1:
1227 case WM8962_DACR_RETUNE_C1_0:
1228 case WM8962_DACR_RETUNE_C2_1:
1229 case WM8962_DACR_RETUNE_C2_0:
1230 case WM8962_DACR_RETUNE_C3_1:
1231 case WM8962_DACR_RETUNE_C3_0:
1232 case WM8962_DACR_RETUNE_C4_1:
1233 case WM8962_DACR_RETUNE_C4_0:
1234 case WM8962_DACR_RETUNE_C5_1:
1235 case WM8962_DACR_RETUNE_C5_0:
1236 case WM8962_DACR_RETUNE_C6_1:
1237 case WM8962_DACR_RETUNE_C6_0:
1238 case WM8962_DACR_RETUNE_C7_1:
1239 case WM8962_DACR_RETUNE_C7_0:
1240 case WM8962_DACR_RETUNE_C8_1:
1241 case WM8962_DACR_RETUNE_C8_0:
1242 case WM8962_DACR_RETUNE_C9_1:
1243 case WM8962_DACR_RETUNE_C9_0:
1244 case WM8962_DACR_RETUNE_C10_1:
1245 case WM8962_DACR_RETUNE_C10_0:
1246 case WM8962_DACR_RETUNE_C11_1:
1247 case WM8962_DACR_RETUNE_C11_0:
1248 case WM8962_DACR_RETUNE_C12_1:
1249 case WM8962_DACR_RETUNE_C12_0:
1250 case WM8962_DACR_RETUNE_C13_1:
1251 case WM8962_DACR_RETUNE_C13_0:
1252 case WM8962_DACR_RETUNE_C14_1:
1253 case WM8962_DACR_RETUNE_C14_0:
1254 case WM8962_DACR_RETUNE_C15_1:
1255 case WM8962_DACR_RETUNE_C15_0:
1256 case WM8962_DACR_RETUNE_C16_1:
1257 case WM8962_DACR_RETUNE_C16_0:
1258 case WM8962_DACR_RETUNE_C17_1:
1259 case WM8962_DACR_RETUNE_C17_0:
1260 case WM8962_DACR_RETUNE_C18_1:
1261 case WM8962_DACR_RETUNE_C18_0:
1262 case WM8962_DACR_RETUNE_C19_1:
1263 case WM8962_DACR_RETUNE_C19_0:
1264 case WM8962_DACR_RETUNE_C20_1:
1265 case WM8962_DACR_RETUNE_C20_0:
1266 case WM8962_DACR_RETUNE_C21_1:
1267 case WM8962_DACR_RETUNE_C21_0:
1268 case WM8962_DACR_RETUNE_C22_1:
1269 case WM8962_DACR_RETUNE_C22_0:
1270 case WM8962_DACR_RETUNE_C23_1:
1271 case WM8962_DACR_RETUNE_C23_0:
1272 case WM8962_DACR_RETUNE_C24_1:
1273 case WM8962_DACR_RETUNE_C24_0:
1274 case WM8962_DACR_RETUNE_C25_1:
1275 case WM8962_DACR_RETUNE_C25_0:
1276 case WM8962_DACR_RETUNE_C26_1:
1277 case WM8962_DACR_RETUNE_C26_0:
1278 case WM8962_DACR_RETUNE_C27_1:
1279 case WM8962_DACR_RETUNE_C27_0:
1280 case WM8962_DACR_RETUNE_C28_1:
1281 case WM8962_DACR_RETUNE_C28_0:
1282 case WM8962_DACR_RETUNE_C29_1:
1283 case WM8962_DACR_RETUNE_C29_0:
1284 case WM8962_DACR_RETUNE_C30_1:
1285 case WM8962_DACR_RETUNE_C30_0:
1286 case WM8962_DACR_RETUNE_C31_1:
1287 case WM8962_DACR_RETUNE_C31_0:
1288 case WM8962_DACR_RETUNE_C32_1:
1289 case WM8962_DACR_RETUNE_C32_0:
1290 case WM8962_VSS_XHD2_1:
1291 case WM8962_VSS_XHD2_0:
1292 case WM8962_VSS_XHD3_1:
1293 case WM8962_VSS_XHD3_0:
1294 case WM8962_VSS_XHN1_1:
1295 case WM8962_VSS_XHN1_0:
1296 case WM8962_VSS_XHN2_1:
1297 case WM8962_VSS_XHN2_0:
1298 case WM8962_VSS_XHN3_1:
1299 case WM8962_VSS_XHN3_0:
1300 case WM8962_VSS_XLA_1:
1301 case WM8962_VSS_XLA_0:
1302 case WM8962_VSS_XLB_1:
1303 case WM8962_VSS_XLB_0:
1304 case WM8962_VSS_XLG_1:
1305 case WM8962_VSS_XLG_0:
1306 case WM8962_VSS_PG2_1:
1307 case WM8962_VSS_PG2_0:
1308 case WM8962_VSS_PG_1:
1309 case WM8962_VSS_PG_0:
1310 case WM8962_VSS_XTD1_1:
1311 case WM8962_VSS_XTD1_0:
1312 case WM8962_VSS_XTD2_1:
1313 case WM8962_VSS_XTD2_0:
1314 case WM8962_VSS_XTD3_1:
1315 case WM8962_VSS_XTD3_0:
1316 case WM8962_VSS_XTD4_1:
1317 case WM8962_VSS_XTD4_0:
1318 case WM8962_VSS_XTD5_1:
1319 case WM8962_VSS_XTD5_0:
1320 case WM8962_VSS_XTD6_1:
1321 case WM8962_VSS_XTD6_0:
1322 case WM8962_VSS_XTD7_1:
1323 case WM8962_VSS_XTD7_0:
1324 case WM8962_VSS_XTD8_1:
1325 case WM8962_VSS_XTD8_0:
1326 case WM8962_VSS_XTD9_1:
1327 case WM8962_VSS_XTD9_0:
1328 case WM8962_VSS_XTD10_1:
1329 case WM8962_VSS_XTD10_0:
1330 case WM8962_VSS_XTD11_1:
1331 case WM8962_VSS_XTD11_0:
1332 case WM8962_VSS_XTD12_1:
1333 case WM8962_VSS_XTD12_0:
1334 case WM8962_VSS_XTD13_1:
1335 case WM8962_VSS_XTD13_0:
1336 case WM8962_VSS_XTD14_1:
1337 case WM8962_VSS_XTD14_0:
1338 case WM8962_VSS_XTD15_1:
1339 case WM8962_VSS_XTD15_0:
1340 case WM8962_VSS_XTD16_1:
1341 case WM8962_VSS_XTD16_0:
1342 case WM8962_VSS_XTD17_1:
1343 case WM8962_VSS_XTD17_0:
1344 case WM8962_VSS_XTD18_1:
1345 case WM8962_VSS_XTD18_0:
1346 case WM8962_VSS_XTD19_1:
1347 case WM8962_VSS_XTD19_0:
1348 case WM8962_VSS_XTD20_1:
1349 case WM8962_VSS_XTD20_0:
1350 case WM8962_VSS_XTD21_1:
1351 case WM8962_VSS_XTD21_0:
1352 case WM8962_VSS_XTD22_1:
1353 case WM8962_VSS_XTD22_0:
1354 case WM8962_VSS_XTD23_1:
1355 case WM8962_VSS_XTD23_0:
1356 case WM8962_VSS_XTD24_1:
1357 case WM8962_VSS_XTD24_0:
1358 case WM8962_VSS_XTD25_1:
1359 case WM8962_VSS_XTD25_0:
1360 case WM8962_VSS_XTD26_1:
1361 case WM8962_VSS_XTD26_0:
1362 case WM8962_VSS_XTD27_1:
1363 case WM8962_VSS_XTD27_0:
1364 case WM8962_VSS_XTD28_1:
1365 case WM8962_VSS_XTD28_0:
1366 case WM8962_VSS_XTD29_1:
1367 case WM8962_VSS_XTD29_0:
1368 case WM8962_VSS_XTD30_1:
1369 case WM8962_VSS_XTD30_0:
1370 case WM8962_VSS_XTD31_1:
1371 case WM8962_VSS_XTD31_0:
1372 case WM8962_VSS_XTD32_1:
1373 case WM8962_VSS_XTD32_0:
1374 case WM8962_VSS_XTS1_1:
1375 case WM8962_VSS_XTS1_0:
1376 case WM8962_VSS_XTS2_1:
1377 case WM8962_VSS_XTS2_0:
1378 case WM8962_VSS_XTS3_1:
1379 case WM8962_VSS_XTS3_0:
1380 case WM8962_VSS_XTS4_1:
1381 case WM8962_VSS_XTS4_0:
1382 case WM8962_VSS_XTS5_1:
1383 case WM8962_VSS_XTS5_0:
1384 case WM8962_VSS_XTS6_1:
1385 case WM8962_VSS_XTS6_0:
1386 case WM8962_VSS_XTS7_1:
1387 case WM8962_VSS_XTS7_0:
1388 case WM8962_VSS_XTS8_1:
1389 case WM8962_VSS_XTS8_0:
1390 case WM8962_VSS_XTS9_1:
1391 case WM8962_VSS_XTS9_0:
1392 case WM8962_VSS_XTS10_1:
1393 case WM8962_VSS_XTS10_0:
1394 case WM8962_VSS_XTS11_1:
1395 case WM8962_VSS_XTS11_0:
1396 case WM8962_VSS_XTS12_1:
1397 case WM8962_VSS_XTS12_0:
1398 case WM8962_VSS_XTS13_1:
1399 case WM8962_VSS_XTS13_0:
1400 case WM8962_VSS_XTS14_1:
1401 case WM8962_VSS_XTS14_0:
1402 case WM8962_VSS_XTS15_1:
1403 case WM8962_VSS_XTS15_0:
1404 case WM8962_VSS_XTS16_1:
1405 case WM8962_VSS_XTS16_0:
1406 case WM8962_VSS_XTS17_1:
1407 case WM8962_VSS_XTS17_0:
1408 case WM8962_VSS_XTS18_1:
1409 case WM8962_VSS_XTS18_0:
1410 case WM8962_VSS_XTS19_1:
1411 case WM8962_VSS_XTS19_0:
1412 case WM8962_VSS_XTS20_1:
1413 case WM8962_VSS_XTS20_0:
1414 case WM8962_VSS_XTS21_1:
1415 case WM8962_VSS_XTS21_0:
1416 case WM8962_VSS_XTS22_1:
1417 case WM8962_VSS_XTS22_0:
1418 case WM8962_VSS_XTS23_1:
1419 case WM8962_VSS_XTS23_0:
1420 case WM8962_VSS_XTS24_1:
1421 case WM8962_VSS_XTS24_0:
1422 case WM8962_VSS_XTS25_1:
1423 case WM8962_VSS_XTS25_0:
1424 case WM8962_VSS_XTS26_1:
1425 case WM8962_VSS_XTS26_0:
1426 case WM8962_VSS_XTS27_1:
1427 case WM8962_VSS_XTS27_0:
1428 case WM8962_VSS_XTS28_1:
1429 case WM8962_VSS_XTS28_0:
1430 case WM8962_VSS_XTS29_1:
1431 case WM8962_VSS_XTS29_0:
1432 case WM8962_VSS_XTS30_1:
1433 case WM8962_VSS_XTS30_0:
1434 case WM8962_VSS_XTS31_1:
1435 case WM8962_VSS_XTS31_0:
1436 case WM8962_VSS_XTS32_1:
1437 case WM8962_VSS_XTS32_0:
1438 return true;
1439 default:
1440 return false;
1441 }
1961} 1442}
1962 1443
1963static int wm8962_reset(struct wm8962_priv *wm8962) 1444static int wm8962_reset(struct wm8962_priv *wm8962)
@@ -2221,6 +1702,8 @@ SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2221SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME, 1702SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
2222 WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv), 1703 WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
2223SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0), 1704SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
1705SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0),
1706SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0),
2224 1707
2225SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1, 1708SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
2226 5, 1, 0), 1709 5, 1, 0),
@@ -2337,65 +1820,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
2337 4, 1, 0, inmix_tlv), 1820 4, 1, 0, inmix_tlv),
2338}; 1821};
2339 1822
2340static int sysclk_event(struct snd_soc_dapm_widget *w,
2341 struct snd_kcontrol *kcontrol, int event)
2342{
2343 struct snd_soc_codec *codec = w->codec;
2344 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2345 unsigned long timeout;
2346 int src;
2347 int fll;
2348
2349 /* Ignore attempts to run the event during startup */
2350 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
2351 return 0;
2352
2353 src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
2354
2355 switch (src) {
2356 case 0: /* MCLK */
2357 fll = 0;
2358 break;
2359 case 0x200: /* FLL */
2360 fll = 1;
2361 break;
2362 default:
2363 dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
2364 return -EINVAL;
2365 }
2366
2367 switch (event) {
2368 case SND_SOC_DAPM_PRE_PMU:
2369 if (fll) {
2370 try_wait_for_completion(&wm8962->fll_lock);
2371
2372 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2373 WM8962_FLL_ENA, WM8962_FLL_ENA);
2374
2375 timeout = msecs_to_jiffies(5);
2376 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
2377 timeout);
2378
2379 if (wm8962->irq && timeout == 0)
2380 dev_err(codec->dev,
2381 "Timed out starting FLL\n");
2382 }
2383 break;
2384
2385 case SND_SOC_DAPM_POST_PMD:
2386 if (fll)
2387 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2388 WM8962_FLL_ENA, 0);
2389 break;
2390
2391 default:
2392 BUG();
2393 return -EINVAL;
2394 }
2395
2396 return 0;
2397}
2398
2399static int cp_event(struct snd_soc_dapm_widget *w, 1823static int cp_event(struct snd_soc_dapm_widget *w,
2400 struct snd_kcontrol *kcontrol, int event) 1824 struct snd_kcontrol *kcontrol, int event)
2401{ 1825{
@@ -2681,8 +2105,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"),
2681SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), 2105SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2682 2106
2683SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2107SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2684SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2108SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0),
2685 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2686SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2109SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2687 SND_SOC_DAPM_POST_PMU), 2110 SND_SOC_DAPM_POST_PMU),
2688SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2111SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
@@ -2796,9 +2219,11 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2796 2219
2797 { "STL", "Left", "ADCL" }, 2220 { "STL", "Left", "ADCL" },
2798 { "STL", "Right", "ADCR" }, 2221 { "STL", "Right", "ADCR" },
2222 { "STL", NULL, "Class G" },
2799 2223
2800 { "STR", "Left", "ADCL" }, 2224 { "STR", "Left", "ADCL" },
2801 { "STR", "Right", "ADCR" }, 2225 { "STR", "Right", "ADCR" },
2226 { "STR", NULL, "Class G" },
2802 2227
2803 { "DACL", NULL, "SYSCLK" }, 2228 { "DACL", NULL, "SYSCLK" },
2804 { "DACL", NULL, "TOCLK" }, 2229 { "DACL", NULL, "TOCLK" },
@@ -2910,13 +2335,13 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2910 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 2335 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
2911 struct snd_soc_dapm_context *dapm = &codec->dapm; 2336 struct snd_soc_dapm_context *dapm = &codec->dapm;
2912 2337
2913 snd_soc_add_controls(codec, wm8962_snd_controls, 2338 snd_soc_add_codec_controls(codec, wm8962_snd_controls,
2914 ARRAY_SIZE(wm8962_snd_controls)); 2339 ARRAY_SIZE(wm8962_snd_controls));
2915 if (pdata && pdata->spk_mono) 2340 if (pdata && pdata->spk_mono)
2916 snd_soc_add_controls(codec, wm8962_spk_mono_controls, 2341 snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
2917 ARRAY_SIZE(wm8962_spk_mono_controls)); 2342 ARRAY_SIZE(wm8962_spk_mono_controls));
2918 else 2343 else
2919 snd_soc_add_controls(codec, wm8962_spk_stereo_controls, 2344 snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls,
2920 ARRAY_SIZE(wm8962_spk_stereo_controls)); 2345 ARRAY_SIZE(wm8962_spk_stereo_controls));
2921 2346
2922 2347
@@ -2950,7 +2375,7 @@ static const int bclk_divs[] = {
2950}; 2375};
2951 2376
2952static const int sysclk_rates[] = { 2377static const int sysclk_rates[] = {
2953 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 2378 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144
2954}; 2379};
2955 2380
2956static void wm8962_configure_bclk(struct snd_soc_codec *codec) 2381static void wm8962_configure_bclk(struct snd_soc_codec *codec)
@@ -2984,6 +2409,8 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2984 return; 2409 return;
2985 } 2410 }
2986 2411
2412 dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
2413
2987 snd_soc_update_bits(codec, WM8962_CLOCKING_4, 2414 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2988 WM8962_SYSCLK_RATE_MASK, clocking4); 2415 WM8962_SYSCLK_RATE_MASK, clocking4);
2989 2416
@@ -3042,9 +2469,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
3042static int wm8962_set_bias_level(struct snd_soc_codec *codec, 2469static int wm8962_set_bias_level(struct snd_soc_codec *codec,
3043 enum snd_soc_bias_level level) 2470 enum snd_soc_bias_level level)
3044{ 2471{
3045 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3046 int ret;
3047
3048 if (level == codec->dapm.bias_level) 2472 if (level == codec->dapm.bias_level)
3049 return 0; 2473 return 0;
3050 2474
@@ -3061,51 +2485,15 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
3061 break; 2485 break;
3062 2486
3063 case SND_SOC_BIAS_STANDBY: 2487 case SND_SOC_BIAS_STANDBY:
3064 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
3065 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3066 wm8962->supplies);
3067 if (ret != 0) {
3068 dev_err(codec->dev,
3069 "Failed to enable supplies: %d\n",
3070 ret);
3071 return ret;
3072 }
3073
3074 regcache_cache_only(wm8962->regmap, false);
3075 regcache_sync(wm8962->regmap);
3076
3077 snd_soc_update_bits(codec, WM8962_ANTI_POP,
3078 WM8962_STARTUP_BIAS_ENA |
3079 WM8962_VMID_BUF_ENA,
3080 WM8962_STARTUP_BIAS_ENA |
3081 WM8962_VMID_BUF_ENA);
3082
3083 /* Bias enable at 2*50k for ramp */
3084 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
3085 WM8962_VMID_SEL_MASK |
3086 WM8962_BIAS_ENA,
3087 WM8962_BIAS_ENA | 0x180);
3088
3089 msleep(5);
3090 }
3091
3092 /* VMID 2*250k */ 2488 /* VMID 2*250k */
3093 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, 2489 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
3094 WM8962_VMID_SEL_MASK, 0x100); 2490 WM8962_VMID_SEL_MASK, 0x100);
3095 break; 2491 break;
3096 2492
3097 case SND_SOC_BIAS_OFF: 2493 case SND_SOC_BIAS_OFF:
3098 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
3099 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
3100
3101 snd_soc_update_bits(codec, WM8962_ANTI_POP,
3102 WM8962_STARTUP_BIAS_ENA |
3103 WM8962_VMID_BUF_ENA, 0);
3104
3105 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
3106 wm8962->supplies);
3107 break; 2494 break;
3108 } 2495 }
2496
3109 codec->dapm.bias_level = level; 2497 codec->dapm.bias_level = level;
3110 return 0; 2498 return 0;
3111} 2499}
@@ -3139,6 +2527,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
3139 int adctl3 = 0; 2527 int adctl3 = 0;
3140 2528
3141 wm8962->bclk = snd_soc_params_to_bclk(params); 2529 wm8962->bclk = snd_soc_params_to_bclk(params);
2530 if (params_channels(params) == 1)
2531 wm8962->bclk *= 2;
2532
3142 wm8962->lrclk = params_rate(params); 2533 wm8962->lrclk = params_rate(params);
3143 2534
3144 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { 2535 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
@@ -3177,7 +2568,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
3177 WM8962_SAMPLE_RATE_INT_MODE | 2568 WM8962_SAMPLE_RATE_INT_MODE |
3178 WM8962_SAMPLE_RATE_MASK, adctl3); 2569 WM8962_SAMPLE_RATE_MASK, adctl3);
3179 2570
3180 wm8962_configure_bclk(codec); 2571 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
2572 wm8962_configure_bclk(codec);
3181 2573
3182 return 0; 2574 return 0;
3183} 2575}
@@ -3207,6 +2599,8 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
3207 2599
3208 wm8962->sysclk_rate = freq; 2600 wm8962->sysclk_rate = freq;
3209 2601
2602 wm8962_configure_bclk(codec);
2603
3210 return 0; 2604 return 0;
3211} 2605}
3212 2606
@@ -3385,8 +2779,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3385 struct _fll_div fll_div; 2779 struct _fll_div fll_div;
3386 unsigned long timeout; 2780 unsigned long timeout;
3387 int ret; 2781 int ret;
3388 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; 2782 int fll1 = 0;
3389 int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
3390 2783
3391 /* Any change? */ 2784 /* Any change? */
3392 if (source == wm8962->fll_src && Fref == wm8962->fll_fref && 2785 if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -3402,6 +2795,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3402 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2795 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
3403 WM8962_FLL_ENA, 0); 2796 WM8962_FLL_ENA, 0);
3404 2797
2798 pm_runtime_put(codec->dev);
2799
3405 return 0; 2800 return 0;
3406 } 2801 }
3407 2802
@@ -3409,6 +2804,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3409 if (ret != 0) 2804 if (ret != 0)
3410 return ret; 2805 return ret;
3411 2806
2807 /* Parameters good, disable so we can reprogram */
2808 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
2809
3412 switch (fll_id) { 2810 switch (fll_id) {
3413 case WM8962_FLL_MCLK: 2811 case WM8962_FLL_MCLK:
3414 case WM8962_FLL_BCLK: 2812 case WM8962_FLL_BCLK:
@@ -3447,12 +2845,11 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3447 2845
3448 try_wait_for_completion(&wm8962->fll_lock); 2846 try_wait_for_completion(&wm8962->fll_lock);
3449 2847
3450 if (sysclk) 2848 pm_runtime_get_sync(codec->dev);
3451 fll1 |= WM8962_FLL_ENA;
3452 2849
3453 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2850 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
3454 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | 2851 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
3455 WM8962_FLL_ENA, fll1); 2852 WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
3456 2853
3457 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2854 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
3458 2855
@@ -3513,14 +2910,14 @@ static struct snd_soc_dai_driver wm8962_dai = {
3513 .name = "wm8962", 2910 .name = "wm8962",
3514 .playback = { 2911 .playback = {
3515 .stream_name = "Playback", 2912 .stream_name = "Playback",
3516 .channels_min = 2, 2913 .channels_min = 1,
3517 .channels_max = 2, 2914 .channels_max = 2,
3518 .rates = WM8962_RATES, 2915 .rates = WM8962_RATES,
3519 .formats = WM8962_FORMATS, 2916 .formats = WM8962_FORMATS,
3520 }, 2917 },
3521 .capture = { 2918 .capture = {
3522 .stream_name = "Capture", 2919 .stream_name = "Capture",
3523 .channels_min = 2, 2920 .channels_min = 1,
3524 .channels_max = 2, 2921 .channels_max = 2,
3525 .rates = WM8962_RATES, 2922 .rates = WM8962_RATES,
3526 .formats = WM8962_FORMATS, 2923 .formats = WM8962_FORMATS,
@@ -3561,54 +2958,73 @@ static void wm8962_mic_work(struct work_struct *work)
3561 2958
3562static irqreturn_t wm8962_irq(int irq, void *data) 2959static irqreturn_t wm8962_irq(int irq, void *data)
3563{ 2960{
3564 struct snd_soc_codec *codec = data; 2961 struct device *dev = data;
3565 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2962 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3566 int mask; 2963 unsigned int mask;
3567 int active; 2964 unsigned int active;
3568 int reg; 2965 int reg, ret;
3569 2966
3570 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 2967 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
2968 &mask);
2969 if (ret != 0) {
2970 dev_err(dev, "Failed to read interrupt mask: %d\n",
2971 ret);
2972 return IRQ_NONE;
2973 }
2974
2975 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
2976 if (ret != 0) {
2977 dev_err(dev, "Failed to read interrupt: %d\n", ret);
2978 return IRQ_NONE;
2979 }
3571 2980
3572 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3573 active &= ~mask; 2981 active &= ~mask;
3574 2982
3575 if (!active) 2983 if (!active)
3576 return IRQ_NONE; 2984 return IRQ_NONE;
3577 2985
3578 /* Acknowledge the interrupts */ 2986 /* Acknowledge the interrupts */
3579 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 2987 ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
2988 if (ret != 0)
2989 dev_warn(dev, "Failed to ack interrupt: %d\n", ret);
3580 2990
3581 if (active & WM8962_FLL_LOCK_EINT) { 2991 if (active & WM8962_FLL_LOCK_EINT) {
3582 dev_dbg(codec->dev, "FLL locked\n"); 2992 dev_dbg(dev, "FLL locked\n");
3583 complete(&wm8962->fll_lock); 2993 complete(&wm8962->fll_lock);
3584 } 2994 }
3585 2995
3586 if (active & WM8962_FIFOS_ERR_EINT) 2996 if (active & WM8962_FIFOS_ERR_EINT)
3587 dev_err(codec->dev, "FIFO error\n"); 2997 dev_err(dev, "FIFO error\n");
3588 2998
3589 if (active & WM8962_TEMP_SHUT_EINT) { 2999 if (active & WM8962_TEMP_SHUT_EINT) {
3590 dev_crit(codec->dev, "Thermal shutdown\n"); 3000 dev_crit(dev, "Thermal shutdown\n");
3591 3001
3592 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); 3002 ret = regmap_read(wm8962->regmap,
3003 WM8962_THERMAL_SHUTDOWN_STATUS, &reg);
3004 if (ret != 0) {
3005 dev_warn(dev, "Failed to read thermal status: %d\n",
3006 ret);
3007 reg = 0;
3008 }
3593 3009
3594 if (reg & WM8962_TEMP_ERR_HP) 3010 if (reg & WM8962_TEMP_ERR_HP)
3595 dev_crit(codec->dev, "Headphone thermal error\n"); 3011 dev_crit(dev, "Headphone thermal error\n");
3596 if (reg & WM8962_TEMP_WARN_HP) 3012 if (reg & WM8962_TEMP_WARN_HP)
3597 dev_crit(codec->dev, "Headphone thermal warning\n"); 3013 dev_crit(dev, "Headphone thermal warning\n");
3598 if (reg & WM8962_TEMP_ERR_SPK) 3014 if (reg & WM8962_TEMP_ERR_SPK)
3599 dev_crit(codec->dev, "Speaker thermal error\n"); 3015 dev_crit(dev, "Speaker thermal error\n");
3600 if (reg & WM8962_TEMP_WARN_SPK) 3016 if (reg & WM8962_TEMP_WARN_SPK)
3601 dev_crit(codec->dev, "Speaker thermal warning\n"); 3017 dev_crit(dev, "Speaker thermal warning\n");
3602 } 3018 }
3603 3019
3604 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3020 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3605 dev_dbg(codec->dev, "Microphone event detected\n"); 3021 dev_dbg(dev, "Microphone event detected\n");
3606 3022
3607#ifndef CONFIG_SND_SOC_WM8962_MODULE 3023#ifndef CONFIG_SND_SOC_WM8962_MODULE
3608 trace_snd_soc_jack_irq(dev_name(codec->dev)); 3024 trace_snd_soc_jack_irq(dev_name(dev));
3609#endif 3025#endif
3610 3026
3611 pm_wakeup_event(codec->dev, 300); 3027 pm_wakeup_event(dev, 300);
3612 3028
3613 schedule_delayed_work(&wm8962->mic_work, 3029 schedule_delayed_work(&wm8962->mic_work,
3614 msecs_to_jiffies(250)); 3030 msecs_to_jiffies(250));
@@ -4089,7 +3505,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
4089 3505
4090 ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, 3506 ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
4091 trigger | IRQF_ONESHOT, 3507 trigger | IRQF_ONESHOT,
4092 "wm8962", codec); 3508 "wm8962", codec->dev);
4093 if (ret != 0) { 3509 if (ret != 0) {
4094 dev_err(codec->dev, "Failed to request IRQ %d: %d\n", 3510 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
4095 wm8962->irq, ret); 3511 wm8962->irq, ret);
@@ -4127,20 +3543,19 @@ static int wm8962_remove(struct snd_soc_codec *codec)
4127 return 0; 3543 return 0;
4128} 3544}
4129 3545
4130static int wm8962_soc_volatile(struct snd_soc_codec *codec,
4131 unsigned int reg)
4132{
4133 return true;
4134}
4135
4136
4137static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { 3546static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
4138 .probe = wm8962_probe, 3547 .probe = wm8962_probe,
4139 .remove = wm8962_remove, 3548 .remove = wm8962_remove,
4140 .set_bias_level = wm8962_set_bias_level, 3549 .set_bias_level = wm8962_set_bias_level,
4141 .set_pll = wm8962_set_fll, 3550 .set_pll = wm8962_set_fll,
4142 .reg_cache_size = WM8962_MAX_REGISTER, 3551 .idle_bias_off = true,
4143 .volatile_register = wm8962_soc_volatile, 3552};
3553
3554/* Improve power consumption for IN4 DC measurement mode */
3555static const struct reg_default wm8962_dc_measure[] = {
3556 { 0xfd, 0x1 },
3557 { 0xcc, 0x40 },
3558 { 0xfd, 0 },
4144}; 3559};
4145 3560
4146static const struct regmap_config wm8962_regmap = { 3561static const struct regmap_config wm8962_regmap = {
@@ -4155,10 +3570,10 @@ static const struct regmap_config wm8962_regmap = {
4155 .cache_type = REGCACHE_RBTREE, 3570 .cache_type = REGCACHE_RBTREE,
4156}; 3571};
4157 3572
4158#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4159static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, 3573static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
4160 const struct i2c_device_id *id) 3574 const struct i2c_device_id *id)
4161{ 3575{
3576 struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev);
4162 struct wm8962_priv *wm8962; 3577 struct wm8962_priv *wm8962;
4163 unsigned int reg; 3578 unsigned int reg;
4164 int ret, i; 3579 int ret, i;
@@ -4212,7 +3627,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
4212 } 3627 }
4213 if (reg != 0x6243) { 3628 if (reg != 0x6243) {
4214 dev_err(&i2c->dev, 3629 dev_err(&i2c->dev,
4215 "Device is not a WM8962, ID %x != 0x6243\n", ret); 3630 "Device is not a WM8962, ID %x != 0x6243\n", reg);
4216 ret = -EINVAL; 3631 ret = -EINVAL;
4217 goto err_regmap; 3632 goto err_regmap;
4218 } 3633 }
@@ -4237,7 +3652,18 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
4237 goto err_regmap; 3652 goto err_regmap;
4238 } 3653 }
4239 3654
4240 regcache_cache_only(wm8962->regmap, true); 3655 if (pdata && pdata->in4_dc_measure) {
3656 ret = regmap_register_patch(wm8962->regmap,
3657 wm8962_dc_measure,
3658 ARRAY_SIZE(wm8962_dc_measure));
3659 if (ret != 0)
3660 dev_err(&i2c->dev,
3661 "Failed to configure for DC mesurement: %d\n",
3662 ret);
3663 }
3664
3665 pm_runtime_enable(&i2c->dev);
3666 pm_request_idle(&i2c->dev);
4241 3667
4242 ret = snd_soc_register_codec(&i2c->dev, 3668 ret = snd_soc_register_codec(&i2c->dev,
4243 &soc_codec_dev_wm8962, &wm8962_dai, 1); 3669 &soc_codec_dev_wm8962, &wm8962_dai, 1);
@@ -4269,6 +3695,65 @@ static __devexit int wm8962_i2c_remove(struct i2c_client *client)
4269 return 0; 3695 return 0;
4270} 3696}
4271 3697
3698#ifdef CONFIG_PM_RUNTIME
3699static int wm8962_runtime_resume(struct device *dev)
3700{
3701 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3702 int ret;
3703
3704 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3705 wm8962->supplies);
3706 if (ret != 0) {
3707 dev_err(dev,
3708 "Failed to enable supplies: %d\n", ret);
3709 return ret;
3710 }
3711
3712 regcache_cache_only(wm8962->regmap, false);
3713 regcache_sync(wm8962->regmap);
3714
3715 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
3716 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
3717 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
3718
3719 /* Bias enable at 2*50k for ramp */
3720 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3721 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
3722 WM8962_BIAS_ENA | 0x180);
3723
3724 msleep(5);
3725
3726 /* VMID back to 2x250k for standby */
3727 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3728 WM8962_VMID_SEL_MASK, 0x100);
3729
3730 return 0;
3731}
3732
3733static int wm8962_runtime_suspend(struct device *dev)
3734{
3735 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3736
3737 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3738 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
3739
3740 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
3741 WM8962_STARTUP_BIAS_ENA |
3742 WM8962_VMID_BUF_ENA, 0);
3743
3744 regcache_cache_only(wm8962->regmap, true);
3745
3746 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
3747 wm8962->supplies);
3748
3749 return 0;
3750}
3751#endif
3752
3753static struct dev_pm_ops wm8962_pm = {
3754 SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
3755};
3756
4272static const struct i2c_device_id wm8962_i2c_id[] = { 3757static const struct i2c_device_id wm8962_i2c_id[] = {
4273 { "wm8962", 0 }, 3758 { "wm8962", 0 },
4274 { } 3759 { }
@@ -4279,34 +3764,14 @@ static struct i2c_driver wm8962_i2c_driver = {
4279 .driver = { 3764 .driver = {
4280 .name = "wm8962", 3765 .name = "wm8962",
4281 .owner = THIS_MODULE, 3766 .owner = THIS_MODULE,
3767 .pm = &wm8962_pm,
4282 }, 3768 },
4283 .probe = wm8962_i2c_probe, 3769 .probe = wm8962_i2c_probe,
4284 .remove = __devexit_p(wm8962_i2c_remove), 3770 .remove = __devexit_p(wm8962_i2c_remove),
4285 .id_table = wm8962_i2c_id, 3771 .id_table = wm8962_i2c_id,
4286}; 3772};
4287#endif
4288
4289static int __init wm8962_modinit(void)
4290{
4291 int ret;
4292#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4293 ret = i2c_add_driver(&wm8962_i2c_driver);
4294 if (ret != 0) {
4295 printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n",
4296 ret);
4297 }
4298#endif
4299 return 0;
4300}
4301module_init(wm8962_modinit);
4302 3773
4303static void __exit wm8962_exit(void) 3774module_i2c_driver(wm8962_i2c_driver);
4304{
4305#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4306 i2c_del_driver(&wm8962_i2c_driver);
4307#endif
4308}
4309module_exit(wm8962_exit);
4310 3775
4311MODULE_DESCRIPTION("ASoC WM8962 driver"); 3776MODULE_DESCRIPTION("ASoC WM8962 driver");
4312MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3777MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 4af893601f00..28fe59e3ce01 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -252,7 +252,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
252 SND_SOC_DAPM_INPUT("MIC"), 252 SND_SOC_DAPM_INPUT("MIC"),
253}; 253};
254 254
255static const struct snd_soc_dapm_route audio_map[] = { 255static const struct snd_soc_dapm_route wm8971_dapm_routes[] = {
256 /* left mixer */ 256 /* left mixer */
257 {"Left Mixer", "Playback Switch", "Left DAC"}, 257 {"Left Mixer", "Playback Switch", "Left DAC"},
258 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, 258 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
@@ -329,17 +329,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
329 {"Right ADC", NULL, "Right ADC Mux"}, 329 {"Right ADC", NULL, "Right ADC Mux"},
330}; 330};
331 331
332static int wm8971_add_widgets(struct snd_soc_codec *codec)
333{
334 struct snd_soc_dapm_context *dapm = &codec->dapm;
335
336 snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
337 ARRAY_SIZE(wm8971_dapm_widgets));
338 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
339
340 return 0;
341}
342
343struct _coeff_div { 332struct _coeff_div {
344 u32 mclk; 333 u32 mclk;
345 u32 rate; 334 u32 rate;
@@ -659,10 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec)
659 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); 648 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
660 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); 649 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
661 650
662 snd_soc_add_controls(codec, wm8971_snd_controls,
663 ARRAY_SIZE(wm8971_snd_controls));
664 wm8971_add_widgets(codec);
665
666 return ret; 651 return ret;
667} 652}
668 653
@@ -686,16 +671,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
686 .reg_cache_size = ARRAY_SIZE(wm8971_reg), 671 .reg_cache_size = ARRAY_SIZE(wm8971_reg),
687 .reg_word_size = sizeof(u16), 672 .reg_word_size = sizeof(u16),
688 .reg_cache_default = wm8971_reg, 673 .reg_cache_default = wm8971_reg,
674
675 .controls = wm8971_snd_controls,
676 .num_controls = ARRAY_SIZE(wm8971_snd_controls),
677 .dapm_widgets = wm8971_dapm_widgets,
678 .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets),
679 .dapm_routes = wm8971_dapm_routes,
680 .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
689}; 681};
690 682
691#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
692static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, 683static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
693 const struct i2c_device_id *id) 684 const struct i2c_device_id *id)
694{ 685{
695 struct wm8971_priv *wm8971; 686 struct wm8971_priv *wm8971;
696 int ret; 687 int ret;
697 688
698 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL); 689 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
690 GFP_KERNEL);
699 if (wm8971 == NULL) 691 if (wm8971 == NULL)
700 return -ENOMEM; 692 return -ENOMEM;
701 693
@@ -704,15 +696,13 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
704 696
705 ret = snd_soc_register_codec(&i2c->dev, 697 ret = snd_soc_register_codec(&i2c->dev,
706 &soc_codec_dev_wm8971, &wm8971_dai, 1); 698 &soc_codec_dev_wm8971, &wm8971_dai, 1);
707 if (ret < 0) 699
708 kfree(wm8971);
709 return ret; 700 return ret;
710} 701}
711 702
712static __devexit int wm8971_i2c_remove(struct i2c_client *client) 703static __devexit int wm8971_i2c_remove(struct i2c_client *client)
713{ 704{
714 snd_soc_unregister_codec(&client->dev); 705 snd_soc_unregister_codec(&client->dev);
715 kfree(i2c_get_clientdata(client));
716 return 0; 706 return 0;
717} 707}
718 708
@@ -731,27 +721,22 @@ static struct i2c_driver wm8971_i2c_driver = {
731 .remove = __devexit_p(wm8971_i2c_remove), 721 .remove = __devexit_p(wm8971_i2c_remove),
732 .id_table = wm8971_i2c_id, 722 .id_table = wm8971_i2c_id,
733}; 723};
734#endif
735 724
736static int __init wm8971_modinit(void) 725static int __init wm8971_modinit(void)
737{ 726{
738 int ret = 0; 727 int ret = 0;
739#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
740 ret = i2c_add_driver(&wm8971_i2c_driver); 728 ret = i2c_add_driver(&wm8971_i2c_driver);
741 if (ret != 0) { 729 if (ret != 0) {
742 printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", 730 printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
743 ret); 731 ret);
744 } 732 }
745#endif
746 return ret; 733 return ret;
747} 734}
748module_init(wm8971_modinit); 735module_init(wm8971_modinit);
749 736
750static void __exit wm8971_exit(void) 737static void __exit wm8971_exit(void)
751{ 738{
752#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
753 i2c_del_driver(&wm8971_i2c_driver); 739 i2c_del_driver(&wm8971_i2c_driver);
754#endif
755} 740}
756module_exit(wm8971_exit); 741module_exit(wm8971_exit);
757 742
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 4a6a7b5a61ba..d93c03f820c9 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -48,10 +48,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
48#define WM8974_POWER1_BIASEN 0x08 48#define WM8974_POWER1_BIASEN 0x08
49#define WM8974_POWER1_BUFIOEN 0x04 49#define WM8974_POWER1_BUFIOEN 0x04
50 50
51struct wm8974_priv {
52 enum snd_soc_control_type control_type;
53};
54
55#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) 51#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
56 52
57static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; 53static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -235,7 +231,7 @@ SND_SOC_DAPM_OUTPUT("SPKOUTP"),
235SND_SOC_DAPM_OUTPUT("SPKOUTN"), 231SND_SOC_DAPM_OUTPUT("SPKOUTN"),
236}; 232};
237 233
238static const struct snd_soc_dapm_route audio_map[] = { 234static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
239 /* Mono output mixer */ 235 /* Mono output mixer */
240 {"Mono Mixer", "PCM Playback Switch", "DAC"}, 236 {"Mono Mixer", "PCM Playback Switch", "DAC"},
241 {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, 237 {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
@@ -269,17 +265,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
269 {"Aux Input", NULL, "AUX"}, 265 {"Aux Input", NULL, "AUX"},
270}; 266};
271 267
272static int wm8974_add_widgets(struct snd_soc_codec *codec)
273{
274 struct snd_soc_dapm_context *dapm = &codec->dapm;
275
276 snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
277 ARRAY_SIZE(wm8974_dapm_widgets));
278 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
279
280 return 0;
281}
282
283struct pll_ { 268struct pll_ {
284 unsigned int pre_div:1; 269 unsigned int pre_div:1;
285 unsigned int n:4; 270 unsigned int n:4;
@@ -611,9 +596,6 @@ static int wm8974_probe(struct snd_soc_codec *codec)
611 } 596 }
612 597
613 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 598 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
614 snd_soc_add_controls(codec, wm8974_snd_controls,
615 ARRAY_SIZE(wm8974_snd_controls));
616 wm8974_add_widgets(codec);
617 599
618 return ret; 600 return ret;
619} 601}
@@ -634,32 +616,30 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
634 .reg_cache_size = ARRAY_SIZE(wm8974_reg), 616 .reg_cache_size = ARRAY_SIZE(wm8974_reg),
635 .reg_word_size = sizeof(u16), 617 .reg_word_size = sizeof(u16),
636 .reg_cache_default = wm8974_reg, 618 .reg_cache_default = wm8974_reg,
619
620 .controls = wm8974_snd_controls,
621 .num_controls = ARRAY_SIZE(wm8974_snd_controls),
622 .dapm_widgets = wm8974_dapm_widgets,
623 .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
624 .dapm_routes = wm8974_dapm_routes,
625 .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
637}; 626};
638 627
639#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
640static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, 628static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
641 const struct i2c_device_id *id) 629 const struct i2c_device_id *id)
642{ 630{
643 struct wm8974_priv *wm8974;
644 int ret; 631 int ret;
645 632
646 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
647 if (wm8974 == NULL)
648 return -ENOMEM;
649
650 i2c_set_clientdata(i2c, wm8974);
651
652 ret = snd_soc_register_codec(&i2c->dev, 633 ret = snd_soc_register_codec(&i2c->dev,
653 &soc_codec_dev_wm8974, &wm8974_dai, 1); 634 &soc_codec_dev_wm8974, &wm8974_dai, 1);
654 if (ret < 0) 635
655 kfree(wm8974);
656 return ret; 636 return ret;
657} 637}
658 638
659static __devexit int wm8974_i2c_remove(struct i2c_client *client) 639static __devexit int wm8974_i2c_remove(struct i2c_client *client)
660{ 640{
661 snd_soc_unregister_codec(&client->dev); 641 snd_soc_unregister_codec(&client->dev);
662 kfree(i2c_get_clientdata(client)); 642
663 return 0; 643 return 0;
664} 644}
665 645
@@ -678,27 +658,22 @@ static struct i2c_driver wm8974_i2c_driver = {
678 .remove = __devexit_p(wm8974_i2c_remove), 658 .remove = __devexit_p(wm8974_i2c_remove),
679 .id_table = wm8974_i2c_id, 659 .id_table = wm8974_i2c_id,
680}; 660};
681#endif
682 661
683static int __init wm8974_modinit(void) 662static int __init wm8974_modinit(void)
684{ 663{
685 int ret = 0; 664 int ret = 0;
686#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
687 ret = i2c_add_driver(&wm8974_i2c_driver); 665 ret = i2c_add_driver(&wm8974_i2c_driver);
688 if (ret != 0) { 666 if (ret != 0) {
689 printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", 667 printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
690 ret); 668 ret);
691 } 669 }
692#endif
693 return ret; 670 return ret;
694} 671}
695module_init(wm8974_modinit); 672module_init(wm8974_modinit);
696 673
697static void __exit wm8974_exit(void) 674static void __exit wm8974_exit(void)
698{ 675{
699#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
700 i2c_del_driver(&wm8974_i2c_driver); 676 i2c_del_driver(&wm8974_i2c_driver);
701#endif
702} 677}
703module_exit(wm8974_exit); 678module_exit(wm8974_exit);
704 679
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 85d514d63a4c..72d5fdcd3cc2 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -29,28 +30,74 @@
29 30
30#include "wm8978.h" 31#include "wm8978.h"
31 32
32/* wm8978 register cache. Note that register 0 is not included in the cache. */ 33static const struct reg_default wm8978_reg_defaults[] = {
33static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { 34 { 1, 0x0000 },
34 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ 35 { 2, 0x0000 },
35 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */ 36 { 3, 0x0000 },
36 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */ 37 { 4, 0x0050 },
37 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */ 38 { 5, 0x0000 },
38 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */ 39 { 6, 0x0140 },
39 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */ 40 { 7, 0x0000 },
40 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */ 41 { 8, 0x0000 },
41 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */ 42 { 9, 0x0000 },
42 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */ 43 { 10, 0x0000 },
43 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */ 44 { 11, 0x00ff },
44 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */ 45 { 12, 0x00ff },
45 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */ 46 { 13, 0x0000 },
46 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */ 47 { 14, 0x0100 },
47 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */ 48 { 15, 0x00ff },
48 0x0001, 0x0001, /* 0x38...0x3b */ 49 { 16, 0x00ff },
50 { 17, 0x0000 },
51 { 18, 0x012c },
52 { 19, 0x002c },
53 { 20, 0x002c },
54 { 21, 0x002c },
55 { 22, 0x002c },
56 { 23, 0x0000 },
57 { 24, 0x0032 },
58 { 25, 0x0000 },
59 { 26, 0x0000 },
60 { 27, 0x0000 },
61 { 28, 0x0000 },
62 { 29, 0x0000 },
63 { 30, 0x0000 },
64 { 31, 0x0000 },
65 { 32, 0x0038 },
66 { 33, 0x000b },
67 { 34, 0x0032 },
68 { 35, 0x0000 },
69 { 36, 0x0008 },
70 { 37, 0x000c },
71 { 38, 0x0093 },
72 { 39, 0x00e9 },
73 { 40, 0x0000 },
74 { 41, 0x0000 },
75 { 42, 0x0000 },
76 { 43, 0x0000 },
77 { 44, 0x0033 },
78 { 45, 0x0010 },
79 { 46, 0x0010 },
80 { 47, 0x0100 },
81 { 48, 0x0100 },
82 { 49, 0x0002 },
83 { 50, 0x0001 },
84 { 51, 0x0001 },
85 { 52, 0x0039 },
86 { 53, 0x0039 },
87 { 54, 0x0039 },
88 { 55, 0x0039 },
89 { 56, 0x0001 },
90 { 57, 0x0001 },
49}; 91};
50 92
93static bool wm8978_volatile(struct device *dev, unsigned int reg)
94{
95 return reg == WM8978_RESET;
96}
97
51/* codec private data */ 98/* codec private data */
52struct wm8978_priv { 99struct wm8978_priv {
53 enum snd_soc_control_type control_type; 100 struct regmap *regmap;
54 unsigned int f_pllout; 101 unsigned int f_pllout;
55 unsigned int f_mclk; 102 unsigned int f_mclk;
56 unsigned int f_256fs; 103 unsigned int f_256fs;
@@ -303,7 +350,7 @@ static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
303 SND_SOC_DAPM_OUTPUT("RSPK"), 350 SND_SOC_DAPM_OUTPUT("RSPK"),
304}; 351};
305 352
306static const struct snd_soc_dapm_route audio_map[] = { 353static const struct snd_soc_dapm_route wm8978_dapm_routes[] = {
307 /* Output mixer */ 354 /* Output mixer */
308 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"}, 355 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
309 {"Right Output Mixer", "Aux Playback Switch", "RAUX"}, 356 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
@@ -352,18 +399,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
352 {"Left Input Mixer", "MicP Switch", "LMICP"}, 399 {"Left Input Mixer", "MicP Switch", "LMICP"},
353}; 400};
354 401
355static int wm8978_add_widgets(struct snd_soc_codec *codec)
356{
357 struct snd_soc_dapm_context *dapm = &codec->dapm;
358
359 snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
360 ARRAY_SIZE(wm8978_dapm_widgets));
361 /* set up the WM8978 audio map */
362 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
363
364 return 0;
365}
366
367/* PLL divisors */ 402/* PLL divisors */
368struct wm8978_pll_div { 403struct wm8978_pll_div {
369 u32 k; 404 u32 k;
@@ -894,26 +929,23 @@ static struct snd_soc_dai_driver wm8978_dai = {
894 929
895static int wm8978_suspend(struct snd_soc_codec *codec) 930static int wm8978_suspend(struct snd_soc_codec *codec)
896{ 931{
932 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
933
897 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); 934 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
898 /* Also switch PLL off */ 935 /* Also switch PLL off */
899 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); 936 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
900 937
938 regcache_mark_dirty(wm8978->regmap);
939
901 return 0; 940 return 0;
902} 941}
903 942
904static int wm8978_resume(struct snd_soc_codec *codec) 943static int wm8978_resume(struct snd_soc_codec *codec)
905{ 944{
906 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 945 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
907 int i;
908 u16 *cache = codec->reg_cache;
909 946
910 /* Sync reg_cache with the hardware */ 947 /* Sync reg_cache with the hardware */
911 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) { 948 regcache_sync(wm8978->regmap);
912 if (i == WM8978_RESET)
913 continue;
914 if (cache[i] != wm8978_reg[i])
915 snd_soc_write(codec, i, cache[i]);
916 }
917 949
918 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 950 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
919 951
@@ -953,7 +985,8 @@ static int wm8978_probe(struct snd_soc_codec *codec)
953 * default hardware setting 985 * default hardware setting
954 */ 986 */
955 wm8978->sysclk = WM8978_PLL; 987 wm8978->sysclk = WM8978_PLL;
956 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); 988 codec->control_data = wm8978->regmap;
989 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
957 if (ret < 0) { 990 if (ret < 0) {
958 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 991 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
959 return ret; 992 return ret;
@@ -967,19 +1000,8 @@ static int wm8978_probe(struct snd_soc_codec *codec)
967 for (i = 0; i < ARRAY_SIZE(update_reg); i++) 1000 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
968 snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100); 1001 snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
969 1002
970 /* Reset the codec */
971 ret = snd_soc_write(codec, WM8978_RESET, 0);
972 if (ret < 0) {
973 dev_err(codec->dev, "Failed to issue reset\n");
974 return ret;
975 }
976
977 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1003 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
978 1004
979 snd_soc_add_controls(codec, wm8978_snd_controls,
980 ARRAY_SIZE(wm8978_snd_controls));
981 wm8978_add_widgets(codec);
982
983 return 0; 1005 return 0;
984} 1006}
985 1007
@@ -996,35 +1018,75 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
996 .suspend = wm8978_suspend, 1018 .suspend = wm8978_suspend,
997 .resume = wm8978_resume, 1019 .resume = wm8978_resume,
998 .set_bias_level = wm8978_set_bias_level, 1020 .set_bias_level = wm8978_set_bias_level,
999 .reg_cache_size = ARRAY_SIZE(wm8978_reg), 1021
1000 .reg_word_size = sizeof(u16), 1022 .controls = wm8978_snd_controls,
1001 .reg_cache_default = wm8978_reg, 1023 .num_controls = ARRAY_SIZE(wm8978_snd_controls),
1024 .dapm_widgets = wm8978_dapm_widgets,
1025 .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets),
1026 .dapm_routes = wm8978_dapm_routes,
1027 .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes),
1028};
1029
1030static const struct regmap_config wm8978_regmap_config = {
1031 .reg_bits = 7,
1032 .val_bits = 9,
1033
1034 .max_register = WM8978_MAX_REGISTER,
1035 .volatile_reg = wm8978_volatile,
1036
1037 .cache_type = REGCACHE_RBTREE,
1038 .reg_defaults = wm8978_reg_defaults,
1039 .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults),
1002}; 1040};
1003 1041
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1005static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, 1042static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1006 const struct i2c_device_id *id) 1043 const struct i2c_device_id *id)
1007{ 1044{
1008 struct wm8978_priv *wm8978; 1045 struct wm8978_priv *wm8978;
1009 int ret; 1046 int ret;
1010 1047
1011 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL); 1048 wm8978 = devm_kzalloc(&i2c->dev, sizeof(struct wm8978_priv),
1049 GFP_KERNEL);
1012 if (wm8978 == NULL) 1050 if (wm8978 == NULL)
1013 return -ENOMEM; 1051 return -ENOMEM;
1014 1052
1053 wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config);
1054 if (IS_ERR(wm8978->regmap)) {
1055 ret = PTR_ERR(wm8978->regmap);
1056 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
1057 return ret;
1058 }
1059
1015 i2c_set_clientdata(i2c, wm8978); 1060 i2c_set_clientdata(i2c, wm8978);
1016 1061
1062 /* Reset the codec */
1063 ret = regmap_write(wm8978->regmap, WM8978_RESET, 0);
1064 if (ret != 0) {
1065 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
1066 goto err;
1067 }
1068
1017 ret = snd_soc_register_codec(&i2c->dev, 1069 ret = snd_soc_register_codec(&i2c->dev,
1018 &soc_codec_dev_wm8978, &wm8978_dai, 1); 1070 &soc_codec_dev_wm8978, &wm8978_dai, 1);
1019 if (ret < 0) 1071 if (ret != 0) {
1020 kfree(wm8978); 1072 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1073 goto err;
1074 }
1075
1076 return 0;
1077
1078err:
1079 regmap_exit(wm8978->regmap);
1021 return ret; 1080 return ret;
1022} 1081}
1023 1082
1024static __devexit int wm8978_i2c_remove(struct i2c_client *client) 1083static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1025{ 1084{
1085 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1086
1026 snd_soc_unregister_codec(&client->dev); 1087 snd_soc_unregister_codec(&client->dev);
1027 kfree(i2c_get_clientdata(client)); 1088 regmap_exit(wm8978->regmap);
1089
1028 return 0; 1090 return 0;
1029} 1091}
1030 1092
@@ -1043,27 +1105,22 @@ static struct i2c_driver wm8978_i2c_driver = {
1043 .remove = __devexit_p(wm8978_i2c_remove), 1105 .remove = __devexit_p(wm8978_i2c_remove),
1044 .id_table = wm8978_i2c_id, 1106 .id_table = wm8978_i2c_id,
1045}; 1107};
1046#endif
1047 1108
1048static int __init wm8978_modinit(void) 1109static int __init wm8978_modinit(void)
1049{ 1110{
1050 int ret = 0; 1111 int ret = 0;
1051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1052 ret = i2c_add_driver(&wm8978_i2c_driver); 1112 ret = i2c_add_driver(&wm8978_i2c_driver);
1053 if (ret != 0) { 1113 if (ret != 0) {
1054 printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", 1114 printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
1055 ret); 1115 ret);
1056 } 1116 }
1057#endif
1058 return ret; 1117 return ret;
1059} 1118}
1060module_init(wm8978_modinit); 1119module_init(wm8978_modinit);
1061 1120
1062static void __exit wm8978_exit(void) 1121static void __exit wm8978_exit(void)
1063{ 1122{
1064#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1065 i2c_del_driver(&wm8978_i2c_driver); 1123 i2c_del_driver(&wm8978_i2c_driver);
1066#endif
1067} 1124}
1068module_exit(wm8978_exit); 1125module_exit(wm8978_exit);
1069 1126
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
index c75525b7f154..6ae43495b7cf 100644
--- a/sound/soc/codecs/wm8978.h
+++ b/sound/soc/codecs/wm8978.h
@@ -67,6 +67,8 @@
67#define WM8978_OUT3_MIXER_CONTROL 0x38 67#define WM8978_OUT3_MIXER_CONTROL 0x38
68#define WM8978_OUT4_MIXER_CONTROL 0x39 68#define WM8978_OUT4_MIXER_CONTROL 0x39
69 69
70#define WM8978_MAX_REGISTER 0x39
71
70#define WM8978_CACHEREGNUM 58 72#define WM8978_CACHEREGNUM 58
71 73
72/* Clock divider Id's */ 74/* Clock divider Id's */
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index cebde568d191..367388fdc486 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -249,9 +249,6 @@ static const char *eq5_cutoff_text[] = {
249static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, 249static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,
250 eq5_cutoff_text); 250 eq5_cutoff_text);
251 251
252static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
253static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
254
255static const char *depth_3d_text[] = { 252static const char *depth_3d_text[] = {
256 "Off", 253 "Off",
257 "6.67%", 254 "6.67%",
@@ -369,8 +366,6 @@ static const struct snd_kcontrol_new wm8983_snd_controls[] = {
369 SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), 366 SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
370 367
371 SOC_ENUM("3D Depth", depth_3d), 368 SOC_ENUM("3D Depth", depth_3d),
372
373 SOC_ENUM("Speaker Mode", speaker_mode)
374}; 369};
375 370
376static const struct snd_kcontrol_new left_out_mixer[] = { 371static const struct snd_kcontrol_new left_out_mixer[] = {
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index c0c86b3c6adf..14f666398d0c 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -19,6 +19,7 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
23#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -39,73 +40,127 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
39 "AVDD2" 40 "AVDD2"
40}; 41};
41 42
42static const u16 wm8985_reg_defs[] = { 43static const struct reg_default wm8985_reg_defaults[] = {
43 0x0000, /* R0 - Software Reset */ 44 { 1, 0x0000 }, /* R1 - Power management 1 */
44 0x0000, /* R1 - Power management 1 */ 45 { 2, 0x0000 }, /* R2 - Power management 2 */
45 0x0000, /* R2 - Power management 2 */ 46 { 3, 0x0000 }, /* R3 - Power management 3 */
46 0x0000, /* R3 - Power management 3 */ 47 { 4, 0x0050 }, /* R4 - Audio Interface */
47 0x0050, /* R4 - Audio Interface */ 48 { 5, 0x0000 }, /* R5 - Companding control */
48 0x0000, /* R5 - Companding control */ 49 { 6, 0x0140 }, /* R6 - Clock Gen control */
49 0x0140, /* R6 - Clock Gen control */ 50 { 7, 0x0000 }, /* R7 - Additional control */
50 0x0000, /* R7 - Additional control */ 51 { 8, 0x0000 }, /* R8 - GPIO Control */
51 0x0000, /* R8 - GPIO Control */ 52 { 9, 0x0000 }, /* R9 - Jack Detect Control 1 */
52 0x0000, /* R9 - Jack Detect Control 1 */ 53 { 10, 0x0000 }, /* R10 - DAC Control */
53 0x0000, /* R10 - DAC Control */ 54 { 11, 0x00FF }, /* R11 - Left DAC digital Vol */
54 0x00FF, /* R11 - Left DAC digital Vol */ 55 { 12, 0x00FF }, /* R12 - Right DAC digital vol */
55 0x00FF, /* R12 - Right DAC digital vol */ 56 { 13, 0x0000 }, /* R13 - Jack Detect Control 2 */
56 0x0000, /* R13 - Jack Detect Control 2 */ 57 { 14, 0x0100 }, /* R14 - ADC Control */
57 0x0100, /* R14 - ADC Control */ 58 { 15, 0x00FF }, /* R15 - Left ADC Digital Vol */
58 0x00FF, /* R15 - Left ADC Digital Vol */ 59 { 16, 0x00FF }, /* R16 - Right ADC Digital Vol */
59 0x00FF, /* R16 - Right ADC Digital Vol */ 60 { 18, 0x012C }, /* R18 - EQ1 - low shelf */
60 0x0000, /* R17 */ 61 { 19, 0x002C }, /* R19 - EQ2 - peak 1 */
61 0x012C, /* R18 - EQ1 - low shelf */ 62 { 20, 0x002C }, /* R20 - EQ3 - peak 2 */
62 0x002C, /* R19 - EQ2 - peak 1 */ 63 { 21, 0x002C }, /* R21 - EQ4 - peak 3 */
63 0x002C, /* R20 - EQ3 - peak 2 */ 64 { 22, 0x002C }, /* R22 - EQ5 - high shelf */
64 0x002C, /* R21 - EQ4 - peak 3 */ 65 { 24, 0x0032 }, /* R24 - DAC Limiter 1 */
65 0x002C, /* R22 - EQ5 - high shelf */ 66 { 25, 0x0000 }, /* R25 - DAC Limiter 2 */
66 0x0000, /* R23 */ 67 { 27, 0x0000 }, /* R27 - Notch Filter 1 */
67 0x0032, /* R24 - DAC Limiter 1 */ 68 { 28, 0x0000 }, /* R28 - Notch Filter 2 */
68 0x0000, /* R25 - DAC Limiter 2 */ 69 { 29, 0x0000 }, /* R29 - Notch Filter 3 */
69 0x0000, /* R26 */ 70 { 30, 0x0000 }, /* R30 - Notch Filter 4 */
70 0x0000, /* R27 - Notch Filter 1 */ 71 { 32, 0x0038 }, /* R32 - ALC control 1 */
71 0x0000, /* R28 - Notch Filter 2 */ 72 { 33, 0x000B }, /* R33 - ALC control 2 */
72 0x0000, /* R29 - Notch Filter 3 */ 73 { 34, 0x0032 }, /* R34 - ALC control 3 */
73 0x0000, /* R30 - Notch Filter 4 */ 74 { 35, 0x0000 }, /* R35 - Noise Gate */
74 0x0000, /* R31 */ 75 { 36, 0x0008 }, /* R36 - PLL N */
75 0x0038, /* R32 - ALC control 1 */ 76 { 37, 0x000C }, /* R37 - PLL K 1 */
76 0x000B, /* R33 - ALC control 2 */ 77 { 38, 0x0093 }, /* R38 - PLL K 2 */
77 0x0032, /* R34 - ALC control 3 */ 78 { 39, 0x00E9 }, /* R39 - PLL K 3 */
78 0x0000, /* R35 - Noise Gate */ 79 { 41, 0x0000 }, /* R41 - 3D control */
79 0x0008, /* R36 - PLL N */ 80 { 42, 0x0000 }, /* R42 - OUT4 to ADC */
80 0x000C, /* R37 - PLL K 1 */ 81 { 43, 0x0000 }, /* R43 - Beep control */
81 0x0093, /* R38 - PLL K 2 */ 82 { 44, 0x0033 }, /* R44 - Input ctrl */
82 0x00E9, /* R39 - PLL K 3 */ 83 { 45, 0x0010 }, /* R45 - Left INP PGA gain ctrl */
83 0x0000, /* R40 */ 84 { 46, 0x0010 }, /* R46 - Right INP PGA gain ctrl */
84 0x0000, /* R41 - 3D control */ 85 { 47, 0x0100 }, /* R47 - Left ADC BOOST ctrl */
85 0x0000, /* R42 - OUT4 to ADC */ 86 { 48, 0x0100 }, /* R48 - Right ADC BOOST ctrl */
86 0x0000, /* R43 - Beep control */ 87 { 49, 0x0002 }, /* R49 - Output ctrl */
87 0x0033, /* R44 - Input ctrl */ 88 { 50, 0x0001 }, /* R50 - Left mixer ctrl */
88 0x0010, /* R45 - Left INP PGA gain ctrl */ 89 { 51, 0x0001 }, /* R51 - Right mixer ctrl */
89 0x0010, /* R46 - Right INP PGA gain ctrl */ 90 { 52, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */
90 0x0100, /* R47 - Left ADC BOOST ctrl */ 91 { 53, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */
91 0x0100, /* R48 - Right ADC BOOST ctrl */ 92 { 54, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */
92 0x0002, /* R49 - Output ctrl */ 93 { 55, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */
93 0x0001, /* R50 - Left mixer ctrl */ 94 { 56, 0x0001 }, /* R56 - OUT3 mixer ctrl */
94 0x0001, /* R51 - Right mixer ctrl */ 95 { 57, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */
95 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ 96 { 60, 0x0004 }, /* R60 - OUTPUT ctrl */
96 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ 97 { 61, 0x0000 }, /* R61 - BIAS CTRL */
97 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */
98 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */
99 0x0001, /* R56 - OUT3 mixer ctrl */
100 0x0001, /* R57 - OUT4 (MONO) mix ctrl */
101 0x0001, /* R58 */
102 0x0000, /* R59 */
103 0x0004, /* R60 - OUTPUT ctrl */
104 0x0000, /* R61 - BIAS CTRL */
105 0x0180, /* R62 */
106 0x0000 /* R63 */
107}; 98};
108 99
100static bool wm8985_writeable(struct device *dev, unsigned int reg)
101{
102 switch (reg) {
103 case WM8985_SOFTWARE_RESET:
104 case WM8985_POWER_MANAGEMENT_1:
105 case WM8985_POWER_MANAGEMENT_2:
106 case WM8985_POWER_MANAGEMENT_3:
107 case WM8985_AUDIO_INTERFACE:
108 case WM8985_COMPANDING_CONTROL:
109 case WM8985_CLOCK_GEN_CONTROL:
110 case WM8985_ADDITIONAL_CONTROL:
111 case WM8985_GPIO_CONTROL:
112 case WM8985_JACK_DETECT_CONTROL_1:
113 case WM8985_DAC_CONTROL:
114 case WM8985_LEFT_DAC_DIGITAL_VOL:
115 case WM8985_RIGHT_DAC_DIGITAL_VOL:
116 case WM8985_JACK_DETECT_CONTROL_2:
117 case WM8985_ADC_CONTROL:
118 case WM8985_LEFT_ADC_DIGITAL_VOL:
119 case WM8985_RIGHT_ADC_DIGITAL_VOL:
120 case WM8985_EQ1_LOW_SHELF:
121 case WM8985_EQ2_PEAK_1:
122 case WM8985_EQ3_PEAK_2:
123 case WM8985_EQ4_PEAK_3:
124 case WM8985_EQ5_HIGH_SHELF:
125 case WM8985_DAC_LIMITER_1:
126 case WM8985_DAC_LIMITER_2:
127 case WM8985_NOTCH_FILTER_1:
128 case WM8985_NOTCH_FILTER_2:
129 case WM8985_NOTCH_FILTER_3:
130 case WM8985_NOTCH_FILTER_4:
131 case WM8985_ALC_CONTROL_1:
132 case WM8985_ALC_CONTROL_2:
133 case WM8985_ALC_CONTROL_3:
134 case WM8985_NOISE_GATE:
135 case WM8985_PLL_N:
136 case WM8985_PLL_K_1:
137 case WM8985_PLL_K_2:
138 case WM8985_PLL_K_3:
139 case WM8985_3D_CONTROL:
140 case WM8985_OUT4_TO_ADC:
141 case WM8985_BEEP_CONTROL:
142 case WM8985_INPUT_CTRL:
143 case WM8985_LEFT_INP_PGA_GAIN_CTRL:
144 case WM8985_RIGHT_INP_PGA_GAIN_CTRL:
145 case WM8985_LEFT_ADC_BOOST_CTRL:
146 case WM8985_RIGHT_ADC_BOOST_CTRL:
147 case WM8985_OUTPUT_CTRL0:
148 case WM8985_LEFT_MIXER_CTRL:
149 case WM8985_RIGHT_MIXER_CTRL:
150 case WM8985_LOUT1_HP_VOLUME_CTRL:
151 case WM8985_ROUT1_HP_VOLUME_CTRL:
152 case WM8985_LOUT2_SPK_VOLUME_CTRL:
153 case WM8985_ROUT2_SPK_VOLUME_CTRL:
154 case WM8985_OUT3_MIXER_CTRL:
155 case WM8985_OUT4_MONO_MIX_CTRL:
156 case WM8985_OUTPUT_CTRL1:
157 case WM8985_BIAS_CTRL:
158 return true;
159 default:
160 return false;
161 }
162}
163
109/* 164/*
110 * latch bit 8 of these registers to ensure instant 165 * latch bit 8 of these registers to ensure instant
111 * volume updates 166 * volume updates
@@ -124,7 +179,7 @@ static const int volume_update_regs[] = {
124}; 179};
125 180
126struct wm8985_priv { 181struct wm8985_priv {
127 enum snd_soc_control_type control_type; 182 struct regmap *regmap;
128 struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; 183 struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
129 unsigned int sysclk; 184 unsigned int sysclk;
130 unsigned int bclk; 185 unsigned int bclk;
@@ -428,7 +483,7 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
428 SND_SOC_DAPM_OUTPUT("SPKR") 483 SND_SOC_DAPM_OUTPUT("SPKR")
429}; 484};
430 485
431static const struct snd_soc_dapm_route audio_map[] = { 486static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
432 { "Right Output Mixer", "PCM Switch", "Right DAC" }, 487 { "Right Output Mixer", "PCM Switch", "Right DAC" },
433 { "Right Output Mixer", "Aux Switch", "AUXR" }, 488 { "Right Output Mixer", "Aux Switch", "AUXR" },
434 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, 489 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
@@ -531,17 +586,6 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
531 return 0; 586 return 0;
532} 587}
533 588
534static int wm8985_add_widgets(struct snd_soc_codec *codec)
535{
536 struct snd_soc_dapm_context *dapm = &codec->dapm;
537
538 snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
539 ARRAY_SIZE(wm8985_dapm_widgets));
540 snd_soc_dapm_add_routes(dapm, audio_map,
541 ARRAY_SIZE(audio_map));
542 return 0;
543}
544
545static int wm8985_reset(struct snd_soc_codec *codec) 589static int wm8985_reset(struct snd_soc_codec *codec)
546{ 590{
547 return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0); 591 return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0);
@@ -845,25 +889,6 @@ static int wm8985_set_sysclk(struct snd_soc_dai *dai,
845 return 0; 889 return 0;
846} 890}
847 891
848static void wm8985_sync_cache(struct snd_soc_codec *codec)
849{
850 short i;
851 u16 *cache;
852
853 if (!codec->cache_sync)
854 return;
855 codec->cache_only = 0;
856 /* restore cache */
857 cache = codec->reg_cache;
858 for (i = 0; i < codec->driver->reg_cache_size; i++) {
859 if (i == WM8985_SOFTWARE_RESET
860 || cache[i] == wm8985_reg_defs[i])
861 continue;
862 snd_soc_write(codec, i, cache[i]);
863 }
864 codec->cache_sync = 0;
865}
866
867static int wm8985_set_bias_level(struct snd_soc_codec *codec, 892static int wm8985_set_bias_level(struct snd_soc_codec *codec,
868 enum snd_soc_bias_level level) 893 enum snd_soc_bias_level level)
869{ 894{
@@ -890,7 +915,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
890 return ret; 915 return ret;
891 } 916 }
892 917
893 wm8985_sync_cache(codec); 918 regcache_sync(wm8985->regmap);
894 919
895 /* enable anti-pop features */ 920 /* enable anti-pop features */
896 snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, 921 snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
@@ -933,7 +958,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
933 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); 958 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0);
934 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); 959 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0);
935 960
936 codec->cache_sync = 1; 961 regcache_mark_dirty(wm8985->regmap);
937 962
938 regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), 963 regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies),
939 wm8985->supplies); 964 wm8985->supplies);
@@ -976,11 +1001,11 @@ static int wm8985_probe(struct snd_soc_codec *codec)
976 size_t i; 1001 size_t i;
977 struct wm8985_priv *wm8985; 1002 struct wm8985_priv *wm8985;
978 int ret; 1003 int ret;
979 u16 *cache;
980 1004
981 wm8985 = snd_soc_codec_get_drvdata(codec); 1005 wm8985 = snd_soc_codec_get_drvdata(codec);
1006 codec->control_data = wm8985->regmap;
982 1007
983 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type); 1008 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
984 if (ret < 0) { 1009 if (ret < 0) {
985 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 1010 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
986 return ret; 1011 return ret;
@@ -1009,17 +1034,13 @@ static int wm8985_probe(struct snd_soc_codec *codec)
1009 goto err_reg_enable; 1034 goto err_reg_enable;
1010 } 1035 }
1011 1036
1012 cache = codec->reg_cache;
1013 /* latch volume update bits */ 1037 /* latch volume update bits */
1014 for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i) 1038 for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i)
1015 cache[volume_update_regs[i]] |= 0x100; 1039 snd_soc_update_bits(codec, volume_update_regs[i],
1040 0x100, 0x100);
1016 /* enable BIASCUT */ 1041 /* enable BIASCUT */
1017 cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT; 1042 snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
1018 codec->cache_sync = 1; 1043 WM8985_BIASCUT);
1019
1020 snd_soc_add_controls(codec, wm8985_snd_controls,
1021 ARRAY_SIZE(wm8985_snd_controls));
1022 wm8985_add_widgets(codec);
1023 1044
1024 wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1045 wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1025 return 0; 1046 return 0;
@@ -1068,9 +1089,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
1068 .suspend = wm8985_suspend, 1089 .suspend = wm8985_suspend,
1069 .resume = wm8985_resume, 1090 .resume = wm8985_resume,
1070 .set_bias_level = wm8985_set_bias_level, 1091 .set_bias_level = wm8985_set_bias_level,
1071 .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), 1092
1072 .reg_word_size = sizeof(u16), 1093 .controls = wm8985_snd_controls,
1073 .reg_cache_default = wm8985_reg_defs 1094 .num_controls = ARRAY_SIZE(wm8985_snd_controls),
1095 .dapm_widgets = wm8985_dapm_widgets,
1096 .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets),
1097 .dapm_routes = wm8985_dapm_routes,
1098 .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes),
1099};
1100
1101static const struct regmap_config wm8985_regmap = {
1102 .reg_bits = 7,
1103 .val_bits = 9,
1104
1105 .max_register = WM8985_MAX_REGISTER,
1106 .writeable_reg = wm8985_writeable,
1107
1108 .cache_type = REGCACHE_RBTREE,
1109 .reg_defaults = wm8985_reg_defaults,
1110 .num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults),
1074}; 1111};
1075 1112
1076#if defined(CONFIG_SPI_MASTER) 1113#if defined(CONFIG_SPI_MASTER)
@@ -1079,24 +1116,39 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi)
1079 struct wm8985_priv *wm8985; 1116 struct wm8985_priv *wm8985;
1080 int ret; 1117 int ret;
1081 1118
1082 wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); 1119 wm8985 = devm_kzalloc(&spi->dev, sizeof *wm8985, GFP_KERNEL);
1083 if (!wm8985) 1120 if (!wm8985)
1084 return -ENOMEM; 1121 return -ENOMEM;
1085 1122
1086 wm8985->control_type = SND_SOC_SPI;
1087 spi_set_drvdata(spi, wm8985); 1123 spi_set_drvdata(spi, wm8985);
1088 1124
1125 wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap);
1126 if (IS_ERR(wm8985->regmap)) {
1127 ret = PTR_ERR(wm8985->regmap);
1128 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1129 ret);
1130 goto err;
1131 }
1132
1089 ret = snd_soc_register_codec(&spi->dev, 1133 ret = snd_soc_register_codec(&spi->dev,
1090 &soc_codec_dev_wm8985, &wm8985_dai, 1); 1134 &soc_codec_dev_wm8985, &wm8985_dai, 1);
1091 if (ret < 0) 1135 if (ret != 0)
1092 kfree(wm8985); 1136 goto err;
1137
1138 return 0;
1139
1140err:
1141 regmap_exit(wm8985->regmap);
1093 return ret; 1142 return ret;
1094} 1143}
1095 1144
1096static int __devexit wm8985_spi_remove(struct spi_device *spi) 1145static int __devexit wm8985_spi_remove(struct spi_device *spi)
1097{ 1146{
1147 struct wm8985_priv *wm8985 = spi_get_drvdata(spi);
1148
1098 snd_soc_unregister_codec(&spi->dev); 1149 snd_soc_unregister_codec(&spi->dev);
1099 kfree(spi_get_drvdata(spi)); 1150 regmap_exit(wm8985->regmap);
1151
1100 return 0; 1152 return 0;
1101} 1153}
1102 1154
@@ -1117,24 +1169,39 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c,
1117 struct wm8985_priv *wm8985; 1169 struct wm8985_priv *wm8985;
1118 int ret; 1170 int ret;
1119 1171
1120 wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); 1172 wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL);
1121 if (!wm8985) 1173 if (!wm8985)
1122 return -ENOMEM; 1174 return -ENOMEM;
1123 1175
1124 wm8985->control_type = SND_SOC_I2C;
1125 i2c_set_clientdata(i2c, wm8985); 1176 i2c_set_clientdata(i2c, wm8985);
1126 1177
1178 wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap);
1179 if (IS_ERR(wm8985->regmap)) {
1180 ret = PTR_ERR(wm8985->regmap);
1181 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1182 ret);
1183 goto err;
1184 }
1185
1127 ret = snd_soc_register_codec(&i2c->dev, 1186 ret = snd_soc_register_codec(&i2c->dev,
1128 &soc_codec_dev_wm8985, &wm8985_dai, 1); 1187 &soc_codec_dev_wm8985, &wm8985_dai, 1);
1129 if (ret < 0) 1188 if (ret != 0)
1130 kfree(wm8985); 1189 goto err;
1190
1191 return 0;
1192
1193err:
1194 regmap_exit(wm8985->regmap);
1131 return ret; 1195 return ret;
1132} 1196}
1133 1197
1134static __devexit int wm8985_i2c_remove(struct i2c_client *client) 1198static __devexit int wm8985_i2c_remove(struct i2c_client *i2c)
1135{ 1199{
1136 snd_soc_unregister_codec(&client->dev); 1200 struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c);
1137 kfree(i2c_get_clientdata(client)); 1201
1202 snd_soc_unregister_codec(&i2c->dev);
1203 regmap_exit(wm8985->regmap);
1204
1138 return 0; 1205 return 0;
1139} 1206}
1140 1207
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index ab52963dd04c..6cdf6a2bc283 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -33,24 +33,89 @@
33 * We can't read the WM8988 register space when we 33 * We can't read the WM8988 register space when we
34 * are using 2 wire for device control, so we cache them instead. 34 * are using 2 wire for device control, so we cache them instead.
35 */ 35 */
36static const u16 wm8988_reg[] = { 36static const struct reg_default wm8988_reg_defaults[] = {
37 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 37 { 0, 0x0097 },
38 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 38 { 1, 0x0097 },
39 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 39 { 2, 0x0079 },
40 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 40 { 3, 0x0079 },
41 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 41 { 5, 0x0008 },
42 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 42 { 7, 0x000a },
43 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 43 { 8, 0x0000 },
44 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 44 { 10, 0x00ff },
45 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 45 { 11, 0x00ff },
46 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 46 { 12, 0x000f },
47 0x0079, 0x0079, 0x0079, /* 40 */ 47 { 13, 0x000f },
48 { 16, 0x0000 },
49 { 17, 0x007b },
50 { 18, 0x0000 },
51 { 19, 0x0032 },
52 { 20, 0x0000 },
53 { 21, 0x00c3 },
54 { 22, 0x00c3 },
55 { 23, 0x00c0 },
56 { 24, 0x0000 },
57 { 25, 0x0000 },
58 { 26, 0x0000 },
59 { 27, 0x0000 },
60 { 31, 0x0000 },
61 { 32, 0x0000 },
62 { 33, 0x0000 },
63 { 34, 0x0050 },
64 { 35, 0x0050 },
65 { 36, 0x0050 },
66 { 37, 0x0050 },
67 { 40, 0x0079 },
68 { 41, 0x0079 },
69 { 42, 0x0079 },
48}; 70};
49 71
72static bool wm8988_writeable(struct device *dev, unsigned int reg)
73{
74 switch (reg) {
75 case WM8988_LINVOL:
76 case WM8988_RINVOL:
77 case WM8988_LOUT1V:
78 case WM8988_ROUT1V:
79 case WM8988_ADCDAC:
80 case WM8988_IFACE:
81 case WM8988_SRATE:
82 case WM8988_LDAC:
83 case WM8988_RDAC:
84 case WM8988_BASS:
85 case WM8988_TREBLE:
86 case WM8988_RESET:
87 case WM8988_3D:
88 case WM8988_ALC1:
89 case WM8988_ALC2:
90 case WM8988_ALC3:
91 case WM8988_NGATE:
92 case WM8988_LADC:
93 case WM8988_RADC:
94 case WM8988_ADCTL1:
95 case WM8988_ADCTL2:
96 case WM8988_PWR1:
97 case WM8988_PWR2:
98 case WM8988_ADCTL3:
99 case WM8988_ADCIN:
100 case WM8988_LADCIN:
101 case WM8988_RADCIN:
102 case WM8988_LOUTM1:
103 case WM8988_LOUTM2:
104 case WM8988_ROUTM1:
105 case WM8988_ROUTM2:
106 case WM8988_LOUT2V:
107 case WM8988_ROUT2V:
108 case WM8988_LPPB:
109 return true;
110 default:
111 return false;
112 }
113}
114
50/* codec private data */ 115/* codec private data */
51struct wm8988_priv { 116struct wm8988_priv {
117 struct regmap *regmap;
52 unsigned int sysclk; 118 unsigned int sysclk;
53 enum snd_soc_control_type control_type;
54 struct snd_pcm_hw_constraint_list *sysclk_constraints; 119 struct snd_pcm_hw_constraint_list *sysclk_constraints;
55}; 120};
56 121
@@ -317,7 +382,7 @@ static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
317 SND_SOC_DAPM_INPUT("RINPUT2"), 382 SND_SOC_DAPM_INPUT("RINPUT2"),
318}; 383};
319 384
320static const struct snd_soc_dapm_route audio_map[] = { 385static const struct snd_soc_dapm_route wm8988_dapm_routes[] = {
321 386
322 { "Left Line Mux", "Line 1", "LINPUT1" }, 387 { "Left Line Mux", "Line 1", "LINPUT1" },
323 { "Left Line Mux", "Line 2", "LINPUT2" }, 388 { "Left Line Mux", "Line 2", "LINPUT2" },
@@ -661,6 +726,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
661static int wm8988_set_bias_level(struct snd_soc_codec *codec, 726static int wm8988_set_bias_level(struct snd_soc_codec *codec,
662 enum snd_soc_bias_level level) 727 enum snd_soc_bias_level level)
663{ 728{
729 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
664 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; 730 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
665 731
666 switch (level) { 732 switch (level) {
@@ -674,7 +740,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
674 740
675 case SND_SOC_BIAS_STANDBY: 741 case SND_SOC_BIAS_STANDBY:
676 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 742 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
677 snd_soc_cache_sync(codec); 743 regcache_sync(wm8988->regmap);
678 744
679 /* VREF, VMID=2x5k */ 745 /* VREF, VMID=2x5k */
680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 746 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = {
730 796
731static int wm8988_suspend(struct snd_soc_codec *codec) 797static int wm8988_suspend(struct snd_soc_codec *codec)
732{ 798{
799 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
800
733 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 801 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
802 regcache_mark_dirty(wm8988->regmap);
734 return 0; 803 return 0;
735} 804}
736 805
@@ -743,10 +812,10 @@ static int wm8988_resume(struct snd_soc_codec *codec)
743static int wm8988_probe(struct snd_soc_codec *codec) 812static int wm8988_probe(struct snd_soc_codec *codec)
744{ 813{
745 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 814 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
746 struct snd_soc_dapm_context *dapm = &codec->dapm;
747 int ret = 0; 815 int ret = 0;
748 816
749 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); 817 codec->control_data = wm8988->regmap;
818 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
750 if (ret < 0) { 819 if (ret < 0) {
751 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 820 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
752 return ret; 821 return ret;
@@ -767,12 +836,6 @@ static int wm8988_probe(struct snd_soc_codec *codec)
767 836
768 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 837 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
769 838
770 snd_soc_add_controls(codec, wm8988_snd_controls,
771 ARRAY_SIZE(wm8988_snd_controls));
772 snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
773 ARRAY_SIZE(wm8988_dapm_widgets));
774 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
775
776 return 0; 839 return 0;
777} 840}
778 841
@@ -788,9 +851,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
788 .suspend = wm8988_suspend, 851 .suspend = wm8988_suspend,
789 .resume = wm8988_resume, 852 .resume = wm8988_resume,
790 .set_bias_level = wm8988_set_bias_level, 853 .set_bias_level = wm8988_set_bias_level,
791 .reg_cache_size = ARRAY_SIZE(wm8988_reg), 854
792 .reg_word_size = sizeof(u16), 855 .controls = wm8988_snd_controls,
793 .reg_cache_default = wm8988_reg, 856 .num_controls = ARRAY_SIZE(wm8988_snd_controls),
857 .dapm_widgets = wm8988_dapm_widgets,
858 .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
859 .dapm_routes = wm8988_dapm_routes,
860 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
861};
862
863static struct regmap_config wm8988_regmap = {
864 .reg_bits = 7,
865 .val_bits = 9,
866
867 .max_register = WM8988_LPPB,
868 .writeable_reg = wm8988_writeable,
869
870 .cache_type = REGCACHE_RBTREE,
871 .reg_defaults = wm8988_reg_defaults,
872 .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
794}; 873};
795 874
796#if defined(CONFIG_SPI_MASTER) 875#if defined(CONFIG_SPI_MASTER)
@@ -799,24 +878,33 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
799 struct wm8988_priv *wm8988; 878 struct wm8988_priv *wm8988;
800 int ret; 879 int ret;
801 880
802 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 881 wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv),
882 GFP_KERNEL);
803 if (wm8988 == NULL) 883 if (wm8988 == NULL)
804 return -ENOMEM; 884 return -ENOMEM;
805 885
806 wm8988->control_type = SND_SOC_SPI; 886 wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
887 if (IS_ERR(wm8988->regmap)) {
888 ret = PTR_ERR(wm8988->regmap);
889 dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
890 return ret;
891 }
892
807 spi_set_drvdata(spi, wm8988); 893 spi_set_drvdata(spi, wm8988);
808 894
809 ret = snd_soc_register_codec(&spi->dev, 895 ret = snd_soc_register_codec(&spi->dev,
810 &soc_codec_dev_wm8988, &wm8988_dai, 1); 896 &soc_codec_dev_wm8988, &wm8988_dai, 1);
811 if (ret < 0) 897 if (ret != 0)
812 kfree(wm8988); 898 regmap_exit(wm8988->regmap);
899
813 return ret; 900 return ret;
814} 901}
815 902
816static int __devexit wm8988_spi_remove(struct spi_device *spi) 903static int __devexit wm8988_spi_remove(struct spi_device *spi)
817{ 904{
905 struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
818 snd_soc_unregister_codec(&spi->dev); 906 snd_soc_unregister_codec(&spi->dev);
819 kfree(spi_get_drvdata(spi)); 907 regmap_exit(wm8988->regmap);
820 return 0; 908 return 0;
821} 909}
822 910
@@ -837,24 +925,33 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
837 struct wm8988_priv *wm8988; 925 struct wm8988_priv *wm8988;
838 int ret; 926 int ret;
839 927
840 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 928 wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv),
929 GFP_KERNEL);
841 if (wm8988 == NULL) 930 if (wm8988 == NULL)
842 return -ENOMEM; 931 return -ENOMEM;
843 932
844 i2c_set_clientdata(i2c, wm8988); 933 i2c_set_clientdata(i2c, wm8988);
845 wm8988->control_type = SND_SOC_I2C; 934
935 wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
936 if (IS_ERR(wm8988->regmap)) {
937 ret = PTR_ERR(wm8988->regmap);
938 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
939 return ret;
940 }
846 941
847 ret = snd_soc_register_codec(&i2c->dev, 942 ret = snd_soc_register_codec(&i2c->dev,
848 &soc_codec_dev_wm8988, &wm8988_dai, 1); 943 &soc_codec_dev_wm8988, &wm8988_dai, 1);
849 if (ret < 0) 944 if (ret != 0)
850 kfree(wm8988); 945 regmap_exit(wm8988->regmap);
946
851 return ret; 947 return ret;
852} 948}
853 949
854static __devexit int wm8988_i2c_remove(struct i2c_client *client) 950static __devexit int wm8988_i2c_remove(struct i2c_client *client)
855{ 951{
952 struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
856 snd_soc_unregister_codec(&client->dev); 953 snd_soc_unregister_codec(&client->dev);
857 kfree(i2c_get_clientdata(client)); 954 regmap_exit(wm8988->regmap);
858 return 0; 955 return 0;
859} 956}
860 957
@@ -866,7 +963,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
866 963
867static struct i2c_driver wm8988_i2c_driver = { 964static struct i2c_driver wm8988_i2c_driver = {
868 .driver = { 965 .driver = {
869 .name = "wm8988-codec", 966 .name = "wm8988",
870 .owner = THIS_MODULE, 967 .owner = THIS_MODULE,
871 }, 968 },
872 .probe = wm8988_i2c_probe, 969 .probe = wm8988_i2c_probe,
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index e538edaae1f0..9d242351e6e8 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1356,7 +1356,7 @@ static int wm8990_probe(struct snd_soc_codec *codec)
1356 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1356 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1357 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1357 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1358 1358
1359 snd_soc_add_controls(codec, wm8990_snd_controls, 1359 snd_soc_add_codec_controls(codec, wm8990_snd_controls,
1360 ARRAY_SIZE(wm8990_snd_controls)); 1360 ARRAY_SIZE(wm8990_snd_controls));
1361 wm8990_add_widgets(codec); 1361 wm8990_add_widgets(codec);
1362 1362
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 7ee40da8dbb5..9ac31ba9b82e 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1297,7 +1297,7 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1297 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1297 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1298 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1298 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1299 1299
1300 snd_soc_add_controls(codec, wm8991_snd_controls, 1300 snd_soc_add_codec_controls(codec, wm8991_snd_controls,
1301 ARRAY_SIZE(wm8991_snd_controls)); 1301 ARRAY_SIZE(wm8991_snd_controls));
1302 1302
1303 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, 1303 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 7c7fd925db8d..d256a9340644 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regmap.h>
19#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
20#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -40,134 +41,113 @@ static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
40 "SPKVDD", 41 "SPKVDD",
41}; 42};
42 43
43static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 44static struct reg_default wm8993_reg_defaults[] = {
44 0x8993, /* R0 - Software Reset */ 45 { 1, 0x0000 }, /* R1 - Power Management (1) */
45 0x0000, /* R1 - Power Management (1) */ 46 { 2, 0x6000 }, /* R2 - Power Management (2) */
46 0x6000, /* R2 - Power Management (2) */ 47 { 3, 0x0000 }, /* R3 - Power Management (3) */
47 0x0000, /* R3 - Power Management (3) */ 48 { 4, 0x4050 }, /* R4 - Audio Interface (1) */
48 0x4050, /* R4 - Audio Interface (1) */ 49 { 5, 0x4000 }, /* R5 - Audio Interface (2) */
49 0x4000, /* R5 - Audio Interface (2) */ 50 { 6, 0x01C8 }, /* R6 - Clocking 1 */
50 0x01C8, /* R6 - Clocking 1 */ 51 { 7, 0x0000 }, /* R7 - Clocking 2 */
51 0x0000, /* R7 - Clocking 2 */ 52 { 8, 0x0000 }, /* R8 - Audio Interface (3) */
52 0x0000, /* R8 - Audio Interface (3) */ 53 { 9, 0x0040 }, /* R9 - Audio Interface (4) */
53 0x0040, /* R9 - Audio Interface (4) */ 54 { 10, 0x0004 }, /* R10 - DAC CTRL */
54 0x0004, /* R10 - DAC CTRL */ 55 { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */
55 0x00C0, /* R11 - Left DAC Digital Volume */ 56 { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */
56 0x00C0, /* R12 - Right DAC Digital Volume */ 57 { 13, 0x0000 }, /* R13 - Digital Side Tone */
57 0x0000, /* R13 - Digital Side Tone */ 58 { 14, 0x0300 }, /* R14 - ADC CTRL */
58 0x0300, /* R14 - ADC CTRL */ 59 { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */
59 0x00C0, /* R15 - Left ADC Digital Volume */ 60 { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */
60 0x00C0, /* R16 - Right ADC Digital Volume */ 61 { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */
61 0x0000, /* R17 */ 62 { 19, 0x0010 }, /* R19 - GPIO1 */
62 0x0000, /* R18 - GPIO CTRL 1 */ 63 { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */
63 0x0010, /* R19 - GPIO1 */ 64 { 21, 0x0000 }, /* R21 - Inputs Clamp */
64 0x0000, /* R20 - IRQ_DEBOUNCE */ 65 { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */
65 0x0000, /* R21 */ 66 { 23, 0x0800 }, /* R23 - GPIO_POL */
66 0x8000, /* R22 - GPIOCTRL 2 */ 67 { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
67 0x0800, /* R23 - GPIO_POL */ 68 { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
68 0x008B, /* R24 - Left Line Input 1&2 Volume */ 69 { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
69 0x008B, /* R25 - Left Line Input 3&4 Volume */ 70 { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
70 0x008B, /* R26 - Right Line Input 1&2 Volume */ 71 { 28, 0x006D }, /* R28 - Left Output Volume */
71 0x008B, /* R27 - Right Line Input 3&4 Volume */ 72 { 29, 0x006D }, /* R29 - Right Output Volume */
72 0x006D, /* R28 - Left Output Volume */ 73 { 30, 0x0066 }, /* R30 - Line Outputs Volume */
73 0x006D, /* R29 - Right Output Volume */ 74 { 31, 0x0020 }, /* R31 - HPOUT2 Volume */
74 0x0066, /* R30 - Line Outputs Volume */ 75 { 32, 0x0079 }, /* R32 - Left OPGA Volume */
75 0x0020, /* R31 - HPOUT2 Volume */ 76 { 33, 0x0079 }, /* R33 - Right OPGA Volume */
76 0x0079, /* R32 - Left OPGA Volume */ 77 { 34, 0x0003 }, /* R34 - SPKMIXL Attenuation */
77 0x0079, /* R33 - Right OPGA Volume */ 78 { 35, 0x0003 }, /* R35 - SPKMIXR Attenuation */
78 0x0003, /* R34 - SPKMIXL Attenuation */ 79 { 36, 0x0011 }, /* R36 - SPKOUT Mixers */
79 0x0003, /* R35 - SPKMIXR Attenuation */ 80 { 37, 0x0100 }, /* R37 - SPKOUT Boost */
80 0x0011, /* R36 - SPKOUT Mixers */ 81 { 38, 0x0079 }, /* R38 - Speaker Volume Left */
81 0x0100, /* R37 - SPKOUT Boost */ 82 { 39, 0x0079 }, /* R39 - Speaker Volume Right */
82 0x0079, /* R38 - Speaker Volume Left */ 83 { 40, 0x0000 }, /* R40 - Input Mixer2 */
83 0x0079, /* R39 - Speaker Volume Right */ 84 { 41, 0x0000 }, /* R41 - Input Mixer3 */
84 0x0000, /* R40 - Input Mixer2 */ 85 { 42, 0x0000 }, /* R42 - Input Mixer4 */
85 0x0000, /* R41 - Input Mixer3 */ 86 { 43, 0x0000 }, /* R43 - Input Mixer5 */
86 0x0000, /* R42 - Input Mixer4 */ 87 { 44, 0x0000 }, /* R44 - Input Mixer6 */
87 0x0000, /* R43 - Input Mixer5 */ 88 { 45, 0x0000 }, /* R45 - Output Mixer1 */
88 0x0000, /* R44 - Input Mixer6 */ 89 { 46, 0x0000 }, /* R46 - Output Mixer2 */
89 0x0000, /* R45 - Output Mixer1 */ 90 { 47, 0x0000 }, /* R47 - Output Mixer3 */
90 0x0000, /* R46 - Output Mixer2 */ 91 { 48, 0x0000 }, /* R48 - Output Mixer4 */
91 0x0000, /* R47 - Output Mixer3 */ 92 { 49, 0x0000 }, /* R49 - Output Mixer5 */
92 0x0000, /* R48 - Output Mixer4 */ 93 { 50, 0x0000 }, /* R50 - Output Mixer6 */
93 0x0000, /* R49 - Output Mixer5 */ 94 { 51, 0x0000 }, /* R51 - HPOUT2 Mixer */
94 0x0000, /* R50 - Output Mixer6 */ 95 { 52, 0x0000 }, /* R52 - Line Mixer1 */
95 0x0000, /* R51 - HPOUT2 Mixer */ 96 { 53, 0x0000 }, /* R53 - Line Mixer2 */
96 0x0000, /* R52 - Line Mixer1 */ 97 { 54, 0x0000 }, /* R54 - Speaker Mixer */
97 0x0000, /* R53 - Line Mixer2 */ 98 { 55, 0x0000 }, /* R55 - Additional Control */
98 0x0000, /* R54 - Speaker Mixer */ 99 { 56, 0x0000 }, /* R56 - AntiPOP1 */
99 0x0000, /* R55 - Additional Control */ 100 { 57, 0x0000 }, /* R57 - AntiPOP2 */
100 0x0000, /* R56 - AntiPOP1 */ 101 { 58, 0x0000 }, /* R58 - MICBIAS */
101 0x0000, /* R57 - AntiPOP2 */ 102 { 60, 0x0000 }, /* R60 - FLL Control 1 */
102 0x0000, /* R58 - MICBIAS */ 103 { 61, 0x0000 }, /* R61 - FLL Control 2 */
103 0x0000, /* R59 */ 104 { 62, 0x0000 }, /* R62 - FLL Control 3 */
104 0x0000, /* R60 - FLL Control 1 */ 105 { 63, 0x2EE0 }, /* R63 - FLL Control 4 */
105 0x0000, /* R61 - FLL Control 2 */ 106 { 64, 0x0002 }, /* R64 - FLL Control 5 */
106 0x0000, /* R62 - FLL Control 3 */ 107 { 65, 0x2287 }, /* R65 - Clocking 3 */
107 0x2EE0, /* R63 - FLL Control 4 */ 108 { 66, 0x025F }, /* R66 - Clocking 4 */
108 0x0002, /* R64 - FLL Control 5 */ 109 { 67, 0x0000 }, /* R67 - MW Slave Control */
109 0x2287, /* R65 - Clocking 3 */ 110 { 69, 0x0002 }, /* R69 - Bus Control 1 */
110 0x025F, /* R66 - Clocking 4 */ 111 { 70, 0x0000 }, /* R70 - Write Sequencer 0 */
111 0x0000, /* R67 - MW Slave Control */ 112 { 71, 0x0000 }, /* R71 - Write Sequencer 1 */
112 0x0000, /* R68 */ 113 { 72, 0x0000 }, /* R72 - Write Sequencer 2 */
113 0x0002, /* R69 - Bus Control 1 */ 114 { 73, 0x0000 }, /* R73 - Write Sequencer 3 */
114 0x0000, /* R70 - Write Sequencer 0 */ 115 { 74, 0x0000 }, /* R74 - Write Sequencer 4 */
115 0x0000, /* R71 - Write Sequencer 1 */ 116 { 75, 0x0000 }, /* R75 - Write Sequencer 5 */
116 0x0000, /* R72 - Write Sequencer 2 */ 117 { 76, 0x1F25 }, /* R76 - Charge Pump 1 */
117 0x0000, /* R73 - Write Sequencer 3 */ 118 { 81, 0x0000 }, /* R81 - Class W 0 */
118 0x0000, /* R74 - Write Sequencer 4 */ 119 { 85, 0x054A }, /* R85 - DC Servo 1 */
119 0x0000, /* R75 - Write Sequencer 5 */ 120 { 87, 0x0000 }, /* R87 - DC Servo 3 */
120 0x1F25, /* R76 - Charge Pump 1 */ 121 { 96, 0x0100 }, /* R96 - Analogue HP 0 */
121 0x0000, /* R77 */ 122 { 98, 0x0000 }, /* R98 - EQ1 */
122 0x0000, /* R78 */ 123 { 99, 0x000C }, /* R99 - EQ2 */
123 0x0000, /* R79 */ 124 { 100, 0x000C }, /* R100 - EQ3 */
124 0x0000, /* R80 */ 125 { 101, 0x000C }, /* R101 - EQ4 */
125 0x0000, /* R81 - Class W 0 */ 126 { 102, 0x000C }, /* R102 - EQ5 */
126 0x0000, /* R82 */ 127 { 103, 0x000C }, /* R103 - EQ6 */
127 0x0000, /* R83 */ 128 { 104, 0x0FCA }, /* R104 - EQ7 */
128 0x0000, /* R84 - DC Servo 0 */ 129 { 105, 0x0400 }, /* R105 - EQ8 */
129 0x054A, /* R85 - DC Servo 1 */ 130 { 106, 0x00D8 }, /* R106 - EQ9 */
130 0x0000, /* R86 */ 131 { 107, 0x1EB5 }, /* R107 - EQ10 */
131 0x0000, /* R87 - DC Servo 3 */ 132 { 108, 0xF145 }, /* R108 - EQ11 */
132 0x0000, /* R88 - DC Servo Readback 0 */ 133 { 109, 0x0B75 }, /* R109 - EQ12 */
133 0x0000, /* R89 - DC Servo Readback 1 */ 134 { 110, 0x01C5 }, /* R110 - EQ13 */
134 0x0000, /* R90 - DC Servo Readback 2 */ 135 { 111, 0x1C58 }, /* R111 - EQ14 */
135 0x0000, /* R91 */ 136 { 112, 0xF373 }, /* R112 - EQ15 */
136 0x0000, /* R92 */ 137 { 113, 0x0A54 }, /* R113 - EQ16 */
137 0x0000, /* R93 */ 138 { 114, 0x0558 }, /* R114 - EQ17 */
138 0x0000, /* R94 */ 139 { 115, 0x168E }, /* R115 - EQ18 */
139 0x0000, /* R95 */ 140 { 116, 0xF829 }, /* R116 - EQ19 */
140 0x0100, /* R96 - Analogue HP 0 */ 141 { 117, 0x07AD }, /* R117 - EQ20 */
141 0x0000, /* R97 */ 142 { 118, 0x1103 }, /* R118 - EQ21 */
142 0x0000, /* R98 - EQ1 */ 143 { 119, 0x0564 }, /* R119 - EQ22 */
143 0x000C, /* R99 - EQ2 */ 144 { 120, 0x0559 }, /* R120 - EQ23 */
144 0x000C, /* R100 - EQ3 */ 145 { 121, 0x4000 }, /* R121 - EQ24 */
145 0x000C, /* R101 - EQ4 */ 146 { 122, 0x0000 }, /* R122 - Digital Pulls */
146 0x000C, /* R102 - EQ5 */ 147 { 123, 0x0F08 }, /* R123 - DRC Control 1 */
147 0x000C, /* R103 - EQ6 */ 148 { 124, 0x0000 }, /* R124 - DRC Control 2 */
148 0x0FCA, /* R104 - EQ7 */ 149 { 125, 0x0080 }, /* R125 - DRC Control 3 */
149 0x0400, /* R105 - EQ8 */ 150 { 126, 0x0000 }, /* R126 - DRC Control 4 */
150 0x00D8, /* R106 - EQ9 */
151 0x1EB5, /* R107 - EQ10 */
152 0xF145, /* R108 - EQ11 */
153 0x0B75, /* R109 - EQ12 */
154 0x01C5, /* R110 - EQ13 */
155 0x1C58, /* R111 - EQ14 */
156 0xF373, /* R112 - EQ15 */
157 0x0A54, /* R113 - EQ16 */
158 0x0558, /* R114 - EQ17 */
159 0x168E, /* R115 - EQ18 */
160 0xF829, /* R116 - EQ19 */
161 0x07AD, /* R117 - EQ20 */
162 0x1103, /* R118 - EQ21 */
163 0x0564, /* R119 - EQ22 */
164 0x0559, /* R120 - EQ23 */
165 0x4000, /* R121 - EQ24 */
166 0x0000, /* R122 - Digital Pulls */
167 0x0F08, /* R123 - DRC Control 1 */
168 0x0000, /* R124 - DRC Control 2 */
169 0x0080, /* R125 - DRC Control 3 */
170 0x0000, /* R126 - DRC Control 4 */
171}; 151};
172 152
173static struct { 153static struct {
@@ -225,9 +205,11 @@ static struct {
225 205
226struct wm8993_priv { 206struct wm8993_priv {
227 struct wm_hubs_data hubs_data; 207 struct wm_hubs_data hubs_data;
208 struct device *dev;
209 struct regmap *regmap;
228 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; 210 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
229 struct wm8993_platform_data pdata; 211 struct wm8993_platform_data pdata;
230 enum snd_soc_control_type control_type; 212 struct completion fll_lock;
231 int master; 213 int master;
232 int sysclk_source; 214 int sysclk_source;
233 int tdm_slots; 215 int tdm_slots;
@@ -242,17 +224,137 @@ struct wm8993_priv {
242 int fll_src; 224 int fll_src;
243}; 225};
244 226
245static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg) 227static bool wm8993_volatile(struct device *dev, unsigned int reg)
246{ 228{
247 switch (reg) { 229 switch (reg) {
248 case WM8993_SOFTWARE_RESET: 230 case WM8993_SOFTWARE_RESET:
231 case WM8993_GPIO_CTRL_1:
249 case WM8993_DC_SERVO_0: 232 case WM8993_DC_SERVO_0:
250 case WM8993_DC_SERVO_READBACK_0: 233 case WM8993_DC_SERVO_READBACK_0:
251 case WM8993_DC_SERVO_READBACK_1: 234 case WM8993_DC_SERVO_READBACK_1:
252 case WM8993_DC_SERVO_READBACK_2: 235 case WM8993_DC_SERVO_READBACK_2:
253 return 1; 236 return true;
254 default: 237 default:
255 return 0; 238 return false;
239 }
240}
241
242static bool wm8993_readable(struct device *dev, unsigned int reg)
243{
244 switch (reg) {
245 case WM8993_SOFTWARE_RESET:
246 case WM8993_POWER_MANAGEMENT_1:
247 case WM8993_POWER_MANAGEMENT_2:
248 case WM8993_POWER_MANAGEMENT_3:
249 case WM8993_AUDIO_INTERFACE_1:
250 case WM8993_AUDIO_INTERFACE_2:
251 case WM8993_CLOCKING_1:
252 case WM8993_CLOCKING_2:
253 case WM8993_AUDIO_INTERFACE_3:
254 case WM8993_AUDIO_INTERFACE_4:
255 case WM8993_DAC_CTRL:
256 case WM8993_LEFT_DAC_DIGITAL_VOLUME:
257 case WM8993_RIGHT_DAC_DIGITAL_VOLUME:
258 case WM8993_DIGITAL_SIDE_TONE:
259 case WM8993_ADC_CTRL:
260 case WM8993_LEFT_ADC_DIGITAL_VOLUME:
261 case WM8993_RIGHT_ADC_DIGITAL_VOLUME:
262 case WM8993_GPIO_CTRL_1:
263 case WM8993_GPIO1:
264 case WM8993_IRQ_DEBOUNCE:
265 case WM8993_GPIOCTRL_2:
266 case WM8993_GPIO_POL:
267 case WM8993_LEFT_LINE_INPUT_1_2_VOLUME:
268 case WM8993_LEFT_LINE_INPUT_3_4_VOLUME:
269 case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME:
270 case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME:
271 case WM8993_LEFT_OUTPUT_VOLUME:
272 case WM8993_RIGHT_OUTPUT_VOLUME:
273 case WM8993_LINE_OUTPUTS_VOLUME:
274 case WM8993_HPOUT2_VOLUME:
275 case WM8993_LEFT_OPGA_VOLUME:
276 case WM8993_RIGHT_OPGA_VOLUME:
277 case WM8993_SPKMIXL_ATTENUATION:
278 case WM8993_SPKMIXR_ATTENUATION:
279 case WM8993_SPKOUT_MIXERS:
280 case WM8993_SPKOUT_BOOST:
281 case WM8993_SPEAKER_VOLUME_LEFT:
282 case WM8993_SPEAKER_VOLUME_RIGHT:
283 case WM8993_INPUT_MIXER2:
284 case WM8993_INPUT_MIXER3:
285 case WM8993_INPUT_MIXER4:
286 case WM8993_INPUT_MIXER5:
287 case WM8993_INPUT_MIXER6:
288 case WM8993_OUTPUT_MIXER1:
289 case WM8993_OUTPUT_MIXER2:
290 case WM8993_OUTPUT_MIXER3:
291 case WM8993_OUTPUT_MIXER4:
292 case WM8993_OUTPUT_MIXER5:
293 case WM8993_OUTPUT_MIXER6:
294 case WM8993_HPOUT2_MIXER:
295 case WM8993_LINE_MIXER1:
296 case WM8993_LINE_MIXER2:
297 case WM8993_SPEAKER_MIXER:
298 case WM8993_ADDITIONAL_CONTROL:
299 case WM8993_ANTIPOP1:
300 case WM8993_ANTIPOP2:
301 case WM8993_MICBIAS:
302 case WM8993_FLL_CONTROL_1:
303 case WM8993_FLL_CONTROL_2:
304 case WM8993_FLL_CONTROL_3:
305 case WM8993_FLL_CONTROL_4:
306 case WM8993_FLL_CONTROL_5:
307 case WM8993_CLOCKING_3:
308 case WM8993_CLOCKING_4:
309 case WM8993_MW_SLAVE_CONTROL:
310 case WM8993_BUS_CONTROL_1:
311 case WM8993_WRITE_SEQUENCER_0:
312 case WM8993_WRITE_SEQUENCER_1:
313 case WM8993_WRITE_SEQUENCER_2:
314 case WM8993_WRITE_SEQUENCER_3:
315 case WM8993_WRITE_SEQUENCER_4:
316 case WM8993_WRITE_SEQUENCER_5:
317 case WM8993_CHARGE_PUMP_1:
318 case WM8993_CLASS_W_0:
319 case WM8993_DC_SERVO_0:
320 case WM8993_DC_SERVO_1:
321 case WM8993_DC_SERVO_3:
322 case WM8993_DC_SERVO_READBACK_0:
323 case WM8993_DC_SERVO_READBACK_1:
324 case WM8993_DC_SERVO_READBACK_2:
325 case WM8993_ANALOGUE_HP_0:
326 case WM8993_EQ1:
327 case WM8993_EQ2:
328 case WM8993_EQ3:
329 case WM8993_EQ4:
330 case WM8993_EQ5:
331 case WM8993_EQ6:
332 case WM8993_EQ7:
333 case WM8993_EQ8:
334 case WM8993_EQ9:
335 case WM8993_EQ10:
336 case WM8993_EQ11:
337 case WM8993_EQ12:
338 case WM8993_EQ13:
339 case WM8993_EQ14:
340 case WM8993_EQ15:
341 case WM8993_EQ16:
342 case WM8993_EQ17:
343 case WM8993_EQ18:
344 case WM8993_EQ19:
345 case WM8993_EQ20:
346 case WM8993_EQ21:
347 case WM8993_EQ22:
348 case WM8993_EQ23:
349 case WM8993_EQ24:
350 case WM8993_DIGITAL_PULLS:
351 case WM8993_DRC_CONTROL_1:
352 case WM8993_DRC_CONTROL_2:
353 case WM8993_DRC_CONTROL_3:
354 case WM8993_DRC_CONTROL_4:
355 return true;
356 default:
357 return false;
256 } 358 }
257} 359}
258 360
@@ -369,8 +471,10 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
369 unsigned int Fref, unsigned int Fout) 471 unsigned int Fref, unsigned int Fout)
370{ 472{
371 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 473 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
474 struct i2c_client *i2c = to_i2c_client(codec->dev);
372 u16 reg1, reg4, reg5; 475 u16 reg1, reg4, reg5;
373 struct _fll_div fll_div; 476 struct _fll_div fll_div;
477 unsigned int timeout;
374 int ret; 478 int ret;
375 479
376 /* Any change? */ 480 /* Any change? */
@@ -441,14 +545,22 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
441 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 545 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
442 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); 546 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
443 547
548 /* If we've got an interrupt wired up make sure we get it */
549 if (i2c->irq)
550 timeout = msecs_to_jiffies(20);
551 else if (Fref < 1000000)
552 timeout = msecs_to_jiffies(3);
553 else
554 timeout = msecs_to_jiffies(1);
555
556 try_wait_for_completion(&wm8993->fll_lock);
557
444 /* Enable the FLL */ 558 /* Enable the FLL */
445 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 559 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
446 560
447 /* Both overestimates */ 561 timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout);
448 if (Fref < 1000000) 562 if (i2c->irq && !timeout)
449 msleep(3); 563 dev_warn(codec->dev, "Timed out waiting for FLL\n");
450 else
451 msleep(1);
452 564
453 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 565 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
454 566
@@ -946,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
946 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1058 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
947 int ret; 1059 int ret;
948 1060
1061 wm_hubs_set_bias_level(codec, level);
1062
949 switch (level) { 1063 switch (level) {
950 case SND_SOC_BIAS_ON: 1064 case SND_SOC_BIAS_ON:
951 case SND_SOC_BIAS_PREPARE: 1065 case SND_SOC_BIAS_PREPARE:
@@ -963,12 +1077,10 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
963 if (ret != 0) 1077 if (ret != 0)
964 return ret; 1078 return ret;
965 1079
966 snd_soc_cache_sync(codec); 1080 regcache_cache_only(wm8993->regmap, false);
1081 regcache_sync(wm8993->regmap);
967 1082
968 /* Tune DC servo configuration */ 1083 wm_hubs_vmid_ena(codec);
969 snd_soc_write(codec, 0x44, 3);
970 snd_soc_write(codec, 0x56, 3);
971 snd_soc_write(codec, 0x44, 0);
972 1084
973 /* Bring up VMID with fast soft start */ 1085 /* Bring up VMID with fast soft start */
974 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 1086 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
@@ -1024,14 +1136,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1024 WM8993_VMID_RAMP_MASK | 1136 WM8993_VMID_RAMP_MASK |
1025 WM8993_BIAS_SRC, 0); 1137 WM8993_BIAS_SRC, 0);
1026 1138
1027#ifdef CONFIG_REGULATOR 1139 regcache_cache_only(wm8993->regmap, true);
1028 /* Post 2.6.34 we will be able to get a callback when 1140 regcache_mark_dirty(wm8993->regmap);
1029 * the regulators are disabled which we can use but
1030 * for now just assume that the power will be cut if
1031 * the regulator API is in use.
1032 */
1033 codec->cache_sync = 1;
1034#endif
1035 1141
1036 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), 1142 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1037 wm8993->supplies); 1143 wm8993->supplies);
@@ -1378,6 +1484,45 @@ out:
1378 return 0; 1484 return 0;
1379} 1485}
1380 1486
1487static irqreturn_t wm8993_irq(int irq, void *data)
1488{
1489 struct wm8993_priv *wm8993 = data;
1490 int mask, val, ret;
1491
1492 ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val);
1493 if (ret != 0) {
1494 dev_err(wm8993->dev, "Failed to read interrupt status: %d\n",
1495 ret);
1496 return IRQ_NONE;
1497 }
1498
1499 ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask);
1500 if (ret != 0) {
1501 dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n",
1502 ret);
1503 return IRQ_NONE;
1504 }
1505
1506 /* The IRQ pin status is visible in the register too */
1507 val &= ~(mask | WM8993_IRQ);
1508 if (!val)
1509 return IRQ_NONE;
1510
1511 if (val & WM8993_TEMPOK_EINT)
1512 dev_crit(wm8993->dev, "Thermal warning\n");
1513
1514 if (val & WM8993_FLL_LOCK_EINT) {
1515 dev_dbg(wm8993->dev, "FLL locked\n");
1516 complete(&wm8993->fll_lock);
1517 }
1518
1519 ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val);
1520 if (ret != 0)
1521 dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret);
1522
1523 return IRQ_HANDLED;
1524}
1525
1381static const struct snd_soc_dai_ops wm8993_ops = { 1526static const struct snd_soc_dai_ops wm8993_ops = {
1382 .set_sysclk = wm8993_set_sysclk, 1527 .set_sysclk = wm8993_set_sysclk,
1383 .set_fmt = wm8993_set_dai_fmt, 1528 .set_fmt = wm8993_set_dai_fmt,
@@ -1402,6 +1547,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
1402 .channels_max = 2, 1547 .channels_max = 2,
1403 .rates = WM8993_RATES, 1548 .rates = WM8993_RATES,
1404 .formats = WM8993_FORMATS, 1549 .formats = WM8993_FORMATS,
1550 .sig_bits = 24,
1405 }, 1551 },
1406 .capture = { 1552 .capture = {
1407 .stream_name = "Capture", 1553 .stream_name = "Capture",
@@ -1409,6 +1555,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
1409 .channels_max = 2, 1555 .channels_max = 2,
1410 .rates = WM8993_RATES, 1556 .rates = WM8993_RATES,
1411 .formats = WM8993_FORMATS, 1557 .formats = WM8993_FORMATS,
1558 .sig_bits = 24,
1412 }, 1559 },
1413 .ops = &wm8993_ops, 1560 .ops = &wm8993_ops,
1414 .symmetric_rates = 1, 1561 .symmetric_rates = 1,
@@ -1418,49 +1565,20 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1418{ 1565{
1419 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1566 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1420 struct snd_soc_dapm_context *dapm = &codec->dapm; 1567 struct snd_soc_dapm_context *dapm = &codec->dapm;
1421 int ret, i, val; 1568 int ret;
1422 1569
1423 wm8993->hubs_data.hp_startup_mode = 1; 1570 wm8993->hubs_data.hp_startup_mode = 1;
1424 wm8993->hubs_data.dcs_codes_l = -2; 1571 wm8993->hubs_data.dcs_codes_l = -2;
1425 wm8993->hubs_data.dcs_codes_r = -2; 1572 wm8993->hubs_data.dcs_codes_r = -2;
1426 wm8993->hubs_data.series_startup = 1; 1573 wm8993->hubs_data.series_startup = 1;
1427 1574
1428 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1575 codec->control_data = wm8993->regmap;
1576 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1429 if (ret != 0) { 1577 if (ret != 0) {
1430 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1578 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1431 return ret; 1579 return ret;
1432 } 1580 }
1433 1581
1434 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1435 wm8993->supplies[i].supply = wm8993_supply_names[i];
1436
1437 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1438 wm8993->supplies);
1439 if (ret != 0) {
1440 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1441 return ret;
1442 }
1443
1444 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1445 wm8993->supplies);
1446 if (ret != 0) {
1447 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1448 goto err_get;
1449 }
1450
1451 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1452 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1453 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1454 ret = -EINVAL;
1455 goto err_enable;
1456 }
1457
1458 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1459 if (ret != 0)
1460 goto err_enable;
1461
1462 codec->cache_only = 1;
1463
1464 /* By default we're using the output mixers */ 1582 /* By default we're using the output mixers */
1465 wm8993->class_w_users = 2; 1583 wm8993->class_w_users = 2;
1466 1584
@@ -1489,15 +1607,15 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1489 1607
1490 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1608 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1491 if (ret != 0) 1609 if (ret != 0)
1492 goto err_enable; 1610 return ret;
1493 1611
1494 snd_soc_add_controls(codec, wm8993_snd_controls, 1612 snd_soc_add_codec_controls(codec, wm8993_snd_controls,
1495 ARRAY_SIZE(wm8993_snd_controls)); 1613 ARRAY_SIZE(wm8993_snd_controls));
1496 if (wm8993->pdata.num_retune_configs != 0) { 1614 if (wm8993->pdata.num_retune_configs != 0) {
1497 dev_dbg(codec->dev, "Using ReTune Mobile\n"); 1615 dev_dbg(codec->dev, "Using ReTune Mobile\n");
1498 } else { 1616 } else {
1499 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); 1617 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
1500 snd_soc_add_controls(codec, wm8993_eq_controls, 1618 snd_soc_add_codec_controls(codec, wm8993_eq_controls,
1501 ARRAY_SIZE(wm8993_eq_controls)); 1619 ARRAY_SIZE(wm8993_eq_controls));
1502 } 1620 }
1503 1621
@@ -1509,13 +1627,14 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1509 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1627 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1510 wm8993->pdata.lineout2_diff); 1628 wm8993->pdata.lineout2_diff);
1511 1629
1630 /* If the line outputs are differential then we aren't presenting
1631 * VMID as an output and can disable it.
1632 */
1633 if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff)
1634 codec->dapm.idle_bias_off = 1;
1635
1512 return 0; 1636 return 0;
1513 1637
1514err_enable:
1515 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1516err_get:
1517 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1518 return ret;
1519} 1638}
1520 1639
1521static int wm8993_remove(struct snd_soc_codec *codec) 1640static int wm8993_remove(struct snd_soc_codec *codec)
@@ -1578,41 +1697,149 @@ static int wm8993_resume(struct snd_soc_codec *codec)
1578#define wm8993_resume NULL 1697#define wm8993_resume NULL
1579#endif 1698#endif
1580 1699
1700/* Tune DC servo configuration */
1701static struct reg_default wm8993_regmap_patch[] = {
1702 { 0x44, 3 },
1703 { 0x56, 3 },
1704 { 0x44, 0 },
1705};
1706
1707static const struct regmap_config wm8993_regmap = {
1708 .reg_bits = 8,
1709 .val_bits = 16,
1710
1711 .max_register = WM8993_MAX_REGISTER,
1712 .volatile_reg = wm8993_volatile,
1713 .readable_reg = wm8993_readable,
1714
1715 .cache_type = REGCACHE_RBTREE,
1716 .reg_defaults = wm8993_reg_defaults,
1717 .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
1718};
1719
1581static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { 1720static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
1582 .probe = wm8993_probe, 1721 .probe = wm8993_probe,
1583 .remove = wm8993_remove, 1722 .remove = wm8993_remove,
1584 .suspend = wm8993_suspend, 1723 .suspend = wm8993_suspend,
1585 .resume = wm8993_resume, 1724 .resume = wm8993_resume,
1586 .set_bias_level = wm8993_set_bias_level, 1725 .set_bias_level = wm8993_set_bias_level,
1587 .reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults),
1588 .reg_word_size = sizeof(u16),
1589 .reg_cache_default = wm8993_reg_defaults,
1590 .volatile_register = wm8993_volatile,
1591}; 1726};
1592 1727
1593#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1594static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, 1728static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
1595 const struct i2c_device_id *id) 1729 const struct i2c_device_id *id)
1596{ 1730{
1597 struct wm8993_priv *wm8993; 1731 struct wm8993_priv *wm8993;
1598 int ret; 1732 unsigned int reg;
1733 int ret, i;
1599 1734
1600 wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), 1735 wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv),
1601 GFP_KERNEL); 1736 GFP_KERNEL);
1602 if (wm8993 == NULL) 1737 if (wm8993 == NULL)
1603 return -ENOMEM; 1738 return -ENOMEM;
1604 1739
1740 wm8993->dev = &i2c->dev;
1741 init_completion(&wm8993->fll_lock);
1742
1743 wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap);
1744 if (IS_ERR(wm8993->regmap)) {
1745 ret = PTR_ERR(wm8993->regmap);
1746 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
1747 return ret;
1748 }
1749
1605 i2c_set_clientdata(i2c, wm8993); 1750 i2c_set_clientdata(i2c, wm8993);
1606 1751
1752 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1753 wm8993->supplies[i].supply = wm8993_supply_names[i];
1754
1755 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies),
1756 wm8993->supplies);
1757 if (ret != 0) {
1758 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
1759 goto err;
1760 }
1761
1762 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1763 wm8993->supplies);
1764 if (ret != 0) {
1765 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
1766 goto err_get;
1767 }
1768
1769 ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, &reg);
1770 if (ret != 0) {
1771 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
1772 goto err_enable;
1773 }
1774
1775 if (reg != 0x8993) {
1776 dev_err(&i2c->dev, "Invalid ID register value %x\n", reg);
1777 ret = -EINVAL;
1778 goto err_enable;
1779 }
1780
1781 ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff);
1782 if (ret != 0)
1783 goto err_enable;
1784
1785 ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch,
1786 ARRAY_SIZE(wm8993_regmap_patch));
1787 if (ret != 0)
1788 dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n",
1789 ret);
1790
1791 if (i2c->irq) {
1792 /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */
1793 ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1,
1794 WM8993_GPIO1_PD |
1795 WM8993_GPIO1_SEL_MASK, 7);
1796 if (ret != 0)
1797 goto err_enable;
1798
1799 ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq,
1800 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1801 "wm8993", wm8993);
1802 if (ret != 0)
1803 goto err_enable;
1804
1805 }
1806
1807 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1808
1809 regcache_cache_only(wm8993->regmap, true);
1810
1607 ret = snd_soc_register_codec(&i2c->dev, 1811 ret = snd_soc_register_codec(&i2c->dev,
1608 &soc_codec_dev_wm8993, &wm8993_dai, 1); 1812 &soc_codec_dev_wm8993, &wm8993_dai, 1);
1813 if (ret != 0) {
1814 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1815 goto err_irq;
1816 }
1817
1818 return 0;
1819
1820err_irq:
1821 if (i2c->irq)
1822 free_irq(i2c->irq, wm8993);
1823err_enable:
1824 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1825err_get:
1826 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1827err:
1828 regmap_exit(wm8993->regmap);
1609 return ret; 1829 return ret;
1610} 1830}
1611 1831
1612static __devexit int wm8993_i2c_remove(struct i2c_client *client) 1832static __devexit int wm8993_i2c_remove(struct i2c_client *i2c)
1613{ 1833{
1614 snd_soc_unregister_codec(&client->dev); 1834 struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c);
1615 kfree(i2c_get_clientdata(client)); 1835
1836 snd_soc_unregister_codec(&i2c->dev);
1837 if (i2c->irq)
1838 free_irq(i2c->irq, wm8993);
1839 regmap_exit(wm8993->regmap);
1840 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1841 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1842
1616 return 0; 1843 return 0;
1617} 1844}
1618 1845
@@ -1631,30 +1858,8 @@ static struct i2c_driver wm8993_i2c_driver = {
1631 .remove = __devexit_p(wm8993_i2c_remove), 1858 .remove = __devexit_p(wm8993_i2c_remove),
1632 .id_table = wm8993_i2c_id, 1859 .id_table = wm8993_i2c_id,
1633}; 1860};
1634#endif
1635
1636static int __init wm8993_modinit(void)
1637{
1638 int ret = 0;
1639#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1640 ret = i2c_add_driver(&wm8993_i2c_driver);
1641 if (ret != 0) {
1642 pr_err("WM8993: Unable to register I2C driver: %d\n",
1643 ret);
1644 }
1645#endif
1646 return ret;
1647}
1648module_init(wm8993_modinit);
1649
1650static void __exit wm8993_exit(void)
1651{
1652#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1653 i2c_del_driver(&wm8993_i2c_driver);
1654#endif
1655}
1656module_exit(wm8993_exit);
1657 1861
1862module_i2c_driver(wm8993_i2c_driver);
1658 1863
1659MODULE_DESCRIPTION("ASoC WM8993 driver"); 1864MODULE_DESCRIPTION("ASoC WM8993 driver");
1660MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1865MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 2184617b9611..4478b40c86e3 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -31,6 +31,7 @@
31#define WM8993_GPIO_CTRL_1 0x12 31#define WM8993_GPIO_CTRL_1 0x12
32#define WM8993_GPIO1 0x13 32#define WM8993_GPIO1 0x13
33#define WM8993_IRQ_DEBOUNCE 0x14 33#define WM8993_IRQ_DEBOUNCE 0x14
34#define WM8993_INPUTS_CLAMP_REG 0x15
34#define WM8993_GPIOCTRL_2 0x16 35#define WM8993_GPIOCTRL_2 0x16
35#define WM8993_GPIO_POL 0x17 36#define WM8993_GPIO_POL 0x17
36#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18 37#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18
@@ -656,6 +657,14 @@
656#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */ 657#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */
657 658
658/* 659/*
660 * R21 (0x15) - Inputs Clamp
661 */
662#define WM8993_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
663#define WM8993_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
664#define WM8993_INPUTS_CLAMP_SHIFT 7 /* INPUTS_CLAMP */
665#define WM8993_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
666
667/*
659 * R22 (0x16) - GPIOCTRL 2 668 * R22 (0x16) - GPIOCTRL 2
660 */ 669 */
661#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */ 670#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index ec69a6c152fe..fe7fbaeb7146 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -686,14 +686,23 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
686{ 686{
687 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 687 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
688 688
689 if (!wm8994->jackdet || !wm8994->jack_cb)
690 return;
691
689 if (wm8994->active_refcount) 692 if (wm8994->active_refcount)
690 mode = WM1811_JACKDET_MODE_AUDIO; 693 mode = WM1811_JACKDET_MODE_AUDIO;
691 694
695 if (mode == wm8994->jackdet_mode)
696 return;
697
698 wm8994->jackdet_mode = mode;
699
700 /* Always use audio mode to detect while the system is active */
701 if (mode != WM1811_JACKDET_MODE_NONE)
702 mode = WM1811_JACKDET_MODE_AUDIO;
703
692 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 704 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
693 WM1811_JACKDET_MODE_MASK, mode); 705 WM1811_JACKDET_MODE_MASK, mode);
694
695 if (mode == WM1811_JACKDET_MODE_MIC)
696 msleep(2);
697} 706}
698 707
699static void active_reference(struct snd_soc_codec *codec) 708static void active_reference(struct snd_soc_codec *codec)
@@ -707,15 +716,8 @@ static void active_reference(struct snd_soc_codec *codec)
707 dev_dbg(codec->dev, "Active refcount incremented, now %d\n", 716 dev_dbg(codec->dev, "Active refcount incremented, now %d\n",
708 wm8994->active_refcount); 717 wm8994->active_refcount);
709 718
710 if (wm8994->active_refcount == 1) { 719 /* If we're using jack detection go into audio mode */
711 /* If we're using jack detection go into audio mode */ 720 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO);
712 if (wm8994->jackdet && wm8994->jack_cb) {
713 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
714 WM1811_JACKDET_MODE_MASK,
715 WM1811_JACKDET_MODE_AUDIO);
716 msleep(2);
717 }
718 }
719 721
720 mutex_unlock(&wm8994->accdet_lock); 722 mutex_unlock(&wm8994->accdet_lock);
721} 723}
@@ -734,16 +736,12 @@ static void active_dereference(struct snd_soc_codec *codec)
734 736
735 if (wm8994->active_refcount == 0) { 737 if (wm8994->active_refcount == 0) {
736 /* Go into appropriate detection only mode */ 738 /* Go into appropriate detection only mode */
737 if (wm8994->jackdet && wm8994->jack_cb) { 739 if (wm8994->jack_mic || wm8994->mic_detecting)
738 if (wm8994->jack_mic || wm8994->mic_detecting) 740 mode = WM1811_JACKDET_MODE_MIC;
739 mode = WM1811_JACKDET_MODE_MIC; 741 else
740 else 742 mode = WM1811_JACKDET_MODE_JACK;
741 mode = WM1811_JACKDET_MODE_JACK;
742 743
743 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 744 wm1811_jackdet_set_mode(codec, mode);
744 WM1811_JACKDET_MODE_MASK,
745 mode);
746 }
747 } 745 }
748 746
749 mutex_unlock(&wm8994->accdet_lock); 747 mutex_unlock(&wm8994->accdet_lock);
@@ -778,27 +776,69 @@ static void vmid_reference(struct snd_soc_codec *codec)
778 wm8994->vmid_refcount); 776 wm8994->vmid_refcount);
779 777
780 if (wm8994->vmid_refcount == 1) { 778 if (wm8994->vmid_refcount == 1) {
781 /* Startup bias, VMID ramp & buffer */
782 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
783 WM8994_STARTUP_BIAS_ENA |
784 WM8994_VMID_BUF_ENA |
785 WM8994_VMID_RAMP_MASK,
786 WM8994_STARTUP_BIAS_ENA |
787 WM8994_VMID_BUF_ENA |
788 (0x3 << WM8994_VMID_RAMP_SHIFT));
789
790 /* Remove discharge for line out */
791 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 779 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
792 WM8994_LINEOUT1_DISCH | 780 WM8994_LINEOUT1_DISCH |
793 WM8994_LINEOUT2_DISCH, 0); 781 WM8994_LINEOUT2_DISCH, 0);
794 782
795 /* Main bias enable, VMID=2x40k */ 783 wm_hubs_vmid_ena(codec);
796 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, 784
797 WM8994_BIAS_ENA | 785 switch (wm8994->vmid_mode) {
798 WM8994_VMID_SEL_MASK, 786 default:
799 WM8994_BIAS_ENA | 0x2); 787 WARN_ON(0 == "Invalid VMID mode");
788 case WM8994_VMID_NORMAL:
789 /* Startup bias, VMID ramp & buffer */
790 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
791 WM8994_BIAS_SRC |
792 WM8994_VMID_DISCH |
793 WM8994_STARTUP_BIAS_ENA |
794 WM8994_VMID_BUF_ENA |
795 WM8994_VMID_RAMP_MASK,
796 WM8994_BIAS_SRC |
797 WM8994_STARTUP_BIAS_ENA |
798 WM8994_VMID_BUF_ENA |
799 (0x3 << WM8994_VMID_RAMP_SHIFT));
800
801 /* Main bias enable, VMID=2x40k */
802 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
803 WM8994_BIAS_ENA |
804 WM8994_VMID_SEL_MASK,
805 WM8994_BIAS_ENA | 0x2);
806
807 msleep(50);
808
809 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
810 WM8994_VMID_RAMP_MASK |
811 WM8994_BIAS_SRC,
812 0);
813 break;
814
815 case WM8994_VMID_FORCE:
816 /* Startup bias, slow VMID ramp & buffer */
817 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
818 WM8994_BIAS_SRC |
819 WM8994_VMID_DISCH |
820 WM8994_STARTUP_BIAS_ENA |
821 WM8994_VMID_BUF_ENA |
822 WM8994_VMID_RAMP_MASK,
823 WM8994_BIAS_SRC |
824 WM8994_STARTUP_BIAS_ENA |
825 WM8994_VMID_BUF_ENA |
826 (0x2 << WM8994_VMID_RAMP_SHIFT));
827
828 /* Main bias enable, VMID=2x40k */
829 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
830 WM8994_BIAS_ENA |
831 WM8994_VMID_SEL_MASK,
832 WM8994_BIAS_ENA | 0x2);
833
834 msleep(400);
800 835
801 msleep(20); 836 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
837 WM8994_VMID_RAMP_MASK |
838 WM8994_BIAS_SRC,
839 0);
840 break;
841 }
802 } 842 }
803} 843}
804 844
@@ -812,30 +852,55 @@ static void vmid_dereference(struct snd_soc_codec *codec)
812 wm8994->vmid_refcount); 852 wm8994->vmid_refcount);
813 853
814 if (wm8994->vmid_refcount == 0) { 854 if (wm8994->vmid_refcount == 0) {
815 /* Switch over to startup biases */ 855 if (wm8994->hubs.lineout1_se)
856 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
857 WM8994_LINEOUT1N_ENA |
858 WM8994_LINEOUT1P_ENA,
859 WM8994_LINEOUT1N_ENA |
860 WM8994_LINEOUT1P_ENA);
861
862 if (wm8994->hubs.lineout2_se)
863 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
864 WM8994_LINEOUT2N_ENA |
865 WM8994_LINEOUT2P_ENA,
866 WM8994_LINEOUT2N_ENA |
867 WM8994_LINEOUT2P_ENA);
868
869 /* Start discharging VMID */
816 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 870 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
817 WM8994_BIAS_SRC | 871 WM8994_BIAS_SRC |
818 WM8994_STARTUP_BIAS_ENA | 872 WM8994_VMID_DISCH,
819 WM8994_VMID_BUF_ENA |
820 WM8994_VMID_RAMP_MASK,
821 WM8994_BIAS_SRC | 873 WM8994_BIAS_SRC |
822 WM8994_STARTUP_BIAS_ENA | 874 WM8994_VMID_DISCH);
823 WM8994_VMID_BUF_ENA |
824 (1 << WM8994_VMID_RAMP_SHIFT));
825 875
826 /* Disable main biases */ 876 switch (wm8994->vmid_mode) {
827 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, 877 case WM8994_VMID_FORCE:
828 WM8994_BIAS_ENA | 878 msleep(350);
829 WM8994_VMID_SEL_MASK, 0); 879 break;
880 default:
881 break;
882 }
830 883
831 /* Discharge line */ 884 snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
885 WM8994_VROI, WM8994_VROI);
886
887 /* Active discharge */
832 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 888 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
833 WM8994_LINEOUT1_DISCH | 889 WM8994_LINEOUT1_DISCH |
834 WM8994_LINEOUT2_DISCH, 890 WM8994_LINEOUT2_DISCH,
835 WM8994_LINEOUT1_DISCH | 891 WM8994_LINEOUT1_DISCH |
836 WM8994_LINEOUT2_DISCH); 892 WM8994_LINEOUT2_DISCH);
837 893
838 msleep(5); 894 msleep(150);
895
896 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
897 WM8994_LINEOUT1N_ENA |
898 WM8994_LINEOUT1P_ENA |
899 WM8994_LINEOUT2N_ENA |
900 WM8994_LINEOUT2P_ENA, 0);
901
902 snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
903 WM8994_VROI, 0);
839 904
840 /* Switch off startup biases */ 905 /* Switch off startup biases */
841 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 906 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
@@ -843,6 +908,12 @@ static void vmid_dereference(struct snd_soc_codec *codec)
843 WM8994_STARTUP_BIAS_ENA | 908 WM8994_STARTUP_BIAS_ENA |
844 WM8994_VMID_BUF_ENA | 909 WM8994_VMID_BUF_ENA |
845 WM8994_VMID_RAMP_MASK, 0); 910 WM8994_VMID_RAMP_MASK, 0);
911
912 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
913 WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
914
915 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
916 WM8994_VMID_RAMP_MASK, 0);
846 } 917 }
847 918
848 pm_runtime_put(codec->dev); 919 pm_runtime_put(codec->dev);
@@ -1459,17 +1530,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1459 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, 1530 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
1460 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1531 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1461 1532
1462SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1533SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1463SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 1534SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1464SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 1535SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1465SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 1536SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1466 1537
1467SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1538SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
1468SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), 1539SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1469SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1540SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1470 1541
1471SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1542SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1472SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1543SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1473 1544
1474SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1545SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1475 1546
@@ -1584,6 +1655,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1584 1655
1585 { "TOCLK", NULL, "CLK_SYS" }, 1656 { "TOCLK", NULL, "CLK_SYS" },
1586 1657
1658 { "AIF1DACDAT", NULL, "AIF1 Playback" },
1659 { "AIF2DACDAT", NULL, "AIF2 Playback" },
1660 { "AIF3DACDAT", NULL, "AIF3 Playback" },
1661
1662 { "AIF1 Capture", NULL, "AIF1ADCDAT" },
1663 { "AIF2 Capture", NULL, "AIF2ADCDAT" },
1664 { "AIF3 Capture", NULL, "AIF3ADCDAT" },
1665
1587 /* AIF1 outputs */ 1666 /* AIF1 outputs */
1588 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, 1667 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
1589 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, 1668 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
@@ -1896,7 +1975,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1896 WM8994_FLL1_OUTDIV_MASK | 1975 WM8994_FLL1_OUTDIV_MASK |
1897 WM8994_FLL1_FRATIO_MASK, reg); 1976 WM8994_FLL1_FRATIO_MASK, reg);
1898 1977
1899 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); 1978 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
1979 WM8994_FLL1_K_MASK, fll.k);
1900 1980
1901 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, 1981 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
1902 WM8994_FLL1_N_MASK, 1982 WM8994_FLL1_N_MASK,
@@ -2074,6 +2154,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2074 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2154 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2075 struct wm8994 *control = wm8994->wm8994; 2155 struct wm8994 *control = wm8994->wm8994;
2076 2156
2157 wm_hubs_set_bias_level(codec, level);
2158
2077 switch (level) { 2159 switch (level) {
2078 case SND_SOC_BIAS_ON: 2160 case SND_SOC_BIAS_ON:
2079 break; 2161 break;
@@ -2099,26 +2181,9 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2099 case SND_SOC_BIAS_STANDBY: 2181 case SND_SOC_BIAS_STANDBY:
2100 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 2182 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2101 switch (control->type) { 2183 switch (control->type) {
2102 case WM8994:
2103 if (wm8994->revision < 4) {
2104 /* Tweak DC servo and DSP
2105 * configuration for improved
2106 * performance. */
2107 snd_soc_write(codec, 0x102, 0x3);
2108 snd_soc_write(codec, 0x56, 0x3);
2109 snd_soc_write(codec, 0x817, 0);
2110 snd_soc_write(codec, 0x102, 0);
2111 }
2112 break;
2113
2114 case WM8958: 2184 case WM8958:
2115 if (wm8994->revision == 0) { 2185 if (wm8994->revision == 0) {
2116 /* Optimise performance for rev A */ 2186 /* Optimise performance for rev A */
2117 snd_soc_write(codec, 0x102, 0x3);
2118 snd_soc_write(codec, 0xcb, 0x81);
2119 snd_soc_write(codec, 0x817, 0);
2120 snd_soc_write(codec, 0x102, 0);
2121
2122 snd_soc_update_bits(codec, 2187 snd_soc_update_bits(codec,
2123 WM8958_CHARGE_PUMP_2, 2188 WM8958_CHARGE_PUMP_2,
2124 WM8958_CP_DISCH, 2189 WM8958_CP_DISCH,
@@ -2126,13 +2191,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2126 } 2191 }
2127 break; 2192 break;
2128 2193
2129 case WM1811: 2194 default:
2130 if (wm8994->revision < 2) {
2131 snd_soc_write(codec, 0x102, 0x3);
2132 snd_soc_write(codec, 0x5d, 0x7e);
2133 snd_soc_write(codec, 0x5e, 0x0);
2134 snd_soc_write(codec, 0x102, 0x0);
2135 }
2136 break; 2195 break;
2137 } 2196 }
2138 2197
@@ -2168,11 +2227,61 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2168 wm8994->cur_fw = NULL; 2227 wm8994->cur_fw = NULL;
2169 break; 2228 break;
2170 } 2229 }
2230
2171 codec->dapm.bias_level = level; 2231 codec->dapm.bias_level = level;
2172 2232
2173 return 0; 2233 return 0;
2174} 2234}
2175 2235
2236int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
2237{
2238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2239
2240 switch (mode) {
2241 case WM8994_VMID_NORMAL:
2242 if (wm8994->hubs.lineout1_se) {
2243 snd_soc_dapm_disable_pin(&codec->dapm,
2244 "LINEOUT1N Driver");
2245 snd_soc_dapm_disable_pin(&codec->dapm,
2246 "LINEOUT1P Driver");
2247 }
2248 if (wm8994->hubs.lineout2_se) {
2249 snd_soc_dapm_disable_pin(&codec->dapm,
2250 "LINEOUT2N Driver");
2251 snd_soc_dapm_disable_pin(&codec->dapm,
2252 "LINEOUT2P Driver");
2253 }
2254
2255 /* Do the sync with the old mode to allow it to clean up */
2256 snd_soc_dapm_sync(&codec->dapm);
2257 wm8994->vmid_mode = mode;
2258 break;
2259
2260 case WM8994_VMID_FORCE:
2261 if (wm8994->hubs.lineout1_se) {
2262 snd_soc_dapm_force_enable_pin(&codec->dapm,
2263 "LINEOUT1N Driver");
2264 snd_soc_dapm_force_enable_pin(&codec->dapm,
2265 "LINEOUT1P Driver");
2266 }
2267 if (wm8994->hubs.lineout2_se) {
2268 snd_soc_dapm_force_enable_pin(&codec->dapm,
2269 "LINEOUT2N Driver");
2270 snd_soc_dapm_force_enable_pin(&codec->dapm,
2271 "LINEOUT2P Driver");
2272 }
2273
2274 wm8994->vmid_mode = mode;
2275 snd_soc_dapm_sync(&codec->dapm);
2276 break;
2277
2278 default:
2279 return -EINVAL;
2280 }
2281
2282 return 0;
2283}
2284
2176static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2285static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2177{ 2286{
2178 struct snd_soc_codec *codec = dai->codec; 2287 struct snd_soc_codec *codec = dai->codec;
@@ -2654,6 +2763,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2654 .channels_max = 2, 2763 .channels_max = 2,
2655 .rates = WM8994_RATES, 2764 .rates = WM8994_RATES,
2656 .formats = WM8994_FORMATS, 2765 .formats = WM8994_FORMATS,
2766 .sig_bits = 24,
2657 }, 2767 },
2658 .capture = { 2768 .capture = {
2659 .stream_name = "AIF1 Capture", 2769 .stream_name = "AIF1 Capture",
@@ -2661,6 +2771,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2661 .channels_max = 2, 2771 .channels_max = 2,
2662 .rates = WM8994_RATES, 2772 .rates = WM8994_RATES,
2663 .formats = WM8994_FORMATS, 2773 .formats = WM8994_FORMATS,
2774 .sig_bits = 24,
2664 }, 2775 },
2665 .ops = &wm8994_aif1_dai_ops, 2776 .ops = &wm8994_aif1_dai_ops,
2666 }, 2777 },
@@ -2673,6 +2784,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2673 .channels_max = 2, 2784 .channels_max = 2,
2674 .rates = WM8994_RATES, 2785 .rates = WM8994_RATES,
2675 .formats = WM8994_FORMATS, 2786 .formats = WM8994_FORMATS,
2787 .sig_bits = 24,
2676 }, 2788 },
2677 .capture = { 2789 .capture = {
2678 .stream_name = "AIF2 Capture", 2790 .stream_name = "AIF2 Capture",
@@ -2680,6 +2792,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2680 .channels_max = 2, 2792 .channels_max = 2,
2681 .rates = WM8994_RATES, 2793 .rates = WM8994_RATES,
2682 .formats = WM8994_FORMATS, 2794 .formats = WM8994_FORMATS,
2795 .sig_bits = 24,
2683 }, 2796 },
2684 .probe = wm8994_aif2_probe, 2797 .probe = wm8994_aif2_probe,
2685 .ops = &wm8994_aif2_dai_ops, 2798 .ops = &wm8994_aif2_dai_ops,
@@ -2693,6 +2806,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2693 .channels_max = 2, 2806 .channels_max = 2,
2694 .rates = WM8994_RATES, 2807 .rates = WM8994_RATES,
2695 .formats = WM8994_FORMATS, 2808 .formats = WM8994_FORMATS,
2809 .sig_bits = 24,
2696 }, 2810 },
2697 .capture = { 2811 .capture = {
2698 .stream_name = "AIF3 Capture", 2812 .stream_name = "AIF3 Capture",
@@ -2700,13 +2814,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2700 .channels_max = 2, 2814 .channels_max = 2,
2701 .rates = WM8994_RATES, 2815 .rates = WM8994_RATES,
2702 .formats = WM8994_FORMATS, 2816 .formats = WM8994_FORMATS,
2703 }, 2817 .sig_bits = 24,
2818 },
2704 .ops = &wm8994_aif3_dai_ops, 2819 .ops = &wm8994_aif3_dai_ops,
2705 } 2820 }
2706}; 2821};
2707 2822
2708#ifdef CONFIG_PM 2823#ifdef CONFIG_PM
2709static int wm8994_suspend(struct snd_soc_codec *codec) 2824static int wm8994_codec_suspend(struct snd_soc_codec *codec)
2710{ 2825{
2711 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2826 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2712 struct wm8994 *control = wm8994->wm8994; 2827 struct wm8994 *control = wm8994->wm8994;
@@ -2740,7 +2855,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec)
2740 return 0; 2855 return 0;
2741} 2856}
2742 2857
2743static int wm8994_resume(struct snd_soc_codec *codec) 2858static int wm8994_codec_resume(struct snd_soc_codec *codec)
2744{ 2859{
2745 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2860 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2746 struct wm8994 *control = wm8994->wm8994; 2861 struct wm8994 *control = wm8994->wm8994;
@@ -2762,8 +2877,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2762 codec->cache_only = 0; 2877 codec->cache_only = 0;
2763 } 2878 }
2764 2879
2765 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2766
2767 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2880 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2768 if (!wm8994->fll_suspend[i].out) 2881 if (!wm8994->fll_suspend[i].out)
2769 continue; 2882 continue;
@@ -2791,6 +2904,7 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2791 WM1811_JACKDET_MODE_JACK); 2904 WM1811_JACKDET_MODE_JACK);
2792 break; 2905 break;
2793 } 2906 }
2907 break;
2794 case WM8958: 2908 case WM8958:
2795 if (wm8994->jack_cb) 2909 if (wm8994->jack_cb)
2796 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2910 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -2801,8 +2915,8 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2801 return 0; 2915 return 0;
2802} 2916}
2803#else 2917#else
2804#define wm8994_suspend NULL 2918#define wm8994_codec_suspend NULL
2805#define wm8994_resume NULL 2919#define wm8994_codec_resume NULL
2806#endif 2920#endif
2807 2921
2808static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 2922static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
@@ -2865,7 +2979,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
2865 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 2979 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
2866 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 2980 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
2867 2981
2868 ret = snd_soc_add_controls(wm8994->codec, controls, 2982 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2869 ARRAY_SIZE(controls)); 2983 ARRAY_SIZE(controls));
2870 if (ret != 0) 2984 if (ret != 0)
2871 dev_err(wm8994->codec->dev, 2985 dev_err(wm8994->codec->dev,
@@ -2918,7 +3032,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2918 wm8994->drc_enum.max = pdata->num_drc_cfgs; 3032 wm8994->drc_enum.max = pdata->num_drc_cfgs;
2919 wm8994->drc_enum.texts = wm8994->drc_texts; 3033 wm8994->drc_enum.texts = wm8994->drc_texts;
2920 3034
2921 ret = snd_soc_add_controls(wm8994->codec, controls, 3035 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2922 ARRAY_SIZE(controls)); 3036 ARRAY_SIZE(controls));
2923 if (ret != 0) 3037 if (ret != 0)
2924 dev_err(wm8994->codec->dev, 3038 dev_err(wm8994->codec->dev,
@@ -2934,7 +3048,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2934 if (pdata->num_retune_mobile_cfgs) 3048 if (pdata->num_retune_mobile_cfgs)
2935 wm8994_handle_retune_mobile_pdata(wm8994); 3049 wm8994_handle_retune_mobile_pdata(wm8994);
2936 else 3050 else
2937 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 3051 snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
2938 ARRAY_SIZE(wm8994_eq_controls)); 3052 ARRAY_SIZE(wm8994_eq_controls));
2939 3053
2940 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { 3054 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -2951,8 +3065,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2951 * @codec: WM8994 codec 3065 * @codec: WM8994 codec
2952 * @jack: jack to report detection events on 3066 * @jack: jack to report detection events on
2953 * @micbias: microphone bias to detect on 3067 * @micbias: microphone bias to detect on
2954 * @det: value to report for presence detection
2955 * @shrt: value to report for short detection
2956 * 3068 *
2957 * Enable microphone detection via IRQ on the WM8994. If GPIOs are 3069 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
2958 * being used to bring out signals to the processor then only platform 3070 * being used to bring out signals to the processor then only platform
@@ -2963,43 +3075,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2963 * and micbias2_lvl platform data members. 3075 * and micbias2_lvl platform data members.
2964 */ 3076 */
2965int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 3077int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2966 int micbias, int det, int shrt) 3078 int micbias)
2967{ 3079{
2968 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3080 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2969 struct wm8994_micdet *micdet; 3081 struct wm8994_micdet *micdet;
2970 struct wm8994 *control = wm8994->wm8994; 3082 struct wm8994 *control = wm8994->wm8994;
2971 int reg; 3083 int reg, ret;
2972 3084
2973 if (control->type != WM8994) 3085 if (control->type != WM8994) {
3086 dev_warn(codec->dev, "Not a WM8994\n");
2974 return -EINVAL; 3087 return -EINVAL;
3088 }
2975 3089
2976 switch (micbias) { 3090 switch (micbias) {
2977 case 1: 3091 case 1:
2978 micdet = &wm8994->micdet[0]; 3092 micdet = &wm8994->micdet[0];
3093 if (jack)
3094 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3095 "MICBIAS1");
3096 else
3097 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3098 "MICBIAS1");
2979 break; 3099 break;
2980 case 2: 3100 case 2:
2981 micdet = &wm8994->micdet[1]; 3101 micdet = &wm8994->micdet[1];
3102 if (jack)
3103 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3104 "MICBIAS1");
3105 else
3106 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3107 "MICBIAS1");
2982 break; 3108 break;
2983 default: 3109 default:
3110 dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
2984 return -EINVAL; 3111 return -EINVAL;
2985 } 3112 }
3113
3114 if (ret != 0)
3115 dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
3116 micbias, ret);
2986 3117
2987 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", 3118 dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
2988 micbias, det, shrt); 3119 micbias, jack);
2989 3120
2990 /* Store the configuration */ 3121 /* Store the configuration */
2991 micdet->jack = jack; 3122 micdet->jack = jack;
2992 micdet->det = det; 3123 micdet->detecting = true;
2993 micdet->shrt = shrt;
2994 3124
2995 /* If either of the jacks is set up then enable detection */ 3125 /* If either of the jacks is set up then enable detection */
2996 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) 3126 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2997 reg = WM8994_MICD_ENA; 3127 reg = WM8994_MICD_ENA;
2998 else 3128 else
2999 reg = 0; 3129 reg = 0;
3000 3130
3001 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); 3131 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3002 3132
3133 snd_soc_dapm_sync(&codec->dapm);
3134
3003 return 0; 3135 return 0;
3004} 3136}
3005EXPORT_SYMBOL_GPL(wm8994_mic_detect); 3137EXPORT_SYMBOL_GPL(wm8994_mic_detect);
@@ -3025,20 +3157,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3025 dev_dbg(codec->dev, "Microphone status: %x\n", reg); 3157 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3026 3158
3027 report = 0; 3159 report = 0;
3028 if (reg & WM8994_MIC1_DET_STS) 3160 if (reg & WM8994_MIC1_DET_STS) {
3029 report |= priv->micdet[0].det; 3161 if (priv->micdet[0].detecting)
3030 if (reg & WM8994_MIC1_SHRT_STS) 3162 report = SND_JACK_HEADSET;
3031 report |= priv->micdet[0].shrt; 3163 }
3164 if (reg & WM8994_MIC1_SHRT_STS) {
3165 if (priv->micdet[0].detecting)
3166 report = SND_JACK_HEADPHONE;
3167 else
3168 report |= SND_JACK_BTN_0;
3169 }
3170 if (report)
3171 priv->micdet[0].detecting = false;
3172 else
3173 priv->micdet[0].detecting = true;
3174
3032 snd_soc_jack_report(priv->micdet[0].jack, report, 3175 snd_soc_jack_report(priv->micdet[0].jack, report,
3033 priv->micdet[0].det | priv->micdet[0].shrt); 3176 SND_JACK_HEADSET | SND_JACK_BTN_0);
3034 3177
3035 report = 0; 3178 report = 0;
3036 if (reg & WM8994_MIC2_DET_STS) 3179 if (reg & WM8994_MIC2_DET_STS) {
3037 report |= priv->micdet[1].det; 3180 if (priv->micdet[1].detecting)
3038 if (reg & WM8994_MIC2_SHRT_STS) 3181 report = SND_JACK_HEADSET;
3039 report |= priv->micdet[1].shrt; 3182 }
3183 if (reg & WM8994_MIC2_SHRT_STS) {
3184 if (priv->micdet[1].detecting)
3185 report = SND_JACK_HEADPHONE;
3186 else
3187 report |= SND_JACK_BTN_0;
3188 }
3189 if (report)
3190 priv->micdet[1].detecting = false;
3191 else
3192 priv->micdet[1].detecting = true;
3193
3040 snd_soc_jack_report(priv->micdet[1].jack, report, 3194 snd_soc_jack_report(priv->micdet[1].jack, report,
3041 priv->micdet[1].det | priv->micdet[1].shrt); 3195 SND_JACK_HEADSET | SND_JACK_BTN_0);
3042 3196
3043 return IRQ_HANDLED; 3197 return IRQ_HANDLED;
3044} 3198}
@@ -3087,7 +3241,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3087 } 3241 }
3088 3242
3089 3243
3090 if (wm8994->mic_detecting && status & 0x4) { 3244 if (wm8994->mic_detecting && status & 0xfc) {
3091 dev_dbg(codec->dev, "Detected headphone\n"); 3245 dev_dbg(codec->dev, "Detected headphone\n");
3092 wm8994->mic_detecting = false; 3246 wm8994->mic_detecting = false;
3093 3247
@@ -3098,11 +3252,23 @@ static void wm8958_default_micdet(u16 status, void *data)
3098 3252
3099 /* If we have jackdet that will detect removal */ 3253 /* If we have jackdet that will detect removal */
3100 if (wm8994->jackdet) { 3254 if (wm8994->jackdet) {
3255 mutex_lock(&wm8994->accdet_lock);
3256
3101 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3257 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3102 WM8958_MICD_ENA, 0); 3258 WM8958_MICD_ENA, 0);
3103 3259
3104 wm1811_jackdet_set_mode(codec, 3260 wm1811_jackdet_set_mode(codec,
3105 WM1811_JACKDET_MODE_JACK); 3261 WM1811_JACKDET_MODE_JACK);
3262
3263 mutex_unlock(&wm8994->accdet_lock);
3264
3265 if (wm8994->pdata->jd_ext_cap) {
3266 mutex_lock(&codec->mutex);
3267 snd_soc_dapm_disable_pin(&codec->dapm,
3268 "MICBIAS2");
3269 snd_soc_dapm_sync(&codec->dapm);
3270 mutex_unlock(&codec->mutex);
3271 }
3106 } 3272 }
3107 } 3273 }
3108 3274
@@ -3137,6 +3303,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3137 struct wm8994_priv *wm8994 = data; 3303 struct wm8994_priv *wm8994 = data;
3138 struct snd_soc_codec *codec = wm8994->codec; 3304 struct snd_soc_codec *codec = wm8994->codec;
3139 int reg; 3305 int reg;
3306 bool present;
3140 3307
3141 mutex_lock(&wm8994->accdet_lock); 3308 mutex_lock(&wm8994->accdet_lock);
3142 3309
@@ -3149,11 +3316,17 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3149 3316
3150 dev_dbg(codec->dev, "JACKDET %x\n", reg); 3317 dev_dbg(codec->dev, "JACKDET %x\n", reg);
3151 3318
3152 if (reg & WM1811_JACKDET_LVL) { 3319 present = reg & WM1811_JACKDET_LVL;
3320
3321 if (present) {
3153 dev_dbg(codec->dev, "Jack detected\n"); 3322 dev_dbg(codec->dev, "Jack detected\n");
3154 3323
3155 snd_soc_jack_report(wm8994->micdet[0].jack, 3324 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3156 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); 3325 WM8958_MICB2_DISCH, 0);
3326
3327 /* Disable debounce while inserted */
3328 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3329 WM1811_JACKDET_DB, 0);
3157 3330
3158 /* 3331 /*
3159 * Start off measument of microphone impedence to find 3332 * Start off measument of microphone impedence to find
@@ -3161,14 +3334,18 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3161 */ 3334 */
3162 wm8994->mic_detecting = true; 3335 wm8994->mic_detecting = true;
3163 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); 3336 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
3337
3164 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3338 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3165 WM8958_MICD_ENA, WM8958_MICD_ENA); 3339 WM8958_MICD_ENA, WM8958_MICD_ENA);
3166 } else { 3340 } else {
3167 dev_dbg(codec->dev, "Jack not detected\n"); 3341 dev_dbg(codec->dev, "Jack not detected\n");
3168 3342
3169 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 3343 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3170 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3344 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
3171 wm8994->btn_mask); 3345
3346 /* Enable debounce while removed */
3347 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3348 WM1811_JACKDET_DB, WM1811_JACKDET_DB);
3172 3349
3173 wm8994->mic_detecting = false; 3350 wm8994->mic_detecting = false;
3174 wm8994->jack_mic = false; 3351 wm8994->jack_mic = false;
@@ -3179,6 +3356,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3179 3356
3180 mutex_unlock(&wm8994->accdet_lock); 3357 mutex_unlock(&wm8994->accdet_lock);
3181 3358
3359 /* If required for an external cap force MICBIAS on */
3360 if (wm8994->pdata->jd_ext_cap) {
3361 mutex_lock(&codec->mutex);
3362
3363 if (present)
3364 snd_soc_dapm_force_enable_pin(&codec->dapm,
3365 "MICBIAS2");
3366 else
3367 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3368
3369 snd_soc_dapm_sync(&codec->dapm);
3370 mutex_unlock(&codec->mutex);
3371 }
3372
3373 if (present)
3374 snd_soc_jack_report(wm8994->micdet[0].jack,
3375 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
3376 else
3377 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3378 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3379 wm8994->btn_mask);
3380
3182 return IRQ_HANDLED; 3381 return IRQ_HANDLED;
3183} 3382}
3184 3383
@@ -3221,6 +3420,7 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3221 } 3420 }
3222 3421
3223 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); 3422 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
3423 snd_soc_dapm_sync(&codec->dapm);
3224 3424
3225 wm8994->micdet[0].jack = jack; 3425 wm8994->micdet[0].jack = jack;
3226 wm8994->jack_cb = cb; 3426 wm8994->jack_cb = cb;
@@ -3251,6 +3451,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3251 * otherwise jump straight to microphone detection. 3451 * otherwise jump straight to microphone detection.
3252 */ 3452 */
3253 if (wm8994->jackdet) { 3453 if (wm8994->jackdet) {
3454 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3455 WM8958_MICB2_DISCH,
3456 WM8958_MICB2_DISCH);
3254 snd_soc_update_bits(codec, WM8994_LDO_1, 3457 snd_soc_update_bits(codec, WM8994_LDO_1,
3255 WM8994_LDO1_DISCH, 0); 3458 WM8994_LDO1_DISCH, 0);
3256 wm1811_jackdet_set_mode(codec, 3459 wm1811_jackdet_set_mode(codec,
@@ -3263,7 +3466,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3263 } else { 3466 } else {
3264 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3467 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3265 WM8958_MICD_ENA, 0); 3468 WM8958_MICD_ENA, 0);
3469 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE);
3266 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); 3470 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS");
3471 snd_soc_dapm_sync(&codec->dapm);
3267 } 3472 }
3268 3473
3269 return 0; 3474 return 0;
@@ -3276,17 +3481,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3276 struct snd_soc_codec *codec = wm8994->codec; 3481 struct snd_soc_codec *codec = wm8994->codec;
3277 int reg, count; 3482 int reg, count;
3278 3483
3279 mutex_lock(&wm8994->accdet_lock);
3280
3281 /* 3484 /*
3282 * Jack detection may have detected a removal simulataneously 3485 * Jack detection may have detected a removal simulataneously
3283 * with an update of the MICDET status; if so it will have 3486 * with an update of the MICDET status; if so it will have
3284 * stopped detection and we can ignore this interrupt. 3487 * stopped detection and we can ignore this interrupt.
3285 */ 3488 */
3286 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { 3489 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
3287 mutex_unlock(&wm8994->accdet_lock);
3288 return IRQ_HANDLED; 3490 return IRQ_HANDLED;
3289 }
3290 3491
3291 /* We may occasionally read a detection without an impedence 3492 /* We may occasionally read a detection without an impedence
3292 * range being provided - if that happens loop again. 3493 * range being provided - if that happens loop again.
@@ -3295,7 +3496,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3295 do { 3496 do {
3296 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); 3497 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
3297 if (reg < 0) { 3498 if (reg < 0) {
3298 mutex_unlock(&wm8994->accdet_lock);
3299 dev_err(codec->dev, 3499 dev_err(codec->dev,
3300 "Failed to read mic detect status: %d\n", 3500 "Failed to read mic detect status: %d\n",
3301 reg); 3501 reg);
@@ -3326,8 +3526,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3326 dev_warn(codec->dev, "Accessory detection with no callback\n"); 3526 dev_warn(codec->dev, "Accessory detection with no callback\n");
3327 3527
3328out: 3528out:
3329 mutex_unlock(&wm8994->accdet_lock);
3330
3331 return IRQ_HANDLED; 3529 return IRQ_HANDLED;
3332} 3530}
3333 3531
@@ -3361,23 +3559,16 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data)
3361static int wm8994_codec_probe(struct snd_soc_codec *codec) 3559static int wm8994_codec_probe(struct snd_soc_codec *codec)
3362{ 3560{
3363 struct wm8994 *control = dev_get_drvdata(codec->dev->parent); 3561 struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
3364 struct wm8994_priv *wm8994; 3562 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3365 struct snd_soc_dapm_context *dapm = &codec->dapm; 3563 struct snd_soc_dapm_context *dapm = &codec->dapm;
3366 unsigned int reg; 3564 unsigned int reg;
3367 int ret, i; 3565 int ret, i;
3368 3566
3567 wm8994->codec = codec;
3369 codec->control_data = control->regmap; 3568 codec->control_data = control->regmap;
3370 3569
3371 wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv),
3372 GFP_KERNEL);
3373 if (wm8994 == NULL)
3374 return -ENOMEM;
3375 snd_soc_codec_set_drvdata(codec, wm8994);
3376
3377 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 3570 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
3378 3571
3379 wm8994->wm8994 = dev_get_drvdata(codec->dev->parent);
3380 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3381 wm8994->codec = codec; 3572 wm8994->codec = codec;
3382 3573
3383 mutex_init(&wm8994->accdet_lock); 3574 mutex_init(&wm8994->accdet_lock);
@@ -3392,12 +3583,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3392 WM8994_IRQ_MIC1_DET; 3583 WM8994_IRQ_MIC1_DET;
3393 3584
3394 pm_runtime_enable(codec->dev); 3585 pm_runtime_enable(codec->dev);
3395 pm_runtime_resume(codec->dev); 3586 pm_runtime_idle(codec->dev);
3587
3588 /* By default use idle_bias_off, will override for WM8994 */
3589 codec->dapm.idle_bias_off = 1;
3396 3590
3397 /* Set revision-specific configuration */ 3591 /* Set revision-specific configuration */
3398 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 3592 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3399 switch (control->type) { 3593 switch (control->type) {
3400 case WM8994: 3594 case WM8994:
3595 /* Single ended line outputs should have VMID on. */
3596 if (!wm8994->pdata->lineout1_diff ||
3597 !wm8994->pdata->lineout2_diff)
3598 codec->dapm.idle_bias_off = 0;
3599
3401 switch (wm8994->revision) { 3600 switch (wm8994->revision) {
3402 case 2: 3601 case 2:
3403 case 3: 3602 case 3:
@@ -3415,11 +3614,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3415 3614
3416 case WM8958: 3615 case WM8958:
3417 wm8994->hubs.dcs_readback_mode = 1; 3616 wm8994->hubs.dcs_readback_mode = 1;
3617 wm8994->hubs.hp_startup_mode = 1;
3418 break; 3618 break;
3419 3619
3420 case WM1811: 3620 case WM1811:
3421 wm8994->hubs.dcs_readback_mode = 2; 3621 wm8994->hubs.dcs_readback_mode = 2;
3422 wm8994->hubs.no_series_update = 1; 3622 wm8994->hubs.no_series_update = 1;
3623 wm8994->hubs.hp_startup_mode = 1;
3624 wm8994->hubs.no_cache_class_w = true;
3423 3625
3424 switch (wm8994->revision) { 3626 switch (wm8994->revision) {
3425 case 0: 3627 case 0:
@@ -3536,6 +3738,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3536 wm8994->fll_locked_irq = false; 3738 wm8994->fll_locked_irq = false;
3537 } 3739 }
3538 3740
3741 /* Make sure we can read from the GPIOs if they're inputs */
3742 pm_runtime_get_sync(codec->dev);
3743
3539 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3744 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3540 * configured on init - if a system wants to do this dynamically 3745 * configured on init - if a system wants to do this dynamically
3541 * at runtime we can deal with that then. 3746 * at runtime we can deal with that then.
@@ -3564,7 +3769,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3564 wm8994->lrclk_shared[1] = 0; 3769 wm8994->lrclk_shared[1] = 0;
3565 } 3770 }
3566 3771
3567 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3772 pm_runtime_put(codec->dev);
3568 3773
3569 /* Latch volume updates (right only; we always do left then right). */ 3774 /* Latch volume updates (right only; we always do left then right). */
3570 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, 3775 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
@@ -3642,7 +3847,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3642 wm8994_handle_pdata(wm8994); 3847 wm8994_handle_pdata(wm8994);
3643 3848
3644 wm_hubs_add_analogue_controls(codec); 3849 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls, 3850 snd_soc_add_codec_controls(codec, wm8994_snd_controls,
3646 ARRAY_SIZE(wm8994_snd_controls)); 3851 ARRAY_SIZE(wm8994_snd_controls));
3647 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, 3852 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
3648 ARRAY_SIZE(wm8994_dapm_widgets)); 3853 ARRAY_SIZE(wm8994_dapm_widgets));
@@ -3668,7 +3873,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3668 } 3873 }
3669 break; 3874 break;
3670 case WM8958: 3875 case WM8958:
3671 snd_soc_add_controls(codec, wm8958_snd_controls, 3876 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3672 ARRAY_SIZE(wm8958_snd_controls)); 3877 ARRAY_SIZE(wm8958_snd_controls));
3673 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3878 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3674 ARRAY_SIZE(wm8958_dapm_widgets)); 3879 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3690,7 +3895,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3690 break; 3895 break;
3691 3896
3692 case WM1811: 3897 case WM1811:
3693 snd_soc_add_controls(codec, wm8958_snd_controls, 3898 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3694 ARRAY_SIZE(wm8958_snd_controls)); 3899 ARRAY_SIZE(wm8958_snd_controls));
3695 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3900 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3696 ARRAY_SIZE(wm8958_dapm_widgets)); 3901 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3819,24 +4024,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3819 return 0; 4024 return 0;
3820} 4025}
3821 4026
3822static int wm8994_soc_volatile(struct snd_soc_codec *codec,
3823 unsigned int reg)
3824{
3825 return true;
3826}
3827
3828static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { 4027static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
3829 .probe = wm8994_codec_probe, 4028 .probe = wm8994_codec_probe,
3830 .remove = wm8994_codec_remove, 4029 .remove = wm8994_codec_remove,
3831 .suspend = wm8994_suspend, 4030 .suspend = wm8994_codec_suspend,
3832 .resume = wm8994_resume, 4031 .resume = wm8994_codec_resume,
3833 .set_bias_level = wm8994_set_bias_level, 4032 .set_bias_level = wm8994_set_bias_level,
3834 .reg_cache_size = WM8994_MAX_REGISTER,
3835 .volatile_register = wm8994_soc_volatile,
3836}; 4033};
3837 4034
3838static int __devinit wm8994_probe(struct platform_device *pdev) 4035static int __devinit wm8994_probe(struct platform_device *pdev)
3839{ 4036{
4037 struct wm8994_priv *wm8994;
4038
4039 wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv),
4040 GFP_KERNEL);
4041 if (wm8994 == NULL)
4042 return -ENOMEM;
4043 platform_set_drvdata(pdev, wm8994);
4044
4045 wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
4046 wm8994->pdata = dev_get_platdata(pdev->dev.parent);
4047
3840 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, 4048 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
3841 wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4049 wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842} 4050}
@@ -3847,11 +4055,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev)
3847 return 0; 4055 return 0;
3848} 4056}
3849 4057
4058#ifdef CONFIG_PM_SLEEP
4059static int wm8994_suspend(struct device *dev)
4060{
4061 struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
4062
4063 /* Drop down to power saving mode when system is suspended */
4064 if (wm8994->jackdet && !wm8994->active_refcount)
4065 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
4066 WM1811_JACKDET_MODE_MASK,
4067 wm8994->jackdet_mode);
4068
4069 return 0;
4070}
4071
4072static int wm8994_resume(struct device *dev)
4073{
4074 struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
4075
4076 if (wm8994->jackdet && wm8994->jack_cb)
4077 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
4078 WM1811_JACKDET_MODE_MASK,
4079 WM1811_JACKDET_MODE_AUDIO);
4080
4081 return 0;
4082}
4083#endif
4084
4085static const struct dev_pm_ops wm8994_pm_ops = {
4086 SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
4087};
4088
3850static struct platform_driver wm8994_codec_driver = { 4089static struct platform_driver wm8994_codec_driver = {
3851 .driver = { 4090 .driver = {
3852 .name = "wm8994-codec", 4091 .name = "wm8994-codec",
3853 .owner = THIS_MODULE, 4092 .owner = THIS_MODULE,
3854 }, 4093 .pm = &wm8994_pm_ops,
4094 },
3855 .probe = wm8994_probe, 4095 .probe = wm8994_probe,
3856 .remove = __devexit_p(wm8994_remove), 4096 .remove = __devexit_p(wm8994_remove),
3857}; 4097};
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index c3a42474ab19..c724112998d8 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -32,13 +32,20 @@
32#define WM8994_FLL_SRC_LRCLK 3 32#define WM8994_FLL_SRC_LRCLK 3
33#define WM8994_FLL_SRC_BCLK 4 33#define WM8994_FLL_SRC_BCLK 4
34 34
35enum wm8994_vmid_mode {
36 WM8994_VMID_NORMAL,
37 WM8994_VMID_FORCE,
38};
39
35typedef void (*wm8958_micdet_cb)(u16 status, void *data); 40typedef void (*wm8958_micdet_cb)(u16 status, void *data);
36 41
37int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 42int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
38 int micbias, int det, int shrt); 43 int micbias);
39int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 44int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
40 wm8958_micdet_cb cb, void *cb_data); 45 wm8958_micdet_cb cb, void *cb_data);
41 46
47int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode);
48
42int wm8958_aif_ev(struct snd_soc_dapm_widget *w, 49int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
43 struct snd_kcontrol *kcontrol, int event); 50 struct snd_kcontrol *kcontrol, int event);
44 51
@@ -46,8 +53,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec);
46 53
47struct wm8994_micdet { 54struct wm8994_micdet {
48 struct snd_soc_jack *jack; 55 struct snd_soc_jack *jack;
49 int det; 56 bool detecting;
50 int shrt;
51}; 57};
52 58
53/* codec private data */ 59/* codec private data */
@@ -76,6 +82,7 @@ struct wm8994_priv {
76 82
77 int vmid_refcount; 83 int vmid_refcount;
78 int active_refcount; 84 int active_refcount;
85 enum wm8994_vmid_mode vmid_mode;
79 86
80 int dac_rates[2]; 87 int dac_rates[2];
81 int lrclk_shared[2]; 88 int lrclk_shared[2];
@@ -123,6 +130,7 @@ struct wm8994_priv {
123 bool jack_mic; 130 bool jack_mic;
124 int btn_mask; 131 int btn_mask;
125 bool jackdet; 132 bool jackdet;
133 int jackdet_mode;
126 134
127 wm8958_micdet_cb jack_cb; 135 wm8958_micdet_cb jack_cb;
128 void *jack_cb_data; 136 void *jack_cb_data;
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index c8aada597d70..28c89b094c6e 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2047,7 +2047,6 @@ static int wm8995_probe(struct snd_soc_codec *codec)
2047 int i; 2047 int i;
2048 int ret; 2048 int ret;
2049 2049
2050 codec->dapm.idle_bias_off = 1;
2051 wm8995 = snd_soc_codec_get_drvdata(codec); 2050 wm8995 = snd_soc_codec_get_drvdata(codec);
2052 wm8995->codec = codec; 2051 wm8995->codec = codec;
2053 2052
@@ -2137,7 +2136,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
2137 2136
2138 wm8995_update_class_w(codec); 2137 wm8995_update_class_w(codec);
2139 2138
2140 snd_soc_add_controls(codec, wm8995_snd_controls, 2139 snd_soc_add_codec_controls(codec, wm8995_snd_controls,
2141 ARRAY_SIZE(wm8995_snd_controls)); 2140 ARRAY_SIZE(wm8995_snd_controls));
2142 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, 2141 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
2143 ARRAY_SIZE(wm8995_dapm_widgets)); 2142 ARRAY_SIZE(wm8995_dapm_widgets));
@@ -2241,6 +2240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
2241 .suspend = wm8995_suspend, 2240 .suspend = wm8995_suspend,
2242 .resume = wm8995_resume, 2241 .resume = wm8995_resume,
2243 .set_bias_level = wm8995_set_bias_level, 2242 .set_bias_level = wm8995_set_bias_level,
2243 .idle_bias_off = true,
2244}; 2244};
2245 2245
2246static struct regmap_config wm8995_regmap = { 2246static struct regmap_config wm8995_regmap = {
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 61f7daa4d0e6..1fd635494045 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -73,7 +73,6 @@ struct wm8996_priv {
73 73
74 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 74 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 75 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
76 struct regulator *cpvdd;
77 int bg_ena; 76 int bg_ena;
78 77
79 struct wm8996_pdata pdata; 78 struct wm8996_pdata pdata;
@@ -90,6 +89,7 @@ struct wm8996_priv {
90 struct snd_soc_jack *jack; 89 struct snd_soc_jack *jack;
91 bool detecting; 90 bool detecting;
92 bool jack_mic; 91 bool jack_mic;
92 int jack_flips;
93 wm8996_polarity_fn polarity_cb; 93 wm8996_polarity_fn polarity_cb;
94 94
95#ifdef CONFIG_GPIOLIB 95#ifdef CONFIG_GPIOLIB
@@ -118,7 +118,6 @@ WM8996_REGULATOR_EVENT(1)
118WM8996_REGULATOR_EVENT(2) 118WM8996_REGULATOR_EVENT(2)
119 119
120static struct reg_default wm8996_reg[] = { 120static struct reg_default wm8996_reg[] = {
121 { WM8996_SOFTWARE_RESET, 0x8996 },
122 { WM8996_POWER_MANAGEMENT_1, 0x0 }, 121 { WM8996_POWER_MANAGEMENT_1, 0x0 },
123 { WM8996_POWER_MANAGEMENT_2, 0x0 }, 122 { WM8996_POWER_MANAGEMENT_2, 0x0 },
124 { WM8996_POWER_MANAGEMENT_3, 0x0 }, 123 { WM8996_POWER_MANAGEMENT_3, 0x0 },
@@ -153,7 +152,6 @@ static struct reg_default wm8996_reg[] = {
153 { WM8996_CHARGE_PUMP_1, 0x1f25 }, 152 { WM8996_CHARGE_PUMP_1, 0x1f25 },
154 { WM8996_CHARGE_PUMP_2, 0xab19 }, 153 { WM8996_CHARGE_PUMP_2, 0xab19 },
155 { WM8996_DC_SERVO_1, 0x0 }, 154 { WM8996_DC_SERVO_1, 0x0 },
156 { WM8996_DC_SERVO_2, 0x0 },
157 { WM8996_DC_SERVO_3, 0x0 }, 155 { WM8996_DC_SERVO_3, 0x0 },
158 { WM8996_DC_SERVO_5, 0x2a2a }, 156 { WM8996_DC_SERVO_5, 0x2a2a },
159 { WM8996_DC_SERVO_6, 0x0 }, 157 { WM8996_DC_SERVO_6, 0x0 },
@@ -716,10 +714,16 @@ SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
716SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), 714SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
717SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), 715SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
718SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), 716SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
717SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5,
718 WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA |
719 WM8996_DSP1TXR_DRC_ENA),
719 720
720SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), 721SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
721SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), 722SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
722SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), 723SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
724SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5,
725 WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA |
726 WM8996_DSP2TXR_DRC_ENA),
723}; 727};
724 728
725static const struct snd_kcontrol_new wm8996_eq_controls[] = { 729static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -792,29 +796,18 @@ static int bg_event(struct snd_soc_dapm_widget *w,
792static int cp_event(struct snd_soc_dapm_widget *w, 796static int cp_event(struct snd_soc_dapm_widget *w,
793 struct snd_kcontrol *kcontrol, int event) 797 struct snd_kcontrol *kcontrol, int event)
794{ 798{
795 struct snd_soc_codec *codec = w->codec;
796 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
797 int ret = 0; 799 int ret = 0;
798 800
799 switch (event) { 801 switch (event) {
800 case SND_SOC_DAPM_PRE_PMU:
801 ret = regulator_enable(wm8996->cpvdd);
802 if (ret != 0)
803 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
804 ret);
805 break;
806 case SND_SOC_DAPM_POST_PMU: 802 case SND_SOC_DAPM_POST_PMU:
807 msleep(5); 803 msleep(5);
808 break; 804 break;
809 case SND_SOC_DAPM_POST_PMD:
810 regulator_disable_deferred(wm8996->cpvdd, 20);
811 break;
812 default: 805 default:
813 BUG(); 806 BUG();
814 ret = -EINVAL; 807 ret = -EINVAL;
815 } 808 }
816 809
817 return ret; 810 return 0;
818} 811}
819 812
820static int rmv_short_event(struct snd_soc_dapm_widget *w, 813static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -897,8 +890,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
897 val = 0; 890 val = 0;
898 mask = 0; 891 mask = 0;
899 if (wm8996->hpout_pending & HPOUT1L) { 892 if (wm8996->hpout_pending & HPOUT1L) {
900 val |= WM8996_HPOUT1L_RMV_SHORT; 893 val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
901 mask |= WM8996_HPOUT1L_RMV_SHORT; 894 mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
902 } else { 895 } else {
903 mask |= WM8996_HPOUT1L_RMV_SHORT | 896 mask |= WM8996_HPOUT1L_RMV_SHORT |
904 WM8996_HPOUT1L_OUTP | 897 WM8996_HPOUT1L_OUTP |
@@ -906,8 +899,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
906 } 899 }
907 900
908 if (wm8996->hpout_pending & HPOUT1R) { 901 if (wm8996->hpout_pending & HPOUT1R) {
909 val |= WM8996_HPOUT1R_RMV_SHORT; 902 val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
910 mask |= WM8996_HPOUT1R_RMV_SHORT; 903 mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
911 } else { 904 } else {
912 mask |= WM8996_HPOUT1R_RMV_SHORT | 905 mask |= WM8996_HPOUT1R_RMV_SHORT |
913 WM8996_HPOUT1R_OUTP | 906 WM8996_HPOUT1R_OUTP |
@@ -919,8 +912,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
919 val = 0; 912 val = 0;
920 mask = 0; 913 mask = 0;
921 if (wm8996->hpout_pending & HPOUT2L) { 914 if (wm8996->hpout_pending & HPOUT2L) {
922 val |= WM8996_HPOUT2L_RMV_SHORT; 915 val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
923 mask |= WM8996_HPOUT2L_RMV_SHORT; 916 mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
924 } else { 917 } else {
925 mask |= WM8996_HPOUT2L_RMV_SHORT | 918 mask |= WM8996_HPOUT2L_RMV_SHORT |
926 WM8996_HPOUT2L_OUTP | 919 WM8996_HPOUT2L_OUTP |
@@ -928,8 +921,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
928 } 921 }
929 922
930 if (wm8996->hpout_pending & HPOUT2R) { 923 if (wm8996->hpout_pending & HPOUT2R) {
931 val |= WM8996_HPOUT2R_RMV_SHORT; 924 val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
932 mask |= WM8996_HPOUT2R_RMV_SHORT; 925 mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
933 } else { 926 } else {
934 mask |= WM8996_HPOUT2R_RMV_SHORT | 927 mask |= WM8996_HPOUT2R_RMV_SHORT |
935 WM8996_HPOUT2R_OUTP | 928 WM8996_HPOUT2R_OUTP |
@@ -1116,12 +1109,12 @@ SND_SOC_DAPM_INPUT("IN2RP"),
1116SND_SOC_DAPM_INPUT("DMIC1DAT"), 1109SND_SOC_DAPM_INPUT("DMIC1DAT"),
1117SND_SOC_DAPM_INPUT("DMIC2DAT"), 1110SND_SOC_DAPM_INPUT("DMIC2DAT"),
1118 1111
1112SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
1119SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), 1113SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
1120SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1114SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
1121SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1115SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
1122SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1116SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
1123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1117 SND_SOC_DAPM_POST_PMU),
1124 SND_SOC_DAPM_POST_PMD),
1125SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, 1118SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1126 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1119 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1127SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1120SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
@@ -1180,41 +1173,25 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1180SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1173SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1181SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1174SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1182 1175
1183SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, 1176SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0),
1184 WM8996_POWER_MANAGEMENT_4, 9, 0), 1177SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0),
1185SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1, 1178
1186 WM8996_POWER_MANAGEMENT_4, 8, 0), 1179SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0),
1187 1180SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0),
1188SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, 1181
1189 WM8996_POWER_MANAGEMENT_6, 9, 0), 1182SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0),
1190SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1, 1183SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0),
1191 WM8996_POWER_MANAGEMENT_6, 8, 0), 1184SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0),
1192 1185SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0),
1193SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1186SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0),
1194 WM8996_POWER_MANAGEMENT_4, 5, 0), 1187SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0),
1195SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, 1188
1196 WM8996_POWER_MANAGEMENT_4, 4, 0), 1189SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0),
1197SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, 1190SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0),
1198 WM8996_POWER_MANAGEMENT_4, 3, 0), 1191SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0),
1199SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, 1192SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0),
1200 WM8996_POWER_MANAGEMENT_4, 2, 0), 1193SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0),
1201SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, 1194SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0),
1202 WM8996_POWER_MANAGEMENT_4, 1, 0),
1203SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1204 WM8996_POWER_MANAGEMENT_4, 0, 0),
1205
1206SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1207 WM8996_POWER_MANAGEMENT_6, 5, 0),
1208SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1209 WM8996_POWER_MANAGEMENT_6, 4, 0),
1210SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1211 WM8996_POWER_MANAGEMENT_6, 3, 0),
1212SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1213 WM8996_POWER_MANAGEMENT_6, 2, 0),
1214SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1215 WM8996_POWER_MANAGEMENT_6, 1, 0),
1216SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1217 WM8996_POWER_MANAGEMENT_6, 0, 0),
1218 1195
1219/* We route as stereo pairs so define some dummy widgets to squash 1196/* We route as stereo pairs so define some dummy widgets to squash
1220 * things down for now. RXA = 0,1, RXB = 2,3 and so on */ 1197 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
@@ -1237,7 +1214,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1237SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), 1214SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0),
1238SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, 1215SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start,
1239 SND_SOC_DAPM_POST_PMU), 1216 SND_SOC_DAPM_POST_PMU),
1240SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0),
1241SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, 1217SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1242 rmv_short_event, 1218 rmv_short_event,
1243 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1219 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1246,7 +1222,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1246SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), 1222SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0),
1247SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, 1223SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start,
1248 SND_SOC_DAPM_POST_PMU), 1224 SND_SOC_DAPM_POST_PMU),
1249SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0),
1250SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, 1225SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1251 rmv_short_event, 1226 rmv_short_event,
1252 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1227 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1255,7 +1230,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1255SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), 1230SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0),
1256SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, 1231SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start,
1257 SND_SOC_DAPM_POST_PMU), 1232 SND_SOC_DAPM_POST_PMU),
1258SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0),
1259SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, 1233SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1260 rmv_short_event, 1234 rmv_short_event,
1261 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1235 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1264,7 +1238,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1264SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), 1238SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0),
1265SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, 1239SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start,
1266 SND_SOC_DAPM_POST_PMU), 1240 SND_SOC_DAPM_POST_PMU),
1267SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0),
1268SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, 1241SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1269 rmv_short_event, 1242 rmv_short_event,
1270 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1243 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1280,6 +1253,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1280 { "AIFCLK", NULL, "SYSCLK" }, 1253 { "AIFCLK", NULL, "SYSCLK" },
1281 { "SYSDSPCLK", NULL, "SYSCLK" }, 1254 { "SYSDSPCLK", NULL, "SYSCLK" },
1282 { "Charge Pump", NULL, "SYSCLK" }, 1255 { "Charge Pump", NULL, "SYSCLK" },
1256 { "Charge Pump", NULL, "CPVDD" },
1283 1257
1284 { "MICB1", NULL, "LDO2" }, 1258 { "MICB1", NULL, "LDO2" },
1285 { "MICB1", NULL, "MICB1 Audio" }, 1259 { "MICB1", NULL, "MICB1 Audio" },
@@ -1288,6 +1262,26 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1288 { "MICB2", NULL, "MICB2 Audio" }, 1262 { "MICB2", NULL, "MICB2 Audio" },
1289 { "MICB2", NULL, "Bandgap" }, 1263 { "MICB2", NULL, "Bandgap" },
1290 1264
1265 { "AIF1RX0", NULL, "AIF1 Playback" },
1266 { "AIF1RX1", NULL, "AIF1 Playback" },
1267 { "AIF1RX2", NULL, "AIF1 Playback" },
1268 { "AIF1RX3", NULL, "AIF1 Playback" },
1269 { "AIF1RX4", NULL, "AIF1 Playback" },
1270 { "AIF1RX5", NULL, "AIF1 Playback" },
1271
1272 { "AIF2RX0", NULL, "AIF2 Playback" },
1273 { "AIF2RX1", NULL, "AIF2 Playback" },
1274
1275 { "AIF1 Capture", NULL, "AIF1TX0" },
1276 { "AIF1 Capture", NULL, "AIF1TX1" },
1277 { "AIF1 Capture", NULL, "AIF1TX2" },
1278 { "AIF1 Capture", NULL, "AIF1TX3" },
1279 { "AIF1 Capture", NULL, "AIF1TX4" },
1280 { "AIF1 Capture", NULL, "AIF1TX5" },
1281
1282 { "AIF2 Capture", NULL, "AIF2TX0" },
1283 { "AIF2 Capture", NULL, "AIF2TX1" },
1284
1291 { "IN1L PGA", NULL, "IN2LN" }, 1285 { "IN1L PGA", NULL, "IN2LN" },
1292 { "IN1L PGA", NULL, "IN2LP" }, 1286 { "IN1L PGA", NULL, "IN2LP" },
1293 { "IN1L PGA", NULL, "IN1LN" }, 1287 { "IN1L PGA", NULL, "IN1LN" },
@@ -1436,32 +1430,28 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1436 { "HPOUT2L PGA", NULL, "DAC2L" }, 1430 { "HPOUT2L PGA", NULL, "DAC2L" },
1437 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1431 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1438 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1432 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1439 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, 1433 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" },
1440 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1441 1434
1442 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1435 { "HPOUT2R PGA", NULL, "Charge Pump" },
1443 { "HPOUT2R PGA", NULL, "Bandgap" }, 1436 { "HPOUT2R PGA", NULL, "Bandgap" },
1444 { "HPOUT2R PGA", NULL, "DAC2R" }, 1437 { "HPOUT2R PGA", NULL, "DAC2R" },
1445 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1438 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1446 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1439 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1447 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, 1440 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" },
1448 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1449 1441
1450 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1442 { "HPOUT1L PGA", NULL, "Charge Pump" },
1451 { "HPOUT1L PGA", NULL, "Bandgap" }, 1443 { "HPOUT1L PGA", NULL, "Bandgap" },
1452 { "HPOUT1L PGA", NULL, "DAC1L" }, 1444 { "HPOUT1L PGA", NULL, "DAC1L" },
1453 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1445 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1454 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1446 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1455 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, 1447 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" },
1456 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1457 1448
1458 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1449 { "HPOUT1R PGA", NULL, "Charge Pump" },
1459 { "HPOUT1R PGA", NULL, "Bandgap" }, 1450 { "HPOUT1R PGA", NULL, "Bandgap" },
1460 { "HPOUT1R PGA", NULL, "DAC1R" }, 1451 { "HPOUT1R PGA", NULL, "DAC1R" },
1461 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1452 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1462 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1453 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1463 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, 1454 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" },
1464 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1465 1455
1466 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, 1456 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1467 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, 1457 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
@@ -1720,6 +1710,7 @@ static int wm8996_reset(struct wm8996_priv *wm8996)
1720{ 1710{
1721 if (wm8996->pdata.ldo_ena > 0) { 1711 if (wm8996->pdata.ldo_ena > 0) {
1722 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 1712 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1713 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
1723 return 0; 1714 return 0;
1724 } else { 1715 } else {
1725 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, 1716 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
@@ -1923,7 +1914,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
1923{ 1914{
1924 struct snd_soc_codec *codec = dai->codec; 1915 struct snd_soc_codec *codec = dai->codec;
1925 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 1916 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
1926 int bits, i, bclk_rate; 1917 int bits, i, bclk_rate, best;
1927 int aifdata = 0; 1918 int aifdata = 0;
1928 int lrclk = 0; 1919 int lrclk = 0;
1929 int dsp = 0; 1920 int dsp = 0;
@@ -1972,14 +1963,11 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
1972 return bits; 1963 return bits;
1973 aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits; 1964 aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits;
1974 1965
1966 best = 0;
1975 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { 1967 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
1976 if (dsp_divs[i] == params_rate(params)) 1968 if (abs(dsp_divs[i] - params_rate(params)) <
1977 break; 1969 abs(dsp_divs[best] - params_rate(params)))
1978 } 1970 best = i;
1979 if (i == ARRAY_SIZE(dsp_divs)) {
1980 dev_err(codec->dev, "Unsupported sample rate %dHz\n",
1981 params_rate(params));
1982 return -EINVAL;
1983 } 1971 }
1984 dsp |= i << dsp_shift; 1972 dsp |= i << dsp_shift;
1985 1973
@@ -2039,13 +2027,16 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
2039 } 2027 }
2040 2028
2041 switch (wm8996->sysclk) { 2029 switch (wm8996->sysclk) {
2030 case 5644800:
2042 case 6144000: 2031 case 6144000:
2043 snd_soc_update_bits(codec, WM8996_AIF_RATE, 2032 snd_soc_update_bits(codec, WM8996_AIF_RATE,
2044 WM8996_SYSCLK_RATE, 0); 2033 WM8996_SYSCLK_RATE, 0);
2045 break; 2034 break;
2035 case 22579200:
2046 case 24576000: 2036 case 24576000:
2047 ratediv = WM8996_SYSCLK_DIV; 2037 ratediv = WM8996_SYSCLK_DIV;
2048 wm8996->sysclk /= 2; 2038 wm8996->sysclk /= 2;
2039 case 11289600:
2049 case 12288000: 2040 case 12288000:
2050 snd_soc_update_bits(codec, WM8996_AIF_RATE, 2041 snd_soc_update_bits(codec, WM8996_AIF_RATE,
2051 WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE); 2042 WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE);
@@ -2438,6 +2429,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2438 wm8996->jack = jack; 2429 wm8996->jack = jack;
2439 wm8996->detecting = true; 2430 wm8996->detecting = true;
2440 wm8996->polarity_cb = polarity_cb; 2431 wm8996->polarity_cb = polarity_cb;
2432 wm8996->jack_flips = 0;
2441 2433
2442 if (wm8996->polarity_cb) 2434 if (wm8996->polarity_cb)
2443 wm8996->polarity_cb(codec, 0); 2435 wm8996->polarity_cb(codec, 0);
@@ -2553,6 +2545,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2553 WM8996_HP_POLL, WM8996_HP_POLL); 2545 WM8996_HP_POLL, WM8996_HP_POLL);
2554} 2546}
2555 2547
2548static void wm8996_report_headphone(struct snd_soc_codec *codec)
2549{
2550 dev_dbg(codec->dev, "Headphone detected\n");
2551 wm8996_hpdet_start(codec);
2552
2553 /* Increase the detection rate a bit for responsiveness. */
2554 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2555 WM8996_MICD_RATE_MASK |
2556 WM8996_MICD_BIAS_STARTTIME_MASK,
2557 7 << WM8996_MICD_RATE_SHIFT |
2558 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
2559}
2560
2556static void wm8996_micd(struct snd_soc_codec *codec) 2561static void wm8996_micd(struct snd_soc_codec *codec)
2557{ 2562{
2558 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2563 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2572,6 +2577,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2572 dev_dbg(codec->dev, "Jack removal detected\n"); 2577 dev_dbg(codec->dev, "Jack removal detected\n");
2573 wm8996->jack_mic = false; 2578 wm8996->jack_mic = false;
2574 wm8996->detecting = true; 2579 wm8996->detecting = true;
2580 wm8996->jack_flips = 0;
2575 snd_soc_jack_report(wm8996->jack, 0, 2581 snd_soc_jack_report(wm8996->jack, 0,
2576 SND_JACK_LINEOUT | SND_JACK_HEADSET | 2582 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2577 SND_JACK_BTN_0); 2583 SND_JACK_BTN_0);
@@ -2612,9 +2618,17 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2612 /* If we detected a lower impedence during initial startup 2618 /* If we detected a lower impedence during initial startup
2613 * then we probably have the wrong polarity, flip it. Don't 2619 * then we probably have the wrong polarity, flip it. Don't
2614 * do this for the lowest impedences to speed up detection of 2620 * do this for the lowest impedences to speed up detection of
2615 * plain headphones. 2621 * plain headphones. If both polarities report a low
2622 * impedence then give up and report headphones.
2616 */ 2623 */
2617 if (wm8996->detecting && (val & 0x3f0)) { 2624 if (wm8996->detecting && (val & 0x3f0)) {
2625 wm8996->jack_flips++;
2626
2627 if (wm8996->jack_flips > 1) {
2628 wm8996_report_headphone(codec);
2629 return;
2630 }
2631
2618 reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); 2632 reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
2619 reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | 2633 reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
2620 WM8996_MICD_BIAS_SRC; 2634 WM8996_MICD_BIAS_SRC;
@@ -2641,17 +2655,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2641 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, 2655 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2642 SND_JACK_BTN_0); 2656 SND_JACK_BTN_0);
2643 } else if (wm8996->detecting) { 2657 } else if (wm8996->detecting) {
2644 dev_dbg(codec->dev, "Headphone detected\n"); 2658 wm8996_report_headphone(codec);
2645 wm8996_hpdet_start(codec);
2646
2647 /* Increase the detection rate a bit for
2648 * responsiveness.
2649 */
2650 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2651 WM8996_MICD_RATE_MASK |
2652 WM8996_MICD_BIAS_STARTTIME_MASK,
2653 7 << WM8996_MICD_RATE_SHIFT |
2654 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
2655 } 2659 }
2656 } 2660 }
2657} 2661}
@@ -2768,7 +2772,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
2768 wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; 2772 wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts;
2769 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; 2773 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
2770 2774
2771 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 2775 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
2772 if (ret != 0) 2776 if (ret != 0)
2773 dev_err(codec->dev, 2777 dev_err(codec->dev,
2774 "Failed to add ReTune Mobile controls: %d\n", ret); 2778 "Failed to add ReTune Mobile controls: %d\n", ret);
@@ -2791,7 +2795,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2791 int ret; 2795 int ret;
2792 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2796 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2793 struct i2c_client *i2c = to_i2c_client(codec->dev); 2797 struct i2c_client *i2c = to_i2c_client(codec->dev);
2794 struct snd_soc_dapm_context *dapm = &codec->dapm;
2795 int i, irq_flags; 2798 int i, irq_flags;
2796 2799
2797 wm8996->codec = codec; 2800 wm8996->codec = codec;
@@ -2799,8 +2802,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2799 init_completion(&wm8996->dcs_done); 2802 init_completion(&wm8996->dcs_done);
2800 init_completion(&wm8996->fll_lock); 2803 init_completion(&wm8996->fll_lock);
2801 2804
2802 dapm->idle_bias_off = true;
2803
2804 codec->control_data = wm8996->regmap; 2805 codec->control_data = wm8996->regmap;
2805 2806
2806 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 2807 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
@@ -2966,7 +2967,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2966 if (wm8996->pdata.num_retune_mobile_cfgs) 2967 if (wm8996->pdata.num_retune_mobile_cfgs)
2967 wm8996_retune_mobile_pdata(codec); 2968 wm8996_retune_mobile_pdata(codec);
2968 else 2969 else
2969 snd_soc_add_controls(codec, wm8996_eq_controls, 2970 snd_soc_add_codec_controls(codec, wm8996_eq_controls,
2970 ARRAY_SIZE(wm8996_eq_controls)); 2971 ARRAY_SIZE(wm8996_eq_controls));
2971 2972
2972 /* If the TX LRCLK pins are not in LRCLK mode configure the 2973 /* If the TX LRCLK pins are not in LRCLK mode configure the
@@ -3038,22 +3039,16 @@ static int wm8996_remove(struct snd_soc_codec *codec)
3038 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3039 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3039 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3040 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3040 &wm8996->disable_nb[i]); 3041 &wm8996->disable_nb[i]);
3041 regulator_put(wm8996->cpvdd);
3042 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3042 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3043 3043
3044 return 0; 3044 return 0;
3045} 3045}
3046 3046
3047static int wm8996_soc_volatile_register(struct snd_soc_codec *codec,
3048 unsigned int reg)
3049{
3050 return true;
3051}
3052
3053static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { 3047static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
3054 .probe = wm8996_probe, 3048 .probe = wm8996_probe,
3055 .remove = wm8996_remove, 3049 .remove = wm8996_remove,
3056 .set_bias_level = wm8996_set_bias_level, 3050 .set_bias_level = wm8996_set_bias_level,
3051 .idle_bias_off = true,
3057 .seq_notifier = wm8996_seq_notifier, 3052 .seq_notifier = wm8996_seq_notifier,
3058 .controls = wm8996_snd_controls, 3053 .controls = wm8996_snd_controls,
3059 .num_controls = ARRAY_SIZE(wm8996_snd_controls), 3054 .num_controls = ARRAY_SIZE(wm8996_snd_controls),
@@ -3062,12 +3057,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
3062 .dapm_routes = wm8996_dapm_routes, 3057 .dapm_routes = wm8996_dapm_routes,
3063 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), 3058 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
3064 .set_pll = wm8996_set_fll, 3059 .set_pll = wm8996_set_fll,
3065 .reg_cache_size = WM8996_MAX_REGISTER,
3066 .volatile_register = wm8996_soc_volatile_register,
3067}; 3060};
3068 3061
3069#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 3062#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
3070 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) 3063 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
3064 SNDRV_PCM_RATE_48000)
3071#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 3065#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
3072 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ 3066 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
3073 SNDRV_PCM_FMTBIT_S32_LE) 3067 SNDRV_PCM_FMTBIT_S32_LE)
@@ -3087,6 +3081,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3087 .channels_max = 6, 3081 .channels_max = 6,
3088 .rates = WM8996_RATES, 3082 .rates = WM8996_RATES,
3089 .formats = WM8996_FORMATS, 3083 .formats = WM8996_FORMATS,
3084 .sig_bits = 24,
3090 }, 3085 },
3091 .capture = { 3086 .capture = {
3092 .stream_name = "AIF1 Capture", 3087 .stream_name = "AIF1 Capture",
@@ -3094,6 +3089,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3094 .channels_max = 6, 3089 .channels_max = 6,
3095 .rates = WM8996_RATES, 3090 .rates = WM8996_RATES,
3096 .formats = WM8996_FORMATS, 3091 .formats = WM8996_FORMATS,
3092 .sig_bits = 24,
3097 }, 3093 },
3098 .ops = &wm8996_dai_ops, 3094 .ops = &wm8996_dai_ops,
3099 }, 3095 },
@@ -3105,6 +3101,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3105 .channels_max = 2, 3101 .channels_max = 2,
3106 .rates = WM8996_RATES, 3102 .rates = WM8996_RATES,
3107 .formats = WM8996_FORMATS, 3103 .formats = WM8996_FORMATS,
3104 .sig_bits = 24,
3108 }, 3105 },
3109 .capture = { 3106 .capture = {
3110 .stream_name = "AIF2 Capture", 3107 .stream_name = "AIF2 Capture",
@@ -3112,6 +3109,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3112 .channels_max = 2, 3109 .channels_max = 2,
3113 .rates = WM8996_RATES, 3110 .rates = WM8996_RATES,
3114 .formats = WM8996_FORMATS, 3111 .formats = WM8996_FORMATS,
3112 .sig_bits = 24,
3115 }, 3113 },
3116 .ops = &wm8996_dai_ops, 3114 .ops = &wm8996_dai_ops,
3117 }, 3115 },
@@ -3149,25 +3147,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3149 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3147 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3150 wm8996->supplies[i].supply = wm8996_supply_names[i]; 3148 wm8996->supplies[i].supply = wm8996_supply_names[i];
3151 3149
3152 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), 3150 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
3153 wm8996->supplies); 3151 wm8996->supplies);
3154 if (ret != 0) { 3152 if (ret != 0) {
3155 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); 3153 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
3156 goto err_gpio; 3154 goto err_gpio;
3157 } 3155 }
3158 3156
3159 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
3160 if (IS_ERR(wm8996->cpvdd)) {
3161 ret = PTR_ERR(wm8996->cpvdd);
3162 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
3163 goto err_get;
3164 }
3165
3166 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), 3157 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3167 wm8996->supplies); 3158 wm8996->supplies);
3168 if (ret != 0) { 3159 if (ret != 0) {
3169 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 3160 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
3170 goto err_cpvdd; 3161 goto err_gpio;
3171 } 3162 }
3172 3163
3173 if (wm8996->pdata.ldo_ena > 0) { 3164 if (wm8996->pdata.ldo_ena > 0) {
@@ -3188,7 +3179,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3188 goto err_regmap; 3179 goto err_regmap;
3189 } 3180 }
3190 if (reg != 0x8915) { 3181 if (reg != 0x8915) {
3191 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); 3182 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);
3192 ret = -EINVAL; 3183 ret = -EINVAL;
3193 goto err_regmap; 3184 goto err_regmap;
3194 } 3185 }
@@ -3229,10 +3220,6 @@ err_enable:
3229 if (wm8996->pdata.ldo_ena > 0) 3220 if (wm8996->pdata.ldo_ena > 0)
3230 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3221 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3231 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3222 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3232err_cpvdd:
3233 regulator_put(wm8996->cpvdd);
3234err_get:
3235 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3236err_gpio: 3223err_gpio:
3237 if (wm8996->pdata.ldo_ena > 0) 3224 if (wm8996->pdata.ldo_ena > 0)
3238 gpio_free(wm8996->pdata.ldo_ena); 3225 gpio_free(wm8996->pdata.ldo_ena);
@@ -3247,8 +3234,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3247 3234
3248 snd_soc_unregister_codec(&client->dev); 3235 snd_soc_unregister_codec(&client->dev);
3249 wm8996_free_gpio(wm8996); 3236 wm8996_free_gpio(wm8996);
3250 regulator_put(wm8996->cpvdd);
3251 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3252 regmap_exit(wm8996->regmap); 3237 regmap_exit(wm8996->regmap);
3253 if (wm8996->pdata.ldo_ena > 0) { 3238 if (wm8996->pdata.ldo_ena > 0) {
3254 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3239 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3273,25 +3258,7 @@ static struct i2c_driver wm8996_i2c_driver = {
3273 .id_table = wm8996_i2c_id, 3258 .id_table = wm8996_i2c_id,
3274}; 3259};
3275 3260
3276static int __init wm8996_modinit(void) 3261module_i2c_driver(wm8996_i2c_driver);
3277{
3278 int ret;
3279
3280 ret = i2c_add_driver(&wm8996_i2c_driver);
3281 if (ret != 0) {
3282 printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n",
3283 ret);
3284 }
3285
3286 return ret;
3287}
3288module_init(wm8996_modinit);
3289
3290static void __exit wm8996_exit(void)
3291{
3292 i2c_del_driver(&wm8996_i2c_driver);
3293}
3294module_exit(wm8996_exit);
3295 3262
3296MODULE_DESCRIPTION("ASoC WM8996 driver"); 3263MODULE_DESCRIPTION("ASoC WM8996 driver");
3297MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3264MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a6bab392700e..076c126ed9b1 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
824static int wm9081_set_bias_level(struct snd_soc_codec *codec, 824static int wm9081_set_bias_level(struct snd_soc_codec *codec,
825 enum snd_soc_bias_level level) 825 enum snd_soc_bias_level level)
826{ 826{
827 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
828
827 switch (level) { 829 switch (level) {
828 case SND_SOC_BIAS_ON: 830 case SND_SOC_BIAS_ON:
829 break; 831 break;
@@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
841 case SND_SOC_BIAS_STANDBY: 843 case SND_SOC_BIAS_STANDBY:
842 /* Initial cold start */ 844 /* Initial cold start */
843 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 845 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
846 regcache_cache_only(wm9081->regmap, false);
847 regcache_sync(wm9081->regmap);
848
844 /* Disable LINEOUT discharge */ 849 /* Disable LINEOUT discharge */
845 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, 850 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
846 WM9081_LINEOUT_DISCH, 0); 851 WM9081_LINEOUT_DISCH, 0);
@@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
892 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, 897 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
893 WM9081_LINEOUT_DISCH, 898 WM9081_LINEOUT_DISCH,
894 WM9081_LINEOUT_DISCH); 899 WM9081_LINEOUT_DISCH);
900
901 regcache_cache_only(wm9081->regmap, true);
895 break; 902 break;
896 } 903 }
897 904
@@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1258{ 1265{
1259 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1266 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1260 int ret; 1267 int ret;
1261 u16 reg;
1262 1268
1263 codec->control_data = wm9081->regmap; 1269 codec->control_data = wm9081->regmap;
1264 1270
@@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1268 return ret; 1274 return ret;
1269 } 1275 }
1270 1276
1271 reg = 0;
1272 if (wm9081->pdata.irq_high)
1273 reg |= WM9081_IRQ_POL;
1274 if (!wm9081->pdata.irq_cmos)
1275 reg |= WM9081_IRQ_OP_CTRL;
1276 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1277 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1278
1279 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1280
1281 /* Enable zero cross by default */ 1277 /* Enable zero cross by default */
1282 snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, 1278 snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
1283 WM9081_LINEOUTZC, WM9081_LINEOUTZC); 1279 WM9081_LINEOUTZC, WM9081_LINEOUTZC);
@@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1287 if (!wm9081->pdata.num_retune_configs) { 1283 if (!wm9081->pdata.num_retune_configs) {
1288 dev_dbg(codec->dev, 1284 dev_dbg(codec->dev,
1289 "No ReTune Mobile data, using normal EQ\n"); 1285 "No ReTune Mobile data, using normal EQ\n");
1290 snd_soc_add_controls(codec, wm9081_eq_controls, 1286 snd_soc_add_codec_controls(codec, wm9081_eq_controls,
1291 ARRAY_SIZE(wm9081_eq_controls)); 1287 ARRAY_SIZE(wm9081_eq_controls));
1292 } 1288 }
1293 1289
@@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec)
1300 return 0; 1296 return 0;
1301} 1297}
1302 1298
1303#ifdef CONFIG_PM
1304static int wm9081_suspend(struct snd_soc_codec *codec)
1305{
1306 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1307
1308 return 0;
1309}
1310
1311static int wm9081_resume(struct snd_soc_codec *codec)
1312{
1313 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1314
1315 regcache_sync(wm9081->regmap);
1316
1317 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1318
1319 return 0;
1320}
1321#else
1322#define wm9081_suspend NULL
1323#define wm9081_resume NULL
1324#endif
1325
1326static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { 1299static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1327 .probe = wm9081_probe, 1300 .probe = wm9081_probe,
1328 .remove = wm9081_remove, 1301 .remove = wm9081_remove,
1329 .suspend = wm9081_suspend,
1330 .resume = wm9081_resume,
1331 1302
1332 .set_sysclk = wm9081_set_sysclk, 1303 .set_sysclk = wm9081_set_sysclk,
1333 .set_bias_level = wm9081_set_bias_level, 1304 .set_bias_level = wm9081_set_bias_level,
1334 1305
1306 .idle_bias_off = true,
1307
1335 .controls = wm9081_snd_controls, 1308 .controls = wm9081_snd_controls,
1336 .num_controls = ARRAY_SIZE(wm9081_snd_controls), 1309 .num_controls = ARRAY_SIZE(wm9081_snd_controls),
1337 .dapm_widgets = wm9081_dapm_widgets, 1310 .dapm_widgets = wm9081_dapm_widgets,
@@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1395 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), 1368 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1396 sizeof(wm9081->pdata)); 1369 sizeof(wm9081->pdata));
1397 1370
1371 reg = 0;
1372 if (wm9081->pdata.irq_high)
1373 reg |= WM9081_IRQ_POL;
1374 if (!wm9081->pdata.irq_cmos)
1375 reg |= WM9081_IRQ_OP_CTRL;
1376 regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL,
1377 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1378
1379 regcache_cache_only(wm9081->regmap, true);
1380
1398 ret = snd_soc_register_codec(&i2c->dev, 1381 ret = snd_soc_register_codec(&i2c->dev,
1399 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1382 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1400 if (ret < 0) 1383 if (ret < 0)
@@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = {
1435}; 1418};
1436#endif 1419#endif
1437 1420
1438static int __init wm9081_modinit(void) 1421module_i2c_driver(wm9081_i2c_driver);
1439{
1440 int ret = 0;
1441#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1442 ret = i2c_add_driver(&wm9081_i2c_driver);
1443 if (ret != 0) {
1444 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
1445 ret);
1446 }
1447#endif
1448 return ret;
1449}
1450module_init(wm9081_modinit);
1451
1452static void __exit wm9081_exit(void)
1453{
1454#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1455 i2c_del_driver(&wm9081_i2c_driver);
1456#endif
1457}
1458module_exit(wm9081_exit);
1459
1460 1422
1461MODULE_DESCRIPTION("ASoC WM9081 driver"); 1423MODULE_DESCRIPTION("ASoC WM9081 driver");
1462MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1424MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 41ebe0dce772..4b263b6edf13 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/regmap.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
29#include <sound/initval.h> 30#include <sound/initval.h>
30#include <sound/soc.h> 31#include <sound/soc.h>
@@ -33,116 +34,51 @@
33 34
34#include "wm9090.h" 35#include "wm9090.h"
35 36
36static const u16 wm9090_reg_defaults[] = { 37static const struct reg_default wm9090_reg_defaults[] = {
37 0x9093, /* R0 - Software Reset */ 38 { 1, 0x0006 }, /* R1 - Power Management (1) */
38 0x0006, /* R1 - Power Management (1) */ 39 { 2, 0x6000 }, /* R2 - Power Management (2) */
39 0x6000, /* R2 - Power Management (2) */ 40 { 3, 0x0000 }, /* R3 - Power Management (3) */
40 0x0000, /* R3 - Power Management (3) */ 41 { 6, 0x01C0 }, /* R6 - Clocking 1 */
41 0x0000, /* R4 */ 42 { 22, 0x0003 }, /* R22 - IN1 Line Control */
42 0x0000, /* R5 */ 43 { 23, 0x0003 }, /* R23 - IN2 Line Control */
43 0x01C0, /* R6 - Clocking 1 */ 44 { 24, 0x0083 }, /* R24 - IN1 Line Input A Volume */
44 0x0000, /* R7 */ 45 { 25, 0x0083 }, /* R25 - IN1 Line Input B Volume */
45 0x0000, /* R8 */ 46 { 26, 0x0083 }, /* R26 - IN2 Line Input A Volume */
46 0x0000, /* R9 */ 47 { 27, 0x0083 }, /* R27 - IN2 Line Input B Volume */
47 0x0000, /* R10 */ 48 { 28, 0x002D }, /* R28 - Left Output Volume */
48 0x0000, /* R11 */ 49 { 29, 0x002D }, /* R29 - Right Output Volume */
49 0x0000, /* R12 */ 50 { 34, 0x0100 }, /* R34 - SPKMIXL Attenuation */
50 0x0000, /* R13 */ 51 { 35, 0x0010 }, /* R36 - SPKOUT Mixers */
51 0x0000, /* R14 */ 52 { 37, 0x0140 }, /* R37 - ClassD3 */
52 0x0000, /* R15 */ 53 { 38, 0x0039 }, /* R38 - Speaker Volume Left */
53 0x0000, /* R16 */ 54 { 45, 0x0000 }, /* R45 - Output Mixer1 */
54 0x0000, /* R17 */ 55 { 46, 0x0000 }, /* R46 - Output Mixer2 */
55 0x0000, /* R18 */ 56 { 47, 0x0100 }, /* R47 - Output Mixer3 */
56 0x0000, /* R19 */ 57 { 48, 0x0100 }, /* R48 - Output Mixer4 */
57 0x0000, /* R20 */ 58 { 54, 0x0000 }, /* R54 - Speaker Mixer */
58 0x0000, /* R21 */ 59 { 57, 0x000D }, /* R57 - AntiPOP2 */
59 0x0003, /* R22 - IN1 Line Control */ 60 { 70, 0x0000 }, /* R70 - Write Sequencer 0 */
60 0x0003, /* R23 - IN2 Line Control */ 61 { 71, 0x0000 }, /* R71 - Write Sequencer 1 */
61 0x0083, /* R24 - IN1 Line Input A Volume */ 62 { 72, 0x0000 }, /* R72 - Write Sequencer 2 */
62 0x0083, /* R25 - IN1 Line Input B Volume */ 63 { 73, 0x0000 }, /* R73 - Write Sequencer 3 */
63 0x0083, /* R26 - IN2 Line Input A Volume */ 64 { 74, 0x0000 }, /* R74 - Write Sequencer 4 */
64 0x0083, /* R27 - IN2 Line Input B Volume */ 65 { 75, 0x0000 }, /* R75 - Write Sequencer 5 */
65 0x002D, /* R28 - Left Output Volume */ 66 { 76, 0x1F25 }, /* R76 - Charge Pump 1 */
66 0x002D, /* R29 - Right Output Volume */ 67 { 85, 0x054A }, /* R85 - DC Servo 1 */
67 0x0000, /* R30 */ 68 { 87, 0x0000 }, /* R87 - DC Servo 3 */
68 0x0000, /* R31 */ 69 { 96, 0x0100 }, /* R96 - Analogue HP 0 */
69 0x0000, /* R32 */ 70 { 98, 0x8640 }, /* R98 - AGC Control 0 */
70 0x0000, /* R33 */ 71 { 99, 0xC000 }, /* R99 - AGC Control 1 */
71 0x0100, /* R34 - SPKMIXL Attenuation */ 72 { 100, 0x0200 }, /* R100 - AGC Control 2 */
72 0x0000, /* R35 */
73 0x0010, /* R36 - SPKOUT Mixers */
74 0x0140, /* R37 - ClassD3 */
75 0x0039, /* R38 - Speaker Volume Left */
76 0x0000, /* R39 */
77 0x0000, /* R40 */
78 0x0000, /* R41 */
79 0x0000, /* R42 */
80 0x0000, /* R43 */
81 0x0000, /* R44 */
82 0x0000, /* R45 - Output Mixer1 */
83 0x0000, /* R46 - Output Mixer2 */
84 0x0100, /* R47 - Output Mixer3 */
85 0x0100, /* R48 - Output Mixer4 */
86 0x0000, /* R49 */
87 0x0000, /* R50 */
88 0x0000, /* R51 */
89 0x0000, /* R52 */
90 0x0000, /* R53 */
91 0x0000, /* R54 - Speaker Mixer */
92 0x0000, /* R55 */
93 0x0000, /* R56 */
94 0x000D, /* R57 - AntiPOP2 */
95 0x0000, /* R58 */
96 0x0000, /* R59 */
97 0x0000, /* R60 */
98 0x0000, /* R61 */
99 0x0000, /* R62 */
100 0x0000, /* R63 */
101 0x0000, /* R64 */
102 0x0000, /* R65 */
103 0x0000, /* R66 */
104 0x0000, /* R67 */
105 0x0000, /* R68 */
106 0x0000, /* R69 */
107 0x0000, /* R70 - Write Sequencer 0 */
108 0x0000, /* R71 - Write Sequencer 1 */
109 0x0000, /* R72 - Write Sequencer 2 */
110 0x0000, /* R73 - Write Sequencer 3 */
111 0x0000, /* R74 - Write Sequencer 4 */
112 0x0000, /* R75 - Write Sequencer 5 */
113 0x1F25, /* R76 - Charge Pump 1 */
114 0x0000, /* R77 */
115 0x0000, /* R78 */
116 0x0000, /* R79 */
117 0x0000, /* R80 */
118 0x0000, /* R81 */
119 0x0000, /* R82 */
120 0x0000, /* R83 */
121 0x0000, /* R84 - DC Servo 0 */
122 0x054A, /* R85 - DC Servo 1 */
123 0x0000, /* R86 */
124 0x0000, /* R87 - DC Servo 3 */
125 0x0000, /* R88 - DC Servo Readback 0 */
126 0x0000, /* R89 - DC Servo Readback 1 */
127 0x0000, /* R90 - DC Servo Readback 2 */
128 0x0000, /* R91 */
129 0x0000, /* R92 */
130 0x0000, /* R93 */
131 0x0000, /* R94 */
132 0x0000, /* R95 */
133 0x0100, /* R96 - Analogue HP 0 */
134 0x0000, /* R97 */
135 0x8640, /* R98 - AGC Control 0 */
136 0xC000, /* R99 - AGC Control 1 */
137 0x0200, /* R100 - AGC Control 2 */
138}; 73};
139 74
140/* This struct is used to save the context */ 75/* This struct is used to save the context */
141struct wm9090_priv { 76struct wm9090_priv {
142 struct wm9090_platform_data pdata; 77 struct wm9090_platform_data pdata;
78 struct regmap *regmap;
143}; 79};
144 80
145static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) 81static bool wm9090_volatile(struct device *dev, unsigned int reg)
146{ 82{
147 switch (reg) { 83 switch (reg) {
148 case WM9090_SOFTWARE_RESET: 84 case WM9090_SOFTWARE_RESET:
@@ -150,10 +86,60 @@ static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
150 case WM9090_DC_SERVO_READBACK_0: 86 case WM9090_DC_SERVO_READBACK_0:
151 case WM9090_DC_SERVO_READBACK_1: 87 case WM9090_DC_SERVO_READBACK_1:
152 case WM9090_DC_SERVO_READBACK_2: 88 case WM9090_DC_SERVO_READBACK_2:
153 return 1; 89 return true;
154 90
155 default: 91 default:
156 return 0; 92 return false;
93 }
94}
95
96static bool wm9090_readable(struct device *dev, unsigned int reg)
97{
98 switch (reg) {
99 case WM9090_SOFTWARE_RESET:
100 case WM9090_POWER_MANAGEMENT_1:
101 case WM9090_POWER_MANAGEMENT_2:
102 case WM9090_POWER_MANAGEMENT_3:
103 case WM9090_CLOCKING_1:
104 case WM9090_IN1_LINE_CONTROL:
105 case WM9090_IN2_LINE_CONTROL:
106 case WM9090_IN1_LINE_INPUT_A_VOLUME:
107 case WM9090_IN1_LINE_INPUT_B_VOLUME:
108 case WM9090_IN2_LINE_INPUT_A_VOLUME:
109 case WM9090_IN2_LINE_INPUT_B_VOLUME:
110 case WM9090_LEFT_OUTPUT_VOLUME:
111 case WM9090_RIGHT_OUTPUT_VOLUME:
112 case WM9090_SPKMIXL_ATTENUATION:
113 case WM9090_SPKOUT_MIXERS:
114 case WM9090_CLASSD3:
115 case WM9090_SPEAKER_VOLUME_LEFT:
116 case WM9090_OUTPUT_MIXER1:
117 case WM9090_OUTPUT_MIXER2:
118 case WM9090_OUTPUT_MIXER3:
119 case WM9090_OUTPUT_MIXER4:
120 case WM9090_SPEAKER_MIXER:
121 case WM9090_ANTIPOP2:
122 case WM9090_WRITE_SEQUENCER_0:
123 case WM9090_WRITE_SEQUENCER_1:
124 case WM9090_WRITE_SEQUENCER_2:
125 case WM9090_WRITE_SEQUENCER_3:
126 case WM9090_WRITE_SEQUENCER_4:
127 case WM9090_WRITE_SEQUENCER_5:
128 case WM9090_CHARGE_PUMP_1:
129 case WM9090_DC_SERVO_0:
130 case WM9090_DC_SERVO_1:
131 case WM9090_DC_SERVO_3:
132 case WM9090_DC_SERVO_READBACK_0:
133 case WM9090_DC_SERVO_READBACK_1:
134 case WM9090_DC_SERVO_READBACK_2:
135 case WM9090_ANALOGUE_HP_0:
136 case WM9090_AGC_CONTROL_0:
137 case WM9090_AGC_CONTROL_1:
138 case WM9090_AGC_CONTROL_2:
139 return true;
140
141 default:
142 return false;
157 } 143 }
158} 144}
159 145
@@ -447,7 +433,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
447 433
448 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 434 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
449 435
450 snd_soc_add_controls(codec, wm9090_controls, 436 snd_soc_add_codec_controls(codec, wm9090_controls,
451 ARRAY_SIZE(wm9090_controls)); 437 ARRAY_SIZE(wm9090_controls));
452 438
453 if (wm9090->pdata.lin1_diff) { 439 if (wm9090->pdata.lin1_diff) {
@@ -456,7 +442,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
456 } else { 442 } else {
457 snd_soc_dapm_add_routes(dapm, audio_map_in1_se, 443 snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
458 ARRAY_SIZE(audio_map_in1_se)); 444 ARRAY_SIZE(audio_map_in1_se));
459 snd_soc_add_controls(codec, wm9090_in1_se_controls, 445 snd_soc_add_codec_controls(codec, wm9090_in1_se_controls,
460 ARRAY_SIZE(wm9090_in1_se_controls)); 446 ARRAY_SIZE(wm9090_in1_se_controls));
461 } 447 }
462 448
@@ -466,7 +452,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
466 } else { 452 } else {
467 snd_soc_dapm_add_routes(dapm, audio_map_in2_se, 453 snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
468 ARRAY_SIZE(audio_map_in2_se)); 454 ARRAY_SIZE(audio_map_in2_se));
469 snd_soc_add_controls(codec, wm9090_in2_se_controls, 455 snd_soc_add_codec_controls(codec, wm9090_in2_se_controls,
470 ARRAY_SIZE(wm9090_in2_se_controls)); 456 ARRAY_SIZE(wm9090_in2_se_controls));
471 } 457 }
472 458
@@ -492,8 +478,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
492static int wm9090_set_bias_level(struct snd_soc_codec *codec, 478static int wm9090_set_bias_level(struct snd_soc_codec *codec,
493 enum snd_soc_bias_level level) 479 enum snd_soc_bias_level level)
494{ 480{
495 u16 *reg_cache = codec->reg_cache; 481 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
496 int i, ret;
497 482
498 switch (level) { 483 switch (level) {
499 case SND_SOC_BIAS_ON: 484 case SND_SOC_BIAS_ON:
@@ -513,7 +498,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
513 case SND_SOC_BIAS_STANDBY: 498 case SND_SOC_BIAS_STANDBY:
514 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 499 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
515 /* Restore the register cache */ 500 /* Restore the register cache */
516 snd_soc_cache_sync(codec); 501 regcache_sync(wm9090->regmap);
517 } 502 }
518 503
519 /* We keep VMID off during standby since the combination of 504 /* We keep VMID off during standby since the combination of
@@ -537,26 +522,16 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
537 522
538static int wm9090_probe(struct snd_soc_codec *codec) 523static int wm9090_probe(struct snd_soc_codec *codec)
539{ 524{
525 struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev);
540 int ret; 526 int ret;
541 527
542 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 528 codec->control_data = wm9090->regmap;
529 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
543 if (ret != 0) { 530 if (ret != 0) {
544 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 531 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
545 return ret; 532 return ret;
546 } 533 }
547 534
548 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
549 if (ret < 0)
550 return ret;
551 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
552 dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
553 return -EINVAL;
554 }
555
556 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
557 if (ret < 0)
558 return ret;
559
560 /* Configure some defaults; they will be written out when we 535 /* Configure some defaults; they will be written out when we
561 * bring the bias up. 536 * bring the bias up.
562 */ 537 */
@@ -624,16 +599,27 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
624 .suspend = wm9090_suspend, 599 .suspend = wm9090_suspend,
625 .resume = wm9090_resume, 600 .resume = wm9090_resume,
626 .set_bias_level = wm9090_set_bias_level, 601 .set_bias_level = wm9090_set_bias_level,
627 .reg_cache_size = (WM9090_MAX_REGISTER + 1),
628 .reg_word_size = sizeof(u16),
629 .reg_cache_default = wm9090_reg_defaults,
630 .volatile_register = wm9090_volatile,
631}; 602};
632 603
604static const struct regmap_config wm9090_regmap = {
605 .reg_bits = 8,
606 .val_bits = 16,
607
608 .max_register = WM9090_MAX_REGISTER,
609 .volatile_reg = wm9090_volatile,
610 .readable_reg = wm9090_readable,
611
612 .cache_type = REGCACHE_RBTREE,
613 .reg_defaults = wm9090_reg_defaults,
614 .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults),
615};
616
617
633static int wm9090_i2c_probe(struct i2c_client *i2c, 618static int wm9090_i2c_probe(struct i2c_client *i2c,
634 const struct i2c_device_id *id) 619 const struct i2c_device_id *id)
635{ 620{
636 struct wm9090_priv *wm9090; 621 struct wm9090_priv *wm9090;
622 unsigned int reg;
637 int ret; 623 int ret;
638 624
639 wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL); 625 wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
@@ -642,6 +628,26 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
642 return -ENOMEM; 628 return -ENOMEM;
643 } 629 }
644 630
631 wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap);
632 if (IS_ERR(wm9090->regmap)) {
633 ret = PTR_ERR(wm9090->regmap);
634 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
635 return ret;
636 }
637
638 ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, &reg);
639 if (ret < 0)
640 goto err;
641 if (reg != 0x9093) {
642 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
643 ret = -ENODEV;
644 goto err;
645 }
646
647 ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
648 if (ret < 0)
649 goto err;
650
645 if (i2c->dev.platform_data) 651 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data, 652 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata)); 653 sizeof(wm9090->pdata));
@@ -650,6 +656,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
650 656
651 ret = snd_soc_register_codec(&i2c->dev, 657 ret = snd_soc_register_codec(&i2c->dev,
652 &soc_codec_dev_wm9090, NULL, 0); 658 &soc_codec_dev_wm9090, NULL, 0);
659 if (ret != 0) {
660 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
661 goto err;
662 }
663
664 return 0;
665
666err:
667 regmap_exit(wm9090->regmap);
653 return ret; 668 return ret;
654} 669}
655 670
@@ -658,6 +673,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
658 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); 673 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
659 674
660 snd_soc_unregister_codec(&i2c->dev); 675 snd_soc_unregister_codec(&i2c->dev);
676 regmap_exit(wm9090->regmap);
661 677
662 return 0; 678 return 0;
663} 679}
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 40c92ead85a3..cacc6a86b46f 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -351,7 +351,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
351 if (ret) 351 if (ret)
352 goto reset_err; 352 goto reset_err;
353 353
354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls,
355 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
356 356
357 return 0; 357 return 0;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index b7b31f84c10b..b342ae50bcd6 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,10 +20,9 @@
20#include <sound/ac97_codec.h> 20#include <sound/ac97_codec.h>
21#include <sound/initval.h> 21#include <sound/initval.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/tlv.h>
23#include "wm9712.h" 24#include "wm9712.h"
24 25
25#define WM9712_VERSION "0.4"
26
27static unsigned int ac97_read(struct snd_soc_codec *codec, 26static unsigned int ac97_read(struct snd_soc_codec *codec,
28 unsigned int reg); 27 unsigned int reg);
29static int ac97_write(struct snd_soc_codec *codec, 28static int ac97_write(struct snd_soc_codec *codec,
@@ -71,6 +70,9 @@ static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer",
71static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; 70static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"};
72static const char *wm9712_diff_sel[] = {"Mic", "Line"}; 71static const char *wm9712_diff_sel[] = {"Mic", "Line"};
73 72
73static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
74static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0);
75
74static const struct soc_enum wm9712_enum[] = { 76static const struct soc_enum wm9712_enum[] = {
75SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), 77SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select),
76SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), 78SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux),
@@ -149,9 +151,9 @@ SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
149SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), 151SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
150SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 152SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
151 153
152SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 154SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
153SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 155SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
154SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 156SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv),
155}; 157};
156 158
157/* We have to create a fake left and right HP mixers because 159/* We have to create a fake left and right HP mixers because
@@ -619,8 +621,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
619{ 621{
620 int ret = 0; 622 int ret = 0;
621 623
622 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
623
624 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 624 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
625 if (ret < 0) { 625 if (ret < 0) {
626 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 626 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
@@ -637,7 +637,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
637 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); 637 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
638 638
639 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 639 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
640 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 640 snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls,
641 ARRAY_SIZE(wm9712_snd_ac97_controls)); 641 ARRAY_SIZE(wm9712_snd_ac97_controls));
642 642
643 return 0; 643 return 0;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2b8479bfcd93..2d22cc70d536 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1216,7 +1216,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1216 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1216 reg = ac97_read(codec, AC97_CD) & 0x7fff;
1217 ac97_write(codec, AC97_CD, reg); 1217 ac97_write(codec, AC97_CD, reg);
1218 1218
1219 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1219 snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls,
1220 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1220 ARRAY_SIZE(wm9713_snd_ac97_controls));
1221 1221
1222 return 0; 1222 return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 8a68cea4a3ee..f13f2886339c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -172,7 +172,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
172 break; 172 break;
173 default: 173 default:
174 WARN(1, "Unknown DCS readback method\n"); 174 WARN(1, "Unknown DCS readback method\n");
175 break; 175 return;
176 } 176 }
177 177
178 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 178 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
@@ -207,7 +207,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
207 207
208 /* Save the callibrated offset if we're in class W mode and 208 /* Save the callibrated offset if we're in class W mode and
209 * therefore don't have any analogue signal mixed in. */ 209 * therefore don't have any analogue signal mixed in. */
210 if (hubs->class_w) 210 if (hubs->class_w && !hubs->no_cache_class_w)
211 hubs->class_w_dcs = dcs_cfg; 211 hubs->class_w_dcs = dcs_cfg;
212} 212}
213 213
@@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
500 return 0; 500 return 0;
501} 501}
502 502
503static int lineout_event(struct snd_soc_dapm_widget *w,
504 struct snd_kcontrol *control, int event)
505{
506 struct snd_soc_codec *codec = w->codec;
507 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
508 bool *flag;
509
510 switch (w->shift) {
511 case WM8993_LINEOUT1N_ENA_SHIFT:
512 flag = &hubs->lineout1n_ena;
513 break;
514 case WM8993_LINEOUT1P_ENA_SHIFT:
515 flag = &hubs->lineout1p_ena;
516 break;
517 case WM8993_LINEOUT2N_ENA_SHIFT:
518 flag = &hubs->lineout2n_ena;
519 break;
520 case WM8993_LINEOUT2P_ENA_SHIFT:
521 flag = &hubs->lineout2p_ena;
522 break;
523 default:
524 WARN(1, "Unknown line output");
525 return -EINVAL;
526 }
527
528 *flag = SND_SOC_DAPM_EVENT_ON(event);
529
530 return 0;
531}
532
503static const struct snd_kcontrol_new in1l_pga[] = { 533static const struct snd_kcontrol_new in1l_pga[] = {
504SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), 534SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
505SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), 535SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
@@ -613,8 +643,6 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
613SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), 643SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
614SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), 644SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
615 645
616SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0),
617
618SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, 646SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
619 in1l_pga, ARRAY_SIZE(in1l_pga)), 647 in1l_pga, ARRAY_SIZE(in1l_pga)),
620SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, 648SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
@@ -640,9 +668,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
640 668
641SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, 669SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
642 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 670 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
643SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 671SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
644 NULL, 0, 672 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
645 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
646 673
647SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 674SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
648 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), 675 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
@@ -656,10 +683,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
656 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), 683 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
657 684
658SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), 685SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
659SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, 686SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
660 NULL, 0), 687 NULL, 0),
661SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, 688SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
662 NULL, 0), 689 NULL, 0),
663 690
664SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, 691SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
665 line1_mix, ARRAY_SIZE(line1_mix)), 692 line1_mix, ARRAY_SIZE(line1_mix)),
@@ -675,14 +702,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
675SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, 702SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
676 line2p_mix, ARRAY_SIZE(line2p_mix)), 703 line2p_mix, ARRAY_SIZE(line2p_mix)),
677 704
678SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, 705SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
679 NULL, 0), 706 NULL, 0, lineout_event,
680SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, 707 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
681 NULL, 0), 708SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
682SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, 709 NULL, 0, lineout_event,
683 NULL, 0), 710 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
684SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, 711SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
685 NULL, 0), 712 NULL, 0, lineout_event,
713 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
714SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
715 NULL, 0, lineout_event,
716 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
686 717
687SND_SOC_DAPM_OUTPUT("SPKOUTLP"), 718SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
688SND_SOC_DAPM_OUTPUT("SPKOUTLN"), 719SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
@@ -836,11 +867,9 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
836}; 867};
837 868
838static const struct snd_soc_dapm_route lineout1_se_routes[] = { 869static const struct snd_soc_dapm_route lineout1_se_routes[] = {
839 { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" },
840 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, 870 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
841 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, 871 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
842 872
843 { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" },
844 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, 873 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
845 874
846 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, 875 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
@@ -857,11 +886,9 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
857}; 886};
858 887
859static const struct snd_soc_dapm_route lineout2_se_routes[] = { 888static const struct snd_soc_dapm_route lineout2_se_routes[] = {
860 { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" },
861 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, 889 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
862 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, 890 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
863 891
864 { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" },
865 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, 892 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
866 893
867 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, 894 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
@@ -901,7 +928,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
901 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 928 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
902 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 929 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
903 930
904 snd_soc_add_controls(codec, analogue_snd_controls, 931 snd_soc_add_codec_controls(codec, analogue_snd_controls,
905 ARRAY_SIZE(analogue_snd_controls)); 932 ARRAY_SIZE(analogue_snd_controls));
906 933
907 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, 934 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
@@ -949,6 +976,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
949 int jd_scthr, int jd_thr, int micbias1_lvl, 976 int jd_scthr, int jd_thr, int micbias1_lvl,
950 int micbias2_lvl) 977 int micbias2_lvl)
951{ 978{
979 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
980
981 hubs->lineout1_se = !lineout1_diff;
982 hubs->lineout2_se = !lineout2_diff;
983
952 if (!lineout1_diff) 984 if (!lineout1_diff)
953 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 985 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
954 WM8993_LINEOUT1_MODE, 986 WM8993_LINEOUT1_MODE,
@@ -958,11 +990,10 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
958 WM8993_LINEOUT2_MODE, 990 WM8993_LINEOUT2_MODE,
959 WM8993_LINEOUT2_MODE); 991 WM8993_LINEOUT2_MODE);
960 992
961 /* If the line outputs are differential then we aren't presenting 993 if (!lineout1_diff && !lineout2_diff)
962 * VMID as an output and can disable it. 994 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
963 */ 995 WM8993_LINEOUT_VMID_BUF_ENA,
964 if (lineout1_diff && lineout2_diff) 996 WM8993_LINEOUT_VMID_BUF_ENA);
965 codec->dapm.idle_bias_off = 1;
966 997
967 if (lineout1fb) 998 if (lineout1fb)
968 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 999 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
@@ -984,6 +1015,69 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
984} 1015}
985EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); 1016EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
986 1017
1018void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
1019{
1020 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1021 int val = 0;
1022
1023 if (hubs->lineout1_se)
1024 val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
1025
1026 if (hubs->lineout2_se)
1027 val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
1028
1029 /* Enable the line outputs while we power up */
1030 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
1031}
1032EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
1033
1034void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
1035 enum snd_soc_bias_level level)
1036{
1037 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1038 int val;
1039
1040 switch (level) {
1041 case SND_SOC_BIAS_STANDBY:
1042 /* Clamp the inputs to VMID while we ramp to charge caps */
1043 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1044 WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
1045 break;
1046
1047 case SND_SOC_BIAS_ON:
1048 /* Turn off any unneded single ended outputs */
1049 val = 0;
1050
1051 if (hubs->lineout1_se && hubs->lineout1n_ena)
1052 val |= WM8993_LINEOUT1N_ENA;
1053
1054 if (hubs->lineout1_se && hubs->lineout1p_ena)
1055 val |= WM8993_LINEOUT1P_ENA;
1056
1057 if (hubs->lineout2_se && hubs->lineout2n_ena)
1058 val |= WM8993_LINEOUT2N_ENA;
1059
1060 if (hubs->lineout2_se && hubs->lineout2p_ena)
1061 val |= WM8993_LINEOUT2P_ENA;
1062
1063 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
1064 WM8993_LINEOUT1N_ENA |
1065 WM8993_LINEOUT1P_ENA |
1066 WM8993_LINEOUT2N_ENA |
1067 WM8993_LINEOUT2P_ENA,
1068 val);
1069
1070 /* Remove the input clamps */
1071 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1072 WM8993_INPUTS_CLAMP, 0);
1073 break;
1074
1075 default:
1076 break;
1077 }
1078}
1079EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
1080
987MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 1081MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
988MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1082MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
989MODULE_LICENSE("GPL"); 1083MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index c674c7a502a6..5705276f4943 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -30,9 +30,18 @@ struct wm_hubs_data {
30 int series_startup; 30 int series_startup;
31 int no_series_update; 31 int no_series_update;
32 32
33 bool no_cache_class_w;
33 bool class_w; 34 bool class_w;
34 u16 class_w_dcs; 35 u16 class_w_dcs;
35 36
37 bool lineout1_se;
38 bool lineout1n_ena;
39 bool lineout1p_ena;
40
41 bool lineout2_se;
42 bool lineout2n_ena;
43 bool lineout2p_ena;
44
36 bool dcs_done_irq; 45 bool dcs_done_irq;
37 struct completion dcs_done; 46 struct completion dcs_done;
38}; 47};
@@ -46,5 +55,8 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
46 int micbias1_lvl, int micbias2_lvl); 55 int micbias1_lvl, int micbias2_lvl);
47 56
48extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); 57extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
58extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
59extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
60 enum snd_soc_bias_level level);
49 61
50#endif 62#endif
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index b26401f87b85..97d77b298968 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -826,7 +826,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
826 } 826 }
827} 827}
828 828
829static u64 davinci_pcm_dmamask = 0xffffffff; 829static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32);
830 830
831static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) 831static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
832{ 832{
@@ -837,7 +837,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
837 if (!card->dev->dma_mask) 837 if (!card->dev->dma_mask)
838 card->dev->dma_mask = &davinci_pcm_dmamask; 838 card->dev->dma_mask = &davinci_pcm_dmamask;
839 if (!card->dev->coherent_dma_mask) 839 if (!card->dev->coherent_dma_mask)
840 card->dev->coherent_dma_mask = 0xffffffff; 840 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
841 841
842 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 842 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
843 ret = davinci_pcm_preallocate_dma_buffer(pcm, 843 ret = davinci_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
index 91a28de94109..88143db7e753 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/ep93xx/Kconfig
@@ -1,6 +1,7 @@
1config SND_EP93XX_SOC 1config SND_EP93XX_SOC
2 tristate "SoC Audio support for the Cirrus Logic EP93xx series" 2 tristate "SoC Audio support for the Cirrus Logic EP93xx series"
3 depends on ARCH_EP93XX && SND_SOC 3 depends on ARCH_EP93XX && SND_SOC
4 select SND_SOC_DMAENGINE_PCM
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the EP93xx I2S or AC97 interfaces. 7 the EP93xx I2S or AC97 interfaces.
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index de8390449873..162dbb74f4cc 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -23,6 +23,7 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h>
26 27
27#include <mach/dma.h> 28#include <mach/dma.h>
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -52,26 +53,6 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
52 .fifo_size = 32, 53 .fifo_size = 32,
53}; 54};
54 55
55struct ep93xx_runtime_data
56{
57 int pointer_bytes;
58 int periods;
59 int period_bytes;
60 struct dma_chan *dma_chan;
61 struct ep93xx_dma_data dma_data;
62};
63
64static void ep93xx_pcm_dma_callback(void *data)
65{
66 struct snd_pcm_substream *substream = data;
67 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
68
69 rtd->pointer_bytes += rtd->period_bytes;
70 rtd->pointer_bytes %= rtd->period_bytes * rtd->periods;
71
72 snd_pcm_period_elapsed(substream);
73}
74
75static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) 56static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
76{ 57{
77 struct ep93xx_dma_data *data = filter_param; 58 struct ep93xx_dma_data *data = filter_param;
@@ -86,98 +67,48 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
86 67
87static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 68static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
88{ 69{
89 struct snd_soc_pcm_runtime *soc_rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai; 71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 struct ep93xx_pcm_dma_params *dma_params; 72 struct ep93xx_pcm_dma_params *dma_params;
92 struct ep93xx_runtime_data *rtd; 73 struct ep93xx_dma_data *dma_data;
93 dma_cap_mask_t mask;
94 int ret; 74 int ret;
95 75
96 ret = snd_pcm_hw_constraint_integer(substream->runtime,
97 SNDRV_PCM_HW_PARAM_PERIODS);
98 if (ret < 0)
99 return ret;
100
101 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); 76 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
102 77
103 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); 78 dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL);
104 if (!rtd) 79 if (!dma_data)
105 return -ENOMEM; 80 return -ENOMEM;
106 81
107 dma_cap_zero(mask);
108 dma_cap_set(DMA_SLAVE, mask);
109 dma_cap_set(DMA_CYCLIC, mask);
110
111 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); 82 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
112 rtd->dma_data.port = dma_params->dma_port; 83 dma_data->port = dma_params->dma_port;
113 rtd->dma_data.name = dma_params->name; 84 dma_data->name = dma_params->name;
114 85 dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 rtd->dma_data.direction = DMA_MEM_TO_DEV;
117 else
118 rtd->dma_data.direction = DMA_DEV_TO_MEM;
119
120 rtd->dma_chan = dma_request_channel(mask, ep93xx_pcm_dma_filter,
121 &rtd->dma_data);
122 if (!rtd->dma_chan) {
123 kfree(rtd);
124 return -EINVAL;
125 }
126
127 substream->runtime->private_data = rtd;
128 return 0;
129}
130 86
131static int ep93xx_pcm_close(struct snd_pcm_substream *substream) 87 ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
132{ 88 if (ret) {
133 struct ep93xx_runtime_data *rtd = substream->runtime->private_data; 89 kfree(dma_data);
90 return ret;
91 }
134 92
135 dma_release_channel(rtd->dma_chan); 93 snd_dmaengine_pcm_set_data(substream, dma_data);
136 kfree(rtd);
137 return 0;
138}
139 94
140static int ep93xx_pcm_dma_submit(struct snd_pcm_substream *substream)
141{
142 struct snd_pcm_runtime *runtime = substream->runtime;
143 struct ep93xx_runtime_data *rtd = runtime->private_data;
144 struct dma_chan *chan = rtd->dma_chan;
145 struct dma_device *dma_dev = chan->device;
146 struct dma_async_tx_descriptor *desc;
147
148 rtd->pointer_bytes = 0;
149 desc = dma_dev->device_prep_dma_cyclic(chan, runtime->dma_addr,
150 rtd->period_bytes * rtd->periods,
151 rtd->period_bytes,
152 rtd->dma_data.direction);
153 if (!desc)
154 return -EINVAL;
155
156 desc->callback = ep93xx_pcm_dma_callback;
157 desc->callback_param = substream;
158
159 dmaengine_submit(desc);
160 return 0; 95 return 0;
161} 96}
162 97
163static void ep93xx_pcm_dma_flush(struct snd_pcm_substream *substream) 98static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
164{ 99{
165 struct snd_pcm_runtime *runtime = substream->runtime; 100 struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
166 struct ep93xx_runtime_data *rtd = runtime->private_data;
167 101
168 dmaengine_terminate_all(rtd->dma_chan); 102 snd_dmaengine_pcm_close(substream);
103 kfree(dma_data);
104 return 0;
169} 105}
170 106
171static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, 107static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
172 struct snd_pcm_hw_params *params) 108 struct snd_pcm_hw_params *params)
173{ 109{
174 struct snd_pcm_runtime *runtime = substream->runtime;
175 struct ep93xx_runtime_data *rtd = runtime->private_data;
176
177 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 110 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
178 111
179 rtd->periods = params_periods(params);
180 rtd->period_bytes = params_period_bytes(params);
181 return 0; 112 return 0;
182} 113}
183 114
@@ -187,41 +118,6 @@ static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
187 return 0; 118 return 0;
188} 119}
189 120
190static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
191{
192 int ret;
193
194 ret = 0;
195 switch (cmd) {
196 case SNDRV_PCM_TRIGGER_START:
197 case SNDRV_PCM_TRIGGER_RESUME:
198 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
199 ret = ep93xx_pcm_dma_submit(substream);
200 break;
201
202 case SNDRV_PCM_TRIGGER_STOP:
203 case SNDRV_PCM_TRIGGER_SUSPEND:
204 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
205 ep93xx_pcm_dma_flush(substream);
206 break;
207
208 default:
209 ret = -EINVAL;
210 break;
211 }
212
213 return ret;
214}
215
216static snd_pcm_uframes_t ep93xx_pcm_pointer(struct snd_pcm_substream *substream)
217{
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
220
221 /* FIXME: implement this with sub-period granularity */
222 return bytes_to_frames(runtime, rtd->pointer_bytes);
223}
224
225static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, 121static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
226 struct vm_area_struct *vma) 122 struct vm_area_struct *vma)
227{ 123{
@@ -239,8 +135,8 @@ static struct snd_pcm_ops ep93xx_pcm_ops = {
239 .ioctl = snd_pcm_lib_ioctl, 135 .ioctl = snd_pcm_lib_ioctl,
240 .hw_params = ep93xx_pcm_hw_params, 136 .hw_params = ep93xx_pcm_hw_params,
241 .hw_free = ep93xx_pcm_hw_free, 137 .hw_free = ep93xx_pcm_hw_free,
242 .trigger = ep93xx_pcm_trigger, 138 .trigger = snd_dmaengine_pcm_trigger,
243 .pointer = ep93xx_pcm_pointer, 139 .pointer = snd_dmaengine_pcm_pointer,
244 .mmap = ep93xx_pcm_mmap, 140 .mmap = ep93xx_pcm_mmap,
245}; 141};
246 142
@@ -281,7 +177,7 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
281 } 177 }
282} 178}
283 179
284static u64 ep93xx_pcm_dmamask = 0xffffffff; 180static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32);
285 181
286static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) 182static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
287{ 183{
@@ -292,7 +188,7 @@ static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
292 if (!card->dev->dma_mask) 188 if (!card->dev->dma_mask)
293 card->dev->dma_mask = &ep93xx_pcm_dmamask; 189 card->dev->dma_mask = &ep93xx_pcm_dmamask;
294 if (!card->dev->coherent_dma_mask) 190 if (!card->dev->coherent_dma_mask)
295 card->dev->coherent_dma_mask = 0xffffffff; 191 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
296 192
297 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 193 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
298 ret = ep93xx_pcm_preallocate_dma_buffer(pcm, 194 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 4f59bbaba48f..96bb92dd174c 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -311,23 +311,23 @@ static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
311 * should allocate a DMA buffer only for the streams that are valid. 311 * should allocate a DMA buffer only for the streams that are valid.
312 */ 312 */
313 313
314 if (pcm->streams[0].substream) { 314 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
315 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, 315 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
316 fsl_dma_hardware.buffer_bytes_max, 316 fsl_dma_hardware.buffer_bytes_max,
317 &pcm->streams[0].substream->dma_buffer); 317 &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
318 if (ret) { 318 if (ret) {
319 dev_err(card->dev, "can't alloc playback dma buffer\n"); 319 dev_err(card->dev, "can't alloc playback dma buffer\n");
320 return ret; 320 return ret;
321 } 321 }
322 } 322 }
323 323
324 if (pcm->streams[1].substream) { 324 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
325 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, 325 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
326 fsl_dma_hardware.buffer_bytes_max, 326 fsl_dma_hardware.buffer_bytes_max,
327 &pcm->streams[1].substream->dma_buffer); 327 &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
328 if (ret) { 328 if (ret) {
329 dev_err(card->dev, "can't alloc capture dma buffer\n"); 329 dev_err(card->dev, "can't alloc capture dma buffer\n");
330 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); 330 snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
331 return ret; 331 return ret;
332 } 332 }
333 } 333 }
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 3e066966d878..2eb407fa3b48 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -716,12 +716,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
716 } 716 }
717 717
718 /* Trigger the machine driver's probe function. The platform driver 718 /* Trigger the machine driver's probe function. The platform driver
719 * name of the machine driver is taken from the /model property of the 719 * name of the machine driver is taken from /compatible property of the
720 * device tree. We also pass the address of the CPU DAI driver 720 * device tree. We also pass the address of the CPU DAI driver
721 * structure. 721 * structure.
722 */ 722 */
723 sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); 723 sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
724 /* Sometimes the model name has a "fsl," prefix, so we strip that. */ 724 /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
725 p = strrchr(sprop, ','); 725 p = strrchr(sprop, ',');
726 if (p) 726 if (p)
727 sprop = p + 1; 727 sprop = p + 1;
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index e7803d34c425..9a3f7c5ab687 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/dma-mapping.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
12#include <linux/of_platform.h> 13#include <linux/of_platform.h>
13 14
@@ -298,7 +299,7 @@ static struct snd_pcm_ops psc_dma_ops = {
298 .hw_params = psc_dma_hw_params, 299 .hw_params = psc_dma_hw_params,
299}; 300};
300 301
301static u64 psc_dma_dmamask = 0xffffffff; 302static u64 psc_dma_dmamask = DMA_BIT_MASK(32);
302static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) 303static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
303{ 304{
304 struct snd_card *card = rtd->card->snd_card; 305 struct snd_card *card = rtd->card->snd_card;
@@ -314,18 +315,18 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
314 if (!card->dev->dma_mask) 315 if (!card->dev->dma_mask)
315 card->dev->dma_mask = &psc_dma_dmamask; 316 card->dev->dma_mask = &psc_dma_dmamask;
316 if (!card->dev->coherent_dma_mask) 317 if (!card->dev->coherent_dma_mask)
317 card->dev->coherent_dma_mask = 0xffffffff; 318 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
318 319
319 if (pcm->streams[0].substream) { 320 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
320 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, 321 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
321 size, &pcm->streams[0].substream->dma_buffer); 322 size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
322 if (rc) 323 if (rc)
323 goto playback_alloc_err; 324 goto playback_alloc_err;
324 } 325 }
325 326
326 if (pcm->streams[1].substream) { 327 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
327 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, 328 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
328 size, &pcm->streams[1].substream->dma_buffer); 329 size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
329 if (rc) 330 if (rc)
330 goto capture_alloc_err; 331 goto capture_alloc_err;
331 } 332 }
@@ -336,8 +337,8 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
336 return 0; 337 return 0;
337 338
338 capture_alloc_err: 339 capture_alloc_err:
339 if (pcm->streams[0].substream) 340 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
340 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); 341 snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
341 342
342 playback_alloc_err: 343 playback_alloc_err:
343 dev_err(card->dev, "Cannot allocate buffer(s)\n"); 344 dev_err(card->dev, "Cannot allocate buffer(s)\n");
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 0ea4a5a96e06..afbabf427f27 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -245,7 +245,7 @@ static int get_parent_cell_index(struct device_node *np)
245 * 'struct device' It's ugly and hackish, but it works. 245 * 'struct device' It's ugly and hackish, but it works.
246 * 246 *
247 * The dev_name for such devices include the bus number and I2C address. For 247 * The dev_name for such devices include the bus number and I2C address. For
248 * example, "cs4270-codec.0-004f". 248 * example, "cs4270.0-004f".
249 */ 249 */
250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) 250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
251{ 251{
@@ -267,13 +267,13 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
267 if (!i2c) 267 if (!i2c)
268 return -ENODEV; 268 return -ENODEV;
269 269
270 snprintf(buf, len, "%s-codec.%u-%04x", temp, i2c->adapter->nr, addr); 270 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
271 271
272 return 0; 272 return 0;
273} 273}
274 274
275static int get_dma_channel(struct device_node *ssi_np, 275static int get_dma_channel(struct device_node *ssi_np,
276 const char *compatible, 276 const char *name,
277 struct snd_soc_dai_link *dai, 277 struct snd_soc_dai_link *dai,
278 unsigned int *dma_channel_id, 278 unsigned int *dma_channel_id,
279 unsigned int *dma_id) 279 unsigned int *dma_id)
@@ -283,7 +283,7 @@ static int get_dma_channel(struct device_node *ssi_np,
283 const u32 *iprop; 283 const u32 *iprop;
284 int ret; 284 int ret;
285 285
286 dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, 286 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
287 "fsl,ssi-dma-channel"); 287 "fsl,ssi-dma-channel");
288 if (!dma_channel_np) 288 if (!dma_channel_np)
289 return -EINVAL; 289 return -EINVAL;
@@ -336,12 +336,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
336 const char *sprop; 336 const char *sprop;
337 const u32 *iprop; 337 const u32 *iprop;
338 338
339 /* We are only interested in SSIs with a codec phandle in them, 339 /* Find the codec node for this SSI. */
340 * so let's make sure this SSI has one. The MPC8610 HPCD only 340 codec_np = of_parse_phandle(np, "codec-handle", 0);
341 * knows about the CS4270 codec, so reject anything else.
342 */
343 codec_np = get_node_by_phandle_name(np, "codec-handle",
344 "cirrus,cs4270");
345 if (!codec_np) { 341 if (!codec_np) {
346 dev_err(dev, "invalid codec node\n"); 342 dev_err(dev, "invalid codec node\n");
347 return -EINVAL; 343 return -EINVAL;
@@ -550,7 +546,7 @@ static struct platform_driver mpc8610_hpcd_driver = {
550 .probe = mpc8610_hpcd_probe, 546 .probe = mpc8610_hpcd_probe,
551 .remove = __devexit_p(mpc8610_hpcd_remove), 547 .remove = __devexit_p(mpc8610_hpcd_remove),
552 .driver = { 548 .driver = {
553 /* The name must match the 'model' property in the device tree, 549 /* The name must match 'compatible' property in the device tree,
554 * in lowercase letters. 550 * in lowercase letters.
555 */ 551 */
556 .name = "snd-soc-mpc8610hpcd", 552 .name = "snd-soc-mpc8610hpcd",
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index a5d4e80a9cf4..46623405a2ce 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -276,7 +276,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
276} 276}
277 277
278static int get_dma_channel(struct device_node *ssi_np, 278static int get_dma_channel(struct device_node *ssi_np,
279 const char *compatible, 279 const char *name,
280 struct snd_soc_dai_link *dai, 280 struct snd_soc_dai_link *dai,
281 unsigned int *dma_channel_id, 281 unsigned int *dma_channel_id,
282 unsigned int *dma_id) 282 unsigned int *dma_id)
@@ -286,7 +286,7 @@ static int get_dma_channel(struct device_node *ssi_np,
286 const u32 *iprop; 286 const u32 *iprop;
287 int ret; 287 int ret;
288 288
289 dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, 289 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
290 "fsl,ssi-dma-channel"); 290 "fsl,ssi-dma-channel");
291 if (!dma_channel_np) 291 if (!dma_channel_np)
292 return -EINVAL; 292 return -EINVAL;
@@ -395,7 +395,8 @@ static int p1022_ds_probe(struct platform_device *pdev)
395 } 395 }
396 396
397 if (strcasecmp(sprop, "i2s-slave") == 0) { 397 if (strcasecmp(sprop, "i2s-slave") == 0) {
398 mdata->dai_format = SND_SOC_DAIFMT_I2S; 398 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
399 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
399 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; 400 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
400 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; 401 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
401 402
@@ -412,31 +413,38 @@ static int p1022_ds_probe(struct platform_device *pdev)
412 } 413 }
413 mdata->clk_frequency = be32_to_cpup(iprop); 414 mdata->clk_frequency = be32_to_cpup(iprop);
414 } else if (strcasecmp(sprop, "i2s-master") == 0) { 415 } else if (strcasecmp(sprop, "i2s-master") == 0) {
415 mdata->dai_format = SND_SOC_DAIFMT_I2S; 416 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
417 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
416 mdata->codec_clk_direction = SND_SOC_CLOCK_IN; 418 mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
417 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; 419 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
418 } else if (strcasecmp(sprop, "lj-slave") == 0) { 420 } else if (strcasecmp(sprop, "lj-slave") == 0) {
419 mdata->dai_format = SND_SOC_DAIFMT_LEFT_J; 421 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
422 SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
420 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; 423 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
421 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; 424 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
422 } else if (strcasecmp(sprop, "lj-master") == 0) { 425 } else if (strcasecmp(sprop, "lj-master") == 0) {
423 mdata->dai_format = SND_SOC_DAIFMT_LEFT_J; 426 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
427 SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
424 mdata->codec_clk_direction = SND_SOC_CLOCK_IN; 428 mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
425 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; 429 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
426 } else if (strcasecmp(sprop, "rj-slave") == 0) { 430 } else if (strcasecmp(sprop, "rj-slave") == 0) {
427 mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J; 431 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
432 SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
428 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; 433 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
429 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; 434 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
430 } else if (strcasecmp(sprop, "rj-master") == 0) { 435 } else if (strcasecmp(sprop, "rj-master") == 0) {
431 mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J; 436 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
437 SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
432 mdata->codec_clk_direction = SND_SOC_CLOCK_IN; 438 mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
433 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; 439 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
434 } else if (strcasecmp(sprop, "ac97-slave") == 0) { 440 } else if (strcasecmp(sprop, "ac97-slave") == 0) {
435 mdata->dai_format = SND_SOC_DAIFMT_AC97; 441 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
442 SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
436 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; 443 mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
437 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; 444 mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
438 } else if (strcasecmp(sprop, "ac97-master") == 0) { 445 } else if (strcasecmp(sprop, "ac97-master") == 0) {
439 mdata->dai_format = SND_SOC_DAIFMT_AC97; 446 mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
447 SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
440 mdata->codec_clk_direction = SND_SOC_CLOCK_IN; 448 mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
441 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; 449 mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
442 } else { 450 } else {
@@ -543,6 +551,11 @@ static struct platform_driver p1022_ds_driver = {
543 .probe = p1022_ds_probe, 551 .probe = p1022_ds_probe,
544 .remove = __devexit_p(p1022_ds_remove), 552 .remove = __devexit_p(p1022_ds_remove),
545 .driver = { 553 .driver = {
554 /*
555 * The name must match 'compatible' property in the device tree,
556 * in lowercase letters.
557 */
558 .name = "snd-soc-p1022ds",
546 .owner = THIS_MODULE, 559 .owner = THIS_MODULE,
547 }, 560 },
548}; 561};
@@ -556,33 +569,6 @@ static int __init p1022_ds_init(void)
556{ 569{
557 struct device_node *guts_np; 570 struct device_node *guts_np;
558 struct resource res; 571 struct resource res;
559 const char *sprop;
560
561 /*
562 * Check if we're actually running on a P1022DS. Older device trees
563 * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we
564 * need to support both. The SSI driver uses that property to link to
565 * the machine driver, so have to match it.
566 */
567 sprop = of_get_property(of_find_node_by_path("/"), "model", NULL);
568 if (!sprop) {
569 pr_err("snd-soc-p1022ds: missing /model node");
570 return -ENODEV;
571 }
572
573 pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop);
574
575 /*
576 * The name of this board, taken from the device tree. Normally, this is a*
577 * fixed string, but some P1022DS device trees have a /model property of
578 * "fsl,P1022", and others have "fsl,P1022DS".
579 */
580 if (strcasecmp(sprop, "fsl,p1022ds") == 0)
581 p1022_ds_driver.driver.name = "snd-soc-p1022ds";
582 else if (strcasecmp(sprop, "fsl,p1022") == 0)
583 p1022_ds_driver.driver.name = "snd-soc-p1022";
584 else
585 return -ENODEV;
586 572
587 /* Get the physical address of the global utilities registers */ 573 /* Get the physical address of the global utilities registers */
588 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); 574 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 738391757f2c..810acaa09009 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,9 +1,6 @@
1menuconfig SND_IMX_SOC 1menuconfig SND_IMX_SOC
2 tristate "SoC Audio for Freescale i.MX CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MXC 3 depends on ARCH_MXC
4 select SND_PCM
5 select FIQ
6 select SND_SOC_AC97_BUS
7 help 4 help
8 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
9 the i.MX SSI interface. 6 the i.MX SSI interface.
@@ -11,10 +8,23 @@ menuconfig SND_IMX_SOC
11 8
12if SND_IMX_SOC 9if SND_IMX_SOC
13 10
11config SND_SOC_IMX_SSI
12 tristate
13
14config SND_SOC_IMX_PCM
15 tristate
16
14config SND_MXC_SOC_FIQ 17config SND_MXC_SOC_FIQ
15 tristate 18 tristate
19 select FIQ
20 select SND_SOC_IMX_PCM
16 21
17config SND_MXC_SOC_MX2 22config SND_MXC_SOC_MX2
23 select SND_SOC_DMAENGINE_PCM
24 tristate
25 select SND_SOC_IMX_PCM
26
27config SND_SOC_IMX_AUDMUX
18 tristate 28 tristate
19 29
20config SND_MXC_SOC_WM1133_EV1 30config SND_MXC_SOC_WM1133_EV1
@@ -22,6 +32,8 @@ config SND_MXC_SOC_WM1133_EV1
22 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL 32 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
23 select SND_SOC_WM8350 33 select SND_SOC_WM8350
24 select SND_MXC_SOC_FIQ 34 select SND_MXC_SOC_FIQ
35 select SND_SOC_IMX_AUDMUX
36 select SND_SOC_IMX_SSI
25 help 37 help
26 Enable support for audio on the i.MX31ADS with the WM1133-EV1 38 Enable support for audio on the i.MX31ADS with the WM1133-EV1
27 PMIC board with WM8835x fitted. 39 PMIC board with WM8835x fitted.
@@ -31,6 +43,8 @@ config SND_SOC_MX27VIS_AIC32X4
31 depends on MACH_IMX27_VISSTRIM_M10 && I2C 43 depends on MACH_IMX27_VISSTRIM_M10 && I2C
32 select SND_SOC_TLV320AIC32X4 44 select SND_SOC_TLV320AIC32X4
33 select SND_MXC_SOC_MX2 45 select SND_MXC_SOC_MX2
46 select SND_SOC_IMX_AUDMUX
47 select SND_SOC_IMX_SSI
34 help 48 help
35 Say Y if you want to add support for SoC audio on Visstrim SM10 49 Say Y if you want to add support for SoC audio on Visstrim SM10
36 board with TLV320AIC32X4 codec. 50 board with TLV320AIC32X4 codec.
@@ -38,8 +52,11 @@ config SND_SOC_MX27VIS_AIC32X4
38config SND_SOC_PHYCORE_AC97 52config SND_SOC_PHYCORE_AC97
39 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 53 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
40 depends on MACH_PCM043 || MACH_PCA100 54 depends on MACH_PCM043 || MACH_PCA100
55 select SND_SOC_AC97_BUS
41 select SND_SOC_WM9712 56 select SND_SOC_WM9712
42 select SND_MXC_SOC_FIQ 57 select SND_MXC_SOC_FIQ
58 select SND_SOC_IMX_AUDMUX
59 select SND_SOC_IMX_SSI
43 help 60 help
44 Say Y if you want to add support for SoC audio on Phytec phyCORE 61 Say Y if you want to add support for SoC audio on Phytec phyCORE
45 and phyCARD boards in AC97 mode 62 and phyCARD boards in AC97 mode
@@ -53,6 +70,8 @@ config SND_SOC_EUKREA_TLV320
53 depends on I2C 70 depends on I2C
54 select SND_SOC_TLV320AIC23 71 select SND_SOC_TLV320AIC23
55 select SND_MXC_SOC_FIQ 72 select SND_MXC_SOC_FIQ
73 select SND_SOC_IMX_AUDMUX
74 select SND_SOC_IMX_SSI
56 help 75 help
57 Enable I2S based access to the TLV320AIC23B codec attached 76 Enable I2S based access to the TLV320AIC23B codec attached
58 to the SSI interface 77 to the SSI interface
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index d6d609ba7e24..f5db3e92d0d1 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,11 +1,14 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-imx-objs := imx-ssi.o 2snd-soc-imx-ssi-objs := imx-ssi.o
3snd-soc-imx-fiq-objs := imx-pcm-fiq.o 3snd-soc-imx-audmux-objs := imx-audmux.o
4snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
5 4
6obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o 5obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
7obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o 6obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
8obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o 7
8obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
9snd-soc-imx-pcm-y := imx-pcm.o
10snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
11snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
9 12
10# i.MX Machine Support 13# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 14snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index 1c1fdd10f73f..7d4475cfdb24 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -26,6 +26,7 @@
26 26
27#include "../codecs/tlv320aic23.h" 27#include "../codecs/tlv320aic23.h"
28#include "imx-ssi.h" 28#include "imx-ssi.h"
29#include "imx-audmux.h"
29 30
30#define CODEC_CLOCK 12000000 31#define CODEC_CLOCK 12000000
31 32
@@ -97,12 +98,43 @@ static struct platform_device *eukrea_tlv320_snd_device;
97static int __init eukrea_tlv320_init(void) 98static int __init eukrea_tlv320_init(void)
98{ 99{
99 int ret; 100 int ret;
100 101 int int_port = 0, ext_port;
101 if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd() 102
102 && !machine_is_eukrea_cpuimx35sd() 103 if (machine_is_eukrea_cpuimx27()) {
103 && !machine_is_eukrea_cpuimx51sd()) 104 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
105 IMX_AUDMUX_V1_PCR_SYN |
106 IMX_AUDMUX_V1_PCR_TFSDIR |
107 IMX_AUDMUX_V1_PCR_TCLKDIR |
108 IMX_AUDMUX_V1_PCR_RFSDIR |
109 IMX_AUDMUX_V1_PCR_RCLKDIR |
110 IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
111 IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
112 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
113 );
114 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
115 IMX_AUDMUX_V1_PCR_SYN |
116 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
117 );
118 } else if (machine_is_eukrea_cpuimx25sd() ||
119 machine_is_eukrea_cpuimx35sd() ||
120 machine_is_eukrea_cpuimx51sd()) {
121 ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
122 imx_audmux_v2_configure_port(int_port,
123 IMX_AUDMUX_V2_PTCR_SYN |
124 IMX_AUDMUX_V2_PTCR_TFSDIR |
125 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
126 IMX_AUDMUX_V2_PTCR_TCLKDIR |
127 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port),
128 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)
129 );
130 imx_audmux_v2_configure_port(ext_port,
131 IMX_AUDMUX_V2_PTCR_SYN,
132 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
133 );
134 } else {
104 /* return happy. We might run on a totally different machine */ 135 /* return happy. We might run on a totally different machine */
105 return 0; 136 return 0;
137 }
106 138
107 eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1); 139 eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
108 if (!eukrea_tlv320_snd_device) 140 if (!eukrea_tlv320_snd_device)
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c
new file mode 100644
index 000000000000..a839494c5ea8
--- /dev/null
+++ b/sound/soc/imx/imx-audmux.c
@@ -0,0 +1,314 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * Initial development of this code was funded by
7 * Phytec Messtechnik GmbH, http://www.phytec.de
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/clk.h>
21#include <linux/debugfs.h>
22#include <linux/err.h>
23#include <linux/io.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/of_device.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29
30#include "imx-audmux.h"
31
32#define DRIVER_NAME "imx-audmux"
33
34static struct clk *audmux_clk;
35static void __iomem *audmux_base;
36
37#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
38#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
39
40#ifdef CONFIG_DEBUG_FS
41static struct dentry *audmux_debugfs_root;
42
43static int audmux_open_file(struct inode *inode, struct file *file)
44{
45 file->private_data = inode->i_private;
46 return 0;
47}
48
49/* There is an annoying discontinuity in the SSI numbering with regard
50 * to the Linux number of the devices */
51static const char *audmux_port_string(int port)
52{
53 switch (port) {
54 case MX31_AUDMUX_PORT1_SSI0:
55 return "imx-ssi.0";
56 case MX31_AUDMUX_PORT2_SSI1:
57 return "imx-ssi.1";
58 case MX31_AUDMUX_PORT3_SSI_PINS_3:
59 return "SSI3";
60 case MX31_AUDMUX_PORT4_SSI_PINS_4:
61 return "SSI4";
62 case MX31_AUDMUX_PORT5_SSI_PINS_5:
63 return "SSI5";
64 case MX31_AUDMUX_PORT6_SSI_PINS_6:
65 return "SSI6";
66 default:
67 return "UNKNOWN";
68 }
69}
70
71static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
72 size_t count, loff_t *ppos)
73{
74 ssize_t ret;
75 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
76 int port = (int)file->private_data;
77 u32 pdcr, ptcr;
78
79 if (!buf)
80 return -ENOMEM;
81
82 if (audmux_clk)
83 clk_enable(audmux_clk);
84
85 ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
86 pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
87
88 if (audmux_clk)
89 clk_disable(audmux_clk);
90
91 ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
92 pdcr, ptcr);
93
94 if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
95 ret += snprintf(buf + ret, PAGE_SIZE - ret,
96 "TxFS output from %s, ",
97 audmux_port_string((ptcr >> 27) & 0x7));
98 else
99 ret += snprintf(buf + ret, PAGE_SIZE - ret,
100 "TxFS input, ");
101
102 if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
103 ret += snprintf(buf + ret, PAGE_SIZE - ret,
104 "TxClk output from %s",
105 audmux_port_string((ptcr >> 22) & 0x7));
106 else
107 ret += snprintf(buf + ret, PAGE_SIZE - ret,
108 "TxClk input");
109
110 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
111
112 if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
113 ret += snprintf(buf + ret, PAGE_SIZE - ret,
114 "Port is symmetric");
115 } else {
116 if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
117 ret += snprintf(buf + ret, PAGE_SIZE - ret,
118 "RxFS output from %s, ",
119 audmux_port_string((ptcr >> 17) & 0x7));
120 else
121 ret += snprintf(buf + ret, PAGE_SIZE - ret,
122 "RxFS input, ");
123
124 if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
125 ret += snprintf(buf + ret, PAGE_SIZE - ret,
126 "RxClk output from %s",
127 audmux_port_string((ptcr >> 12) & 0x7));
128 else
129 ret += snprintf(buf + ret, PAGE_SIZE - ret,
130 "RxClk input");
131 }
132
133 ret += snprintf(buf + ret, PAGE_SIZE - ret,
134 "\nData received from %s\n",
135 audmux_port_string((pdcr >> 13) & 0x7));
136
137 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
138
139 kfree(buf);
140
141 return ret;
142}
143
144static const struct file_operations audmux_debugfs_fops = {
145 .open = audmux_open_file,
146 .read = audmux_read_file,
147 .llseek = default_llseek,
148};
149
150static void __init audmux_debugfs_init(void)
151{
152 int i;
153 char buf[20];
154
155 audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
156 if (!audmux_debugfs_root) {
157 pr_warning("Failed to create AUDMUX debugfs root\n");
158 return;
159 }
160
161 for (i = 1; i < 8; i++) {
162 snprintf(buf, sizeof(buf), "ssi%d", i);
163 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
164 (void *)i, &audmux_debugfs_fops))
165 pr_warning("Failed to create AUDMUX port %d debugfs file\n",
166 i);
167 }
168}
169
170static void __devexit audmux_debugfs_remove(void)
171{
172 debugfs_remove_recursive(audmux_debugfs_root);
173}
174#else
175static inline void audmux_debugfs_init(void)
176{
177}
178
179static inline void audmux_debugfs_remove(void)
180{
181}
182#endif
183
184enum imx_audmux_type {
185 IMX21_AUDMUX,
186 IMX31_AUDMUX,
187} audmux_type;
188
189static struct platform_device_id imx_audmux_ids[] = {
190 {
191 .name = "imx21-audmux",
192 .driver_data = IMX21_AUDMUX,
193 }, {
194 .name = "imx31-audmux",
195 .driver_data = IMX31_AUDMUX,
196 }, {
197 /* sentinel */
198 }
199};
200MODULE_DEVICE_TABLE(platform, imx_audmux_ids);
201
202static const struct of_device_id imx_audmux_dt_ids[] = {
203 { .compatible = "fsl,imx21-audmux", .data = &imx_audmux_ids[0], },
204 { .compatible = "fsl,imx31-audmux", .data = &imx_audmux_ids[1], },
205 { /* sentinel */ }
206};
207MODULE_DEVICE_TABLE(of, imx_audmux_dt_ids);
208
209static const uint8_t port_mapping[] = {
210 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
211};
212
213int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
214{
215 if (audmux_type != IMX21_AUDMUX)
216 return -EINVAL;
217
218 if (!audmux_base)
219 return -ENOSYS;
220
221 if (port >= ARRAY_SIZE(port_mapping))
222 return -EINVAL;
223
224 writel(pcr, audmux_base + port_mapping[port]);
225
226 return 0;
227}
228EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
229
230int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
231 unsigned int pdcr)
232{
233 if (audmux_type != IMX31_AUDMUX)
234 return -EINVAL;
235
236 if (!audmux_base)
237 return -ENOSYS;
238
239 if (audmux_clk)
240 clk_enable(audmux_clk);
241
242 writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
243 writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
244
245 if (audmux_clk)
246 clk_disable(audmux_clk);
247
248 return 0;
249}
250EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
251
252static int __devinit imx_audmux_probe(struct platform_device *pdev)
253{
254 struct resource *res;
255 const struct of_device_id *of_id =
256 of_match_device(imx_audmux_dt_ids, &pdev->dev);
257
258 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
259 audmux_base = devm_request_and_ioremap(&pdev->dev, res);
260 if (!audmux_base)
261 return -EADDRNOTAVAIL;
262
263 audmux_clk = clk_get(&pdev->dev, "audmux");
264 if (IS_ERR(audmux_clk)) {
265 dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
266 PTR_ERR(audmux_clk));
267 audmux_clk = NULL;
268 }
269
270 if (of_id)
271 pdev->id_entry = of_id->data;
272 audmux_type = pdev->id_entry->driver_data;
273 if (audmux_type == IMX31_AUDMUX)
274 audmux_debugfs_init();
275
276 return 0;
277}
278
279static int __devexit imx_audmux_remove(struct platform_device *pdev)
280{
281 if (audmux_type == IMX31_AUDMUX)
282 audmux_debugfs_remove();
283 clk_put(audmux_clk);
284
285 return 0;
286}
287
288static struct platform_driver imx_audmux_driver = {
289 .probe = imx_audmux_probe,
290 .remove = __devexit_p(imx_audmux_remove),
291 .id_table = imx_audmux_ids,
292 .driver = {
293 .name = DRIVER_NAME,
294 .owner = THIS_MODULE,
295 .of_match_table = imx_audmux_dt_ids,
296 }
297};
298
299static int __init imx_audmux_init(void)
300{
301 return platform_driver_register(&imx_audmux_driver);
302}
303subsys_initcall(imx_audmux_init);
304
305static void __exit imx_audmux_exit(void)
306{
307 platform_driver_unregister(&imx_audmux_driver);
308}
309module_exit(imx_audmux_exit);
310
311MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver");
312MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
313MODULE_LICENSE("GPL v2");
314MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/sound/soc/imx/imx-audmux.h b/sound/soc/imx/imx-audmux.h
new file mode 100644
index 000000000000..04ebbab8d7b9
--- /dev/null
+++ b/sound/soc/imx/imx-audmux.h
@@ -0,0 +1,60 @@
1#ifndef __IMX_AUDMUX_H
2#define __IMX_AUDMUX_H
3
4#define MX27_AUDMUX_HPCR1_SSI0 0
5#define MX27_AUDMUX_HPCR2_SSI1 1
6#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
7#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
8#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
9#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
10
11#define MX31_AUDMUX_PORT1_SSI0 0
12#define MX31_AUDMUX_PORT2_SSI1 1
13#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
17
18#define MX51_AUDMUX_PORT1_SSI0 0
19#define MX51_AUDMUX_PORT2_SSI1 1
20#define MX51_AUDMUX_PORT3 2
21#define MX51_AUDMUX_PORT4 3
22#define MX51_AUDMUX_PORT5 4
23#define MX51_AUDMUX_PORT6 5
24#define MX51_AUDMUX_PORT7 6
25
26/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
27#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
28#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
29#define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10)
30#define IMX_AUDMUX_V1_PCR_SYN (1 << 12)
31#define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
32#define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
33#define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
34#define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25)
35#define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
36#define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
37#define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31)
38
39/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
40#define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
41#define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
42#define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
43#define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
44#define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
45#define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
46#define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
47#define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
48#define IMX_AUDMUX_V2_PTCR_SYN (1 << 11)
49
50#define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
51#define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
52#define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
53#define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
54
55int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
56
57int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
58 unsigned int pdcr);
59
60#endif /* __IMX_AUDMUX_H */
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 5780c9b9d569..e43c8fa2788b 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -27,212 +27,54 @@
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/dmaengine_pcm.h>
30 31
31#include <mach/dma.h> 32#include <mach/dma.h>
32 33
33#include "imx-ssi.h" 34#include "imx-pcm.h"
34
35struct imx_pcm_runtime_data {
36 int period_bytes;
37 int periods;
38 int dma;
39 unsigned long offset;
40 unsigned long size;
41 void *buf;
42 int period_time;
43 struct dma_async_tx_descriptor *desc;
44 struct dma_chan *dma_chan;
45 struct imx_dma_data dma_data;
46};
47
48static void audio_dma_irq(void *data)
49{
50 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
51 struct snd_pcm_runtime *runtime = substream->runtime;
52 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
53
54 iprtd->offset += iprtd->period_bytes;
55 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
56
57 snd_pcm_period_elapsed(substream);
58}
59 35
60static bool filter(struct dma_chan *chan, void *param) 36static bool filter(struct dma_chan *chan, void *param)
61{ 37{
62 struct imx_pcm_runtime_data *iprtd = param;
63
64 if (!imx_dma_is_general_purpose(chan)) 38 if (!imx_dma_is_general_purpose(chan))
65 return false; 39 return false;
66 40
67 chan->private = &iprtd->dma_data; 41 chan->private = param;
68 42
69 return true; 43 return true;
70} 44}
71 45
72static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, 46static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 47 struct snd_pcm_hw_params *params)
74{ 48{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
76 struct imx_pcm_dma_params *dma_params; 51 struct imx_pcm_dma_params *dma_params;
77 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
79 struct dma_slave_config slave_config; 52 struct dma_slave_config slave_config;
80 dma_cap_mask_t mask;
81 enum dma_slave_buswidth buswidth;
82 int ret; 53 int ret;
83 54
84 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 55 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
85 56
86 iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; 57 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
87 iprtd->dma_data.priority = DMA_PRIO_HIGH; 58 if (ret)
88 iprtd->dma_data.dma_request = dma_params->dma; 59 return ret;
89
90 /* Try to grab a DMA channel */
91 if (!iprtd->dma_chan) {
92 dma_cap_zero(mask);
93 dma_cap_set(DMA_SLAVE, mask);
94 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
95 if (!iprtd->dma_chan)
96 return -EINVAL;
97 }
98
99 switch (params_format(params)) {
100 case SNDRV_PCM_FORMAT_S16_LE:
101 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
102 break;
103 case SNDRV_PCM_FORMAT_S20_3LE:
104 case SNDRV_PCM_FORMAT_S24_LE:
105 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
106 break;
107 default:
108 return 0;
109 }
110 60
111 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 61 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
112 slave_config.direction = DMA_MEM_TO_DEV;
113 slave_config.dst_addr = dma_params->dma_addr; 62 slave_config.dst_addr = dma_params->dma_addr;
114 slave_config.dst_addr_width = buswidth;
115 slave_config.dst_maxburst = dma_params->burstsize; 63 slave_config.dst_maxburst = dma_params->burstsize;
116 } else { 64 } else {
117 slave_config.direction = DMA_DEV_TO_MEM;
118 slave_config.src_addr = dma_params->dma_addr; 65 slave_config.src_addr = dma_params->dma_addr;
119 slave_config.src_addr_width = buswidth;
120 slave_config.src_maxburst = dma_params->burstsize; 66 slave_config.src_maxburst = dma_params->burstsize;
121 } 67 }
122 68
123 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); 69 ret = dmaengine_slave_config(chan, &slave_config);
124 if (ret) 70 if (ret)
125 return ret; 71 return ret;
126 72
127 return 0;
128}
129
130static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
131 struct snd_pcm_hw_params *params)
132{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
136 unsigned long dma_addr;
137 struct dma_chan *chan;
138 struct imx_pcm_dma_params *dma_params;
139 int ret;
140
141 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
142 ret = imx_ssi_dma_alloc(substream, params);
143 if (ret)
144 return ret;
145 chan = iprtd->dma_chan;
146
147 iprtd->size = params_buffer_bytes(params);
148 iprtd->periods = params_periods(params);
149 iprtd->period_bytes = params_period_bytes(params);
150 iprtd->offset = 0;
151 iprtd->period_time = HZ / (params_rate(params) /
152 params_period_size(params));
153
154 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 73 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
155 74
156 dma_addr = runtime->dma_addr;
157
158 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
159
160 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
161 iprtd->period_bytes * iprtd->periods,
162 iprtd->period_bytes,
163 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
164 DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
165 if (!iprtd->desc) {
166 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
167 return -EINVAL;
168 }
169
170 iprtd->desc->callback = audio_dma_irq;
171 iprtd->desc->callback_param = substream;
172
173 return 0;
174}
175
176static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
177{
178 struct snd_pcm_runtime *runtime = substream->runtime;
179 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
180
181 if (iprtd->dma_chan) {
182 dma_release_channel(iprtd->dma_chan);
183 iprtd->dma_chan = NULL;
184 }
185
186 return 0;
187}
188
189static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
190{
191 struct snd_soc_pcm_runtime *rtd = substream->private_data;
192 struct imx_pcm_dma_params *dma_params;
193
194 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
195
196 return 0; 75 return 0;
197} 76}
198 77
199static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
203
204 switch (cmd) {
205 case SNDRV_PCM_TRIGGER_START:
206 case SNDRV_PCM_TRIGGER_RESUME:
207 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
208 dmaengine_submit(iprtd->desc);
209
210 break;
211
212 case SNDRV_PCM_TRIGGER_STOP:
213 case SNDRV_PCM_TRIGGER_SUSPEND:
214 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
215 dmaengine_terminate_all(iprtd->dma_chan);
216
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 return 0;
223}
224
225static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
226{
227 struct snd_pcm_runtime *runtime = substream->runtime;
228 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
229
230 pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
231 bytes_to_frames(substream->runtime, iprtd->offset));
232
233 return bytes_to_frames(substream->runtime, iprtd->offset);
234}
235
236static struct snd_pcm_hardware snd_imx_hardware = { 78static struct snd_pcm_hardware snd_imx_hardware = {
237 .info = SNDRV_PCM_INFO_INTERLEAVED | 79 .info = SNDRV_PCM_INFO_INTERLEAVED |
238 SNDRV_PCM_INFO_BLOCK_TRANSFER | 80 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -254,33 +96,37 @@ static struct snd_pcm_hardware snd_imx_hardware = {
254 96
255static int snd_imx_open(struct snd_pcm_substream *substream) 97static int snd_imx_open(struct snd_pcm_substream *substream)
256{ 98{
257 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
258 struct imx_pcm_runtime_data *iprtd; 100 struct imx_pcm_dma_params *dma_params;
101 struct imx_dma_data *dma_data;
259 int ret; 102 int ret;
260 103
261 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 104 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
262 if (iprtd == NULL)
263 return -ENOMEM;
264 runtime->private_data = iprtd;
265 105
266 ret = snd_pcm_hw_constraint_integer(substream->runtime, 106 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
267 SNDRV_PCM_HW_PARAM_PERIODS); 107
268 if (ret < 0) { 108 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
269 kfree(iprtd); 109 dma_data->peripheral_type = IMX_DMATYPE_SSI;
270 return ret; 110 dma_data->priority = DMA_PRIO_HIGH;
111 dma_data->dma_request = dma_params->dma;
112
113 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
114 if (ret) {
115 kfree(dma_data);
116 return 0;
271 } 117 }
272 118
273 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 119 snd_dmaengine_pcm_set_data(substream, dma_data);
274 120
275 return 0; 121 return 0;
276} 122}
277 123
278static int snd_imx_close(struct snd_pcm_substream *substream) 124static int snd_imx_close(struct snd_pcm_substream *substream)
279{ 125{
280 struct snd_pcm_runtime *runtime = substream->runtime; 126 struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
281 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
282 127
283 kfree(iprtd); 128 snd_dmaengine_pcm_close(substream);
129 kfree(dma_data);
284 130
285 return 0; 131 return 0;
286} 132}
@@ -290,10 +136,8 @@ static struct snd_pcm_ops imx_pcm_ops = {
290 .close = snd_imx_close, 136 .close = snd_imx_close,
291 .ioctl = snd_pcm_lib_ioctl, 137 .ioctl = snd_pcm_lib_ioctl,
292 .hw_params = snd_imx_pcm_hw_params, 138 .hw_params = snd_imx_pcm_hw_params,
293 .hw_free = snd_imx_pcm_hw_free, 139 .trigger = snd_dmaengine_pcm_trigger,
294 .prepare = snd_imx_pcm_prepare, 140 .pointer = snd_dmaengine_pcm_pointer,
295 .trigger = snd_imx_pcm_trigger,
296 .pointer = snd_imx_pcm_pointer,
297 .mmap = snd_imx_pcm_mmap, 141 .mmap = snd_imx_pcm_mmap,
298}; 142};
299 143
@@ -305,11 +149,6 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
305 149
306static int __devinit imx_soc_platform_probe(struct platform_device *pdev) 150static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
307{ 151{
308 struct imx_ssi *ssi = platform_get_drvdata(pdev);
309
310 ssi->dma_params_tx.burstsize = 6;
311 ssi->dma_params_rx.burstsize = 4;
312
313 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); 152 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
314} 153}
315 154
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/imx/imx-pcm.c
new file mode 100644
index 000000000000..93dc360b1777
--- /dev/null
+++ b/sound/soc/imx/imx-pcm.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * This code is based on code copyrighted by Freescale,
5 * Liam Girdwood, Javier Martin and probably others.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/dma-mapping.h>
14#include <linux/module.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include "imx-pcm.h"
18
19int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
20 struct vm_area_struct *vma)
21{
22 struct snd_pcm_runtime *runtime = substream->runtime;
23 int ret;
24
25 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
26 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
27
28 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
29 runtime->dma_area,
30 runtime->dma_addr,
31 runtime->dma_bytes);
32 return ret;
33}
34EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
35
36static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
37{
38 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
39 struct snd_dma_buffer *buf = &substream->dma_buffer;
40 size_t size = IMX_SSI_DMABUF_SIZE;
41
42 buf->dev.type = SNDRV_DMA_TYPE_DEV;
43 buf->dev.dev = pcm->card->dev;
44 buf->private_data = NULL;
45 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
46 &buf->addr, GFP_KERNEL);
47 if (!buf->area)
48 return -ENOMEM;
49 buf->bytes = size;
50
51 return 0;
52}
53
54static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
55
56int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
57{
58 struct snd_card *card = rtd->card->snd_card;
59 struct snd_pcm *pcm = rtd->pcm;
60 int ret = 0;
61
62 if (!card->dev->dma_mask)
63 card->dev->dma_mask = &imx_pcm_dmamask;
64 if (!card->dev->coherent_dma_mask)
65 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
66 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
67 ret = imx_pcm_preallocate_dma_buffer(pcm,
68 SNDRV_PCM_STREAM_PLAYBACK);
69 if (ret)
70 goto out;
71 }
72
73 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
74 ret = imx_pcm_preallocate_dma_buffer(pcm,
75 SNDRV_PCM_STREAM_CAPTURE);
76 if (ret)
77 goto out;
78 }
79
80out:
81 return ret;
82}
83EXPORT_SYMBOL_GPL(imx_pcm_new);
84
85void imx_pcm_free(struct snd_pcm *pcm)
86{
87 struct snd_pcm_substream *substream;
88 struct snd_dma_buffer *buf;
89 int stream;
90
91 for (stream = 0; stream < 2; stream++) {
92 substream = pcm->streams[stream].substream;
93 if (!substream)
94 continue;
95
96 buf = &substream->dma_buffer;
97 if (!buf->area)
98 continue;
99
100 dma_free_writecombine(pcm->card->dev, buf->bytes,
101 buf->area, buf->addr);
102 buf->area = NULL;
103 }
104}
105EXPORT_SYMBOL_GPL(imx_pcm_free);
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h
new file mode 100644
index 000000000000..b5f5c3acf34d
--- /dev/null
+++ b/sound/soc/imx/imx-pcm.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * This code is based on code copyrighted by Freescale,
5 * Liam Girdwood, Javier Martin and probably others.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _IMX_PCM_H
14#define _IMX_PCM_H
15
16/*
17 * Do not change this as the FIQ handler depends on this size
18 */
19#define IMX_SSI_DMABUF_SIZE (64 * 1024)
20
21struct imx_pcm_dma_params {
22 int dma;
23 unsigned long dma_addr;
24 int burstsize;
25};
26
27int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
28 struct vm_area_struct *vma);
29int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
30void imx_pcm_free(struct snd_pcm *pcm);
31
32#endif /* _IMX_PCM_H */
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index b6adbed6e506..4f81ed456325 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -233,6 +233,23 @@ static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
233 return 0; 233 return 0;
234} 234}
235 235
236static int imx_ssi_startup(struct snd_pcm_substream *substream,
237 struct snd_soc_dai *cpu_dai)
238{
239 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
240 struct imx_pcm_dma_params *dma_data;
241
242 /* Tx/Rx config */
243 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
244 dma_data = &ssi->dma_params_tx;
245 else
246 dma_data = &ssi->dma_params_rx;
247
248 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
249
250 return 0;
251}
252
236/* 253/*
237 * Should only be called when port is inactive (i.e. SSIEN = 0), 254 * Should only be called when port is inactive (i.e. SSIEN = 0),
238 * although can be called multiple times by upper layers. 255 * although can be called multiple times by upper layers.
@@ -242,23 +259,17 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_dai *cpu_dai) 259 struct snd_soc_dai *cpu_dai)
243{ 260{
244 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); 261 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
245 struct imx_pcm_dma_params *dma_data;
246 u32 reg, sccr; 262 u32 reg, sccr;
247 263
248 /* Tx/Rx config */ 264 /* Tx/Rx config */
249 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 265 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
250 reg = SSI_STCCR; 266 reg = SSI_STCCR;
251 dma_data = &ssi->dma_params_tx; 267 else
252 } else {
253 reg = SSI_SRCCR; 268 reg = SSI_SRCCR;
254 dma_data = &ssi->dma_params_rx;
255 }
256 269
257 if (ssi->flags & IMX_SSI_SYN) 270 if (ssi->flags & IMX_SSI_SYN)
258 reg = SSI_STCCR; 271 reg = SSI_STCCR;
259 272
260 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
261
262 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; 273 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
263 274
264 /* DAI data (word) size */ 275 /* DAI data (word) size */
@@ -343,6 +354,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
343} 354}
344 355
345static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { 356static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
357 .startup = imx_ssi_startup,
346 .hw_params = imx_ssi_hw_params, 358 .hw_params = imx_ssi_hw_params,
347 .set_fmt = imx_ssi_set_dai_fmt, 359 .set_fmt = imx_ssi_set_dai_fmt,
348 .set_clkdiv = imx_ssi_set_dai_clkdiv, 360 .set_clkdiv = imx_ssi_set_dai_clkdiv,
@@ -351,94 +363,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
351 .trigger = imx_ssi_trigger, 363 .trigger = imx_ssi_trigger,
352}; 364};
353 365
354int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
355 struct vm_area_struct *vma)
356{
357 struct snd_pcm_runtime *runtime = substream->runtime;
358 int ret;
359
360 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
361 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
362
363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
364 runtime->dma_area,
365 runtime->dma_addr,
366 runtime->dma_bytes);
367 return ret;
368}
369EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
370
371static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
372{
373 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
374 struct snd_dma_buffer *buf = &substream->dma_buffer;
375 size_t size = IMX_SSI_DMABUF_SIZE;
376
377 buf->dev.type = SNDRV_DMA_TYPE_DEV;
378 buf->dev.dev = pcm->card->dev;
379 buf->private_data = NULL;
380 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
381 &buf->addr, GFP_KERNEL);
382 if (!buf->area)
383 return -ENOMEM;
384 buf->bytes = size;
385
386 return 0;
387}
388
389static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
390
391int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
392{
393 struct snd_card *card = rtd->card->snd_card;
394 struct snd_pcm *pcm = rtd->pcm;
395 int ret = 0;
396
397 if (!card->dev->dma_mask)
398 card->dev->dma_mask = &imx_pcm_dmamask;
399 if (!card->dev->coherent_dma_mask)
400 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
401 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
402 ret = imx_pcm_preallocate_dma_buffer(pcm,
403 SNDRV_PCM_STREAM_PLAYBACK);
404 if (ret)
405 goto out;
406 }
407
408 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
409 ret = imx_pcm_preallocate_dma_buffer(pcm,
410 SNDRV_PCM_STREAM_CAPTURE);
411 if (ret)
412 goto out;
413 }
414
415out:
416 return ret;
417}
418EXPORT_SYMBOL_GPL(imx_pcm_new);
419
420void imx_pcm_free(struct snd_pcm *pcm)
421{
422 struct snd_pcm_substream *substream;
423 struct snd_dma_buffer *buf;
424 int stream;
425
426 for (stream = 0; stream < 2; stream++) {
427 substream = pcm->streams[stream].substream;
428 if (!substream)
429 continue;
430
431 buf = &substream->dma_buffer;
432 if (!buf->area)
433 continue;
434
435 dma_free_writecombine(pcm->card->dev, buf->bytes,
436 buf->area, buf->addr);
437 buf->area = NULL;
438 }
439}
440EXPORT_SYMBOL_GPL(imx_pcm_free);
441
442static int imx_ssi_dai_probe(struct snd_soc_dai *dai) 366static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
443{ 367{
444 struct imx_ssi *ssi = dev_get_drvdata(dai->dev); 368 struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
@@ -656,7 +580,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 580 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 581 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
658 582
659 ssi->dma_params_tx.burstsize = 4; 583 ssi->dma_params_tx.burstsize = 6;
660 ssi->dma_params_rx.burstsize = 4; 584 ssi->dma_params_rx.burstsize = 4;
661 585
662 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 586 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 1072dfb53e47..5744e86ca878 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -187,12 +187,7 @@
187 187
188#include <linux/dmaengine.h> 188#include <linux/dmaengine.h>
189#include <mach/dma.h> 189#include <mach/dma.h>
190 190#include "imx-pcm.h"
191struct imx_pcm_dma_params {
192 int dma;
193 unsigned long dma_addr;
194 int burstsize;
195};
196 191
197struct imx_ssi { 192struct imx_ssi {
198 struct platform_device *ac97_dev; 193 struct platform_device *ac97_dev;
@@ -218,13 +213,4 @@ struct imx_ssi {
218 struct platform_device *soc_platform_pdev_fiq; 213 struct platform_device *soc_platform_pdev_fiq;
219}; 214};
220 215
221int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
222int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
223void imx_pcm_free(struct snd_pcm *pcm);
224
225/*
226 * Do not change this as the FIQ handler depends on this size
227 */
228#define IMX_SSI_DMABUF_SIZE (64 * 1024)
229
230#endif /* _IMX_SSI_H */ 216#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
index 3c2eed9094d5..f6d04ad4bb39 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -25,15 +25,36 @@
25#include <linux/moduleparam.h> 25#include <linux/moduleparam.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/gpio.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/soc.h> 31#include <sound/soc.h>
31#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
32#include <asm/mach-types.h> 34#include <asm/mach-types.h>
33#include <mach/audmux.h> 35#include <mach/iomux-mx27.h>
34 36
35#include "../codecs/tlv320aic32x4.h" 37#include "../codecs/tlv320aic32x4.h"
36#include "imx-ssi.h" 38#include "imx-ssi.h"
39#include "imx-audmux.h"
40
41#define MX27VIS_AMP_GAIN 0
42#define MX27VIS_AMP_MUTE 1
43
44#define MX27VIS_PIN_G0 (GPIO_PORTF + 9)
45#define MX27VIS_PIN_G1 (GPIO_PORTF + 8)
46#define MX27VIS_PIN_SDL (GPIO_PORTE + 5)
47#define MX27VIS_PIN_SDR (GPIO_PORTF + 7)
48
49static int mx27vis_amp_gain;
50static int mx27vis_amp_mute;
51
52static const int mx27vis_amp_pins[] = {
53 MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
54 MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
55 MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
56 MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
57};
37 58
38static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, 59static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 60 struct snd_pcm_hw_params *params)
@@ -74,6 +95,76 @@ static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
74 .hw_params = mx27vis_aic32x4_hw_params, 95 .hw_params = mx27vis_aic32x4_hw_params,
75}; 96};
76 97
98static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_value *ucontrol)
100{
101 struct soc_mixer_control *mc =
102 (struct soc_mixer_control *)kcontrol->private_value;
103 int value = ucontrol->value.integer.value[0];
104 unsigned int reg = mc->reg;
105 int max = mc->max;
106
107 if (value > max)
108 return -EINVAL;
109
110 switch (reg) {
111 case MX27VIS_AMP_GAIN:
112 gpio_set_value(MX27VIS_PIN_G0, value & 1);
113 gpio_set_value(MX27VIS_PIN_G1, value >> 1);
114 mx27vis_amp_gain = value;
115 break;
116 case MX27VIS_AMP_MUTE:
117 gpio_set_value(MX27VIS_PIN_SDL, value & 1);
118 gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
119 mx27vis_amp_mute = value;
120 break;
121 }
122 return 0;
123}
124
125static int mx27vis_amp_get(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol)
127{
128 struct soc_mixer_control *mc =
129 (struct soc_mixer_control *)kcontrol->private_value;
130 unsigned int reg = mc->reg;
131
132 switch (reg) {
133 case MX27VIS_AMP_GAIN:
134 ucontrol->value.integer.value[0] = mx27vis_amp_gain;
135 break;
136 case MX27VIS_AMP_MUTE:
137 ucontrol->value.integer.value[0] = mx27vis_amp_mute;
138 break;
139 }
140 return 0;
141}
142
143/* From 6dB to 24dB in steps of 6dB */
144static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0);
145
146static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = {
147 SOC_DAPM_PIN_SWITCH("External Mic"),
148 SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0,
149 mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv),
150 SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0,
151 mx27vis_amp_get, mx27vis_amp_set),
152};
153
154static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
155 SND_SOC_DAPM_MIC("External Mic", NULL),
156};
157
158static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
159 {"Mic Bias", NULL, "External Mic"},
160 {"IN1_R", NULL, "Mic Bias"},
161 {"IN2_R", NULL, "Mic Bias"},
162 {"IN3_R", NULL, "Mic Bias"},
163 {"IN1_L", NULL, "Mic Bias"},
164 {"IN2_L", NULL, "Mic Bias"},
165 {"IN3_L", NULL, "Mic Bias"},
166};
167
77static struct snd_soc_dai_link mx27vis_aic32x4_dai = { 168static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
78 .name = "tlv320aic32x4", 169 .name = "tlv320aic32x4",
79 .stream_name = "TLV320AIC32X4", 170 .stream_name = "TLV320AIC32X4",
@@ -89,50 +180,66 @@ static struct snd_soc_card mx27vis_aic32x4 = {
89 .owner = THIS_MODULE, 180 .owner = THIS_MODULE,
90 .dai_link = &mx27vis_aic32x4_dai, 181 .dai_link = &mx27vis_aic32x4_dai,
91 .num_links = 1, 182 .num_links = 1,
183 .controls = mx27vis_aic32x4_controls,
184 .num_controls = ARRAY_SIZE(mx27vis_aic32x4_controls),
185 .dapm_widgets = aic32x4_dapm_widgets,
186 .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
187 .dapm_routes = aic32x4_dapm_routes,
188 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
92}; 189};
93 190
94static struct platform_device *mx27vis_aic32x4_snd_device; 191static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
95
96static int __init mx27vis_aic32x4_init(void)
97{ 192{
98 int ret; 193 int ret;
99 194
100 mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1); 195 mx27vis_aic32x4.dev = &pdev->dev;
101 if (!mx27vis_aic32x4_snd_device) 196 ret = snd_soc_register_card(&mx27vis_aic32x4);
102 return -ENOMEM;
103
104 platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
105 ret = platform_device_add(mx27vis_aic32x4_snd_device);
106
107 if (ret) { 197 if (ret) {
108 printk(KERN_ERR "ASoC: Platform device allocation failed\n"); 198 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
109 platform_device_put(mx27vis_aic32x4_snd_device); 199 ret);
200 return ret;
110 } 201 }
111 202
112 /* Connect SSI0 as clock slave to SSI1 external pins */ 203 /* Connect SSI0 as clock slave to SSI1 external pins */
113 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, 204 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
114 MXC_AUDMUX_V1_PCR_SYN | 205 IMX_AUDMUX_V1_PCR_SYN |
115 MXC_AUDMUX_V1_PCR_TFSDIR | 206 IMX_AUDMUX_V1_PCR_TFSDIR |
116 MXC_AUDMUX_V1_PCR_TCLKDIR | 207 IMX_AUDMUX_V1_PCR_TCLKDIR |
117 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) | 208 IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
118 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) 209 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
119 ); 210 );
120 mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1, 211 imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
121 MXC_AUDMUX_V1_PCR_SYN | 212 IMX_AUDMUX_V1_PCR_SYN |
122 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) 213 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
123 ); 214 );
124 215
216 ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
217 ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
218 if (ret)
219 printk(KERN_ERR "ASoC: unable to setup gpios\n");
220
125 return ret; 221 return ret;
126} 222}
127 223
128static void __exit mx27vis_aic32x4_exit(void) 224static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
129{ 225{
130 platform_device_unregister(mx27vis_aic32x4_snd_device); 226 snd_soc_unregister_card(&mx27vis_aic32x4);
227
228 return 0;
131} 229}
132 230
133module_init(mx27vis_aic32x4_init); 231static struct platform_driver mx27vis_aic32x4_audio_driver = {
134module_exit(mx27vis_aic32x4_exit); 232 .driver = {
233 .name = "mx27vis",
234 .owner = THIS_MODULE,
235 },
236 .probe = mx27vis_aic32x4_probe,
237 .remove = __devexit_p(mx27vis_aic32x4_remove),
238};
239
240module_platform_driver(mx27vis_aic32x4_audio_driver);
135 241
136MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); 242MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
137MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim"); 243MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
138MODULE_LICENSE("GPL"); 244MODULE_LICENSE("GPL");
245MODULE_ALIAS("platform:mx27vis");
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 6ac12111de6a..f8da6dd115ed 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -19,6 +19,8 @@
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21 21
22#include "imx-audmux.h"
23
22static struct snd_soc_card imx_phycore; 24static struct snd_soc_card imx_phycore;
23 25
24static struct snd_soc_ops imx_phycore_hifi_ops = { 26static struct snd_soc_ops imx_phycore_hifi_ops = {
@@ -50,9 +52,32 @@ static int __init imx_phycore_init(void)
50{ 52{
51 int ret; 53 int ret;
52 54
53 if (!machine_is_pcm043() && !machine_is_pca100()) 55 if (machine_is_pca100()) {
56 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
57 IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
58 IMX_AUDMUX_V1_PCR_TFCSEL(3) |
59 IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
60 IMX_AUDMUX_V1_PCR_RXDSEL(3));
61 imx_audmux_v1_configure_port(3,
62 IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
63 IMX_AUDMUX_V1_PCR_TFCSEL(0) |
64 IMX_AUDMUX_V1_PCR_TFSDIR |
65 IMX_AUDMUX_V1_PCR_RXDSEL(0));
66 } else if (machine_is_pcm043()) {
67 imx_audmux_v2_configure_port(3,
68 IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
69 IMX_AUDMUX_V2_PTCR_TFSEL(0) |
70 IMX_AUDMUX_V2_PTCR_TFSDIR,
71 IMX_AUDMUX_V2_PDCR_RXDSEL(0));
72 imx_audmux_v2_configure_port(0,
73 IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
74 IMX_AUDMUX_V2_PTCR_TCSEL(3) |
75 IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
76 IMX_AUDMUX_V2_PDCR_RXDSEL(3));
77 } else {
54 /* return happy. We might run on a totally different machine */ 78 /* return happy. We might run on a totally different machine */
55 return 0; 79 return 0;
80 }
56 81
57 imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1); 82 imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
58 if (!imx_phycore_snd_ac97_device) 83 if (!imx_phycore_snd_ac97_device)
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index 37480c90e997..fe54a69073e5 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -21,10 +21,9 @@
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23 23
24#include <mach/audmux.h>
25
26#include "imx-ssi.h" 24#include "imx-ssi.h"
27#include "../codecs/wm8350.h" 25#include "../codecs/wm8350.h"
26#include "imx-audmux.h"
28 27
29/* There is a silicon mic on the board optionally connected via a solder pad 28/* There is a silicon mic on the board optionally connected via a solder pad
30 * SP1. Define this to enable it. 29 * SP1. Define this to enable it.
@@ -268,17 +267,17 @@ static int __init wm1133_ev1_audio_init(void)
268 unsigned int ptcr, pdcr; 267 unsigned int ptcr, pdcr;
269 268
270 /* SSI0 mastered by port 5 */ 269 /* SSI0 mastered by port 5 */
271 ptcr = MXC_AUDMUX_V2_PTCR_SYN | 270 ptcr = IMX_AUDMUX_V2_PTCR_SYN |
272 MXC_AUDMUX_V2_PTCR_TFSDIR | 271 IMX_AUDMUX_V2_PTCR_TFSDIR |
273 MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) | 272 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
274 MXC_AUDMUX_V2_PTCR_TCLKDIR | 273 IMX_AUDMUX_V2_PTCR_TCLKDIR |
275 MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); 274 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
276 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); 275 pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
277 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr); 276 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
278 277
279 ptcr = MXC_AUDMUX_V2_PTCR_SYN; 278 ptcr = IMX_AUDMUX_V2_PTCR_SYN;
280 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0); 279 pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
281 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr); 280 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
282 281
283 wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1); 282 wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
284 if (!wm1133_ev1_snd_device) 283 if (!wm1133_ev1_snd_device)
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index 0097c3b13a1a..e8aaff18d7cc 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -91,56 +91,52 @@ static struct snd_soc_card qi_lb60 = {
91 .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), 91 .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
92}; 92};
93 93
94static struct platform_device *qi_lb60_snd_device;
95
96static const struct gpio qi_lb60_gpios[] = { 94static const struct gpio qi_lb60_gpios[] = {
97 { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, 95 { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
98 { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, 96 { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
99}; 97};
100 98
101static int __init qi_lb60_init(void) 99static int __devinit qi_lb60_probe(struct platform_device *pdev)
102{ 100{
101 struct snd_soc_card *card = &qi_lb60;
103 int ret; 102 int ret;
104 103
105 qi_lb60_snd_device = platform_device_alloc("soc-audio", -1);
106
107 if (!qi_lb60_snd_device)
108 return -ENOMEM;
109
110 ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); 104 ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
111 if (ret) { 105 if (ret)
112 pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret); 106 return ret;
113 goto err_device_put;
114 }
115 107
116 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); 108 card->dev = &pdev->dev;
117 109
118 ret = platform_device_add(qi_lb60_snd_device); 110 ret = snd_soc_register_card(card);
119 if (ret) { 111 if (ret) {
120 pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret); 112 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
121 goto err_unset_pdata; 113 ret);
114 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
122 } 115 }
123
124 return 0;
125
126err_unset_pdata:
127 platform_set_drvdata(qi_lb60_snd_device, NULL);
128/*err_gpio_free_array:*/
129 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
130err_device_put:
131 platform_device_put(qi_lb60_snd_device);
132
133 return ret; 116 return ret;
134} 117}
135module_init(qi_lb60_init);
136 118
137static void __exit qi_lb60_exit(void) 119static int __devexit qi_lb60_remove(struct platform_device *pdev)
138{ 120{
139 platform_device_unregister(qi_lb60_snd_device); 121 struct snd_soc_card *card = platform_get_drvdata(pdev);
122
123 snd_soc_unregister_card(card);
140 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); 124 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
125 return 0;
141} 126}
142module_exit(qi_lb60_exit); 127
128static struct platform_driver qi_lb60_driver = {
129 .driver = {
130 .name = "qi-lb60-audio",
131 .owner = THIS_MODULE,
132 },
133 .probe = qi_lb60_probe,
134 .remove = __devexit_p(qi_lb60_remove),
135};
136
137module_platform_driver(qi_lb60_driver);
143 138
144MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 139MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
145MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); 140MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support");
146MODULE_LICENSE("GPL v2"); 141MODULE_LICENSE("GPL v2");
142MODULE_ALIAS("platform:qi-lb60-audio");
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index d03854027128..b9f16598324c 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -55,7 +55,7 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
55 .fifo_size = 0, 55 .fifo_size = 0,
56}; 56};
57 57
58static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL; 58static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32);
59 59
60static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) 60static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
61{ 61{
@@ -324,7 +324,7 @@ static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd)
324 if (!card->dev->dma_mask) 324 if (!card->dev->dma_mask)
325 card->dev->dma_mask = &kirkwood_dma_dmamask; 325 card->dev->dma_mask = &kirkwood_dma_dmamask;
326 if (!card->dev->coherent_dma_mask) 326 if (!card->dev->coherent_dma_mask)
327 card->dev->coherent_dma_mask = 0xffffffff; 327 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
328 328
329 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 329 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
330 ret = kirkwood_dma_preallocate_dma_buffer(pcm, 330 ret = kirkwood_dma_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 55d2ed3df30d..80bd59c33be4 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -71,41 +71,41 @@ static struct snd_soc_card openrd_client = {
71 .num_links = ARRAY_SIZE(openrd_client_dai), 71 .num_links = ARRAY_SIZE(openrd_client_dai),
72}; 72};
73 73
74static struct platform_device *openrd_client_snd_device; 74static int __devinit openrd_probe(struct platform_device *pdev)
75
76static int __init openrd_client_init(void)
77{ 75{
76 struct snd_soc_card *card = &openrd_client;
78 int ret; 77 int ret;
79 78
80 if (!machine_is_openrd_client() && !machine_is_openrd_ultimate()) 79 card->dev = &pdev->dev;
81 return 0;
82
83 openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
84 if (!openrd_client_snd_device)
85 return -ENOMEM;
86
87 platform_set_drvdata(openrd_client_snd_device,
88 &openrd_client);
89
90 ret = platform_device_add(openrd_client_snd_device);
91 if (ret) {
92 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
93 platform_device_put(openrd_client_snd_device);
94 }
95 80
81 ret = snd_soc_register_card(card);
82 if (ret)
83 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
84 ret);
96 return ret; 85 return ret;
97} 86}
98 87
99static void __exit openrd_client_exit(void) 88static int __devexit openrd_remove(struct platform_device *pdev)
100{ 89{
101 platform_device_unregister(openrd_client_snd_device); 90 struct snd_soc_card *card = platform_get_drvdata(pdev);
91
92 snd_soc_unregister_card(card);
93 return 0;
102} 94}
103 95
104module_init(openrd_client_init); 96static struct platform_driver openrd_driver = {
105module_exit(openrd_client_exit); 97 .driver = {
98 .name = "openrd-client-audio",
99 .owner = THIS_MODULE,
100 },
101 .probe = openrd_probe,
102 .remove = __devexit_p(openrd_remove),
103};
104
105module_platform_driver(openrd_driver);
106 106
107/* Module information */ 107/* Module information */
108MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 108MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
109MODULE_DESCRIPTION("ALSA SoC OpenRD Client"); 109MODULE_DESCRIPTION("ALSA SoC OpenRD Client");
110MODULE_LICENSE("GPL"); 110MODULE_LICENSE("GPL");
111MODULE_ALIAS("platform:soc-audio"); 111MODULE_ALIAS("platform:openrd-client-audio");
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index b47cc4e9b746..f8983635f7ef 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -80,7 +80,6 @@ static struct snd_soc_dai_link t5325_dai[] = {
80}, 80},
81}; 81};
82 82
83
84static struct snd_soc_card t5325 = { 83static struct snd_soc_card t5325 = {
85 .name = "t5325", 84 .name = "t5325",
86 .owner = THIS_MODULE, 85 .owner = THIS_MODULE,
@@ -93,38 +92,40 @@ static struct snd_soc_card t5325 = {
93 .num_dapm_routes = ARRAY_SIZE(t5325_route), 92 .num_dapm_routes = ARRAY_SIZE(t5325_route),
94}; 93};
95 94
96static struct platform_device *t5325_snd_device; 95static int __devinit t5325_probe(struct platform_device *pdev)
97
98static int __init t5325_init(void)
99{ 96{
97 struct snd_soc_card *card = &t5325;
100 int ret; 98 int ret;
101 99
102 if (!machine_is_t5325()) 100 card->dev = &pdev->dev;
103 return 0;
104
105 t5325_snd_device = platform_device_alloc("soc-audio", -1);
106 if (!t5325_snd_device)
107 return -ENOMEM;
108
109 platform_set_drvdata(t5325_snd_device,
110 &t5325);
111
112 ret = platform_device_add(t5325_snd_device);
113 if (ret) {
114 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
115 platform_device_put(t5325_snd_device);
116 }
117 101
102 ret = snd_soc_register_card(card);
103 if (ret)
104 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
105 ret);
118 return ret; 106 return ret;
119} 107}
120module_init(t5325_init);
121 108
122static void __exit t5325_exit(void) 109static int __devexit t5325_remove(struct platform_device *pdev)
123{ 110{
124 platform_device_unregister(t5325_snd_device); 111 struct snd_soc_card *card = platform_get_drvdata(pdev);
112
113 snd_soc_unregister_card(card);
114 return 0;
125} 115}
126module_exit(t5325_exit); 116
117static struct platform_driver t5325_driver = {
118 .driver = {
119 .name = "t5325-audio",
120 .owner = THIS_MODULE,
121 },
122 .probe = t5325_probe,
123 .remove = __devexit_p(t5325_remove),
124};
125
126module_platform_driver(t5325_driver);
127 127
128MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 128MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
129MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); 129MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
130MODULE_LICENSE("GPL"); 130MODULE_LICENSE("GPL");
131MODULE_ALIAS("platform:t5325-audio");
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 6f77eef0f131..2937e54da49e 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -235,7 +235,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
235 snd_soc_dapm_enable_pin(dapm, "Headphones"); 235 snd_soc_dapm_enable_pin(dapm, "Headphones");
236 snd_soc_dapm_enable_pin(dapm, "Mic"); 236 snd_soc_dapm_enable_pin(dapm, "Mic");
237 237
238 ret_val = snd_soc_add_controls(codec, mfld_snd_controls, 238 ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
239 ARRAY_SIZE(mfld_snd_controls)); 239 ARRAY_SIZE(mfld_snd_controls));
240 if (ret_val) { 240 if (ret_val) {
241 pr_err("soc_add_controls failed %d", ret_val); 241 pr_err("soc_add_controls failed %d", ret_val);
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index e4ba8d5f25fa..99a997f19bb9 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -1,7 +1,7 @@
1menuconfig SND_MXS_SOC 1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs" 2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS 3 depends on ARCH_MXS
4 select SND_PCM 4 select SND_SOC_DMAENGINE_PCM
5 help 5 help
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
7 the MXS SAIF interface. 7 the MXS SAIF interface.
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 105f42a394df..6ca1f46d84a4 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -34,10 +34,16 @@
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
36#include <sound/soc.h> 36#include <sound/soc.h>
37#include <sound/dmaengine_pcm.h>
37 38
38#include <mach/dma.h> 39#include <mach/dma.h>
39#include "mxs-pcm.h" 40#include "mxs-pcm.h"
40 41
42struct mxs_pcm_dma_data {
43 struct mxs_dma_data dma_data;
44 struct mxs_pcm_dma_params *dma_params;
45};
46
41static struct snd_pcm_hardware snd_mxs_hardware = { 47static struct snd_pcm_hardware snd_mxs_hardware = {
42 .info = SNDRV_PCM_INFO_MMAP | 48 .info = SNDRV_PCM_INFO_MMAP |
43 SNDRV_PCM_INFO_MMAP_VALID | 49 SNDRV_PCM_INFO_MMAP_VALID |
@@ -58,21 +64,10 @@ static struct snd_pcm_hardware snd_mxs_hardware = {
58 64
59}; 65};
60 66
61static void audio_dma_irq(void *data)
62{
63 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
64 struct snd_pcm_runtime *runtime = substream->runtime;
65 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
66
67 iprtd->offset += iprtd->period_bytes;
68 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
69 snd_pcm_period_elapsed(substream);
70}
71
72static bool filter(struct dma_chan *chan, void *param) 67static bool filter(struct dma_chan *chan, void *param)
73{ 68{
74 struct mxs_pcm_runtime_data *iprtd = param; 69 struct mxs_pcm_dma_data *pcm_dma_data = param;
75 struct mxs_pcm_dma_params *dma_params = iprtd->dma_params; 70 struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
76 71
77 if (!mxs_dma_is_apbx(chan)) 72 if (!mxs_dma_is_apbx(chan))
78 return false; 73 return false;
@@ -80,150 +75,51 @@ static bool filter(struct dma_chan *chan, void *param)
80 if (chan->chan_id != dma_params->chan_num) 75 if (chan->chan_id != dma_params->chan_num)
81 return false; 76 return false;
82 77
83 chan->private = &iprtd->dma_data; 78 chan->private = &pcm_dma_data->dma_data;
84 79
85 return true; 80 return true;
86} 81}
87 82
88static int mxs_dma_alloc(struct snd_pcm_substream *substream,
89 struct snd_pcm_hw_params *params)
90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data;
92 struct snd_pcm_runtime *runtime = substream->runtime;
93 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
94 dma_cap_mask_t mask;
95
96 iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
97
98 dma_cap_zero(mask);
99 dma_cap_set(DMA_SLAVE, mask);
100 iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
101 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
102 if (!iprtd->dma_chan)
103 return -EINVAL;
104
105 return 0;
106}
107
108static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, 83static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params) 84 struct snd_pcm_hw_params *params)
110{ 85{
111 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
113 unsigned long dma_addr;
114 struct dma_chan *chan;
115 int ret;
116
117 ret = mxs_dma_alloc(substream, params);
118 if (ret)
119 return ret;
120 chan = iprtd->dma_chan;
121
122 iprtd->size = params_buffer_bytes(params);
123 iprtd->periods = params_periods(params);
124 iprtd->period_bytes = params_period_bytes(params);
125 iprtd->offset = 0;
126 iprtd->period_time = HZ / (params_rate(params) /
127 params_period_size(params));
128
129 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 86 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
130 87
131 dma_addr = runtime->dma_addr;
132
133 iprtd->buf = substream->dma_buffer.area;
134
135 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
136 iprtd->period_bytes * iprtd->periods,
137 iprtd->period_bytes,
138 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
139 DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
140 if (!iprtd->desc) {
141 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
142 return -EINVAL;
143 }
144
145 iprtd->desc->callback = audio_dma_irq;
146 iprtd->desc->callback_param = substream;
147
148 return 0;
149}
150
151static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
152{
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
155
156 if (iprtd->dma_chan) {
157 dma_release_channel(iprtd->dma_chan);
158 iprtd->dma_chan = NULL;
159 }
160
161 return 0;
162}
163
164static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct snd_pcm_runtime *runtime = substream->runtime;
167 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 case SNDRV_PCM_TRIGGER_RESUME:
172 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
173 dmaengine_submit(iprtd->desc);
174
175 break;
176 case SNDRV_PCM_TRIGGER_STOP:
177 case SNDRV_PCM_TRIGGER_SUSPEND:
178 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179 dmaengine_terminate_all(iprtd->dma_chan);
180
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 return 0; 88 return 0;
187} 89}
188 90
189static snd_pcm_uframes_t snd_mxs_pcm_pointer(
190 struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
194
195 return bytes_to_frames(substream->runtime, iprtd->offset);
196}
197
198static int snd_mxs_open(struct snd_pcm_substream *substream) 91static int snd_mxs_open(struct snd_pcm_substream *substream)
199{ 92{
200 struct snd_pcm_runtime *runtime = substream->runtime; 93 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201 struct mxs_pcm_runtime_data *iprtd; 94 struct mxs_pcm_dma_data *pcm_dma_data;
202 int ret; 95 int ret;
203 96
204 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 97 pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
205 if (iprtd == NULL) 98 if (pcm_dma_data == NULL)
206 return -ENOMEM; 99 return -ENOMEM;
207 runtime->private_data = iprtd;
208 100
209 ret = snd_pcm_hw_constraint_integer(substream->runtime, 101 pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
210 SNDRV_PCM_HW_PARAM_PERIODS); 102 pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
211 if (ret < 0) { 103
212 kfree(iprtd); 104 ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
105 if (ret) {
106 kfree(pcm_dma_data);
213 return ret; 107 return ret;
214 } 108 }
215 109
216 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); 110 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
217 111
112 snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
113
218 return 0; 114 return 0;
219} 115}
220 116
221static int snd_mxs_close(struct snd_pcm_substream *substream) 117static int snd_mxs_close(struct snd_pcm_substream *substream)
222{ 118{
223 struct snd_pcm_runtime *runtime = substream->runtime; 119 struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
224 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
225 120
226 kfree(iprtd); 121 snd_dmaengine_pcm_close(substream);
122 kfree(pcm_dma_data);
227 123
228 return 0; 124 return 0;
229} 125}
@@ -244,9 +140,8 @@ static struct snd_pcm_ops mxs_pcm_ops = {
244 .close = snd_mxs_close, 140 .close = snd_mxs_close,
245 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
246 .hw_params = snd_mxs_pcm_hw_params, 142 .hw_params = snd_mxs_pcm_hw_params,
247 .hw_free = snd_mxs_pcm_hw_free, 143 .trigger = snd_dmaengine_pcm_trigger,
248 .trigger = snd_mxs_pcm_trigger, 144 .pointer = snd_dmaengine_pcm_pointer,
249 .pointer = snd_mxs_pcm_pointer,
250 .mmap = snd_mxs_pcm_mmap, 145 .mmap = snd_mxs_pcm_mmap,
251}; 146};
252 147
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index f55ac4f7a76a..5f01a9124b3d 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,25 +19,9 @@
19#ifndef _MXS_PCM_H 19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H 20#define _MXS_PCM_H
21 21
22#include <mach/dma.h>
23
24struct mxs_pcm_dma_params { 22struct mxs_pcm_dma_params {
25 int chan_irq; 23 int chan_irq;
26 int chan_num; 24 int chan_num;
27}; 25};
28 26
29struct mxs_pcm_runtime_data {
30 int period_bytes;
31 int periods;
32 int dma;
33 unsigned long offset;
34 unsigned long size;
35 void *buf;
36 int period_time;
37 struct dma_async_tx_descriptor *desc;
38 struct dma_chan *dma_chan;
39 struct mxs_dma_data dma_data;
40 struct mxs_pcm_dma_params *dma_params;
41};
42
43#endif 27#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index f204dbac11d4..12be05b16880 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -630,7 +630,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
630 if (pdev->id >= ARRAY_SIZE(mxs_saif)) 630 if (pdev->id >= ARRAY_SIZE(mxs_saif))
631 return -EINVAL; 631 return -EINVAL;
632 632
633 saif = kzalloc(sizeof(*saif), GFP_KERNEL); 633 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
634 if (!saif) 634 if (!saif)
635 return -ENOMEM; 635 return -ENOMEM;
636 636
@@ -655,29 +655,16 @@ static int mxs_saif_probe(struct platform_device *pdev)
655 ret = PTR_ERR(saif->clk); 655 ret = PTR_ERR(saif->clk);
656 dev_err(&pdev->dev, "Cannot get the clock: %d\n", 656 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
657 ret); 657 ret);
658 goto failed_clk; 658 return ret;
659 } 659 }
660 660
661 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 661 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
662 if (!iores) {
663 ret = -ENODEV;
664 dev_err(&pdev->dev, "failed to get io resource: %d\n",
665 ret);
666 goto failed_get_resource;
667 }
668 662
669 if (!request_mem_region(iores->start, resource_size(iores), 663 saif->base = devm_request_and_ioremap(&pdev->dev, iores);
670 "mxs-saif")) {
671 dev_err(&pdev->dev, "request_mem_region failed\n");
672 ret = -EBUSY;
673 goto failed_get_resource;
674 }
675
676 saif->base = ioremap(iores->start, resource_size(iores));
677 if (!saif->base) { 664 if (!saif->base) {
678 dev_err(&pdev->dev, "ioremap failed\n"); 665 dev_err(&pdev->dev, "ioremap failed\n");
679 ret = -ENODEV; 666 ret = -ENODEV;
680 goto failed_ioremap; 667 goto failed_get_resource;
681 } 668 }
682 669
683 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 670 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -685,7 +672,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
685 ret = -ENODEV; 672 ret = -ENODEV;
686 dev_err(&pdev->dev, "failed to get dma resource: %d\n", 673 dev_err(&pdev->dev, "failed to get dma resource: %d\n",
687 ret); 674 ret);
688 goto failed_ioremap; 675 goto failed_get_resource;
689 } 676 }
690 saif->dma_param.chan_num = dmares->start; 677 saif->dma_param.chan_num = dmares->start;
691 678
@@ -694,14 +681,15 @@ static int mxs_saif_probe(struct platform_device *pdev)
694 ret = saif->irq; 681 ret = saif->irq;
695 dev_err(&pdev->dev, "failed to get irq resource: %d\n", 682 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
696 ret); 683 ret);
697 goto failed_get_irq1; 684 goto failed_get_resource;
698 } 685 }
699 686
700 saif->dev = &pdev->dev; 687 saif->dev = &pdev->dev;
701 ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif); 688 ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
689 "mxs-saif", saif);
702 if (ret) { 690 if (ret) {
703 dev_err(&pdev->dev, "failed to request irq\n"); 691 dev_err(&pdev->dev, "failed to request irq\n");
704 goto failed_get_irq1; 692 goto failed_get_resource;
705 } 693 }
706 694
707 saif->dma_param.chan_irq = platform_get_irq(pdev, 1); 695 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -709,7 +697,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
709 ret = saif->dma_param.chan_irq; 697 ret = saif->dma_param.chan_irq;
710 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", 698 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
711 ret); 699 ret);
712 goto failed_get_irq2; 700 goto failed_get_resource;
713 } 701 }
714 702
715 platform_set_drvdata(pdev, saif); 703 platform_set_drvdata(pdev, saif);
@@ -717,7 +705,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
717 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); 705 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
718 if (ret) { 706 if (ret) {
719 dev_err(&pdev->dev, "register DAI failed\n"); 707 dev_err(&pdev->dev, "register DAI failed\n");
720 goto failed_register; 708 goto failed_get_resource;
721 } 709 }
722 710
723 saif->soc_platform_pdev = platform_device_alloc( 711 saif->soc_platform_pdev = platform_device_alloc(
@@ -740,36 +728,19 @@ failed_pdev_add:
740 platform_device_put(saif->soc_platform_pdev); 728 platform_device_put(saif->soc_platform_pdev);
741failed_pdev_alloc: 729failed_pdev_alloc:
742 snd_soc_unregister_dai(&pdev->dev); 730 snd_soc_unregister_dai(&pdev->dev);
743failed_register:
744failed_get_irq2:
745 free_irq(saif->irq, saif);
746failed_get_irq1:
747 iounmap(saif->base);
748failed_ioremap:
749 release_mem_region(iores->start, resource_size(iores));
750failed_get_resource: 731failed_get_resource:
751 clk_put(saif->clk); 732 clk_put(saif->clk);
752failed_clk:
753 kfree(saif);
754 733
755 return ret; 734 return ret;
756} 735}
757 736
758static int __devexit mxs_saif_remove(struct platform_device *pdev) 737static int __devexit mxs_saif_remove(struct platform_device *pdev)
759{ 738{
760 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
761 struct mxs_saif *saif = platform_get_drvdata(pdev); 739 struct mxs_saif *saif = platform_get_drvdata(pdev);
762 740
763 platform_device_unregister(saif->soc_platform_pdev); 741 platform_device_unregister(saif->soc_platform_pdev);
764
765 snd_soc_unregister_dai(&pdev->dev); 742 snd_soc_unregister_dai(&pdev->dev);
766
767 iounmap(saif->base);
768 release_mem_region(res->start, resource_size(res));
769 free_irq(saif->irq, saif);
770
771 clk_put(saif->clk); 743 clk_put(saif->clk);
772 kfree(saif);
773 744
774 return 0; 745 return 0;
775} 746}
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index fb1bf2581efb..e00dd0b1139c 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -7,7 +7,6 @@ config SND_OMAP_SOC_DMIC
7 7
8config SND_OMAP_SOC_MCBSP 8config SND_OMAP_SOC_MCBSP
9 tristate 9 tristate
10 select OMAP_MCBSP
11 10
12config SND_OMAP_SOC_MCPDM 11config SND_OMAP_SOC_MCPDM
13 tristate 12 tristate
@@ -27,7 +26,6 @@ config SND_OMAP_SOC_N810
27config SND_OMAP_SOC_RX51 26config SND_OMAP_SOC_RX51
28 tristate "SoC Audio support for Nokia RX-51" 27 tristate "SoC Audio support for Nokia RX-51"
29 depends on SND_OMAP_SOC && MACH_NOKIA_RX51 28 depends on SND_OMAP_SOC && MACH_NOKIA_RX51
30 select OMAP_MCBSP
31 select SND_OMAP_SOC_MCBSP 29 select SND_OMAP_SOC_MCBSP
32 select SND_SOC_TLV320AIC3X 30 select SND_SOC_TLV320AIC3X
33 select SND_SOC_TPA6130A2 31 select SND_SOC_TPA6130A2
@@ -97,16 +95,19 @@ config SND_OMAP_SOC_SDP3430
97 Say Y if you want to add support for SoC audio on Texas Instruments 95 Say Y if you want to add support for SoC audio on Texas Instruments
98 SDP3430. 96 SDP3430.
99 97
100config SND_OMAP_SOC_SDP4430 98config SND_OMAP_SOC_OMAP_ABE_TWL6040
101 tristate "SoC Audio support for Texas Instruments SDP4430" 99 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
102 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP 100 depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
103 select SND_OMAP_SOC_DMIC 101 select SND_OMAP_SOC_DMIC
104 select SND_OMAP_SOC_MCPDM 102 select SND_OMAP_SOC_MCPDM
105 select SND_SOC_TWL6040 103 select SND_SOC_TWL6040
106 select SND_SOC_DMIC 104 select SND_SOC_DMIC
107 help 105 help
108 Say Y if you want to add support for SoC audio on Texas Instruments 106 Say Y if you want to add support for SoC audio on OMAP boards using
109 SDP4430. 107 ABE and twl6040 codec. This driver currently supports:
108 - SDP4430/Blaze boards
109 - PandaBoard (4430)
110 - PandaBoardES (4460)
110 111
111config SND_OMAP_SOC_OMAP4_HDMI 112config SND_OMAP_SOC_OMAP4_HDMI
112 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" 113 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI"
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 1fd723fb559d..1d656bce01d4 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,7 +1,7 @@
1# OMAP Platform Support 1# OMAP Platform Support
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-dmic-objs := omap-dmic.o 3snd-soc-omap-dmic-objs := omap-dmic.o
4snd-soc-omap-mcbsp-objs := omap-mcbsp.o 4snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
5snd-soc-omap-mcpdm-objs := omap-mcpdm.o 5snd-soc-omap-mcpdm-objs := omap-mcpdm.o
6snd-soc-omap-hdmi-objs := omap-hdmi.o 6snd-soc-omap-hdmi-objs := omap-hdmi.o
7 7
@@ -20,7 +20,7 @@ snd-soc-overo-objs := overo.o
20snd-soc-omap3evm-objs := omap3evm.o 20snd-soc-omap3evm-objs := omap3evm.o
21snd-soc-am3517evm-objs := am3517evm.o 21snd-soc-am3517evm-objs := am3517evm.o
22snd-soc-sdp3430-objs := sdp3430.o 22snd-soc-sdp3430-objs := sdp3430.o
23snd-soc-sdp4430-objs := sdp4430.o 23snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
24snd-soc-omap3pandora-objs := omap3pandora.o 24snd-soc-omap3pandora-objs := omap3pandora.o
25snd-soc-omap3beagle-objs := omap3beagle.o 25snd-soc-omap3beagle-objs := omap3beagle.o
26snd-soc-zoom2-objs := zoom2.o 26snd-soc-zoom2-objs := zoom2.o
@@ -36,7 +36,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
36obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o 36obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
37obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 37obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
38obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 38obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
39obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o 39obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
40obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 40obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
41obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 41obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
42obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 42obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index add4866d7e67..009533ab8d18 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -95,7 +95,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
95static struct snd_soc_dai_link am3517evm_dai = { 95static struct snd_soc_dai_link am3517evm_dai = {
96 .name = "TLV320AIC23", 96 .name = "TLV320AIC23",
97 .stream_name = "AIC23", 97 .stream_name = "AIC23",
98 .cpu_dai_name ="omap-mcbsp-dai.0", 98 .cpu_dai_name = "omap-mcbsp.1",
99 .codec_dai_name = "tlv320aic23-hifi", 99 .codec_dai_name = "tlv320aic23-hifi",
100 .platform_name = "omap-pcm-audio", 100 .platform_name = "omap-pcm-audio",
101 .codec_name = "tlv320aic23-codec.2-001a", 101 .codec_name = "tlv320aic23-codec.2-001a",
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index a67f4370bc9f..49fe63ce51f7 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -570,7 +570,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
570 snd_soc_dapm_disable_pin(dapm, "AGCOUT"); 570 snd_soc_dapm_disable_pin(dapm, "AGCOUT");
571 571
572 /* Add virtual switch */ 572 /* Add virtual switch */
573 ret = snd_soc_add_controls(codec, ams_delta_audio_controls, 573 ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls,
574 ARRAY_SIZE(ams_delta_audio_controls)); 574 ARRAY_SIZE(ams_delta_audio_controls));
575 if (ret) 575 if (ret)
576 dev_warn(card->dev, 576 dev_warn(card->dev,
@@ -584,7 +584,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
584static struct snd_soc_dai_link ams_delta_dai_link = { 584static struct snd_soc_dai_link ams_delta_dai_link = {
585 .name = "CX20442", 585 .name = "CX20442",
586 .stream_name = "CX20442", 586 .stream_name = "CX20442",
587 .cpu_dai_name ="omap-mcbsp-dai.0", 587 .cpu_dai_name = "omap-mcbsp.1",
588 .codec_dai_name = "cx20442-voice", 588 .codec_dai_name = "cx20442-voice",
589 .init = ams_delta_cx20442_init, 589 .init = ams_delta_cx20442_init,
590 .platform_name = "omap-pcm-audio", 590 .platform_name = "omap-pcm-audio",
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index ccae58a1339c..e8357819175b 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -60,7 +60,7 @@ static struct snd_soc_ops igep2_ops = {
60static struct snd_soc_dai_link igep2_dai = { 60static struct snd_soc_dai_link igep2_dai = {
61 .name = "TWL4030", 61 .name = "TWL4030",
62 .stream_name = "TWL4030", 62 .stream_name = "TWL4030",
63 .cpu_dai_name = "omap-mcbsp-dai.1", 63 .cpu_dai_name = "omap-mcbsp.2",
64 .codec_dai_name = "twl4030-hifi", 64 .codec_dai_name = "twl4030-hifi",
65 .platform_name = "omap-pcm-audio", 65 .platform_name = "omap-pcm-audio",
66 .codec_name = "twl4030-codec", 66 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
new file mode 100644
index 000000000000..e5f44440d1b9
--- /dev/null
+++ b/sound/soc/omap/mcbsp.c
@@ -0,0 +1,1040 @@
1/*
2 * sound/soc/omap/mcbsp.c
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
6 *
7 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
8 * Peter Ujfalusi <peter.ujfalusi@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Multichannel mode not supported.
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/delay.h>
25#include <linux/io.h>
26#include <linux/slab.h>
27
28#include <plat/mcbsp.h>
29
30#include "mcbsp.h"
31
32static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
33{
34 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
35
36 if (mcbsp->pdata->reg_size == 2) {
37 ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
38 __raw_writew((u16)val, addr);
39 } else {
40 ((u32 *)mcbsp->reg_cache)[reg] = val;
41 __raw_writel(val, addr);
42 }
43}
44
45static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
46{
47 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
48
49 if (mcbsp->pdata->reg_size == 2) {
50 return !from_cache ? __raw_readw(addr) :
51 ((u16 *)mcbsp->reg_cache)[reg];
52 } else {
53 return !from_cache ? __raw_readl(addr) :
54 ((u32 *)mcbsp->reg_cache)[reg];
55 }
56}
57
58static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
59{
60 __raw_writel(val, mcbsp->st_data->io_base_st + reg);
61}
62
63static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
64{
65 return __raw_readl(mcbsp->st_data->io_base_st + reg);
66}
67
68#define MCBSP_READ(mcbsp, reg) \
69 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
70#define MCBSP_WRITE(mcbsp, reg, val) \
71 omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
72#define MCBSP_READ_CACHE(mcbsp, reg) \
73 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
74
75#define MCBSP_ST_READ(mcbsp, reg) \
76 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
77#define MCBSP_ST_WRITE(mcbsp, reg, val) \
78 omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
79
80static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
81{
82 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
83 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
84 MCBSP_READ(mcbsp, DRR2));
85 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
86 MCBSP_READ(mcbsp, DRR1));
87 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
88 MCBSP_READ(mcbsp, DXR2));
89 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
90 MCBSP_READ(mcbsp, DXR1));
91 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
92 MCBSP_READ(mcbsp, SPCR2));
93 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
94 MCBSP_READ(mcbsp, SPCR1));
95 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
96 MCBSP_READ(mcbsp, RCR2));
97 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
98 MCBSP_READ(mcbsp, RCR1));
99 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
100 MCBSP_READ(mcbsp, XCR2));
101 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
102 MCBSP_READ(mcbsp, XCR1));
103 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
104 MCBSP_READ(mcbsp, SRGR2));
105 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
106 MCBSP_READ(mcbsp, SRGR1));
107 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
108 MCBSP_READ(mcbsp, PCR0));
109 dev_dbg(mcbsp->dev, "***********************\n");
110}
111
112static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
113{
114 struct omap_mcbsp *mcbsp_tx = dev_id;
115 u16 irqst_spcr2;
116
117 irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
118 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
119
120 if (irqst_spcr2 & XSYNC_ERR) {
121 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
122 irqst_spcr2);
123 /* Writing zero to XSYNC_ERR clears the IRQ */
124 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
125 }
126
127 return IRQ_HANDLED;
128}
129
130static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
131{
132 struct omap_mcbsp *mcbsp_rx = dev_id;
133 u16 irqst_spcr1;
134
135 irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
136 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
137
138 if (irqst_spcr1 & RSYNC_ERR) {
139 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
140 irqst_spcr1);
141 /* Writing zero to RSYNC_ERR clears the IRQ */
142 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
143 }
144
145 return IRQ_HANDLED;
146}
147
148/*
149 * omap_mcbsp_config simply write a config to the
150 * appropriate McBSP.
151 * You either call this function or set the McBSP registers
152 * by yourself before calling omap_mcbsp_start().
153 */
154void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
155 const struct omap_mcbsp_reg_cfg *config)
156{
157 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
158 mcbsp->id, mcbsp->phys_base);
159
160 /* We write the given config */
161 MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
162 MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
163 MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
164 MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
165 MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
166 MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
167 MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
168 MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
169 MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
170 MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
171 MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
172 if (mcbsp->pdata->has_ccr) {
173 MCBSP_WRITE(mcbsp, XCCR, config->xccr);
174 MCBSP_WRITE(mcbsp, RCCR, config->rccr);
175 }
176 /* Enable wakeup behavior */
177 if (mcbsp->pdata->has_wakeup)
178 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
179}
180
181/**
182 * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
183 * @id - mcbsp id
184 * @stream - indicates the direction of data flow (rx or tx)
185 *
186 * Returns the address of mcbsp data transmit register or data receive register
187 * to be used by DMA for transferring/receiving data based on the value of
188 * @stream for the requested mcbsp given by @id
189 */
190static int omap_mcbsp_dma_reg_params(struct omap_mcbsp *mcbsp,
191 unsigned int stream)
192{
193 int data_reg;
194
195 if (mcbsp->pdata->reg_size == 2) {
196 if (stream)
197 data_reg = OMAP_MCBSP_REG_DRR1;
198 else
199 data_reg = OMAP_MCBSP_REG_DXR1;
200 } else {
201 if (stream)
202 data_reg = OMAP_MCBSP_REG_DRR;
203 else
204 data_reg = OMAP_MCBSP_REG_DXR;
205 }
206
207 return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
208}
209
210static void omap_st_on(struct omap_mcbsp *mcbsp)
211{
212 unsigned int w;
213
214 if (mcbsp->pdata->enable_st_clock)
215 mcbsp->pdata->enable_st_clock(mcbsp->id, 1);
216
217 /* Enable McBSP Sidetone */
218 w = MCBSP_READ(mcbsp, SSELCR);
219 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
220
221 /* Enable Sidetone from Sidetone Core */
222 w = MCBSP_ST_READ(mcbsp, SSELCR);
223 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
224}
225
226static void omap_st_off(struct omap_mcbsp *mcbsp)
227{
228 unsigned int w;
229
230 w = MCBSP_ST_READ(mcbsp, SSELCR);
231 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
232
233 w = MCBSP_READ(mcbsp, SSELCR);
234 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
235
236 if (mcbsp->pdata->enable_st_clock)
237 mcbsp->pdata->enable_st_clock(mcbsp->id, 0);
238}
239
240static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
241{
242 u16 val, i;
243
244 val = MCBSP_ST_READ(mcbsp, SSELCR);
245
246 if (val & ST_COEFFWREN)
247 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
248
249 MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
250
251 for (i = 0; i < 128; i++)
252 MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
253
254 i = 0;
255
256 val = MCBSP_ST_READ(mcbsp, SSELCR);
257 while (!(val & ST_COEFFWRDONE) && (++i < 1000))
258 val = MCBSP_ST_READ(mcbsp, SSELCR);
259
260 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
261
262 if (i == 1000)
263 dev_err(mcbsp->dev, "McBSP FIR load error!\n");
264}
265
266static void omap_st_chgain(struct omap_mcbsp *mcbsp)
267{
268 u16 w;
269 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
270
271 w = MCBSP_ST_READ(mcbsp, SSELCR);
272
273 MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
274 ST_CH1GAIN(st_data->ch1gain));
275}
276
277int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain)
278{
279 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
280 int ret = 0;
281
282 if (!st_data)
283 return -ENOENT;
284
285 spin_lock_irq(&mcbsp->lock);
286 if (channel == 0)
287 st_data->ch0gain = chgain;
288 else if (channel == 1)
289 st_data->ch1gain = chgain;
290 else
291 ret = -EINVAL;
292
293 if (st_data->enabled)
294 omap_st_chgain(mcbsp);
295 spin_unlock_irq(&mcbsp->lock);
296
297 return ret;
298}
299
300int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain)
301{
302 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
303 int ret = 0;
304
305 if (!st_data)
306 return -ENOENT;
307
308 spin_lock_irq(&mcbsp->lock);
309 if (channel == 0)
310 *chgain = st_data->ch0gain;
311 else if (channel == 1)
312 *chgain = st_data->ch1gain;
313 else
314 ret = -EINVAL;
315 spin_unlock_irq(&mcbsp->lock);
316
317 return ret;
318}
319
320static int omap_st_start(struct omap_mcbsp *mcbsp)
321{
322 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
323
324 if (st_data->enabled && !st_data->running) {
325 omap_st_fir_write(mcbsp, st_data->taps);
326 omap_st_chgain(mcbsp);
327
328 if (!mcbsp->free) {
329 omap_st_on(mcbsp);
330 st_data->running = 1;
331 }
332 }
333
334 return 0;
335}
336
337int omap_st_enable(struct omap_mcbsp *mcbsp)
338{
339 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
340
341 if (!st_data)
342 return -ENODEV;
343
344 spin_lock_irq(&mcbsp->lock);
345 st_data->enabled = 1;
346 omap_st_start(mcbsp);
347 spin_unlock_irq(&mcbsp->lock);
348
349 return 0;
350}
351
352static int omap_st_stop(struct omap_mcbsp *mcbsp)
353{
354 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
355
356 if (st_data->running) {
357 if (!mcbsp->free) {
358 omap_st_off(mcbsp);
359 st_data->running = 0;
360 }
361 }
362
363 return 0;
364}
365
366int omap_st_disable(struct omap_mcbsp *mcbsp)
367{
368 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
369 int ret = 0;
370
371 if (!st_data)
372 return -ENODEV;
373
374 spin_lock_irq(&mcbsp->lock);
375 omap_st_stop(mcbsp);
376 st_data->enabled = 0;
377 spin_unlock_irq(&mcbsp->lock);
378
379 return ret;
380}
381
382int omap_st_is_enabled(struct omap_mcbsp *mcbsp)
383{
384 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
385
386 if (!st_data)
387 return -ENODEV;
388
389 return st_data->enabled;
390}
391
392/*
393 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
394 * The threshold parameter is 1 based, and it is converted (threshold - 1)
395 * for the THRSH2 register.
396 */
397void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
398{
399 if (mcbsp->pdata->buffer_size == 0)
400 return;
401
402 if (threshold && threshold <= mcbsp->max_tx_thres)
403 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
404}
405
406/*
407 * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
408 * The threshold parameter is 1 based, and it is converted (threshold - 1)
409 * for the THRSH1 register.
410 */
411void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
412{
413 if (mcbsp->pdata->buffer_size == 0)
414 return;
415
416 if (threshold && threshold <= mcbsp->max_rx_thres)
417 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
418}
419
420/*
421 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
422 */
423u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp)
424{
425 u16 buffstat;
426
427 if (mcbsp->pdata->buffer_size == 0)
428 return 0;
429
430 /* Returns the number of free locations in the buffer */
431 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
432
433 /* Number of slots are different in McBSP ports */
434 return mcbsp->pdata->buffer_size - buffstat;
435}
436
437/*
438 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
439 * to reach the threshold value (when the DMA will be triggered to read it)
440 */
441u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp)
442{
443 u16 buffstat, threshold;
444
445 if (mcbsp->pdata->buffer_size == 0)
446 return 0;
447
448 /* Returns the number of used locations in the buffer */
449 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
450 /* RX threshold */
451 threshold = MCBSP_READ(mcbsp, THRSH1);
452
453 /* Return the number of location till we reach the threshold limit */
454 if (threshold <= buffstat)
455 return 0;
456 else
457 return threshold - buffstat;
458}
459
460int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
461{
462 void *reg_cache;
463 int err;
464
465 reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
466 if (!reg_cache) {
467 return -ENOMEM;
468 }
469
470 spin_lock(&mcbsp->lock);
471 if (!mcbsp->free) {
472 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
473 mcbsp->id);
474 err = -EBUSY;
475 goto err_kfree;
476 }
477
478 mcbsp->free = false;
479 mcbsp->reg_cache = reg_cache;
480 spin_unlock(&mcbsp->lock);
481
482 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
483 mcbsp->pdata->ops->request(mcbsp->id - 1);
484
485 /*
486 * Make sure that transmitter, receiver and sample-rate generator are
487 * not running before activating IRQs.
488 */
489 MCBSP_WRITE(mcbsp, SPCR1, 0);
490 MCBSP_WRITE(mcbsp, SPCR2, 0);
491
492 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
493 0, "McBSP", (void *)mcbsp);
494 if (err != 0) {
495 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
496 "for McBSP%d\n", mcbsp->tx_irq,
497 mcbsp->id);
498 goto err_clk_disable;
499 }
500
501 if (mcbsp->rx_irq) {
502 err = request_irq(mcbsp->rx_irq,
503 omap_mcbsp_rx_irq_handler,
504 0, "McBSP", (void *)mcbsp);
505 if (err != 0) {
506 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
507 "for McBSP%d\n", mcbsp->rx_irq,
508 mcbsp->id);
509 goto err_free_irq;
510 }
511 }
512
513 return 0;
514err_free_irq:
515 free_irq(mcbsp->tx_irq, (void *)mcbsp);
516err_clk_disable:
517 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
518 mcbsp->pdata->ops->free(mcbsp->id - 1);
519
520 /* Disable wakeup behavior */
521 if (mcbsp->pdata->has_wakeup)
522 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
523
524 spin_lock(&mcbsp->lock);
525 mcbsp->free = true;
526 mcbsp->reg_cache = NULL;
527err_kfree:
528 spin_unlock(&mcbsp->lock);
529 kfree(reg_cache);
530
531 return err;
532}
533
534void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
535{
536 void *reg_cache;
537
538 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
539 mcbsp->pdata->ops->free(mcbsp->id - 1);
540
541 /* Disable wakeup behavior */
542 if (mcbsp->pdata->has_wakeup)
543 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
544
545 if (mcbsp->rx_irq)
546 free_irq(mcbsp->rx_irq, (void *)mcbsp);
547 free_irq(mcbsp->tx_irq, (void *)mcbsp);
548
549 reg_cache = mcbsp->reg_cache;
550
551 /*
552 * Select CLKS source from internal source unconditionally before
553 * marking the McBSP port as free.
554 * If the external clock source via MCBSP_CLKS pin has been selected the
555 * system will refuse to enter idle if the CLKS pin source is not reset
556 * back to internal source.
557 */
558 if (!cpu_class_is_omap1())
559 omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC);
560
561 spin_lock(&mcbsp->lock);
562 if (mcbsp->free)
563 dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
564 else
565 mcbsp->free = true;
566 mcbsp->reg_cache = NULL;
567 spin_unlock(&mcbsp->lock);
568
569 if (reg_cache)
570 kfree(reg_cache);
571}
572
573/*
574 * Here we start the McBSP, by enabling transmitter, receiver or both.
575 * If no transmitter or receiver is active prior calling, then sample-rate
576 * generator and frame sync are started.
577 */
578void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx)
579{
580 int enable_srg = 0;
581 u16 w;
582
583 if (mcbsp->st_data)
584 omap_st_start(mcbsp);
585
586 /* Only enable SRG, if McBSP is master */
587 w = MCBSP_READ_CACHE(mcbsp, PCR0);
588 if (w & (FSXM | FSRM | CLKXM | CLKRM))
589 enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
590 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
591
592 if (enable_srg) {
593 /* Start the sample generator */
594 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
595 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
596 }
597
598 /* Enable transmitter and receiver */
599 tx &= 1;
600 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
601 MCBSP_WRITE(mcbsp, SPCR2, w | tx);
602
603 rx &= 1;
604 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
605 MCBSP_WRITE(mcbsp, SPCR1, w | rx);
606
607 /*
608 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
609 * REVISIT: 100us may give enough time for two CLKSRG, however
610 * due to some unknown PM related, clock gating etc. reason it
611 * is now at 500us.
612 */
613 udelay(500);
614
615 if (enable_srg) {
616 /* Start frame sync */
617 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
618 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
619 }
620
621 if (mcbsp->pdata->has_ccr) {
622 /* Release the transmitter and receiver */
623 w = MCBSP_READ_CACHE(mcbsp, XCCR);
624 w &= ~(tx ? XDISABLE : 0);
625 MCBSP_WRITE(mcbsp, XCCR, w);
626 w = MCBSP_READ_CACHE(mcbsp, RCCR);
627 w &= ~(rx ? RDISABLE : 0);
628 MCBSP_WRITE(mcbsp, RCCR, w);
629 }
630
631 /* Dump McBSP Regs */
632 omap_mcbsp_dump_reg(mcbsp);
633}
634
635void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
636{
637 int idle;
638 u16 w;
639
640 /* Reset transmitter */
641 tx &= 1;
642 if (mcbsp->pdata->has_ccr) {
643 w = MCBSP_READ_CACHE(mcbsp, XCCR);
644 w |= (tx ? XDISABLE : 0);
645 MCBSP_WRITE(mcbsp, XCCR, w);
646 }
647 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
648 MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
649
650 /* Reset receiver */
651 rx &= 1;
652 if (mcbsp->pdata->has_ccr) {
653 w = MCBSP_READ_CACHE(mcbsp, RCCR);
654 w |= (rx ? RDISABLE : 0);
655 MCBSP_WRITE(mcbsp, RCCR, w);
656 }
657 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
658 MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
659
660 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
661 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
662
663 if (idle) {
664 /* Reset the sample rate generator */
665 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
666 MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
667 }
668
669 if (mcbsp->st_data)
670 omap_st_stop(mcbsp);
671}
672
673int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
674{
675 const char *src;
676
677 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
678 src = "clks_ext";
679 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
680 src = "clks_fclk";
681 else
682 return -EINVAL;
683
684 if (mcbsp->pdata->set_clk_src)
685 return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
686 else
687 return -EINVAL;
688}
689
690int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
691{
692 const char *signal, *src;
693
694 if (mcbsp->pdata->mux_signal)
695 return -EINVAL;
696
697 switch (mux) {
698 case CLKR_SRC_CLKR:
699 signal = "clkr";
700 src = "clkr";
701 break;
702 case CLKR_SRC_CLKX:
703 signal = "clkr";
704 src = "clkx";
705 break;
706 case FSR_SRC_FSR:
707 signal = "fsr";
708 src = "fsr";
709 break;
710 case FSR_SRC_FSX:
711 signal = "fsr";
712 src = "fsx";
713 break;
714 default:
715 return -EINVAL;
716 }
717
718 return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src);
719}
720
721#define max_thres(m) (mcbsp->pdata->buffer_size)
722#define valid_threshold(m, val) ((val) <= max_thres(m))
723#define THRESHOLD_PROP_BUILDER(prop) \
724static ssize_t prop##_show(struct device *dev, \
725 struct device_attribute *attr, char *buf) \
726{ \
727 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
728 \
729 return sprintf(buf, "%u\n", mcbsp->prop); \
730} \
731 \
732static ssize_t prop##_store(struct device *dev, \
733 struct device_attribute *attr, \
734 const char *buf, size_t size) \
735{ \
736 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
737 unsigned long val; \
738 int status; \
739 \
740 status = strict_strtoul(buf, 0, &val); \
741 if (status) \
742 return status; \
743 \
744 if (!valid_threshold(mcbsp, val)) \
745 return -EDOM; \
746 \
747 mcbsp->prop = val; \
748 return size; \
749} \
750 \
751static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
752
753THRESHOLD_PROP_BUILDER(max_tx_thres);
754THRESHOLD_PROP_BUILDER(max_rx_thres);
755
756static const char *dma_op_modes[] = {
757 "element", "threshold", "frame",
758};
759
760static ssize_t dma_op_mode_show(struct device *dev,
761 struct device_attribute *attr, char *buf)
762{
763 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
764 int dma_op_mode, i = 0;
765 ssize_t len = 0;
766 const char * const *s;
767
768 dma_op_mode = mcbsp->dma_op_mode;
769
770 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
771 if (dma_op_mode == i)
772 len += sprintf(buf + len, "[%s] ", *s);
773 else
774 len += sprintf(buf + len, "%s ", *s);
775 }
776 len += sprintf(buf + len, "\n");
777
778 return len;
779}
780
781static ssize_t dma_op_mode_store(struct device *dev,
782 struct device_attribute *attr,
783 const char *buf, size_t size)
784{
785 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
786 const char * const *s;
787 int i = 0;
788
789 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
790 if (sysfs_streq(buf, *s))
791 break;
792
793 if (i == ARRAY_SIZE(dma_op_modes))
794 return -EINVAL;
795
796 spin_lock_irq(&mcbsp->lock);
797 if (!mcbsp->free) {
798 size = -EBUSY;
799 goto unlock;
800 }
801 mcbsp->dma_op_mode = i;
802
803unlock:
804 spin_unlock_irq(&mcbsp->lock);
805
806 return size;
807}
808
809static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
810
811static const struct attribute *additional_attrs[] = {
812 &dev_attr_max_tx_thres.attr,
813 &dev_attr_max_rx_thres.attr,
814 &dev_attr_dma_op_mode.attr,
815 NULL,
816};
817
818static const struct attribute_group additional_attr_group = {
819 .attrs = (struct attribute **)additional_attrs,
820};
821
822static ssize_t st_taps_show(struct device *dev,
823 struct device_attribute *attr, char *buf)
824{
825 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
826 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
827 ssize_t status = 0;
828 int i;
829
830 spin_lock_irq(&mcbsp->lock);
831 for (i = 0; i < st_data->nr_taps; i++)
832 status += sprintf(&buf[status], (i ? ", %d" : "%d"),
833 st_data->taps[i]);
834 if (i)
835 status += sprintf(&buf[status], "\n");
836 spin_unlock_irq(&mcbsp->lock);
837
838 return status;
839}
840
841static ssize_t st_taps_store(struct device *dev,
842 struct device_attribute *attr,
843 const char *buf, size_t size)
844{
845 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
846 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
847 int val, tmp, status, i = 0;
848
849 spin_lock_irq(&mcbsp->lock);
850 memset(st_data->taps, 0, sizeof(st_data->taps));
851 st_data->nr_taps = 0;
852
853 do {
854 status = sscanf(buf, "%d%n", &val, &tmp);
855 if (status < 0 || status == 0) {
856 size = -EINVAL;
857 goto out;
858 }
859 if (val < -32768 || val > 32767) {
860 size = -EINVAL;
861 goto out;
862 }
863 st_data->taps[i++] = val;
864 buf += tmp;
865 if (*buf != ',')
866 break;
867 buf++;
868 } while (1);
869
870 st_data->nr_taps = i;
871
872out:
873 spin_unlock_irq(&mcbsp->lock);
874
875 return size;
876}
877
878static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
879
880static const struct attribute *sidetone_attrs[] = {
881 &dev_attr_st_taps.attr,
882 NULL,
883};
884
885static const struct attribute_group sidetone_attr_group = {
886 .attrs = (struct attribute **)sidetone_attrs,
887};
888
889static int __devinit omap_st_add(struct omap_mcbsp *mcbsp,
890 struct resource *res)
891{
892 struct omap_mcbsp_st_data *st_data;
893 int err;
894
895 st_data = devm_kzalloc(mcbsp->dev, sizeof(*mcbsp->st_data), GFP_KERNEL);
896 if (!st_data)
897 return -ENOMEM;
898
899 st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start,
900 resource_size(res));
901 if (!st_data->io_base_st)
902 return -ENOMEM;
903
904 err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
905 if (err)
906 return err;
907
908 mcbsp->st_data = st_data;
909 return 0;
910}
911
912/*
913 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
914 * 730 has only 2 McBSP, and both of them are MPU peripherals.
915 */
916int __devinit omap_mcbsp_init(struct platform_device *pdev)
917{
918 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
919 struct resource *res;
920 int ret = 0;
921
922 spin_lock_init(&mcbsp->lock);
923 mcbsp->free = true;
924
925 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
926 if (!res) {
927 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
928 if (!res) {
929 dev_err(mcbsp->dev, "invalid memory resource\n");
930 return -ENOMEM;
931 }
932 }
933 if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
934 dev_name(&pdev->dev))) {
935 dev_err(mcbsp->dev, "memory region already claimed\n");
936 return -ENODEV;
937 }
938
939 mcbsp->phys_base = res->start;
940 mcbsp->reg_cache_size = resource_size(res);
941 mcbsp->io_base = devm_ioremap(&pdev->dev, res->start,
942 resource_size(res));
943 if (!mcbsp->io_base)
944 return -ENOMEM;
945
946 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
947 if (!res)
948 mcbsp->phys_dma_base = mcbsp->phys_base;
949 else
950 mcbsp->phys_dma_base = res->start;
951
952 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
953 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
954
955 /* From OMAP4 there will be a single irq line */
956 if (mcbsp->tx_irq == -ENXIO) {
957 mcbsp->tx_irq = platform_get_irq(pdev, 0);
958 mcbsp->rx_irq = 0;
959 }
960
961 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
962 if (!res) {
963 dev_err(&pdev->dev, "invalid rx DMA channel\n");
964 return -ENODEV;
965 }
966 /* RX DMA request number, and port address configuration */
967 mcbsp->dma_data[1].name = "Audio Capture";
968 mcbsp->dma_data[1].dma_req = res->start;
969 mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
970
971 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
972 if (!res) {
973 dev_err(&pdev->dev, "invalid tx DMA channel\n");
974 return -ENODEV;
975 }
976 /* TX DMA request number, and port address configuration */
977 mcbsp->dma_data[0].name = "Audio Playback";
978 mcbsp->dma_data[0].dma_req = res->start;
979 mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
980
981 mcbsp->fclk = clk_get(&pdev->dev, "fck");
982 if (IS_ERR(mcbsp->fclk)) {
983 ret = PTR_ERR(mcbsp->fclk);
984 dev_err(mcbsp->dev, "unable to get fck: %d\n", ret);
985 return ret;
986 }
987
988 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
989 if (mcbsp->pdata->buffer_size) {
990 /*
991 * Initially configure the maximum thresholds to a safe value.
992 * The McBSP FIFO usage with these values should not go under
993 * 16 locations.
994 * If the whole FIFO without safety buffer is used, than there
995 * is a possibility that the DMA will be not able to push the
996 * new data on time, causing channel shifts in runtime.
997 */
998 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
999 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1000
1001 ret = sysfs_create_group(&mcbsp->dev->kobj,
1002 &additional_attr_group);
1003 if (ret) {
1004 dev_err(mcbsp->dev,
1005 "Unable to create additional controls\n");
1006 goto err_thres;
1007 }
1008 } else {
1009 mcbsp->max_tx_thres = -EINVAL;
1010 mcbsp->max_rx_thres = -EINVAL;
1011 }
1012
1013 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
1014 if (res) {
1015 ret = omap_st_add(mcbsp, res);
1016 if (ret) {
1017 dev_err(mcbsp->dev,
1018 "Unable to create sidetone controls\n");
1019 goto err_st;
1020 }
1021 }
1022
1023 return 0;
1024
1025err_st:
1026 if (mcbsp->pdata->buffer_size)
1027 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
1028err_thres:
1029 clk_put(mcbsp->fclk);
1030 return ret;
1031}
1032
1033void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp)
1034{
1035 if (mcbsp->pdata->buffer_size)
1036 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
1037
1038 if (mcbsp->st_data)
1039 sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1040}
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
new file mode 100644
index 000000000000..a944fcc9073c
--- /dev/null
+++ b/sound/soc/omap/mcbsp.h
@@ -0,0 +1,346 @@
1/*
2 * sound/soc/omap/mcbsp.h
3 *
4 * OMAP Multi-Channel Buffered Serial Port
5 *
6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24#ifndef __ASOC_MCBSP_H
25#define __ASOC_MCBSP_H
26
27#include "omap-pcm.h"
28
29/* McBSP register numbers. Register address offset = num * reg_step */
30enum {
31 /* Common registers */
32 OMAP_MCBSP_REG_SPCR2 = 4,
33 OMAP_MCBSP_REG_SPCR1,
34 OMAP_MCBSP_REG_RCR2,
35 OMAP_MCBSP_REG_RCR1,
36 OMAP_MCBSP_REG_XCR2,
37 OMAP_MCBSP_REG_XCR1,
38 OMAP_MCBSP_REG_SRGR2,
39 OMAP_MCBSP_REG_SRGR1,
40 OMAP_MCBSP_REG_MCR2,
41 OMAP_MCBSP_REG_MCR1,
42 OMAP_MCBSP_REG_RCERA,
43 OMAP_MCBSP_REG_RCERB,
44 OMAP_MCBSP_REG_XCERA,
45 OMAP_MCBSP_REG_XCERB,
46 OMAP_MCBSP_REG_PCR0,
47 OMAP_MCBSP_REG_RCERC,
48 OMAP_MCBSP_REG_RCERD,
49 OMAP_MCBSP_REG_XCERC,
50 OMAP_MCBSP_REG_XCERD,
51 OMAP_MCBSP_REG_RCERE,
52 OMAP_MCBSP_REG_RCERF,
53 OMAP_MCBSP_REG_XCERE,
54 OMAP_MCBSP_REG_XCERF,
55 OMAP_MCBSP_REG_RCERG,
56 OMAP_MCBSP_REG_RCERH,
57 OMAP_MCBSP_REG_XCERG,
58 OMAP_MCBSP_REG_XCERH,
59
60 /* OMAP1-OMAP2420 registers */
61 OMAP_MCBSP_REG_DRR2 = 0,
62 OMAP_MCBSP_REG_DRR1,
63 OMAP_MCBSP_REG_DXR2,
64 OMAP_MCBSP_REG_DXR1,
65
66 /* OMAP2430 and onwards */
67 OMAP_MCBSP_REG_DRR = 0,
68 OMAP_MCBSP_REG_DXR = 2,
69 OMAP_MCBSP_REG_SYSCON = 35,
70 OMAP_MCBSP_REG_THRSH2,
71 OMAP_MCBSP_REG_THRSH1,
72 OMAP_MCBSP_REG_IRQST = 40,
73 OMAP_MCBSP_REG_IRQEN,
74 OMAP_MCBSP_REG_WAKEUPEN,
75 OMAP_MCBSP_REG_XCCR,
76 OMAP_MCBSP_REG_RCCR,
77 OMAP_MCBSP_REG_XBUFFSTAT,
78 OMAP_MCBSP_REG_RBUFFSTAT,
79 OMAP_MCBSP_REG_SSELCR,
80};
81
82/* OMAP3 sidetone control registers */
83#define OMAP_ST_REG_REV 0x00
84#define OMAP_ST_REG_SYSCONFIG 0x10
85#define OMAP_ST_REG_IRQSTATUS 0x18
86#define OMAP_ST_REG_IRQENABLE 0x1C
87#define OMAP_ST_REG_SGAINCR 0x24
88#define OMAP_ST_REG_SFIRCR 0x28
89#define OMAP_ST_REG_SSELCR 0x2C
90
91/************************** McBSP SPCR1 bit definitions ***********************/
92#define RRST BIT(0)
93#define RRDY BIT(1)
94#define RFULL BIT(2)
95#define RSYNC_ERR BIT(3)
96#define RINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */
97#define ABIS BIT(6)
98#define DXENA BIT(7)
99#define CLKSTP(value) (((value) & 0x3) << 11) /* bits 11:12 */
100#define RJUST(value) (((value) & 0x3) << 13) /* bits 13:14 */
101#define ALB BIT(15)
102#define DLB BIT(15)
103
104/************************** McBSP SPCR2 bit definitions ***********************/
105#define XRST BIT(0)
106#define XRDY BIT(1)
107#define XEMPTY BIT(2)
108#define XSYNC_ERR BIT(3)
109#define XINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */
110#define GRST BIT(6)
111#define FRST BIT(7)
112#define SOFT BIT(8)
113#define FREE BIT(9)
114
115/************************** McBSP PCR bit definitions *************************/
116#define CLKRP BIT(0)
117#define CLKXP BIT(1)
118#define FSRP BIT(2)
119#define FSXP BIT(3)
120#define DR_STAT BIT(4)
121#define DX_STAT BIT(5)
122#define CLKS_STAT BIT(6)
123#define SCLKME BIT(7)
124#define CLKRM BIT(8)
125#define CLKXM BIT(9)
126#define FSRM BIT(10)
127#define FSXM BIT(11)
128#define RIOEN BIT(12)
129#define XIOEN BIT(13)
130#define IDLE_EN BIT(14)
131
132/************************** McBSP RCR1 bit definitions ************************/
133#define RWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */
134#define RFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
135
136/************************** McBSP XCR1 bit definitions ************************/
137#define XWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */
138#define XFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
139
140/*************************** McBSP RCR2 bit definitions ***********************/
141#define RDATDLY(value) ((value) & 0x3) /* Bits 0:1 */
142#define RFIG BIT(2)
143#define RCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */
144#define RWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */
145#define RFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
146#define RPHASE BIT(15)
147
148/*************************** McBSP XCR2 bit definitions ***********************/
149#define XDATDLY(value) ((value) & 0x3) /* Bits 0:1 */
150#define XFIG BIT(2)
151#define XCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */
152#define XWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */
153#define XFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
154#define XPHASE BIT(15)
155
156/************************* McBSP SRGR1 bit definitions ************************/
157#define CLKGDV(value) ((value) & 0x7f) /* Bits 0:7 */
158#define FWID(value) (((value) & 0xff) << 8) /* Bits 8:15 */
159
160/************************* McBSP SRGR2 bit definitions ************************/
161#define FPER(value) ((value) & 0x0fff) /* Bits 0:11 */
162#define FSGM BIT(12)
163#define CLKSM BIT(13)
164#define CLKSP BIT(14)
165#define GSYNC BIT(15)
166
167/************************* McBSP MCR1 bit definitions *************************/
168#define RMCM BIT(0)
169#define RCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */
170#define RPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */
171#define RPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */
172
173/************************* McBSP MCR2 bit definitions *************************/
174#define XMCM(value) ((value) & 0x3) /* Bits 0:1 */
175#define XCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */
176#define XPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */
177#define XPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */
178
179/*********************** McBSP XCCR bit definitions *************************/
180#define XDISABLE BIT(0)
181#define XDMAEN BIT(3)
182#define DILB BIT(5)
183#define XFULL_CYCLE BIT(11)
184#define DXENDLY(value) (((value) & 0x3) << 12) /* Bits 12:13 */
185#define PPCONNECT BIT(14)
186#define EXTCLKGATE BIT(15)
187
188/********************** McBSP RCCR bit definitions *************************/
189#define RDISABLE BIT(0)
190#define RDMAEN BIT(3)
191#define RFULL_CYCLE BIT(11)
192
193/********************** McBSP SYSCONFIG bit definitions ********************/
194#define SOFTRST BIT(1)
195#define ENAWAKEUP BIT(2)
196#define SIDLEMODE(value) (((value) & 0x3) << 3)
197#define CLOCKACTIVITY(value) (((value) & 0x3) << 8)
198
199/********************** McBSP SSELCR bit definitions ***********************/
200#define SIDETONEEN BIT(10)
201
202/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
203#define ST_AUTOIDLE BIT(0)
204
205/********************** McBSP Sidetone SGAINCR bit definitions *************/
206#define ST_CH0GAIN(value) ((value) & 0xffff) /* Bits 0:15 */
207#define ST_CH1GAIN(value) (((value) & 0xffff) << 16) /* Bits 16:31 */
208
209/********************** McBSP Sidetone SFIRCR bit definitions **************/
210#define ST_FIRCOEFF(value) ((value) & 0xffff) /* Bits 0:15 */
211
212/********************** McBSP Sidetone SSELCR bit definitions **************/
213#define ST_SIDETONEEN BIT(0)
214#define ST_COEFFWREN BIT(1)
215#define ST_COEFFWRDONE BIT(2)
216
217/********************** McBSP DMA operating modes **************************/
218#define MCBSP_DMA_MODE_ELEMENT 0
219#define MCBSP_DMA_MODE_THRESHOLD 1
220#define MCBSP_DMA_MODE_FRAME 2
221
222/********************** McBSP WAKEUPEN bit definitions *********************/
223#define RSYNCERREN BIT(0)
224#define RFSREN BIT(1)
225#define REOFEN BIT(2)
226#define RRDYEN BIT(3)
227#define XSYNCERREN BIT(7)
228#define XFSXEN BIT(8)
229#define XEOFEN BIT(9)
230#define XRDYEN BIT(10)
231#define XEMPTYEOFEN BIT(14)
232
233/* Clock signal muxing options */
234#define CLKR_SRC_CLKR 0 /* CLKR signal is from the CLKR pin */
235#define CLKR_SRC_CLKX 1 /* CLKR signal is from the CLKX pin */
236#define FSR_SRC_FSR 2 /* FSR signal is from the FSR pin */
237#define FSR_SRC_FSX 3 /* FSR signal is from the FSX pin */
238
239/* McBSP functional clock sources */
240#define MCBSP_CLKS_PRCM_SRC 0
241#define MCBSP_CLKS_PAD_SRC 1
242
243/* we don't do multichannel for now */
244struct omap_mcbsp_reg_cfg {
245 u16 spcr2;
246 u16 spcr1;
247 u16 rcr2;
248 u16 rcr1;
249 u16 xcr2;
250 u16 xcr1;
251 u16 srgr2;
252 u16 srgr1;
253 u16 mcr2;
254 u16 mcr1;
255 u16 pcr0;
256 u16 rcerc;
257 u16 rcerd;
258 u16 xcerc;
259 u16 xcerd;
260 u16 rcere;
261 u16 rcerf;
262 u16 xcere;
263 u16 xcerf;
264 u16 rcerg;
265 u16 rcerh;
266 u16 xcerg;
267 u16 xcerh;
268 u16 xccr;
269 u16 rccr;
270};
271
272struct omap_mcbsp_st_data {
273 void __iomem *io_base_st;
274 bool running;
275 bool enabled;
276 s16 taps[128]; /* Sidetone filter coefficients */
277 int nr_taps; /* Number of filter coefficients in use */
278 s16 ch0gain;
279 s16 ch1gain;
280};
281
282struct omap_mcbsp {
283 struct device *dev;
284 struct clk *fclk;
285 spinlock_t lock;
286 unsigned long phys_base;
287 unsigned long phys_dma_base;
288 void __iomem *io_base;
289 u8 id;
290 /*
291 * Flags indicating is the bus already activated and configured by
292 * another substream
293 */
294 int active;
295 int configured;
296 u8 free;
297
298 int rx_irq;
299 int tx_irq;
300
301 /* Protect the field .free, while checking if the mcbsp is in use */
302 struct omap_mcbsp_platform_data *pdata;
303 struct omap_mcbsp_st_data *st_data;
304 struct omap_mcbsp_reg_cfg cfg_regs;
305 struct omap_pcm_dma_data dma_data[2];
306 int dma_op_mode;
307 u16 max_tx_thres;
308 u16 max_rx_thres;
309 void *reg_cache;
310 int reg_cache_size;
311
312 unsigned int fmt;
313 unsigned int in_freq;
314 int clk_div;
315 int wlen;
316};
317
318void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
319 const struct omap_mcbsp_reg_cfg *config);
320void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold);
321void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold);
322u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp);
323u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp);
324int omap_mcbsp_get_dma_op_mode(struct omap_mcbsp *mcbsp);
325int omap_mcbsp_request(struct omap_mcbsp *mcbsp);
326void omap_mcbsp_free(struct omap_mcbsp *mcbsp);
327void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx);
328void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
329
330/* McBSP functional clock source changing function */
331int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
332
333/* McBSP signal muxing API */
334int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
335
336/* Sidetone specific API */
337int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
338int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
339int omap_st_enable(struct omap_mcbsp *mcbsp);
340int omap_st_disable(struct omap_mcbsp *mcbsp);
341int omap_st_is_enabled(struct omap_mcbsp *mcbsp);
342
343int __devinit omap_mcbsp_init(struct platform_device *pdev);
344void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp);
345
346#endif /* __ASOC_MCBSP_H */
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 597be412f1e4..abac4b690750 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -55,9 +55,8 @@ static int n810_spk_func;
55static int n810_jack_func; 55static int n810_jack_func;
56static int n810_dmic_func; 56static int n810_dmic_func;
57 57
58static void n810_ext_control(struct snd_soc_codec *codec) 58static void n810_ext_control(struct snd_soc_dapm_context *dapm)
59{ 59{
60 struct snd_soc_dapm_context *dapm = &codec->dapm;
61 int hp = 0, line1l = 0; 60 int hp = 0, line1l = 0;
62 61
63 switch (n810_jack_func) { 62 switch (n810_jack_func) {
@@ -102,7 +101,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
102 snd_pcm_hw_constraint_minmax(runtime, 101 snd_pcm_hw_constraint_minmax(runtime,
103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 102 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
104 103
105 n810_ext_control(codec); 104 n810_ext_control(&codec->dapm);
106 return clk_enable(sys_clkout2); 105 return clk_enable(sys_clkout2);
107} 106}
108 107
@@ -142,13 +141,13 @@ static int n810_get_spk(struct snd_kcontrol *kcontrol,
142static int n810_set_spk(struct snd_kcontrol *kcontrol, 141static int n810_set_spk(struct snd_kcontrol *kcontrol,
143 struct snd_ctl_elem_value *ucontrol) 142 struct snd_ctl_elem_value *ucontrol)
144{ 143{
145 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 144 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
146 145
147 if (n810_spk_func == ucontrol->value.integer.value[0]) 146 if (n810_spk_func == ucontrol->value.integer.value[0])
148 return 0; 147 return 0;
149 148
150 n810_spk_func = ucontrol->value.integer.value[0]; 149 n810_spk_func = ucontrol->value.integer.value[0];
151 n810_ext_control(codec); 150 n810_ext_control(&card->dapm);
152 151
153 return 1; 152 return 1;
154} 153}
@@ -164,13 +163,13 @@ static int n810_get_jack(struct snd_kcontrol *kcontrol,
164static int n810_set_jack(struct snd_kcontrol *kcontrol, 163static int n810_set_jack(struct snd_kcontrol *kcontrol,
165 struct snd_ctl_elem_value *ucontrol) 164 struct snd_ctl_elem_value *ucontrol)
166{ 165{
167 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 166 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
168 167
169 if (n810_jack_func == ucontrol->value.integer.value[0]) 168 if (n810_jack_func == ucontrol->value.integer.value[0])
170 return 0; 169 return 0;
171 170
172 n810_jack_func = ucontrol->value.integer.value[0]; 171 n810_jack_func = ucontrol->value.integer.value[0];
173 n810_ext_control(codec); 172 n810_ext_control(&card->dapm);
174 173
175 return 1; 174 return 1;
176} 175}
@@ -186,13 +185,13 @@ static int n810_get_input(struct snd_kcontrol *kcontrol,
186static int n810_set_input(struct snd_kcontrol *kcontrol, 185static int n810_set_input(struct snd_kcontrol *kcontrol,
187 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
188{ 187{
189 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
190 189
191 if (n810_dmic_func == ucontrol->value.integer.value[0]) 190 if (n810_dmic_func == ucontrol->value.integer.value[0])
192 return 0; 191 return 0;
193 192
194 n810_dmic_func = ucontrol->value.integer.value[0]; 193 n810_dmic_func = ucontrol->value.integer.value[0];
195 n810_ext_control(codec); 194 n810_ext_control(&card->dapm);
196 195
197 return 1; 196 return 1;
198} 197}
@@ -276,7 +275,7 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
276static struct snd_soc_dai_link n810_dai = { 275static struct snd_soc_dai_link n810_dai = {
277 .name = "TLV320AIC33", 276 .name = "TLV320AIC33",
278 .stream_name = "AIC33", 277 .stream_name = "AIC33",
279 .cpu_dai_name = "omap-mcbsp-dai.1", 278 .cpu_dai_name = "omap-mcbsp.2",
280 .platform_name = "omap-pcm-audio", 279 .platform_name = "omap-pcm-audio",
281 .codec_name = "tlv320aic3x-codec.2-0018", 280 .codec_name = "tlv320aic3x-codec.2-0018",
282 .codec_dai_name = "tlv320aic3x-hifi", 281 .codec_dai_name = "tlv320aic3x-hifi",
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
new file mode 100644
index 000000000000..93bb8eee22b3
--- /dev/null
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -0,0 +1,349 @@
1/*
2 * omap-abe-twl6040.c -- SoC audio for TI OMAP based boards with ABE and
3 * twl6040 codec
4 *
5 * Author: Misael Lopez Cruz <misael.lopez@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/platform_device.h>
25#include <linux/mfd/twl6040.h>
26#include <linux/platform_data/omap-abe-twl6040.h>
27#include <linux/module.h>
28
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/soc.h>
32#include <sound/jack.h>
33
34#include <asm/mach-types.h>
35#include <plat/hardware.h>
36#include <plat/mux.h>
37
38#include "omap-dmic.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h"
41#include "../codecs/twl6040.h"
42
43static int omap_abe_hw_params(struct snd_pcm_substream *substream,
44 struct snd_pcm_hw_params *params)
45{
46 struct snd_soc_pcm_runtime *rtd = substream->private_data;
47 struct snd_soc_dai *codec_dai = rtd->codec_dai;
48 struct snd_soc_codec *codec = rtd->codec;
49 struct snd_soc_card *card = codec->card;
50 struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
51 int clk_id, freq;
52 int ret;
53
54 clk_id = twl6040_get_clk_id(rtd->codec);
55 if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
56 freq = pdata->mclk_freq;
57 else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
58 freq = 32768;
59 else
60 return -EINVAL;
61
62 /* set the codec mclk */
63 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
64 SND_SOC_CLOCK_IN);
65 if (ret) {
66 printk(KERN_ERR "can't set codec system clock\n");
67 return ret;
68 }
69 return ret;
70}
71
72static struct snd_soc_ops omap_abe_ops = {
73 .hw_params = omap_abe_hw_params,
74};
75
76static int omap_abe_dmic_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params)
78{
79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 int ret = 0;
82
83 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
84 19200000, SND_SOC_CLOCK_IN);
85 if (ret < 0) {
86 printk(KERN_ERR "can't set DMIC cpu system clock\n");
87 return ret;
88 }
89 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
90 SND_SOC_CLOCK_OUT);
91 if (ret < 0) {
92 printk(KERN_ERR "can't set DMIC output clock\n");
93 return ret;
94 }
95 return 0;
96}
97
98static struct snd_soc_ops omap_abe_dmic_ops = {
99 .hw_params = omap_abe_dmic_hw_params,
100};
101
102/* Headset jack */
103static struct snd_soc_jack hs_jack;
104
105/*Headset jack detection DAPM pins */
106static struct snd_soc_jack_pin hs_jack_pins[] = {
107 {
108 .pin = "Headset Mic",
109 .mask = SND_JACK_MICROPHONE,
110 },
111 {
112 .pin = "Headset Stereophone",
113 .mask = SND_JACK_HEADPHONE,
114 },
115};
116
117/* SDP4430 machine DAPM */
118static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
119 /* Outputs */
120 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
121 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
122 SND_SOC_DAPM_SPK("Ext Spk", NULL),
123 SND_SOC_DAPM_LINE("Line Out", NULL),
124 SND_SOC_DAPM_SPK("Vibrator", NULL),
125
126 /* Inputs */
127 SND_SOC_DAPM_MIC("Headset Mic", NULL),
128 SND_SOC_DAPM_MIC("Main Handset Mic", NULL),
129 SND_SOC_DAPM_MIC("Sub Handset Mic", NULL),
130 SND_SOC_DAPM_LINE("Line In", NULL),
131};
132
133static const struct snd_soc_dapm_route audio_map[] = {
134 /* Routings for outputs */
135 {"Headset Stereophone", NULL, "HSOL"},
136 {"Headset Stereophone", NULL, "HSOR"},
137
138 {"Earphone Spk", NULL, "EP"},
139
140 {"Ext Spk", NULL, "HFL"},
141 {"Ext Spk", NULL, "HFR"},
142
143 {"Line Out", NULL, "AUXL"},
144 {"Line Out", NULL, "AUXR"},
145
146 {"Vibrator", NULL, "VIBRAL"},
147 {"Vibrator", NULL, "VIBRAR"},
148
149 /* Routings for inputs */
150 {"HSMIC", NULL, "Headset Mic"},
151 {"Headset Mic", NULL, "Headset Mic Bias"},
152
153 {"MAINMIC", NULL, "Main Handset Mic"},
154 {"Main Handset Mic", NULL, "Main Mic Bias"},
155
156 {"SUBMIC", NULL, "Sub Handset Mic"},
157 {"Sub Handset Mic", NULL, "Main Mic Bias"},
158
159 {"AFML", NULL, "Line In"},
160 {"AFMR", NULL, "Line In"},
161};
162
163static inline void twl6040_disconnect_pin(struct snd_soc_dapm_context *dapm,
164 int connected, char *pin)
165{
166 if (!connected)
167 snd_soc_dapm_disable_pin(dapm, pin);
168}
169
170static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
171{
172 struct snd_soc_codec *codec = rtd->codec;
173 struct snd_soc_card *card = codec->card;
174 struct snd_soc_dapm_context *dapm = &codec->dapm;
175 struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
176 int hs_trim;
177 int ret = 0;
178
179 /* Disable not connected paths if not used */
180 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
181 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
182 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
183 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
184 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
185 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
186 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
187 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
188 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
189
190 /*
191 * Configure McPDM offset cancellation based on the HSOTRIM value from
192 * twl6040.
193 */
194 hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
195 omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
196 TWL6040_HSF_TRIM_RIGHT(hs_trim));
197
198 /* Headset jack detection only if it is supported */
199 if (pdata->jack_detection) {
200 ret = snd_soc_jack_new(codec, "Headset Jack",
201 SND_JACK_HEADSET, &hs_jack);
202 if (ret)
203 return ret;
204
205 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
206 hs_jack_pins);
207 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
208 }
209
210 return ret;
211}
212
213static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
214 SND_SOC_DAPM_MIC("Digital Mic", NULL),
215};
216
217static const struct snd_soc_dapm_route dmic_audio_map[] = {
218 {"DMic", NULL, "Digital Mic"},
219 {"Digital Mic", NULL, "Digital Mic1 Bias"},
220};
221
222static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
223{
224 struct snd_soc_codec *codec = rtd->codec;
225 struct snd_soc_dapm_context *dapm = &codec->dapm;
226 int ret;
227
228 ret = snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
229 ARRAY_SIZE(dmic_dapm_widgets));
230 if (ret)
231 return ret;
232
233 return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
234 ARRAY_SIZE(dmic_audio_map));
235}
236
237/* Digital audio interface glue - connects codec <--> CPU */
238static struct snd_soc_dai_link twl6040_dmic_dai[] = {
239 {
240 .name = "TWL6040",
241 .stream_name = "TWL6040",
242 .cpu_dai_name = "omap-mcpdm",
243 .codec_dai_name = "twl6040-legacy",
244 .platform_name = "omap-pcm-audio",
245 .codec_name = "twl6040-codec",
246 .init = omap_abe_twl6040_init,
247 .ops = &omap_abe_ops,
248 },
249 {
250 .name = "DMIC",
251 .stream_name = "DMIC Capture",
252 .cpu_dai_name = "omap-dmic",
253 .codec_dai_name = "dmic-hifi",
254 .platform_name = "omap-pcm-audio",
255 .codec_name = "dmic-codec",
256 .init = omap_abe_dmic_init,
257 .ops = &omap_abe_dmic_ops,
258 },
259};
260
261static struct snd_soc_dai_link twl6040_only_dai[] = {
262 {
263 .name = "TWL6040",
264 .stream_name = "TWL6040",
265 .cpu_dai_name = "omap-mcpdm",
266 .codec_dai_name = "twl6040-legacy",
267 .platform_name = "omap-pcm-audio",
268 .codec_name = "twl6040-codec",
269 .init = omap_abe_twl6040_init,
270 .ops = &omap_abe_ops,
271 },
272};
273
274/* Audio machine driver */
275static struct snd_soc_card omap_abe_card = {
276 .owner = THIS_MODULE,
277
278 .dapm_widgets = twl6040_dapm_widgets,
279 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
280 .dapm_routes = audio_map,
281 .num_dapm_routes = ARRAY_SIZE(audio_map),
282};
283
284static __devinit int omap_abe_probe(struct platform_device *pdev)
285{
286 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
287 struct snd_soc_card *card = &omap_abe_card;
288 int ret;
289
290 card->dev = &pdev->dev;
291
292 if (!pdata) {
293 dev_err(&pdev->dev, "Missing pdata\n");
294 return -ENODEV;
295 }
296
297 if (pdata->card_name) {
298 card->name = pdata->card_name;
299 } else {
300 dev_err(&pdev->dev, "Card name is not provided\n");
301 return -ENODEV;
302 }
303
304 if (!pdata->mclk_freq) {
305 dev_err(&pdev->dev, "MCLK frequency missing\n");
306 return -ENODEV;
307 }
308
309 if (pdata->has_dmic) {
310 card->dai_link = twl6040_dmic_dai;
311 card->num_links = ARRAY_SIZE(twl6040_dmic_dai);
312 } else {
313 card->dai_link = twl6040_only_dai;
314 card->num_links = ARRAY_SIZE(twl6040_only_dai);
315 }
316
317 ret = snd_soc_register_card(card);
318 if (ret)
319 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
320 ret);
321
322 return ret;
323}
324
325static int __devexit omap_abe_remove(struct platform_device *pdev)
326{
327 struct snd_soc_card *card = platform_get_drvdata(pdev);
328
329 snd_soc_unregister_card(card);
330
331 return 0;
332}
333
334static struct platform_driver omap_abe_driver = {
335 .driver = {
336 .name = "omap-abe-twl6040",
337 .owner = THIS_MODULE,
338 .pm = &snd_soc_pm_ops,
339 },
340 .probe = omap_abe_probe,
341 .remove = __devexit_p(omap_abe_remove),
342};
343
344module_platform_driver(omap_abe_driver);
345
346MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
347MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec");
348MODULE_LICENSE("GPL");
349MODULE_ALIAS("platform:omap-abe-twl6040");
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 0855c1cfa7fd..4dcb5a7e40e8 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -113,12 +113,10 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
113 113
114 mutex_lock(&dmic->mutex); 114 mutex_lock(&dmic->mutex);
115 115
116 if (!dai->active) { 116 if (!dai->active)
117 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
118 dmic->active = 1; 117 dmic->active = 1;
119 } else { 118 else
120 ret = -EBUSY; 119 ret = -EBUSY;
121 }
122 120
123 mutex_unlock(&dmic->mutex); 121 mutex_unlock(&dmic->mutex);
124 122
@@ -445,6 +443,7 @@ static struct snd_soc_dai_driver omap_dmic_dai = {
445 .channels_max = 6, 443 .channels_max = 6,
446 .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, 444 .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
447 .formats = SNDRV_PCM_FMTBIT_S32_LE, 445 .formats = SNDRV_PCM_FMTBIT_S32_LE,
446 .sig_bits = 24,
448 }, 447 },
449 .ops = &omap_dmic_dai_ops, 448 .ops = &omap_dmic_dai_ops,
450}; 449};
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 017371913ec3..6912ac7cb625 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -25,6 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/pm_runtime.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -33,6 +34,7 @@
33 34
34#include <plat/dma.h> 35#include <plat/dma.h>
35#include <plat/mcbsp.h> 36#include <plat/mcbsp.h>
37#include "mcbsp.h"
36#include "omap-mcbsp.h" 38#include "omap-mcbsp.h"
37#include "omap-pcm.h" 39#include "omap-pcm.h"
38 40
@@ -46,42 +48,31 @@
46 .private_value = (unsigned long) &(struct soc_mixer_control) \ 48 .private_value = (unsigned long) &(struct soc_mixer_control) \
47 {.min = xmin, .max = xmax} } 49 {.min = xmin, .max = xmax} }
48 50
49struct omap_mcbsp_data { 51enum {
50 unsigned int bus_id; 52 OMAP_MCBSP_WORD_8 = 0,
51 struct omap_mcbsp_reg_cfg regs; 53 OMAP_MCBSP_WORD_12,
52 unsigned int fmt; 54 OMAP_MCBSP_WORD_16,
53 /* 55 OMAP_MCBSP_WORD_20,
54 * Flags indicating is the bus already activated and configured by 56 OMAP_MCBSP_WORD_24,
55 * another substream 57 OMAP_MCBSP_WORD_32,
56 */
57 int active;
58 int configured;
59 unsigned int in_freq;
60 int clk_div;
61 int wlen;
62}; 58};
63 59
64static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
65
66/* 60/*
67 * Stream DMA parameters. DMA request line and port address are set runtime 61 * Stream DMA parameters. DMA request line and port address are set runtime
68 * since they are different between OMAP1 and later OMAPs 62 * since they are different between OMAP1 and later OMAPs
69 */ 63 */
70static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2];
71
72static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 64static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
73{ 65{
74 struct snd_soc_pcm_runtime *rtd = substream->private_data; 66 struct snd_soc_pcm_runtime *rtd = substream->private_data;
75 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 67 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
76 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 68 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
77 struct omap_pcm_dma_data *dma_data; 69 struct omap_pcm_dma_data *dma_data;
78 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id);
79 int words; 70 int words;
80 71
81 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 72 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
82 73
83 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 74 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
84 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) 75 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
85 /* 76 /*
86 * Configure McBSP threshold based on either: 77 * Configure McBSP threshold based on either:
87 * packet_size, when the sDMA is in packet mode, or 78 * packet_size, when the sDMA is in packet mode, or
@@ -91,15 +82,15 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
91 words = dma_data->packet_size; 82 words = dma_data->packet_size;
92 else 83 else
93 words = snd_pcm_lib_period_bytes(substream) / 84 words = snd_pcm_lib_period_bytes(substream) /
94 (mcbsp_data->wlen / 8); 85 (mcbsp->wlen / 8);
95 else 86 else
96 words = 1; 87 words = 1;
97 88
98 /* Configure McBSP internal buffer usage */ 89 /* Configure McBSP internal buffer usage */
99 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 90 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
100 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words); 91 omap_mcbsp_set_tx_threshold(mcbsp, words);
101 else 92 else
102 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words); 93 omap_mcbsp_set_rx_threshold(mcbsp, words);
103} 94}
104 95
105static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, 96static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
@@ -109,12 +100,12 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
109 SNDRV_PCM_HW_PARAM_BUFFER_SIZE); 100 SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
110 struct snd_interval *channels = hw_param_interval(params, 101 struct snd_interval *channels = hw_param_interval(params,
111 SNDRV_PCM_HW_PARAM_CHANNELS); 102 SNDRV_PCM_HW_PARAM_CHANNELS);
112 struct omap_mcbsp_data *mcbsp_data = rule->private; 103 struct omap_mcbsp *mcbsp = rule->private;
113 struct snd_interval frames; 104 struct snd_interval frames;
114 int size; 105 int size;
115 106
116 snd_interval_any(&frames); 107 snd_interval_any(&frames);
117 size = omap_mcbsp_get_fifo_size(mcbsp_data->bus_id); 108 size = mcbsp->pdata->buffer_size;
118 109
119 frames.min = size / channels->min; 110 frames.min = size / channels->min;
120 frames.integer = 1; 111 frames.integer = 1;
@@ -124,12 +115,11 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
124static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 115static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
125 struct snd_soc_dai *cpu_dai) 116 struct snd_soc_dai *cpu_dai)
126{ 117{
127 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 118 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
128 int bus_id = mcbsp_data->bus_id;
129 int err = 0; 119 int err = 0;
130 120
131 if (!cpu_dai->active) 121 if (!cpu_dai->active)
132 err = omap_mcbsp_request(bus_id); 122 err = omap_mcbsp_request(mcbsp);
133 123
134 /* 124 /*
135 * OMAP3 McBSP FIFO is word structured. 125 * OMAP3 McBSP FIFO is word structured.
@@ -146,16 +136,16 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
146 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) 136 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
147 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 137 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
148 */ 138 */
149 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 139 if (mcbsp->pdata->buffer_size) {
150 /* 140 /*
151 * Rule for the buffer size. We should not allow 141 * Rule for the buffer size. We should not allow
152 * smaller buffer than the FIFO size to avoid underruns 142 * smaller buffer than the FIFO size to avoid underruns
153 */ 143 */
154 snd_pcm_hw_rule_add(substream->runtime, 0, 144 snd_pcm_hw_rule_add(substream->runtime, 0,
155 SNDRV_PCM_HW_PARAM_CHANNELS, 145 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
156 omap_mcbsp_hwrule_min_buffersize, 146 omap_mcbsp_hwrule_min_buffersize,
157 mcbsp_data, 147 mcbsp,
158 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); 148 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
159 149
160 /* Make sure, that the period size is always even */ 150 /* Make sure, that the period size is always even */
161 snd_pcm_hw_constraint_step(substream->runtime, 0, 151 snd_pcm_hw_constraint_step(substream->runtime, 0,
@@ -168,33 +158,33 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
168static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream, 158static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *cpu_dai) 159 struct snd_soc_dai *cpu_dai)
170{ 160{
171 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 161 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
172 162
173 if (!cpu_dai->active) { 163 if (!cpu_dai->active) {
174 omap_mcbsp_free(mcbsp_data->bus_id); 164 omap_mcbsp_free(mcbsp);
175 mcbsp_data->configured = 0; 165 mcbsp->configured = 0;
176 } 166 }
177} 167}
178 168
179static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, 169static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
180 struct snd_soc_dai *cpu_dai) 170 struct snd_soc_dai *cpu_dai)
181{ 171{
182 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 172 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
183 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 173 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
184 174
185 switch (cmd) { 175 switch (cmd) {
186 case SNDRV_PCM_TRIGGER_START: 176 case SNDRV_PCM_TRIGGER_START:
187 case SNDRV_PCM_TRIGGER_RESUME: 177 case SNDRV_PCM_TRIGGER_RESUME:
188 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 178 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
189 mcbsp_data->active++; 179 mcbsp->active++;
190 omap_mcbsp_start(mcbsp_data->bus_id, play, !play); 180 omap_mcbsp_start(mcbsp, play, !play);
191 break; 181 break;
192 182
193 case SNDRV_PCM_TRIGGER_STOP: 183 case SNDRV_PCM_TRIGGER_STOP:
194 case SNDRV_PCM_TRIGGER_SUSPEND: 184 case SNDRV_PCM_TRIGGER_SUSPEND:
195 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 185 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
196 omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); 186 omap_mcbsp_stop(mcbsp, play, !play);
197 mcbsp_data->active--; 187 mcbsp->active--;
198 break; 188 break;
199 default: 189 default:
200 err = -EINVAL; 190 err = -EINVAL;
@@ -209,14 +199,14 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay(
209{ 199{
210 struct snd_soc_pcm_runtime *rtd = substream->private_data; 200 struct snd_soc_pcm_runtime *rtd = substream->private_data;
211 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 201 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
212 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 202 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
213 u16 fifo_use; 203 u16 fifo_use;
214 snd_pcm_sframes_t delay; 204 snd_pcm_sframes_t delay;
215 205
216 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 206 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
217 fifo_use = omap_mcbsp_get_tx_delay(mcbsp_data->bus_id); 207 fifo_use = omap_mcbsp_get_tx_delay(mcbsp);
218 else 208 else
219 fifo_use = omap_mcbsp_get_rx_delay(mcbsp_data->bus_id); 209 fifo_use = omap_mcbsp_get_rx_delay(mcbsp);
220 210
221 /* 211 /*
222 * Divide the used locations with the channel count to get the 212 * Divide the used locations with the channel count to get the
@@ -232,19 +222,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
232 struct snd_pcm_hw_params *params, 222 struct snd_pcm_hw_params *params,
233 struct snd_soc_dai *cpu_dai) 223 struct snd_soc_dai *cpu_dai)
234{ 224{
235 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 225 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
236 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 226 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
237 struct omap_pcm_dma_data *dma_data; 227 struct omap_pcm_dma_data *dma_data;
238 int dma, bus_id = mcbsp_data->bus_id;
239 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 228 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
240 int pkt_size = 0; 229 int pkt_size = 0;
241 unsigned long port;
242 unsigned int format, div, framesize, master; 230 unsigned int format, div, framesize, master;
243 231
244 dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream]; 232 dma_data = &mcbsp->dma_data[substream->stream];
245
246 dma = omap_mcbsp_dma_ch_params(bus_id, substream->stream);
247 port = omap_mcbsp_dma_reg_params(bus_id, substream->stream);
248 233
249 switch (params_format(params)) { 234 switch (params_format(params)) {
250 case SNDRV_PCM_FORMAT_S16_LE: 235 case SNDRV_PCM_FORMAT_S16_LE:
@@ -258,20 +243,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
258 default: 243 default:
259 return -EINVAL; 244 return -EINVAL;
260 } 245 }
261 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 246 if (mcbsp->pdata->buffer_size) {
262 dma_data->set_threshold = omap_mcbsp_set_threshold; 247 dma_data->set_threshold = omap_mcbsp_set_threshold;
263 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 248 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
264 if (omap_mcbsp_get_dma_op_mode(bus_id) == 249 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
265 MCBSP_DMA_MODE_THRESHOLD) {
266 int period_words, max_thrsh; 250 int period_words, max_thrsh;
267 251
268 period_words = params_period_bytes(params) / (wlen / 8); 252 period_words = params_period_bytes(params) / (wlen / 8);
269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 253 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
270 max_thrsh = omap_mcbsp_get_max_tx_threshold( 254 max_thrsh = mcbsp->max_tx_thres;
271 mcbsp_data->bus_id);
272 else 255 else
273 max_thrsh = omap_mcbsp_get_max_rx_threshold( 256 max_thrsh = mcbsp->max_rx_thres;
274 mcbsp_data->bus_id);
275 /* 257 /*
276 * If the period contains less or equal number of words, 258 * If the period contains less or equal number of words,
277 * we are using the original threshold mode setup: 259 * we are using the original threshold mode setup:
@@ -304,15 +286,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
304 } 286 }
305 } 287 }
306 288
307 dma_data->name = substream->stream ? "Audio Capture" : "Audio Playback";
308 dma_data->dma_req = dma;
309 dma_data->port_addr = port;
310 dma_data->sync_mode = sync_mode; 289 dma_data->sync_mode = sync_mode;
311 dma_data->packet_size = pkt_size; 290 dma_data->packet_size = pkt_size;
312 291
313 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); 292 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
314 293
315 if (mcbsp_data->configured) { 294 if (mcbsp->configured) {
316 /* McBSP already configured by another stream */ 295 /* McBSP already configured by another stream */
317 return 0; 296 return 0;
318 } 297 }
@@ -321,7 +300,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
321 regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7)); 300 regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
322 regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7)); 301 regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
323 regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7)); 302 regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
324 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 303 format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
325 wpf = channels = params_channels(params); 304 wpf = channels = params_channels(params);
326 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || 305 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
327 format == SND_SOC_DAIFMT_LEFT_J)) { 306 format == SND_SOC_DAIFMT_LEFT_J)) {
@@ -359,10 +338,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
359 338
360 /* In McBSP master modes, FRAME (i.e. sample rate) is generated 339 /* In McBSP master modes, FRAME (i.e. sample rate) is generated
361 * by _counting_ BCLKs. Calculate frame size in BCLKs */ 340 * by _counting_ BCLKs. Calculate frame size in BCLKs */
362 master = mcbsp_data->fmt & SND_SOC_DAIFMT_MASTER_MASK; 341 master = mcbsp->fmt & SND_SOC_DAIFMT_MASTER_MASK;
363 if (master == SND_SOC_DAIFMT_CBS_CFS) { 342 if (master == SND_SOC_DAIFMT_CBS_CFS) {
364 div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1; 343 div = mcbsp->clk_div ? mcbsp->clk_div : 1;
365 framesize = (mcbsp_data->in_freq / div) / params_rate(params); 344 framesize = (mcbsp->in_freq / div) / params_rate(params);
366 345
367 if (framesize < wlen * channels) { 346 if (framesize < wlen * channels) {
368 printk(KERN_ERR "%s: not enough bandwidth for desired rate and " 347 printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
@@ -388,9 +367,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
388 break; 367 break;
389 } 368 }
390 369
391 omap_mcbsp_config(bus_id, &mcbsp_data->regs); 370 omap_mcbsp_config(mcbsp, &mcbsp->cfg_regs);
392 mcbsp_data->wlen = wlen; 371 mcbsp->wlen = wlen;
393 mcbsp_data->configured = 1; 372 mcbsp->configured = 1;
394 373
395 return 0; 374 return 0;
396} 375}
@@ -402,14 +381,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
402static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, 381static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
403 unsigned int fmt) 382 unsigned int fmt)
404{ 383{
405 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 384 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
406 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 385 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
407 bool inv_fs = false; 386 bool inv_fs = false;
408 387
409 if (mcbsp_data->configured) 388 if (mcbsp->configured)
410 return 0; 389 return 0;
411 390
412 mcbsp_data->fmt = fmt; 391 mcbsp->fmt = fmt;
413 memset(regs, 0, sizeof(*regs)); 392 memset(regs, 0, sizeof(*regs));
414 /* Generic McBSP register settings */ 393 /* Generic McBSP register settings */
415 regs->spcr2 |= XINTM(3) | FREE; 394 regs->spcr2 |= XINTM(3) | FREE;
@@ -504,13 +483,13 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
504static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, 483static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
505 int div_id, int div) 484 int div_id, int div)
506{ 485{
507 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 486 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
508 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 487 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
509 488
510 if (div_id != OMAP_MCBSP_CLKGDV) 489 if (div_id != OMAP_MCBSP_CLKGDV)
511 return -ENODEV; 490 return -ENODEV;
512 491
513 mcbsp_data->clk_div = div; 492 mcbsp->clk_div = div;
514 regs->srgr1 &= ~CLKGDV(0xff); 493 regs->srgr1 &= ~CLKGDV(0xff);
515 regs->srgr1 |= CLKGDV(div - 1); 494 regs->srgr1 |= CLKGDV(div - 1);
516 495
@@ -521,28 +500,32 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
521 int clk_id, unsigned int freq, 500 int clk_id, unsigned int freq,
522 int dir) 501 int dir)
523{ 502{
524 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 503 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
525 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 504 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
526 int err = 0; 505 int err = 0;
527 506
528 if (mcbsp_data->active) { 507 if (mcbsp->active) {
529 if (freq == mcbsp_data->in_freq) 508 if (freq == mcbsp->in_freq)
530 return 0; 509 return 0;
531 else 510 else
532 return -EBUSY; 511 return -EBUSY;
533 } 512 }
534 513
535 /* The McBSP signal muxing functions are only available on McBSP1 */ 514 if (clk_id == OMAP_MCBSP_SYSCLK_CLK ||
536 if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || 515 clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK ||
537 clk_id == OMAP_MCBSP_CLKR_SRC_CLKX || 516 clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT ||
538 clk_id == OMAP_MCBSP_FSR_SRC_FSR || 517 clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
539 clk_id == OMAP_MCBSP_FSR_SRC_FSX) 518 clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
540 if (cpu_class_is_omap1() || mcbsp_data->bus_id != 0) 519 mcbsp->in_freq = freq;
541 return -EINVAL; 520 regs->srgr2 &= ~CLKSM;
542 521 regs->pcr0 &= ~SCLKME;
543 mcbsp_data->in_freq = freq; 522 } else if (cpu_class_is_omap1()) {
544 regs->srgr2 &= ~CLKSM; 523 /*
545 regs->pcr0 &= ~SCLKME; 524 * McBSP CLKR/FSR signal muxing functions are only available on
525 * OMAP2 or newer versions
526 */
527 return -EINVAL;
528 }
546 529
547 switch (clk_id) { 530 switch (clk_id) {
548 case OMAP_MCBSP_SYSCLK_CLK: 531 case OMAP_MCBSP_SYSCLK_CLK:
@@ -553,7 +536,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
553 err = -EINVAL; 536 err = -EINVAL;
554 break; 537 break;
555 } 538 }
556 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, 539 err = omap2_mcbsp_set_clks_src(mcbsp,
557 MCBSP_CLKS_PRCM_SRC); 540 MCBSP_CLKS_PRCM_SRC);
558 break; 541 break;
559 case OMAP_MCBSP_SYSCLK_CLKS_EXT: 542 case OMAP_MCBSP_SYSCLK_CLKS_EXT:
@@ -561,7 +544,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
561 err = 0; 544 err = 0;
562 break; 545 break;
563 } 546 }
564 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, 547 err = omap2_mcbsp_set_clks_src(mcbsp,
565 MCBSP_CLKS_PAD_SRC); 548 MCBSP_CLKS_PAD_SRC);
566 break; 549 break;
567 550
@@ -573,24 +556,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
573 556
574 557
575 case OMAP_MCBSP_CLKR_SRC_CLKR: 558 case OMAP_MCBSP_CLKR_SRC_CLKR:
576 if (cpu_class_is_omap1()) 559 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
577 break;
578 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
579 break; 560 break;
580 case OMAP_MCBSP_CLKR_SRC_CLKX: 561 case OMAP_MCBSP_CLKR_SRC_CLKX:
581 if (cpu_class_is_omap1()) 562 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
582 break;
583 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
584 break; 563 break;
585 case OMAP_MCBSP_FSR_SRC_FSR: 564 case OMAP_MCBSP_FSR_SRC_FSR:
586 if (cpu_class_is_omap1()) 565 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
587 break;
588 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
589 break; 566 break;
590 case OMAP_MCBSP_FSR_SRC_FSX: 567 case OMAP_MCBSP_FSR_SRC_FSX:
591 if (cpu_class_is_omap1()) 568 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
592 break;
593 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
594 break; 569 break;
595 default: 570 default:
596 err = -ENODEV; 571 err = -ENODEV;
@@ -610,15 +585,27 @@ static const struct snd_soc_dai_ops mcbsp_dai_ops = {
610 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 585 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,
611}; 586};
612 587
613static int mcbsp_dai_probe(struct snd_soc_dai *dai) 588static int omap_mcbsp_probe(struct snd_soc_dai *dai)
614{ 589{
615 mcbsp_data[dai->id].bus_id = dai->id; 590 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
616 snd_soc_dai_set_drvdata(dai, &mcbsp_data[dai->id].bus_id); 591
592 pm_runtime_enable(mcbsp->dev);
593
594 return 0;
595}
596
597static int omap_mcbsp_remove(struct snd_soc_dai *dai)
598{
599 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
600
601 pm_runtime_disable(mcbsp->dev);
602
617 return 0; 603 return 0;
618} 604}
619 605
620static struct snd_soc_dai_driver omap_mcbsp_dai = { 606static struct snd_soc_dai_driver omap_mcbsp_dai = {
621 .probe = mcbsp_dai_probe, 607 .probe = omap_mcbsp_probe,
608 .remove = omap_mcbsp_remove,
622 .playback = { 609 .playback = {
623 .channels_min = 1, 610 .channels_min = 1,
624 .channels_max = 16, 611 .channels_max = 16,
@@ -649,11 +636,13 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
649 return 0; 636 return 0;
650} 637}
651 638
652#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(id, channel) \ 639#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \
653static int \ 640static int \
654omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 641omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
655 struct snd_ctl_elem_value *uc) \ 642 struct snd_ctl_elem_value *uc) \
656{ \ 643{ \
644 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
645 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
657 struct soc_mixer_control *mc = \ 646 struct soc_mixer_control *mc = \
658 (struct soc_mixer_control *)kc->private_value; \ 647 (struct soc_mixer_control *)kc->private_value; \
659 int max = mc->max; \ 648 int max = mc->max; \
@@ -664,46 +653,44 @@ omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
664 return -EINVAL; \ 653 return -EINVAL; \
665 \ 654 \
666 /* OMAP McBSP implementation uses index values 0..4 */ \ 655 /* OMAP McBSP implementation uses index values 0..4 */ \
667 return omap_st_set_chgain((id)-1, channel, val); \ 656 return omap_st_set_chgain(mcbsp, channel, val); \
668} 657}
669 658
670#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(id, channel) \ 659#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \
671static int \ 660static int \
672omap_mcbsp##id##_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 661omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
673 struct snd_ctl_elem_value *uc) \ 662 struct snd_ctl_elem_value *uc) \
674{ \ 663{ \
664 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
665 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
675 s16 chgain; \ 666 s16 chgain; \
676 \ 667 \
677 if (omap_st_get_chgain((id)-1, channel, &chgain)) \ 668 if (omap_st_get_chgain(mcbsp, channel, &chgain)) \
678 return -EAGAIN; \ 669 return -EAGAIN; \
679 \ 670 \
680 uc->value.integer.value[0] = chgain; \ 671 uc->value.integer.value[0] = chgain; \
681 return 0; \ 672 return 0; \
682} 673}
683 674
684OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 0) 675OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0)
685OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 1) 676OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1)
686OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 0) 677OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
687OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 1) 678OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
688OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 0)
689OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 1)
690OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 0)
691OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 1)
692 679
693static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, 680static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol) 681 struct snd_ctl_elem_value *ucontrol)
695{ 682{
696 struct soc_mixer_control *mc = 683 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
697 (struct soc_mixer_control *)kcontrol->private_value; 684 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
698 u8 value = ucontrol->value.integer.value[0]; 685 u8 value = ucontrol->value.integer.value[0];
699 686
700 if (value == omap_st_is_enabled(mc->reg)) 687 if (value == omap_st_is_enabled(mcbsp))
701 return 0; 688 return 0;
702 689
703 if (value) 690 if (value)
704 omap_st_enable(mc->reg); 691 omap_st_enable(mcbsp);
705 else 692 else
706 omap_st_disable(mc->reg); 693 omap_st_disable(mcbsp);
707 694
708 return 1; 695 return 1;
709} 696}
@@ -711,10 +698,10 @@ static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
711static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol, 698static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol) 699 struct snd_ctl_elem_value *ucontrol)
713{ 700{
714 struct soc_mixer_control *mc = 701 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
715 (struct soc_mixer_control *)kcontrol->private_value; 702 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
716 703
717 ucontrol->value.integer.value[0] = omap_st_is_enabled(mc->reg); 704 ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp);
718 return 0; 705 return 0;
719} 706}
720 707
@@ -723,12 +710,12 @@ static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
723 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), 710 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
724 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", 711 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
725 -32768, 32767, 712 -32768, 32767,
726 omap_mcbsp2_get_st_ch0_volume, 713 omap_mcbsp_get_st_ch0_volume,
727 omap_mcbsp2_set_st_ch0_volume), 714 omap_mcbsp_set_st_ch0_volume),
728 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", 715 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
729 -32768, 32767, 716 -32768, 32767,
730 omap_mcbsp2_get_st_ch1_volume, 717 omap_mcbsp_get_st_ch1_volume,
731 omap_mcbsp2_set_st_ch1_volume), 718 omap_mcbsp_set_st_ch1_volume),
732}; 719};
733 720
734static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { 721static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
@@ -736,25 +723,30 @@ static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
736 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), 723 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
737 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume", 724 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
738 -32768, 32767, 725 -32768, 32767,
739 omap_mcbsp3_get_st_ch0_volume, 726 omap_mcbsp_get_st_ch0_volume,
740 omap_mcbsp3_set_st_ch0_volume), 727 omap_mcbsp_set_st_ch0_volume),
741 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume", 728 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
742 -32768, 32767, 729 -32768, 32767,
743 omap_mcbsp3_get_st_ch1_volume, 730 omap_mcbsp_get_st_ch1_volume,
744 omap_mcbsp3_set_st_ch1_volume), 731 omap_mcbsp_set_st_ch1_volume),
745}; 732};
746 733
747int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id) 734int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
748{ 735{
749 if (!cpu_is_omap34xx()) 736 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
737 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
738
739 if (!mcbsp->st_data)
750 return -ENODEV; 740 return -ENODEV;
751 741
752 switch (mcbsp_id) { 742 switch (cpu_dai->id) {
753 case 1: /* McBSP 2 */ 743 case 2: /* McBSP 2 */
754 return snd_soc_add_controls(codec, omap_mcbsp2_st_controls, 744 return snd_soc_add_dai_controls(cpu_dai,
745 omap_mcbsp2_st_controls,
755 ARRAY_SIZE(omap_mcbsp2_st_controls)); 746 ARRAY_SIZE(omap_mcbsp2_st_controls));
756 case 2: /* McBSP 3 */ 747 case 3: /* McBSP 3 */
757 return snd_soc_add_controls(codec, omap_mcbsp3_st_controls, 748 return snd_soc_add_dai_controls(cpu_dai,
749 omap_mcbsp3_st_controls,
758 ARRAY_SIZE(omap_mcbsp3_st_controls)); 750 ARRAY_SIZE(omap_mcbsp3_st_controls));
759 default: 751 default:
760 break; 752 break;
@@ -766,18 +758,51 @@ EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
766 758
767static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) 759static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
768{ 760{
769 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); 761 struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
762 struct omap_mcbsp *mcbsp;
763 int ret;
764
765 if (!pdata) {
766 dev_err(&pdev->dev, "missing platform data.\n");
767 return -EINVAL;
768 }
769 mcbsp = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcbsp), GFP_KERNEL);
770 if (!mcbsp)
771 return -ENOMEM;
772
773 mcbsp->id = pdev->id;
774 mcbsp->pdata = pdata;
775 mcbsp->dev = &pdev->dev;
776 platform_set_drvdata(pdev, mcbsp);
777
778 ret = omap_mcbsp_init(pdev);
779 if (!ret)
780 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai);
781
782 return ret;
770} 783}
771 784
772static int __devexit asoc_mcbsp_remove(struct platform_device *pdev) 785static int __devexit asoc_mcbsp_remove(struct platform_device *pdev)
773{ 786{
787 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
788
774 snd_soc_unregister_dai(&pdev->dev); 789 snd_soc_unregister_dai(&pdev->dev);
790
791 if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
792 mcbsp->pdata->ops->free(mcbsp->id);
793
794 omap_mcbsp_sysfs_remove(mcbsp);
795
796 clk_put(mcbsp->fclk);
797
798 platform_set_drvdata(pdev, NULL);
799
775 return 0; 800 return 0;
776} 801}
777 802
778static struct platform_driver asoc_mcbsp_driver = { 803static struct platform_driver asoc_mcbsp_driver = {
779 .driver = { 804 .driver = {
780 .name = "omap-mcbsp-dai", 805 .name = "omap-mcbsp",
781 .owner = THIS_MODULE, 806 .owner = THIS_MODULE,
782 }, 807 },
783 808
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 65cde9d3807b..f877b16f19c9 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -59,6 +59,6 @@ enum omap_mcbsp_div {
59#define NUM_LINKS 5 59#define NUM_LINKS 5
60#endif 60#endif
61 61
62int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id); 62int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
63 63
64#endif 64#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 0e25df4fa9e5..39705561131a 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -419,12 +419,14 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = {
419 .channels_max = 5, 419 .channels_max = 5,
420 .rates = OMAP_MCPDM_RATES, 420 .rates = OMAP_MCPDM_RATES,
421 .formats = OMAP_MCPDM_FORMATS, 421 .formats = OMAP_MCPDM_FORMATS,
422 .sig_bits = 24,
422 }, 423 },
423 .capture = { 424 .capture = {
424 .channels_min = 1, 425 .channels_min = 1,
425 .channels_max = 3, 426 .channels_max = 3,
426 .rates = OMAP_MCPDM_RATES, 427 .rates = OMAP_MCPDM_RATES,
427 .formats = OMAP_MCPDM_FORMATS, 428 .formats = OMAP_MCPDM_FORMATS,
429 .sig_bits = 24,
428 }, 430 },
429 .ops = &omap_mcpdm_dai_ops, 431 .ops = &omap_mcpdm_dai_ops,
430}; 432};
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index f95fe3064172..b92248cbd47a 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -25,6 +25,8 @@
25#ifndef __OMAP_PCM_H__ 25#ifndef __OMAP_PCM_H__
26#define __OMAP_PCM_H__ 26#define __OMAP_PCM_H__
27 27
28struct snd_pcm_substream;
29
28struct omap_pcm_dma_data { 30struct omap_pcm_dma_data {
29 char *name; /* stream identifier */ 31 char *name; /* stream identifier */
30 int dma_req; /* DMA request line */ 32 int dma_req; /* DMA request line */
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index 3357dcc47ed4..2830dfd05661 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -91,7 +91,7 @@ static struct snd_soc_ops omap3beagle_ops = {
91static struct snd_soc_dai_link omap3beagle_dai = { 91static struct snd_soc_dai_link omap3beagle_dai = {
92 .name = "TWL4030", 92 .name = "TWL4030",
93 .stream_name = "TWL4030", 93 .stream_name = "TWL4030",
94 .cpu_dai_name = "omap-mcbsp-dai.1", 94 .cpu_dai_name = "omap-mcbsp.2",
95 .platform_name = "omap-pcm-audio", 95 .platform_name = "omap-pcm-audio",
96 .codec_dai_name = "twl4030-hifi", 96 .codec_dai_name = "twl4030-hifi",
97 .codec_name = "twl4030-codec", 97 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 071fcb09b8b2..3d468c9179d7 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -58,7 +58,7 @@ static struct snd_soc_ops omap3evm_ops = {
58static struct snd_soc_dai_link omap3evm_dai = { 58static struct snd_soc_dai_link omap3evm_dai = {
59 .name = "TWL4030", 59 .name = "TWL4030",
60 .stream_name = "TWL4030", 60 .stream_name = "TWL4030",
61 .cpu_dai_name = "omap-mcbsp-dai.1", 61 .cpu_dai_name = "omap-mcbsp.2",
62 .codec_dai_name = "twl4030-hifi", 62 .codec_dai_name = "twl4030-hifi",
63 .platform_name = "omap-pcm-audio", 63 .platform_name = "omap-pcm-audio",
64 .codec_name = "twl4030-codec", 64 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 07794bd10952..4c3a0978578a 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -208,7 +208,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
208 { 208 {
209 .name = "PCM1773", 209 .name = "PCM1773",
210 .stream_name = "HiFi Out", 210 .stream_name = "HiFi Out",
211 .cpu_dai_name = "omap-mcbsp-dai.1", 211 .cpu_dai_name = "omap-mcbsp.2",
212 .codec_dai_name = "twl4030-hifi", 212 .codec_dai_name = "twl4030-hifi",
213 .platform_name = "omap-pcm-audio", 213 .platform_name = "omap-pcm-audio",
214 .codec_name = "twl4030-codec", 214 .codec_name = "twl4030-codec",
@@ -219,7 +219,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
219 }, { 219 }, {
220 .name = "TWL4030", 220 .name = "TWL4030",
221 .stream_name = "Line/Mic In", 221 .stream_name = "Line/Mic In",
222 .cpu_dai_name = "omap-mcbsp-dai.3", 222 .cpu_dai_name = "omap-mcbsp.4",
223 .codec_dai_name = "twl4030-hifi", 223 .codec_dai_name = "twl4030-hifi",
224 .platform_name = "omap-pcm-audio", 224 .platform_name = "omap-pcm-audio",
225 .codec_name = "twl4030-codec", 225 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index d859b597e7ec..b1a9d64cbc56 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -96,7 +96,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
96static struct snd_soc_dai_link osk_dai = { 96static struct snd_soc_dai_link osk_dai = {
97 .name = "TLV320AIC23", 97 .name = "TLV320AIC23",
98 .stream_name = "AIC23", 98 .stream_name = "AIC23",
99 .cpu_dai_name = "omap-mcbsp-dai.0", 99 .cpu_dai_name = "omap-mcbsp.1",
100 .codec_dai_name = "tlv320aic23-hifi", 100 .codec_dai_name = "tlv320aic23-hifi",
101 .platform_name = "omap-pcm-audio", 101 .platform_name = "omap-pcm-audio",
102 .codec_name = "tlv320aic23-codec", 102 .codec_name = "tlv320aic23-codec",
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index 2ee889c50256..6ac3e0c3c282 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -60,7 +60,7 @@ static struct snd_soc_ops overo_ops = {
60static struct snd_soc_dai_link overo_dai = { 60static struct snd_soc_dai_link overo_dai = {
61 .name = "TWL4030", 61 .name = "TWL4030",
62 .stream_name = "TWL4030", 62 .stream_name = "TWL4030",
63 .cpu_dai_name = "omap-mcbsp-dai.1", 63 .cpu_dai_name = "omap-mcbsp.2",
64 .codec_dai_name = "twl4030-hifi", 64 .codec_dai_name = "twl4030-hifi",
65 .platform_name = "omap-pcm-audio", 65 .platform_name = "omap-pcm-audio",
66 .codec_name = "twl4030-codec", 66 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index fada6ef43eea..2712dd232b6d 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -59,9 +59,8 @@ static int rx51_spk_func;
59static int rx51_dmic_func; 59static int rx51_dmic_func;
60static int rx51_jack_func; 60static int rx51_jack_func;
61 61
62static void rx51_ext_control(struct snd_soc_codec *codec) 62static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
63{ 63{
64 struct snd_soc_dapm_context *dapm = &codec->dapm;
65 int hp = 0, hs = 0, tvout = 0; 64 int hp = 0, hs = 0, tvout = 0;
66 65
67 switch (rx51_jack_func) { 66 switch (rx51_jack_func) {
@@ -102,11 +101,11 @@ static int rx51_startup(struct snd_pcm_substream *substream)
102{ 101{
103 struct snd_pcm_runtime *runtime = substream->runtime; 102 struct snd_pcm_runtime *runtime = substream->runtime;
104 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
105 struct snd_soc_codec *codec = rtd->codec; 104 struct snd_soc_card *card = rtd->card;
106 105
107 snd_pcm_hw_constraint_minmax(runtime, 106 snd_pcm_hw_constraint_minmax(runtime,
108 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 107 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
109 rx51_ext_control(codec); 108 rx51_ext_control(&card->dapm);
110 109
111 return 0; 110 return 0;
112} 111}
@@ -138,13 +137,13 @@ static int rx51_get_spk(struct snd_kcontrol *kcontrol,
138static int rx51_set_spk(struct snd_kcontrol *kcontrol, 137static int rx51_set_spk(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 138 struct snd_ctl_elem_value *ucontrol)
140{ 139{
141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 140 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
142 141
143 if (rx51_spk_func == ucontrol->value.integer.value[0]) 142 if (rx51_spk_func == ucontrol->value.integer.value[0])
144 return 0; 143 return 0;
145 144
146 rx51_spk_func = ucontrol->value.integer.value[0]; 145 rx51_spk_func = ucontrol->value.integer.value[0];
147 rx51_ext_control(codec); 146 rx51_ext_control(&card->dapm);
148 147
149 return 1; 148 return 1;
150} 149}
@@ -184,13 +183,13 @@ static int rx51_get_input(struct snd_kcontrol *kcontrol,
184static int rx51_set_input(struct snd_kcontrol *kcontrol, 183static int rx51_set_input(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol) 184 struct snd_ctl_elem_value *ucontrol)
186{ 185{
187 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 186 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
188 187
189 if (rx51_dmic_func == ucontrol->value.integer.value[0]) 188 if (rx51_dmic_func == ucontrol->value.integer.value[0])
190 return 0; 189 return 0;
191 190
192 rx51_dmic_func = ucontrol->value.integer.value[0]; 191 rx51_dmic_func = ucontrol->value.integer.value[0];
193 rx51_ext_control(codec); 192 rx51_ext_control(&card->dapm);
194 193
195 return 1; 194 return 1;
196} 195}
@@ -206,13 +205,13 @@ static int rx51_get_jack(struct snd_kcontrol *kcontrol,
206static int rx51_set_jack(struct snd_kcontrol *kcontrol, 205static int rx51_set_jack(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 206 struct snd_ctl_elem_value *ucontrol)
208{ 207{
209 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 208 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
210 209
211 if (rx51_jack_func == ucontrol->value.integer.value[0]) 210 if (rx51_jack_func == ucontrol->value.integer.value[0])
212 return 0; 211 return 0;
213 212
214 rx51_jack_func = ucontrol->value.integer.value[0]; 213 rx51_jack_func = ucontrol->value.integer.value[0];
215 rx51_ext_control(codec); 214 rx51_ext_control(&card->dapm);
216 215
217 return 1; 216 return 1;
218} 217}
@@ -297,7 +296,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
297 snd_soc_dapm_nc_pin(dapm, "LINE1R"); 296 snd_soc_dapm_nc_pin(dapm, "LINE1R");
298 297
299 /* Add RX-51 specific controls */ 298 /* Add RX-51 specific controls */
300 err = snd_soc_add_controls(codec, aic34_rx51_controls, 299 err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
301 ARRAY_SIZE(aic34_rx51_controls)); 300 ARRAY_SIZE(aic34_rx51_controls));
302 if (err < 0) 301 if (err < 0)
303 return err; 302 return err;
@@ -314,7 +313,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
314 return err; 313 return err;
315 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); 314 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
316 315
317 err = omap_mcbsp_st_add_controls(codec, 1); 316 err = omap_mcbsp_st_add_controls(rtd);
318 if (err < 0) 317 if (err < 0)
319 return err; 318 return err;
320 319
@@ -335,7 +334,7 @@ static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
335{ 334{
336 int err; 335 int err;
337 336
338 err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb, 337 err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
339 ARRAY_SIZE(aic34_rx51_controlsb)); 338 ARRAY_SIZE(aic34_rx51_controlsb));
340 if (err < 0) 339 if (err < 0)
341 return err; 340 return err;
@@ -354,7 +353,7 @@ static struct snd_soc_dai_link rx51_dai[] = {
354 { 353 {
355 .name = "TLV320AIC34", 354 .name = "TLV320AIC34",
356 .stream_name = "AIC34", 355 .stream_name = "AIC34",
357 .cpu_dai_name = "omap-mcbsp-dai.1", 356 .cpu_dai_name = "omap-mcbsp.2",
358 .codec_dai_name = "tlv320aic3x-hifi", 357 .codec_dai_name = "tlv320aic3x-hifi",
359 .platform_name = "omap-pcm-audio", 358 .platform_name = "omap-pcm-audio",
360 .codec_name = "tlv320aic3x-codec.2-0018", 359 .codec_name = "tlv320aic3x-codec.2-0018",
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 2c850662ea7e..0e283226e2bf 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -187,7 +187,7 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
187 { 187 {
188 .name = "TWL4030 I2S", 188 .name = "TWL4030 I2S",
189 .stream_name = "TWL4030 Audio", 189 .stream_name = "TWL4030 Audio",
190 .cpu_dai_name = "omap-mcbsp-dai.1", 190 .cpu_dai_name = "omap-mcbsp.2",
191 .codec_dai_name = "twl4030-hifi", 191 .codec_dai_name = "twl4030-hifi",
192 .platform_name = "omap-pcm-audio", 192 .platform_name = "omap-pcm-audio",
193 .codec_name = "twl4030-codec", 193 .codec_name = "twl4030-codec",
@@ -199,7 +199,7 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
199 { 199 {
200 .name = "TWL4030 PCM", 200 .name = "TWL4030 PCM",
201 .stream_name = "TWL4030 Voice", 201 .stream_name = "TWL4030 Voice",
202 .cpu_dai_name = "omap-mcbsp-dai.2", 202 .cpu_dai_name = "omap-mcbsp.3",
203 .codec_dai_name = "twl4030-voice", 203 .codec_dai_name = "twl4030-voice",
204 .platform_name = "omap-pcm-audio", 204 .platform_name = "omap-pcm-audio",
205 .codec_name = "twl4030-codec", 205 .codec_name = "twl4030-codec",
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
deleted file mode 100644
index 175ba9a04edf..000000000000
--- a/sound/soc/omap/sdp4430.c
+++ /dev/null
@@ -1,279 +0,0 @@
1/*
2 * sdp4430.c -- SoC audio for TI OMAP4430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/mfd/twl6040.h>
25#include <linux/module.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/jack.h>
31
32#include <asm/mach-types.h>
33#include <plat/hardware.h>
34#include <plat/mux.h>
35
36#include "omap-dmic.h"
37#include "omap-mcpdm.h"
38#include "omap-pcm.h"
39#include "../codecs/twl6040.h"
40
41static int sdp4430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->codec_dai;
46 int clk_id, freq;
47 int ret;
48
49 clk_id = twl6040_get_clk_id(rtd->codec);
50 if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
51 freq = 38400000;
52 else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
53 freq = 32768;
54 else
55 return -EINVAL;
56
57 /* set the codec mclk */
58 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
59 SND_SOC_CLOCK_IN);
60 if (ret) {
61 printk(KERN_ERR "can't set codec system clock\n");
62 return ret;
63 }
64 return ret;
65}
66
67static struct snd_soc_ops sdp4430_ops = {
68 .hw_params = sdp4430_hw_params,
69};
70
71static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream,
72 struct snd_pcm_hw_params *params)
73{
74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
75 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
76 int ret = 0;
77
78 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
79 19200000, SND_SOC_CLOCK_IN);
80 if (ret < 0) {
81 printk(KERN_ERR "can't set DMIC cpu system clock\n");
82 return ret;
83 }
84 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
85 SND_SOC_CLOCK_OUT);
86 if (ret < 0) {
87 printk(KERN_ERR "can't set DMIC output clock\n");
88 return ret;
89 }
90 return 0;
91}
92
93static struct snd_soc_ops sdp4430_dmic_ops = {
94 .hw_params = sdp4430_dmic_hw_params,
95};
96
97/* Headset jack */
98static struct snd_soc_jack hs_jack;
99
100/*Headset jack detection DAPM pins */
101static struct snd_soc_jack_pin hs_jack_pins[] = {
102 {
103 .pin = "Headset Mic",
104 .mask = SND_JACK_MICROPHONE,
105 },
106 {
107 .pin = "Headset Stereophone",
108 .mask = SND_JACK_HEADPHONE,
109 },
110};
111
112/* SDP4430 machine DAPM */
113static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
114 SND_SOC_DAPM_MIC("Ext Mic", NULL),
115 SND_SOC_DAPM_SPK("Ext Spk", NULL),
116 SND_SOC_DAPM_MIC("Headset Mic", NULL),
117 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
118 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
119 SND_SOC_DAPM_INPUT("FM Stereo In"),
120};
121
122static const struct snd_soc_dapm_route audio_map[] = {
123 /* External Mics: MAINMIC, SUBMIC with bias*/
124 {"MAINMIC", NULL, "Main Mic Bias"},
125 {"SUBMIC", NULL, "Main Mic Bias"},
126 {"Main Mic Bias", NULL, "Ext Mic"},
127
128 /* External Speakers: HFL, HFR */
129 {"Ext Spk", NULL, "HFL"},
130 {"Ext Spk", NULL, "HFR"},
131
132 /* Headset Mic: HSMIC with bias */
133 {"HSMIC", NULL, "Headset Mic Bias"},
134 {"Headset Mic Bias", NULL, "Headset Mic"},
135
136 /* Headset Stereophone (Headphone): HSOL, HSOR */
137 {"Headset Stereophone", NULL, "HSOL"},
138 {"Headset Stereophone", NULL, "HSOR"},
139
140 /* Earphone speaker */
141 {"Earphone Spk", NULL, "EP"},
142
143 /* Aux/FM Stereo In: AFML, AFMR */
144 {"AFML", NULL, "FM Stereo In"},
145 {"AFMR", NULL, "FM Stereo In"},
146};
147
148static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
149{
150 struct snd_soc_codec *codec = rtd->codec;
151 int ret, hs_trim;
152
153 /*
154 * Configure McPDM offset cancellation based on the HSOTRIM value from
155 * twl6040.
156 */
157 hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
158 omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
159 TWL6040_HSF_TRIM_RIGHT(hs_trim));
160
161 /* Headset jack detection */
162 ret = snd_soc_jack_new(codec, "Headset Jack",
163 SND_JACK_HEADSET, &hs_jack);
164 if (ret)
165 return ret;
166
167 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
168 hs_jack_pins);
169
170 if (machine_is_omap_4430sdp())
171 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
172 else
173 snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET);
174
175 return ret;
176}
177
178static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = {
179 SND_SOC_DAPM_MIC("Digital Mic", NULL),
180};
181
182static const struct snd_soc_dapm_route dmic_audio_map[] = {
183 {"DMic", NULL, "Digital Mic1 Bias"},
184 {"Digital Mic1 Bias", NULL, "Digital Mic"},
185};
186
187static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd)
188{
189 struct snd_soc_codec *codec = rtd->codec;
190 struct snd_soc_dapm_context *dapm = &codec->dapm;
191 int ret;
192
193 ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets,
194 ARRAY_SIZE(sdp4430_dmic_dapm_widgets));
195 if (ret)
196 return ret;
197
198 return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
199 ARRAY_SIZE(dmic_audio_map));
200}
201
202/* Digital audio interface glue - connects codec <--> CPU */
203static struct snd_soc_dai_link sdp4430_dai[] = {
204 {
205 .name = "TWL6040",
206 .stream_name = "TWL6040",
207 .cpu_dai_name = "omap-mcpdm",
208 .codec_dai_name = "twl6040-legacy",
209 .platform_name = "omap-pcm-audio",
210 .codec_name = "twl6040-codec",
211 .init = sdp4430_twl6040_init,
212 .ops = &sdp4430_ops,
213 },
214 {
215 .name = "DMIC",
216 .stream_name = "DMIC Capture",
217 .cpu_dai_name = "omap-dmic",
218 .codec_dai_name = "dmic-hifi",
219 .platform_name = "omap-pcm-audio",
220 .codec_name = "dmic-codec",
221 .init = sdp4430_dmic_init,
222 .ops = &sdp4430_dmic_ops,
223 },
224};
225
226/* Audio machine driver */
227static struct snd_soc_card snd_soc_sdp4430 = {
228 .name = "SDP4430",
229 .owner = THIS_MODULE,
230 .dai_link = sdp4430_dai,
231 .num_links = ARRAY_SIZE(sdp4430_dai),
232
233 .dapm_widgets = sdp4430_twl6040_dapm_widgets,
234 .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
235 .dapm_routes = audio_map,
236 .num_dapm_routes = ARRAY_SIZE(audio_map),
237};
238
239static struct platform_device *sdp4430_snd_device;
240
241static int __init sdp4430_soc_init(void)
242{
243 int ret;
244
245 if (!machine_is_omap_4430sdp())
246 return -ENODEV;
247 printk(KERN_INFO "SDP4430 SoC init\n");
248
249 sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
250 if (!sdp4430_snd_device) {
251 printk(KERN_ERR "Platform device allocation failed\n");
252 return -ENOMEM;
253 }
254
255 platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);
256
257 ret = platform_device_add(sdp4430_snd_device);
258 if (ret)
259 goto err;
260
261 return 0;
262
263err:
264 printk(KERN_ERR "Unable to add platform device\n");
265 platform_device_put(sdp4430_snd_device);
266 return ret;
267}
268module_init(sdp4430_soc_init);
269
270static void __exit sdp4430_soc_exit(void)
271{
272 platform_device_unregister(sdp4430_snd_device);
273}
274module_exit(sdp4430_soc_exit);
275
276MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
277MODULE_DESCRIPTION("ALSA SoC SDP4430");
278MODULE_LICENSE("GPL");
279
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 981616d61f67..920e0d9e03db 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -131,7 +131,7 @@ static struct snd_soc_dai_link zoom2_dai[] = {
131 { 131 {
132 .name = "TWL4030 I2S", 132 .name = "TWL4030 I2S",
133 .stream_name = "TWL4030 Audio", 133 .stream_name = "TWL4030 Audio",
134 .cpu_dai_name = "omap-mcbsp-dai.1", 134 .cpu_dai_name = "omap-mcbsp.2",
135 .codec_dai_name = "twl4030-hifi", 135 .codec_dai_name = "twl4030-hifi",
136 .platform_name = "omap-pcm-audio", 136 .platform_name = "omap-pcm-audio",
137 .codec_name = "twl4030-codec", 137 .codec_name = "twl4030-codec",
@@ -143,7 +143,7 @@ static struct snd_soc_dai_link zoom2_dai[] = {
143 { 143 {
144 .name = "TWL4030 PCM", 144 .name = "TWL4030 PCM",
145 .stream_name = "TWL4030 Voice", 145 .stream_name = "TWL4030 Voice",
146 .cpu_dai_name = "omap-mcbsp-dai.2", 146 .cpu_dai_name = "omap-mcbsp.3",
147 .codec_dai_name = "twl4030-voice", 147 .codec_dai_name = "twl4030-voice",
148 .platform_name = "omap-pcm-audio", 148 .platform_name = "omap-pcm-audio",
149 .codec_name = "twl4030-codec", 149 .codec_name = "twl4030-codec",
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index bc21944851c4..863367ad89ce 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -45,10 +45,8 @@
45static int corgi_jack_func; 45static int corgi_jack_func;
46static int corgi_spk_func; 46static int corgi_spk_func;
47 47
48static void corgi_ext_control(struct snd_soc_codec *codec) 48static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
49{ 49{
50 struct snd_soc_dapm_context *dapm = &codec->dapm;
51
52 /* set up jack connection */ 50 /* set up jack connection */
53 switch (corgi_jack_func) { 51 switch (corgi_jack_func) {
54 case CORGI_HP: 52 case CORGI_HP:
@@ -104,7 +102,7 @@ static int corgi_startup(struct snd_pcm_substream *substream)
104 mutex_lock(&codec->mutex); 102 mutex_lock(&codec->mutex);
105 103
106 /* check the jack status at stream startup */ 104 /* check the jack status at stream startup */
107 corgi_ext_control(codec); 105 corgi_ext_control(&codec->dapm);
108 106
109 mutex_unlock(&codec->mutex); 107 mutex_unlock(&codec->mutex);
110 108
@@ -173,13 +171,13 @@ static int corgi_get_jack(struct snd_kcontrol *kcontrol,
173static int corgi_set_jack(struct snd_kcontrol *kcontrol, 171static int corgi_set_jack(struct snd_kcontrol *kcontrol,
174 struct snd_ctl_elem_value *ucontrol) 172 struct snd_ctl_elem_value *ucontrol)
175{ 173{
176 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 174 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
177 175
178 if (corgi_jack_func == ucontrol->value.integer.value[0]) 176 if (corgi_jack_func == ucontrol->value.integer.value[0])
179 return 0; 177 return 0;
180 178
181 corgi_jack_func = ucontrol->value.integer.value[0]; 179 corgi_jack_func = ucontrol->value.integer.value[0];
182 corgi_ext_control(codec); 180 corgi_ext_control(&card->dapm);
183 return 1; 181 return 1;
184} 182}
185 183
@@ -193,13 +191,13 @@ static int corgi_get_spk(struct snd_kcontrol *kcontrol,
193static int corgi_set_spk(struct snd_kcontrol *kcontrol, 191static int corgi_set_spk(struct snd_kcontrol *kcontrol,
194 struct snd_ctl_elem_value *ucontrol) 192 struct snd_ctl_elem_value *ucontrol)
195{ 193{
196 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 194 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
197 195
198 if (corgi_spk_func == ucontrol->value.integer.value[0]) 196 if (corgi_spk_func == ucontrol->value.integer.value[0])
199 return 0; 197 return 0;
200 198
201 corgi_spk_func = ucontrol->value.integer.value[0]; 199 corgi_spk_func = ucontrol->value.integer.value[0];
202 corgi_ext_control(codec); 200 corgi_ext_control(&card->dapm);
203 return 1; 201 return 1;
204} 202}
205 203
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 3f7a8ecb9720..aace19e0fe2c 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -411,7 +411,7 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
411 snd_soc_dapm_nc_pin(dapm, "VINR"); 411 snd_soc_dapm_nc_pin(dapm, "VINR");
412 412
413 /* Add magician specific controls */ 413 /* Add magician specific controls */
414 err = snd_soc_add_controls(codec, uda1380_magician_controls, 414 err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
415 ARRAY_SIZE(uda1380_magician_controls)); 415 ARRAY_SIZE(uda1380_magician_controls));
416 if (err < 0) 416 if (err < 0)
417 return err; 417 return err;
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index fd0ed10c6fe7..d2cc81735036 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -43,10 +43,8 @@
43static int poodle_jack_func; 43static int poodle_jack_func;
44static int poodle_spk_func; 44static int poodle_spk_func;
45 45
46static void poodle_ext_control(struct snd_soc_codec *codec) 46static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
47{ 47{
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
50 /* set up jack connection */ 48 /* set up jack connection */
51 if (poodle_jack_func == POODLE_HP) { 49 if (poodle_jack_func == POODLE_HP) {
52 /* set = unmute headphone */ 50 /* set = unmute headphone */
@@ -81,7 +79,7 @@ static int poodle_startup(struct snd_pcm_substream *substream)
81 mutex_lock(&codec->mutex); 79 mutex_lock(&codec->mutex);
82 80
83 /* check the jack status at stream startup */ 81 /* check the jack status at stream startup */
84 poodle_ext_control(codec); 82 poodle_ext_control(&codec->dapm);
85 83
86 mutex_unlock(&codec->mutex); 84 mutex_unlock(&codec->mutex);
87 85
@@ -152,13 +150,13 @@ static int poodle_get_jack(struct snd_kcontrol *kcontrol,
152static int poodle_set_jack(struct snd_kcontrol *kcontrol, 150static int poodle_set_jack(struct snd_kcontrol *kcontrol,
153 struct snd_ctl_elem_value *ucontrol) 151 struct snd_ctl_elem_value *ucontrol)
154{ 152{
155 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 153 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
156 154
157 if (poodle_jack_func == ucontrol->value.integer.value[0]) 155 if (poodle_jack_func == ucontrol->value.integer.value[0])
158 return 0; 156 return 0;
159 157
160 poodle_jack_func = ucontrol->value.integer.value[0]; 158 poodle_jack_func = ucontrol->value.integer.value[0];
161 poodle_ext_control(codec); 159 poodle_ext_control(&card->dapm);
162 return 1; 160 return 1;
163} 161}
164 162
@@ -172,13 +170,13 @@ static int poodle_get_spk(struct snd_kcontrol *kcontrol,
172static int poodle_set_spk(struct snd_kcontrol *kcontrol, 170static int poodle_set_spk(struct snd_kcontrol *kcontrol,
173 struct snd_ctl_elem_value *ucontrol) 171 struct snd_ctl_elem_value *ucontrol)
174{ 172{
175 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 173 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
176 174
177 if (poodle_spk_func == ucontrol->value.integer.value[0]) 175 if (poodle_spk_func == ucontrol->value.integer.value[0])
178 return 0; 176 return 0;
179 177
180 poodle_spk_func = ucontrol->value.integer.value[0]; 178 poodle_spk_func = ucontrol->value.integer.value[0];
181 poodle_ext_control(codec); 179 poodle_ext_control(&card->dapm);
182 return 1; 180 return 1;
183} 181}
184 182
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a57cfbc038e3..fd04ce139031 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -668,6 +668,38 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
668 return 0; 668 return 0;
669} 669}
670 670
671static void pxa_ssp_set_running_bit(struct snd_pcm_substream *substream,
672 struct ssp_device *ssp, int value)
673{
674 uint32_t sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
675 uint32_t sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
676 uint32_t sspsp = pxa_ssp_read_reg(ssp, SSPSP);
677 uint32_t sssr = pxa_ssp_read_reg(ssp, SSSR);
678
679 if (value && (sscr0 & SSCR0_SSE))
680 pxa_ssp_write_reg(ssp, SSCR0, sscr0 & ~SSCR0_SSE);
681
682 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
683 if (value)
684 sscr1 |= SSCR1_TSRE;
685 else
686 sscr1 &= ~SSCR1_TSRE;
687 } else {
688 if (value)
689 sscr1 |= SSCR1_RSRE;
690 else
691 sscr1 &= ~SSCR1_RSRE;
692 }
693
694 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
695
696 if (value) {
697 pxa_ssp_write_reg(ssp, SSSR, sssr);
698 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
699 pxa_ssp_write_reg(ssp, SSCR0, sscr0 | SSCR0_SSE);
700 }
701}
702
671static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, 703static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
672 struct snd_soc_dai *cpu_dai) 704 struct snd_soc_dai *cpu_dai)
673{ 705{
@@ -681,42 +713,21 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
681 pxa_ssp_enable(ssp); 713 pxa_ssp_enable(ssp);
682 break; 714 break;
683 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 715 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
684 val = pxa_ssp_read_reg(ssp, SSCR1); 716 pxa_ssp_set_running_bit(substream, ssp, 1);
685 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
686 val |= SSCR1_TSRE;
687 else
688 val |= SSCR1_RSRE;
689 pxa_ssp_write_reg(ssp, SSCR1, val);
690 val = pxa_ssp_read_reg(ssp, SSSR); 717 val = pxa_ssp_read_reg(ssp, SSSR);
691 pxa_ssp_write_reg(ssp, SSSR, val); 718 pxa_ssp_write_reg(ssp, SSSR, val);
692 break; 719 break;
693 case SNDRV_PCM_TRIGGER_START: 720 case SNDRV_PCM_TRIGGER_START:
694 val = pxa_ssp_read_reg(ssp, SSCR1); 721 pxa_ssp_set_running_bit(substream, ssp, 1);
695 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
696 val |= SSCR1_TSRE;
697 else
698 val |= SSCR1_RSRE;
699 pxa_ssp_write_reg(ssp, SSCR1, val);
700 pxa_ssp_enable(ssp);
701 break; 722 break;
702 case SNDRV_PCM_TRIGGER_STOP: 723 case SNDRV_PCM_TRIGGER_STOP:
703 val = pxa_ssp_read_reg(ssp, SSCR1); 724 pxa_ssp_set_running_bit(substream, ssp, 0);
704 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
705 val &= ~SSCR1_TSRE;
706 else
707 val &= ~SSCR1_RSRE;
708 pxa_ssp_write_reg(ssp, SSCR1, val);
709 break; 725 break;
710 case SNDRV_PCM_TRIGGER_SUSPEND: 726 case SNDRV_PCM_TRIGGER_SUSPEND:
711 pxa_ssp_disable(ssp); 727 pxa_ssp_disable(ssp);
712 break; 728 break;
713 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 729 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
714 val = pxa_ssp_read_reg(ssp, SSCR1); 730 pxa_ssp_set_running_bit(substream, ssp, 0);
715 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
716 val &= ~SSCR1_TSRE;
717 else
718 val &= ~SSCR1_RSRE;
719 pxa_ssp_write_reg(ssp, SSCR1, val);
720 break; 731 break;
721 732
722 default: 733 default:
@@ -764,7 +775,8 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai)
764 775
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 776#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
766 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 777 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
767 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 778 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
779 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
768 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 780 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
769 781
770#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 782#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 837ff341fd6d..4800d5fe568d 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -103,7 +103,7 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
103#define pxa2xx_ac97_resume NULL 103#define pxa2xx_ac97_resume NULL
104#endif 104#endif
105 105
106static int pxa2xx_ac97_probe(struct snd_soc_dai *dai) 106static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai)
107{ 107{
108 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); 108 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
109} 109}
@@ -179,7 +179,7 @@ static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
179 * There is only 1 physical AC97 interface for pxa2xx, but it 179 * There is only 1 physical AC97 interface for pxa2xx, but it
180 * has extra fifo's that can be used for aux DACs and ADCs. 180 * has extra fifo's that can be used for aux DACs and ADCs.
181 */ 181 */
182static struct snd_soc_dai_driver pxa_ac97_dai[] = { 182static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = {
183{ 183{
184 .name = "pxa2xx-ac97", 184 .name = "pxa2xx-ac97",
185 .ac97_control = 1, 185 .ac97_control = 1,
@@ -244,13 +244,13 @@ static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
244 * driver to do interesting things with the clocking to get us up 244 * driver to do interesting things with the clocking to get us up
245 * and running. 245 * and running.
246 */ 246 */
247 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai, 247 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver,
248 ARRAY_SIZE(pxa_ac97_dai)); 248 ARRAY_SIZE(pxa_ac97_dai_driver));
249} 249}
250 250
251static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) 251static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
252{ 252{
253 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai)); 253 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver));
254 return 0; 254 return 0;
255} 255}
256 256
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index ba1545188ec6..083706595495 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -232,7 +232,7 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
232 .cpu_dai_name = "pxa-ssp-dai.0", \ 232 .cpu_dai_name = "pxa-ssp-dai.0", \
233 .platform_name = "pxa-pcm-audio", \ 233 .platform_name = "pxa-pcm-audio", \
234 .codec_dai_name = "cs4270-hifi", \ 234 .codec_dai_name = "cs4270-hifi", \
235 .codec_name = "cs4270-codec.0-0048", \ 235 .codec_name = "cs4270.0-0048", \
236 .ops = &raumfeld_cs4270_ops, \ 236 .ops = &raumfeld_cs4270_ops, \
237} 237}
238 238
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 90c5245c4742..fc052d8247ff 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -44,10 +44,8 @@ static int spitz_jack_func;
44static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio; 45static int spitz_mic_gpio;
46 46
47static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
48{ 48{
49 struct snd_soc_dapm_context *dapm = &codec->dapm;
50
51 if (spitz_spk_func == SPITZ_SPK_ON) 49 if (spitz_spk_func == SPITZ_SPK_ON)
52 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 50 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
53 else 51 else
@@ -113,7 +111,7 @@ static int spitz_startup(struct snd_pcm_substream *substream)
113 mutex_lock(&codec->mutex); 111 mutex_lock(&codec->mutex);
114 112
115 /* check the jack status at stream startup */ 113 /* check the jack status at stream startup */
116 spitz_ext_control(codec); 114 spitz_ext_control(&codec->dapm);
117 115
118 mutex_unlock(&codec->mutex); 116 mutex_unlock(&codec->mutex);
119 117
@@ -173,13 +171,13 @@ static int spitz_get_jack(struct snd_kcontrol *kcontrol,
173static int spitz_set_jack(struct snd_kcontrol *kcontrol, 171static int spitz_set_jack(struct snd_kcontrol *kcontrol,
174 struct snd_ctl_elem_value *ucontrol) 172 struct snd_ctl_elem_value *ucontrol)
175{ 173{
176 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 174 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
177 175
178 if (spitz_jack_func == ucontrol->value.integer.value[0]) 176 if (spitz_jack_func == ucontrol->value.integer.value[0])
179 return 0; 177 return 0;
180 178
181 spitz_jack_func = ucontrol->value.integer.value[0]; 179 spitz_jack_func = ucontrol->value.integer.value[0];
182 spitz_ext_control(codec); 180 spitz_ext_control(&card->dapm);
183 return 1; 181 return 1;
184} 182}
185 183
@@ -193,13 +191,13 @@ static int spitz_get_spk(struct snd_kcontrol *kcontrol,
193static int spitz_set_spk(struct snd_kcontrol *kcontrol, 191static int spitz_set_spk(struct snd_kcontrol *kcontrol,
194 struct snd_ctl_elem_value *ucontrol) 192 struct snd_ctl_elem_value *ucontrol)
195{ 193{
196 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 194 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
197 195
198 if (spitz_spk_func == ucontrol->value.integer.value[0]) 196 if (spitz_spk_func == ucontrol->value.integer.value[0])
199 return 0; 197 return 0;
200 198
201 spitz_spk_func = ucontrol->value.integer.value[0]; 199 spitz_spk_func = ucontrol->value.integer.value[0];
202 spitz_ext_control(codec); 200 spitz_ext_control(&card->dapm);
203 return 1; 201 return 1;
204} 202}
205 203
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 564ef08a89f2..2aec63f3706a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -197,7 +197,7 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
197 snd_soc_dapm_nc_pin(dapm, "MONOOUT"); 197 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
198 198
199 /* add tosa specific controls */ 199 /* add tosa specific controls */
200 err = snd_soc_add_controls(codec, tosa_controls, 200 err = snd_soc_add_codec_controls(codec, tosa_controls,
201 ARRAY_SIZE(tosa_controls)); 201 ARRAY_SIZE(tosa_controls));
202 if (err < 0) 202 if (err < 0)
203 return err; 203 return err;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 43c014f362f6..716da861c629 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -435,7 +435,8 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
435{ 435{
436 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 436 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
437 struct s6000_pcm_dma_params *params = 437 struct s6000_pcm_dma_params *params =
438 snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream); 438 snd_soc_dai_get_dma_data(runtime->cpu_dai,
439 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
439 440
440 free_irq(params->irq, pcm); 441 free_irq(params->irq, pcm);
441 snd_pcm_lib_preallocate_free_for_all(pcm); 442 snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -451,7 +452,7 @@ static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
451 int res; 452 int res;
452 453
453 params = snd_soc_dai_get_dma_data(runtime->cpu_dai, 454 params = snd_soc_dai_get_dma_data(runtime->cpu_dai,
454 pcm->streams[0].substream); 455 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
455 456
456 if (!card->dev->dma_mask) 457 if (!card->dev->dma_mask)
457 card->dev->dma_mask = &s6000_pcm_dmamask; 458 card->dev->dma_mask = &s6000_pcm_dmamask;
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 7b9bf93e3701..3d04c1fa6781 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -4,7 +4,7 @@
4 * Evolved from s3c2443-ac97.c 4 * Evolved from s3c2443-ac97.c
5 * 5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd 6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com> 7 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
8 * Credits: Graeme Gregory, Sean Choi 8 * Credits: Graeme Gregory, Sean Choi
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -511,7 +511,7 @@ static struct platform_driver s3c_ac97_driver = {
511 511
512module_platform_driver(s3c_ac97_driver); 512module_platform_driver(s3c_ac97_driver);
513 513
514MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 514MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
515MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); 515MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
516MODULE_LICENSE("GPL"); 516MODULE_LICENSE("GPL");
517MODULE_ALIAS("platform:samsung-ac97"); 517MODULE_ALIAS("platform:samsung-ac97");
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index e4ba17ce6b32..ddc6cde14e2a 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -411,7 +411,7 @@ static int dma_new(struct snd_soc_pcm_runtime *rtd)
411 if (!card->dev->dma_mask) 411 if (!card->dev->dma_mask)
412 card->dev->dma_mask = &dma_mask; 412 card->dev->dma_mask = &dma_mask;
413 if (!card->dev->coherent_dma_mask) 413 if (!card->dev->coherent_dma_mask)
414 card->dev->coherent_dma_mask = 0xffffffff; 414 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
415 415
416 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 416 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
417 ret = preallocate_dma_buffer(pcm, 417 ret = preallocate_dma_buffer(pcm,
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 87a874dc7a35..6ac7b8281a02 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver 3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 * 4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd. 5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.com> 6 * Jaswinder Singh <jassisinghbrar@gmail.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -559,6 +559,17 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
559 mod |= MOD_DC1_EN; 559 mod |= MOD_DC1_EN;
560 break; 560 break;
561 case 2: 561 case 2:
562 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
563 i2s->dma_playback.dma_size = 4;
564 else
565 i2s->dma_capture.dma_size = 4;
566 break;
567 case 1:
568 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
569 i2s->dma_playback.dma_size = 2;
570 else
571 i2s->dma_capture.dma_size = 2;
572
562 break; 573 break;
563 default: 574 default:
564 dev_err(&i2s->pdev->dev, "%d channels not supported\n", 575 dev_err(&i2s->pdev->dev, "%d channels not supported\n",
@@ -761,15 +772,13 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
761 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 772 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
762 local_irq_save(flags); 773 local_irq_save(flags);
763 774
764 if (capture) 775 if (capture) {
765 i2s_rxctrl(i2s, 0); 776 i2s_rxctrl(i2s, 0);
766 else
767 i2s_txctrl(i2s, 0);
768
769 if (capture)
770 i2s_fifo(i2s, FIC_RXFLUSH); 777 i2s_fifo(i2s, FIC_RXFLUSH);
771 else 778 } else {
779 i2s_txctrl(i2s, 0);
772 i2s_fifo(i2s, FIC_TXFLUSH); 780 i2s_fifo(i2s, FIC_TXFLUSH);
781 }
773 782
774 local_irq_restore(flags); 783 local_irq_restore(flags);
775 break; 784 break;
@@ -965,7 +974,7 @@ struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
965 i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; 974 i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
966 975
967 if (!sec) { 976 if (!sec) {
968 i2s->i2s_dai_drv.capture.channels_min = 2; 977 i2s->i2s_dai_drv.capture.channels_min = 1;
969 i2s->i2s_dai_drv.capture.channels_max = 2; 978 i2s->i2s_dai_drv.capture.channels_max = 2;
970 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; 979 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
971 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; 980 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
@@ -1143,7 +1152,7 @@ static struct platform_driver samsung_i2s_driver = {
1143module_platform_driver(samsung_i2s_driver); 1152module_platform_driver(samsung_i2s_driver);
1144 1153
1145/* Module information */ 1154/* Module information */
1146MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 1155MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
1147MODULE_DESCRIPTION("Samsung I2S Interface"); 1156MODULE_DESCRIPTION("Samsung I2S Interface");
1148MODULE_ALIAS("platform:samsung-i2s"); 1157MODULE_ALIAS("platform:samsung-i2s");
1149MODULE_LICENSE("GPL"); 1158MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
index 8e15f6a616d1..d420a7ca56ca 100644
--- a/sound/soc/samsung/i2s.h
+++ b/sound/soc/samsung/i2s.h
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver 3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 * 4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd. 5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.com> 6 * Jaswinder Singh <jassisinghbrar@gmail.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 9dd818bde06f..e7416851bf7d 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -189,6 +189,9 @@ static int littlemill_late_probe(struct snd_soc_card *card)
189 /* This will check device compatibility itself */ 189 /* This will check device compatibility itself */
190 wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); 190 wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
191 191
192 /* As will this */
193 wm8994_mic_detect(codec, &littlemill_headset, 1);
194
192 return 0; 195 return 0;
193} 196}
194 197
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index d23b19a59d83..321d51134e47 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -296,7 +296,7 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
296 if (ret) 296 if (ret)
297 return ret; 297 return ret;
298 298
299 ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls, 299 ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls,
300 ARRAY_SIZE(neo1973_gta02_wm8753_controls)); 300 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
301 if (ret) 301 if (ret)
302 return ret; 302 return ret;
@@ -328,7 +328,7 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
328 return ret; 328 return ret;
329 329
330 /* add neo1973 specific controls */ 330 /* add neo1973 specific controls */
331 ret = snd_soc_add_controls(codec, neo1973_wm8753_controls, 331 ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls,
332 ARRAY_SIZE(neo1973_wm8753_controls)); 332 ARRAY_SIZE(neo1973_wm8753_controls));
333 if (ret) 333 if (ret)
334 return ret; 334 return ret;
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 56780206c000..b7b2a1f91425 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - S3C PCM-Controller driver 3 * ALSA SoC Audio Layer - S3C PCM-Controller driver
4 * 4 *
5 * Copyright (c) 2009 Samsung Electronics Co. Ltd 5 * Copyright (c) 2009 Samsung Electronics Co. Ltd
6 * Author: Jaswinder Singh <jassi.brar@samsung.com> 6 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
7 * based upon I2S drivers by Ben Dooks. 7 * based upon I2S drivers by Ben Dooks.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -639,7 +639,7 @@ static struct platform_driver s3c_pcm_driver = {
639module_platform_driver(s3c_pcm_driver); 639module_platform_driver(s3c_pcm_driver);
640 640
641/* Module information */ 641/* Module information */
642MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 642MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
643MODULE_DESCRIPTION("S3C PCM Controller Driver"); 643MODULE_DESCRIPTION("S3C PCM Controller Driver");
644MODULE_LICENSE("GPL"); 644MODULE_LICENSE("GPL");
645MODULE_ALIAS("platform:samsung-pcm"); 645MODULE_ALIAS("platform:samsung-pcm");
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index a253bcc1646a..656d5afe4ca9 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -134,18 +134,18 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = {
134 134
135void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) 135void simtec_audio_init(struct snd_soc_pcm_runtime *rtd)
136{ 136{
137 struct snd_soc_codec *codec = rtd->codec; 137 struct snd_soc_card *card = rtd->card;
138 138
139 if (pdata->amp_gpio > 0) { 139 if (pdata->amp_gpio > 0) {
140 pr_debug("%s: adding amp routes\n", __func__); 140 pr_debug("%s: adding amp routes\n", __func__);
141 141
142 snd_soc_add_controls(codec, amp_unmute_controls, 142 snd_soc_add_card_controls(card, amp_unmute_controls,
143 ARRAY_SIZE(amp_unmute_controls)); 143 ARRAY_SIZE(amp_unmute_controls));
144 } 144 }
145 145
146 if (pdata->amp_gain[0] > 0) { 146 if (pdata->amp_gain[0] > 0) {
147 pr_debug("%s: adding amp controls\n", __func__); 147 pr_debug("%s: adding amp controls\n", __func__);
148 snd_soc_add_controls(codec, amp_gain_controls, 148 snd_soc_add_card_controls(card, amp_gain_controls,
149 ARRAY_SIZE(amp_gain_controls)); 149 ARRAY_SIZE(amp_gain_controls));
150 } 150 }
151} 151}
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index bff8758e7f20..ade2809cf393 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -2,7 +2,7 @@
2 * smdk_wm8580.c 2 * smdk_wm8580.c
3 * 3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd 4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com> 5 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -253,6 +253,6 @@ static void __exit smdk_audio_exit(void)
253} 253}
254module_exit(smdk_audio_exit); 254module_exit(smdk_audio_exit);
255 255
256MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); 256MODULE_AUTHOR("Jaswinder Singh, jassisinghbrar@gmail.com");
257MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); 257MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
258MODULE_LICENSE("GPL"); 258MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 8e26a730fcdc..55b2ca7f3290 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -2,7 +2,7 @@
2 * smdk_wm9713.c -- SoC audio for SMDK 2 * smdk_wm9713.c -- SoC audio for SMDK
3 * 3 *
4 * Copyright 2010 Samsung Electronics Co. Ltd. 4 * Copyright 2010 Samsung Electronics Co. Ltd.
5 * Author: Jaswinder Singh Brar <jassi.brar@samsung.com> 5 * Author: Jaswinder Singh Brar <jassisinghbrar@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
@@ -103,6 +103,6 @@ module_init(smdk_init);
103module_exit(smdk_exit); 103module_exit(smdk_exit);
104 104
105/* Module information */ 105/* Module information */
106MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); 106MODULE_AUTHOR("Jaswinder Singh Brar, jassisinghbrar@gmail.com");
107MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); 107MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
108MODULE_LICENSE("GPL"); 108MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ea4a82d01160..378cc5b056d7 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -13,8 +13,11 @@
13 */ 13 */
14 14
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/dma-mapping.h>
16#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
17#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/scatterlist.h>
20#include <linux/sh_dma.h>
18#include <linux/slab.h> 21#include <linux/slab.h>
19#include <linux/module.h> 22#include <linux/module.h>
20#include <sound/soc.h> 23#include <sound/soc.h>
@@ -53,6 +56,7 @@
53 56
54/* DO_FMT */ 57/* DO_FMT */
55/* DI_FMT */ 58/* DI_FMT */
59#define CR_BWS_MASK (0x3 << 20) /* FSI2 */
56#define CR_BWS_24 (0x0 << 20) /* FSI2 */ 60#define CR_BWS_24 (0x0 << 20) /* FSI2 */
57#define CR_BWS_16 (0x1 << 20) /* FSI2 */ 61#define CR_BWS_16 (0x1 << 20) /* FSI2 */
58#define CR_BWS_20 (0x2 << 20) /* FSI2 */ 62#define CR_BWS_20 (0x2 << 20) /* FSI2 */
@@ -68,6 +72,15 @@
68#define CR_TDM (0x4 << 4) 72#define CR_TDM (0x4 << 4)
69#define CR_TDM_D (0x5 << 4) 73#define CR_TDM_D (0x5 << 4)
70 74
75/* OUT_DMAC */
76/* IN_DMAC */
77#define VDMD_MASK (0x3 << 4)
78#define VDMD_FRONT (0x0 << 4) /* Package in front */
79#define VDMD_BACK (0x1 << 4) /* Package in back */
80#define VDMD_STREAM (0x2 << 4) /* Stream mode(16bit * 2) */
81
82#define DMA_ON (0x1 << 0)
83
71/* DOFF_CTL */ 84/* DOFF_CTL */
72/* DIFF_CTL */ 85/* DIFF_CTL */
73#define IRQ_HALF 0x00100000 86#define IRQ_HALF 0x00100000
@@ -116,7 +129,7 @@
116 129
117#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 130#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
118 131
119typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable); 132typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
120 133
121/* 134/*
122 * FSI driver use below type name for variable 135 * FSI driver use below type name for variable
@@ -159,22 +172,41 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
159 * struct 172 * struct
160 */ 173 */
161 174
175struct fsi_stream_handler;
162struct fsi_stream { 176struct fsi_stream {
163 struct snd_pcm_substream *substream;
164 177
178 /*
179 * these are initialized by fsi_stream_init()
180 */
181 struct snd_pcm_substream *substream;
165 int fifo_sample_capa; /* sample capacity of FSI FIFO */ 182 int fifo_sample_capa; /* sample capacity of FSI FIFO */
166 int buff_sample_capa; /* sample capacity of ALSA buffer */ 183 int buff_sample_capa; /* sample capacity of ALSA buffer */
167 int buff_sample_pos; /* sample position of ALSA buffer */ 184 int buff_sample_pos; /* sample position of ALSA buffer */
168 int period_samples; /* sample number / 1 period */ 185 int period_samples; /* sample number / 1 period */
169 int period_pos; /* current period position */ 186 int period_pos; /* current period position */
170 187 int sample_width; /* sample width */
171 int uerr_num; 188 int uerr_num;
172 int oerr_num; 189 int oerr_num;
190
191 /*
192 * thse are initialized by fsi_handler_init()
193 */
194 struct fsi_stream_handler *handler;
195 struct fsi_priv *priv;
196
197 /*
198 * these are for DMAEngine
199 */
200 struct dma_chan *chan;
201 struct sh_dmae_slave slave; /* see fsi_handler_init() */
202 struct tasklet_struct tasklet;
203 dma_addr_t dma;
173}; 204};
174 205
175struct fsi_priv { 206struct fsi_priv {
176 void __iomem *base; 207 void __iomem *base;
177 struct fsi_master *master; 208 struct fsi_master *master;
209 struct sh_fsi_port_info *info;
178 210
179 struct fsi_stream playback; 211 struct fsi_stream playback;
180 struct fsi_stream capture; 212 struct fsi_stream capture;
@@ -189,6 +221,20 @@ struct fsi_priv {
189 long rate; 221 long rate;
190}; 222};
191 223
224struct fsi_stream_handler {
225 int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
226 int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
227 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
228 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
229 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
230 void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
231 int enable);
232};
233#define fsi_stream_handler_call(io, func, args...) \
234 (!(io) ? -ENODEV : \
235 !((io)->handler->func) ? 0 : \
236 (io)->handler->func(args))
237
192struct fsi_core { 238struct fsi_core {
193 int ver; 239 int ver;
194 240
@@ -205,10 +251,11 @@ struct fsi_master {
205 struct fsi_priv fsia; 251 struct fsi_priv fsia;
206 struct fsi_priv fsib; 252 struct fsi_priv fsib;
207 struct fsi_core *core; 253 struct fsi_core *core;
208 struct sh_fsi_platform_info *info;
209 spinlock_t lock; 254 spinlock_t lock;
210}; 255};
211 256
257static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
258
212/* 259/*
213 * basic read write function 260 * basic read write function
214 */ 261 */
@@ -295,6 +342,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi)
295 return fsi->spdif; 342 return fsi->spdif;
296} 343}
297 344
345static int fsi_is_play(struct snd_pcm_substream *substream)
346{
347 return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
348}
349
298static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) 350static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
299{ 351{
300 struct snd_soc_pcm_runtime *rtd = substream->private_data; 352 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -317,44 +369,25 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
317 return fsi_get_priv_frm_dai(fsi_get_dai(substream)); 369 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
318} 370}
319 371
320static set_rate_func fsi_get_info_set_rate(struct fsi_master *master) 372static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
321{ 373{
322 if (!master->info) 374 if (!fsi->info)
323 return NULL; 375 return NULL;
324 376
325 return master->info->set_rate; 377 return fsi->info->set_rate;
326} 378}
327 379
328static u32 fsi_get_info_flags(struct fsi_priv *fsi) 380static u32 fsi_get_info_flags(struct fsi_priv *fsi)
329{ 381{
330 int is_porta = fsi_is_port_a(fsi); 382 if (!fsi->info)
331 struct fsi_master *master = fsi_get_master(fsi);
332
333 if (!master->info)
334 return 0; 383 return 0;
335 384
336 return is_porta ? master->info->porta_flags : 385 return fsi->info->flags;
337 master->info->portb_flags;
338}
339
340static inline int fsi_stream_is_play(int stream)
341{
342 return stream == SNDRV_PCM_STREAM_PLAYBACK;
343}
344
345static inline int fsi_is_play(struct snd_pcm_substream *substream)
346{
347 return fsi_stream_is_play(substream->stream);
348} 386}
349 387
350static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi, 388static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
351 int is_play)
352{
353 return is_play ? &fsi->playback : &fsi->capture;
354}
355
356static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
357{ 389{
390 int is_play = fsi_stream_is_play(fsi, io);
358 int is_porta = fsi_is_port_a(fsi); 391 int is_porta = fsi_is_port_a(fsi);
359 u32 shift; 392 u32 shift;
360 393
@@ -376,26 +409,81 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
376 return samples / fsi->chan_num; 409 return samples / fsi->chan_num;
377} 410}
378 411
412static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
413 struct fsi_stream *io)
414{
415 int is_play = fsi_stream_is_play(fsi, io);
416 u32 status;
417 int frames;
418
419 status = is_play ?
420 fsi_reg_read(fsi, DOFF_ST) :
421 fsi_reg_read(fsi, DIFF_ST);
422
423 frames = 0x1ff & (status >> 8);
424
425 return fsi_frame2sample(fsi, frames);
426}
427
428static void fsi_count_fifo_err(struct fsi_priv *fsi)
429{
430 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
431 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
432
433 if (ostatus & ERR_OVER)
434 fsi->playback.oerr_num++;
435
436 if (ostatus & ERR_UNDER)
437 fsi->playback.uerr_num++;
438
439 if (istatus & ERR_OVER)
440 fsi->capture.oerr_num++;
441
442 if (istatus & ERR_UNDER)
443 fsi->capture.uerr_num++;
444
445 fsi_reg_write(fsi, DOFF_ST, 0);
446 fsi_reg_write(fsi, DIFF_ST, 0);
447}
448
449/*
450 * fsi_stream_xx() function
451 */
452static inline int fsi_stream_is_play(struct fsi_priv *fsi,
453 struct fsi_stream *io)
454{
455 return &fsi->playback == io;
456}
457
458static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
459 struct snd_pcm_substream *substream)
460{
461 return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
462}
463
379static int fsi_stream_is_working(struct fsi_priv *fsi, 464static int fsi_stream_is_working(struct fsi_priv *fsi,
380 int is_play) 465 struct fsi_stream *io)
381{ 466{
382 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
383 struct fsi_master *master = fsi_get_master(fsi); 467 struct fsi_master *master = fsi_get_master(fsi);
384 unsigned long flags; 468 unsigned long flags;
385 int ret; 469 int ret;
386 470
387 spin_lock_irqsave(&master->lock, flags); 471 spin_lock_irqsave(&master->lock, flags);
388 ret = !!io->substream; 472 ret = !!(io->substream && io->substream->runtime);
389 spin_unlock_irqrestore(&master->lock, flags); 473 spin_unlock_irqrestore(&master->lock, flags);
390 474
391 return ret; 475 return ret;
392} 476}
393 477
394static void fsi_stream_push(struct fsi_priv *fsi, 478static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
395 int is_play, 479{
480 return io->priv;
481}
482
483static void fsi_stream_init(struct fsi_priv *fsi,
484 struct fsi_stream *io,
396 struct snd_pcm_substream *substream) 485 struct snd_pcm_substream *substream)
397{ 486{
398 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
399 struct snd_pcm_runtime *runtime = substream->runtime; 487 struct snd_pcm_runtime *runtime = substream->runtime;
400 struct fsi_master *master = fsi_get_master(fsi); 488 struct fsi_master *master = fsi_get_master(fsi);
401 unsigned long flags; 489 unsigned long flags;
@@ -406,14 +494,15 @@ static void fsi_stream_push(struct fsi_priv *fsi,
406 io->buff_sample_pos = 0; 494 io->buff_sample_pos = 0;
407 io->period_samples = fsi_frame2sample(fsi, runtime->period_size); 495 io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
408 io->period_pos = 0; 496 io->period_pos = 0;
497 io->sample_width = samples_to_bytes(runtime, 1);
409 io->oerr_num = -1; /* ignore 1st err */ 498 io->oerr_num = -1; /* ignore 1st err */
410 io->uerr_num = -1; /* ignore 1st err */ 499 io->uerr_num = -1; /* ignore 1st err */
500 fsi_stream_handler_call(io, init, fsi, io);
411 spin_unlock_irqrestore(&master->lock, flags); 501 spin_unlock_irqrestore(&master->lock, flags);
412} 502}
413 503
414static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) 504static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
415{ 505{
416 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
417 struct snd_soc_dai *dai = fsi_get_dai(io->substream); 506 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
418 struct fsi_master *master = fsi_get_master(fsi); 507 struct fsi_master *master = fsi_get_master(fsi);
419 unsigned long flags; 508 unsigned long flags;
@@ -426,127 +515,87 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
426 if (io->uerr_num > 0) 515 if (io->uerr_num > 0)
427 dev_err(dai->dev, "under_run = %d\n", io->uerr_num); 516 dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
428 517
518 fsi_stream_handler_call(io, quit, fsi, io);
429 io->substream = NULL; 519 io->substream = NULL;
430 io->buff_sample_capa = 0; 520 io->buff_sample_capa = 0;
431 io->buff_sample_pos = 0; 521 io->buff_sample_pos = 0;
432 io->period_samples = 0; 522 io->period_samples = 0;
433 io->period_pos = 0; 523 io->period_pos = 0;
524 io->sample_width = 0;
434 io->oerr_num = 0; 525 io->oerr_num = 0;
435 io->uerr_num = 0; 526 io->uerr_num = 0;
436 spin_unlock_irqrestore(&master->lock, flags); 527 spin_unlock_irqrestore(&master->lock, flags);
437} 528}
438 529
439static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play) 530static int fsi_stream_transfer(struct fsi_stream *io)
440{ 531{
441 u32 status; 532 struct fsi_priv *fsi = fsi_stream_to_priv(io);
442 int frames; 533 if (!fsi)
443 534 return -EIO;
444 status = is_play ?
445 fsi_reg_read(fsi, DOFF_ST) :
446 fsi_reg_read(fsi, DIFF_ST);
447
448 frames = 0x1ff & (status >> 8);
449
450 return fsi_frame2sample(fsi, frames);
451}
452
453static void fsi_count_fifo_err(struct fsi_priv *fsi)
454{
455 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
456 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
457
458 if (ostatus & ERR_OVER)
459 fsi->playback.oerr_num++;
460
461 if (ostatus & ERR_UNDER)
462 fsi->playback.uerr_num++;
463
464 if (istatus & ERR_OVER)
465 fsi->capture.oerr_num++;
466
467 if (istatus & ERR_UNDER)
468 fsi->capture.uerr_num++;
469 535
470 fsi_reg_write(fsi, DOFF_ST, 0); 536 return fsi_stream_handler_call(io, transfer, fsi, io);
471 fsi_reg_write(fsi, DIFF_ST, 0);
472} 537}
473 538
474/* 539#define fsi_stream_start(fsi, io)\
475 * dma function 540 fsi_stream_handler_call(io, start_stop, fsi, io, 1)
476 */
477 541
478static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream) 542#define fsi_stream_stop(fsi, io)\
479{ 543 fsi_stream_handler_call(io, start_stop, fsi, io, 0)
480 int is_play = fsi_stream_is_play(stream);
481 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
482 struct snd_pcm_runtime *runtime = io->substream->runtime;
483 544
484 return runtime->dma_area + 545static int fsi_stream_probe(struct fsi_priv *fsi)
485 samples_to_bytes(runtime, io->buff_sample_pos);
486}
487
488static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
489{ 546{
490 u16 *start; 547 struct fsi_stream *io;
491 int i; 548 int ret1, ret2;
492
493 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
494 549
495 for (i = 0; i < num; i++) 550 io = &fsi->playback;
496 fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8)); 551 ret1 = fsi_stream_handler_call(io, probe, fsi, io);
497}
498
499static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
500{
501 u16 *start;
502 int i;
503 552
504 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE); 553 io = &fsi->capture;
554 ret2 = fsi_stream_handler_call(io, probe, fsi, io);
505 555
556 if (ret1 < 0)
557 return ret1;
558 if (ret2 < 0)
559 return ret2;
506 560
507 for (i = 0; i < num; i++) 561 return 0;
508 *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
509} 562}
510 563
511static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num) 564static int fsi_stream_remove(struct fsi_priv *fsi)
512{ 565{
513 u32 *start; 566 struct fsi_stream *io;
514 int i; 567 int ret1, ret2;
515 568
516 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK); 569 io = &fsi->playback;
517 570 ret1 = fsi_stream_handler_call(io, remove, fsi, io);
518
519 for (i = 0; i < num; i++)
520 fsi_reg_write(fsi, DODT, *(start + i));
521}
522 571
523static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num) 572 io = &fsi->capture;
524{ 573 ret2 = fsi_stream_handler_call(io, remove, fsi, io);
525 u32 *start;
526 int i;
527 574
528 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE); 575 if (ret1 < 0)
576 return ret1;
577 if (ret2 < 0)
578 return ret2;
529 579
530 for (i = 0; i < num; i++) 580 return 0;
531 *(start + i) = fsi_reg_read(fsi, DIDT);
532} 581}
533 582
534/* 583/*
535 * irq function 584 * irq function
536 */ 585 */
537 586
538static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 587static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io)
539{ 588{
540 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 589 u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
541 struct fsi_master *master = fsi_get_master(fsi); 590 struct fsi_master *master = fsi_get_master(fsi);
542 591
543 fsi_core_mask_set(master, imsk, data, data); 592 fsi_core_mask_set(master, imsk, data, data);
544 fsi_core_mask_set(master, iemsk, data, data); 593 fsi_core_mask_set(master, iemsk, data, data);
545} 594}
546 595
547static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 596static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io)
548{ 597{
549 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 598 u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
550 struct fsi_master *master = fsi_get_master(fsi); 599 struct fsi_master *master = fsi_get_master(fsi);
551 600
552 fsi_core_mask_set(master, imsk, data, 0); 601 fsi_core_mask_set(master, imsk, data, 0);
@@ -563,8 +612,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
563 u32 data = 0; 612 u32 data = 0;
564 struct fsi_master *master = fsi_get_master(fsi); 613 struct fsi_master *master = fsi_get_master(fsi);
565 614
566 data |= AB_IO(1, fsi_get_port_shift(fsi, 0)); 615 data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
567 data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); 616 data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
568 617
569 /* clear interrupt factor */ 618 /* clear interrupt factor */
570 fsi_core_mask_set(master, int_st, data, 0); 619 fsi_core_mask_set(master, int_st, data, 0);
@@ -600,11 +649,14 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
600 long rate, int enable) 649 long rate, int enable)
601{ 650{
602 struct fsi_master *master = fsi_get_master(fsi); 651 struct fsi_master *master = fsi_get_master(fsi);
603 set_rate_func set_rate = fsi_get_info_set_rate(master); 652 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
604 int fsi_ver = master->core->ver; 653 int fsi_ver = master->core->ver;
605 int ret; 654 int ret;
606 655
607 ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable); 656 if (!set_rate)
657 return 0;
658
659 ret = set_rate(dev, rate, enable);
608 if (ret < 0) /* error */ 660 if (ret < 0) /* error */
609 return ret; 661 return ret;
610 662
@@ -671,96 +723,64 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
671 return ret; 723 return ret;
672} 724}
673 725
674#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) 726/*
675#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) 727 * pio data transfer handler
676static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) 728 */
729static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
677{ 730{
678 struct fsi_master *master = fsi_get_master(fsi); 731 u16 *buf = (u16 *)_buf;
679 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; 732 int i;
680 733
681 if (enable) 734 for (i = 0; i < samples; i++)
682 fsi_irq_enable(fsi, is_play); 735 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
683 else 736}
684 fsi_irq_disable(fsi, is_play);
685 737
686 if (fsi_is_clk_master(fsi)) 738static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
687 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 739{
740 u16 *buf = (u16 *)_buf;
741 int i;
742
743 for (i = 0; i < samples; i++)
744 *(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
688} 745}
689 746
690/* 747static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples)
691 * ctrl function
692 */
693static void fsi_fifo_init(struct fsi_priv *fsi,
694 int is_play,
695 struct device *dev)
696{ 748{
697 struct fsi_master *master = fsi_get_master(fsi); 749 u32 *buf = (u32 *)_buf;
698 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 750 int i;
699 u32 shift, i;
700 int frame_capa;
701 751
702 /* get on-chip RAM capacity */ 752 for (i = 0; i < samples; i++)
703 shift = fsi_master_read(master, FIFO_SZ); 753 fsi_reg_write(fsi, DODT, *(buf + i));
704 shift >>= fsi_get_port_shift(fsi, is_play); 754}
705 shift &= FIFO_SZ_MASK;
706 frame_capa = 256 << shift;
707 dev_dbg(dev, "fifo = %d words\n", frame_capa);
708 755
709 /* 756static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples)
710 * The maximum number of sample data varies depending 757{
711 * on the number of channels selected for the format. 758 u32 *buf = (u32 *)_buf;
712 * 759 int i;
713 * FIFOs are used in 4-channel units in 3-channel mode
714 * and in 8-channel units in 5- to 7-channel mode
715 * meaning that more FIFOs than the required size of DPRAM
716 * are used.
717 *
718 * ex) if 256 words of DP-RAM is connected
719 * 1 channel: 256 (256 x 1 = 256)
720 * 2 channels: 128 (128 x 2 = 256)
721 * 3 channels: 64 ( 64 x 3 = 192)
722 * 4 channels: 64 ( 64 x 4 = 256)
723 * 5 channels: 32 ( 32 x 5 = 160)
724 * 6 channels: 32 ( 32 x 6 = 192)
725 * 7 channels: 32 ( 32 x 7 = 224)
726 * 8 channels: 32 ( 32 x 8 = 256)
727 */
728 for (i = 1; i < fsi->chan_num; i <<= 1)
729 frame_capa >>= 1;
730 dev_dbg(dev, "%d channel %d store\n",
731 fsi->chan_num, frame_capa);
732 760
733 io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa); 761 for (i = 0; i < samples; i++)
762 *(buf + i) = fsi_reg_read(fsi, DIDT);
763}
734 764
735 /* 765static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
736 * set interrupt generation factor 766{
737 * clear FIFO 767 struct snd_pcm_runtime *runtime = io->substream->runtime;
738 */ 768
739 if (is_play) { 769 return runtime->dma_area +
740 fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); 770 samples_to_bytes(runtime, io->buff_sample_pos);
741 fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
742 } else {
743 fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
744 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
745 }
746} 771}
747 772
748static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) 773static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
774 void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
775 void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
776 int samples)
749{ 777{
750 struct snd_pcm_runtime *runtime; 778 struct snd_pcm_runtime *runtime;
751 struct snd_pcm_substream *substream = NULL; 779 struct snd_pcm_substream *substream;
752 int is_play = fsi_stream_is_play(stream); 780 u8 *buf;
753 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
754 int sample_residues;
755 int sample_width;
756 int samples;
757 int samples_max;
758 int over_period; 781 int over_period;
759 void (*fn)(struct fsi_priv *fsi, int size);
760 782
761 if (!fsi || 783 if (!fsi_stream_is_working(fsi, io))
762 !io->substream ||
763 !io->substream->runtime)
764 return -EINVAL; 784 return -EINVAL;
765 785
766 over_period = 0; 786 over_period = 0;
@@ -780,60 +800,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
780 io->buff_sample_pos = 0; 800 io->buff_sample_pos = 0;
781 } 801 }
782 802
783 /* get 1 sample data width */ 803 buf = fsi_pio_get_area(fsi, io);
784 sample_width = samples_to_bytes(runtime, 1);
785 804
786 /* get number of residue samples */ 805 switch (io->sample_width) {
787 sample_residues = io->buff_sample_capa - io->buff_sample_pos; 806 case 2:
788 807 run16(fsi, buf, samples);
789 if (is_play) { 808 break;
790 /* 809 case 4:
791 * for play-back 810 run32(fsi, buf, samples);
792 * 811 break;
793 * samples_max : number of FSI fifo free samples space 812 default:
794 * samples : number of ALSA residue samples 813 return -EINVAL;
795 */
796 samples_max = io->fifo_sample_capa;
797 samples_max -= fsi_get_current_fifo_samples(fsi, is_play);
798
799 samples = sample_residues;
800
801 switch (sample_width) {
802 case 2:
803 fn = fsi_dma_soft_push16;
804 break;
805 case 4:
806 fn = fsi_dma_soft_push32;
807 break;
808 default:
809 return -EINVAL;
810 }
811 } else {
812 /*
813 * for capture
814 *
815 * samples_max : number of ALSA free samples space
816 * samples : number of samples in FSI fifo
817 */
818 samples_max = sample_residues;
819 samples = fsi_get_current_fifo_samples(fsi, is_play);
820
821 switch (sample_width) {
822 case 2:
823 fn = fsi_dma_soft_pop16;
824 break;
825 case 4:
826 fn = fsi_dma_soft_pop32;
827 break;
828 default:
829 return -EINVAL;
830 }
831 } 814 }
832 815
833 samples = min(samples, samples_max);
834
835 fn(fsi, samples);
836
837 /* update buff_sample_pos */ 816 /* update buff_sample_pos */
838 io->buff_sample_pos += samples; 817 io->buff_sample_pos += samples;
839 818
@@ -843,16 +822,66 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
843 return 0; 822 return 0;
844} 823}
845 824
846static int fsi_data_pop(struct fsi_priv *fsi) 825static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
826{
827 int sample_residues; /* samples in FSI fifo */
828 int sample_space; /* ALSA free samples space */
829 int samples;
830
831 sample_residues = fsi_get_current_fifo_samples(fsi, io);
832 sample_space = io->buff_sample_capa - io->buff_sample_pos;
833
834 samples = min(sample_residues, sample_space);
835
836 return fsi_pio_transfer(fsi, io,
837 fsi_pio_pop16,
838 fsi_pio_pop32,
839 samples);
840}
841
842static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
847{ 843{
848 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE); 844 int sample_residues; /* ALSA residue samples */
845 int sample_space; /* FSI fifo free samples space */
846 int samples;
847
848 sample_residues = io->buff_sample_capa - io->buff_sample_pos;
849 sample_space = io->fifo_sample_capa -
850 fsi_get_current_fifo_samples(fsi, io);
851
852 samples = min(sample_residues, sample_space);
853
854 return fsi_pio_transfer(fsi, io,
855 fsi_pio_push16,
856 fsi_pio_push32,
857 samples);
849} 858}
850 859
851static int fsi_data_push(struct fsi_priv *fsi) 860static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
861 int enable)
852{ 862{
853 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK); 863 struct fsi_master *master = fsi_get_master(fsi);
864 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
865
866 if (enable)
867 fsi_irq_enable(fsi, io);
868 else
869 fsi_irq_disable(fsi, io);
870
871 if (fsi_is_clk_master(fsi))
872 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
854} 873}
855 874
875static struct fsi_stream_handler fsi_pio_push_handler = {
876 .transfer = fsi_pio_push,
877 .start_stop = fsi_pio_start_stop,
878};
879
880static struct fsi_stream_handler fsi_pio_pop_handler = {
881 .transfer = fsi_pio_pop,
882 .start_stop = fsi_pio_start_stop,
883};
884
856static irqreturn_t fsi_interrupt(int irq, void *data) 885static irqreturn_t fsi_interrupt(int irq, void *data)
857{ 886{
858 struct fsi_master *master = data; 887 struct fsi_master *master = data;
@@ -863,13 +892,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
863 fsi_master_mask_set(master, SOFT_RST, IR, IR); 892 fsi_master_mask_set(master, SOFT_RST, IR, IR);
864 893
865 if (int_st & AB_IO(1, AO_SHIFT)) 894 if (int_st & AB_IO(1, AO_SHIFT))
866 fsi_data_push(&master->fsia); 895 fsi_stream_transfer(&master->fsia.playback);
867 if (int_st & AB_IO(1, BO_SHIFT)) 896 if (int_st & AB_IO(1, BO_SHIFT))
868 fsi_data_push(&master->fsib); 897 fsi_stream_transfer(&master->fsib.playback);
869 if (int_st & AB_IO(1, AI_SHIFT)) 898 if (int_st & AB_IO(1, AI_SHIFT))
870 fsi_data_pop(&master->fsia); 899 fsi_stream_transfer(&master->fsia.capture);
871 if (int_st & AB_IO(1, BI_SHIFT)) 900 if (int_st & AB_IO(1, BI_SHIFT))
872 fsi_data_pop(&master->fsib); 901 fsi_stream_transfer(&master->fsib.capture);
873 902
874 fsi_count_fifo_err(&master->fsia); 903 fsi_count_fifo_err(&master->fsia);
875 fsi_count_fifo_err(&master->fsib); 904 fsi_count_fifo_err(&master->fsib);
@@ -881,11 +910,271 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
881} 910}
882 911
883/* 912/*
913 * dma data transfer handler
914 */
915static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
916{
917 struct snd_pcm_runtime *runtime = io->substream->runtime;
918 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
919 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
920 DMA_TO_DEVICE : DMA_FROM_DEVICE;
921
922 io->dma = dma_map_single(dai->dev, runtime->dma_area,
923 snd_pcm_lib_buffer_bytes(io->substream), dir);
924 return 0;
925}
926
927static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
928{
929 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
930 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
931 DMA_TO_DEVICE : DMA_FROM_DEVICE;
932
933 dma_unmap_single(dai->dev, io->dma,
934 snd_pcm_lib_buffer_bytes(io->substream), dir);
935 return 0;
936}
937
938static void fsi_dma_complete(void *data)
939{
940 struct fsi_stream *io = (struct fsi_stream *)data;
941 struct fsi_priv *fsi = fsi_stream_to_priv(io);
942 struct snd_pcm_runtime *runtime = io->substream->runtime;
943 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
944 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
945 DMA_TO_DEVICE : DMA_FROM_DEVICE;
946
947 dma_sync_single_for_cpu(dai->dev, io->dma,
948 samples_to_bytes(runtime, io->period_samples), dir);
949
950 io->buff_sample_pos += io->period_samples;
951 io->period_pos++;
952
953 if (io->period_pos >= runtime->periods) {
954 io->period_pos = 0;
955 io->buff_sample_pos = 0;
956 }
957
958 fsi_count_fifo_err(fsi);
959 fsi_stream_transfer(io);
960
961 snd_pcm_period_elapsed(io->substream);
962}
963
964static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
965{
966 struct snd_pcm_runtime *runtime = io->substream->runtime;
967
968 return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
969}
970
971static void fsi_dma_do_tasklet(unsigned long data)
972{
973 struct fsi_stream *io = (struct fsi_stream *)data;
974 struct fsi_priv *fsi = fsi_stream_to_priv(io);
975 struct dma_chan *chan;
976 struct snd_soc_dai *dai;
977 struct dma_async_tx_descriptor *desc;
978 struct scatterlist sg;
979 struct snd_pcm_runtime *runtime;
980 enum dma_data_direction dir;
981 dma_cookie_t cookie;
982 int is_play = fsi_stream_is_play(fsi, io);
983 int len;
984 dma_addr_t buf;
985
986 if (!fsi_stream_is_working(fsi, io))
987 return;
988
989 dai = fsi_get_dai(io->substream);
990 chan = io->chan;
991 runtime = io->substream->runtime;
992 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
993 len = samples_to_bytes(runtime, io->period_samples);
994 buf = fsi_dma_get_area(io);
995
996 dma_sync_single_for_device(dai->dev, io->dma, len, dir);
997
998 sg_init_table(&sg, 1);
999 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
1000 len , offset_in_page(buf));
1001 sg_dma_address(&sg) = buf;
1002 sg_dma_len(&sg) = len;
1003
1004 desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
1005 DMA_PREP_INTERRUPT |
1006 DMA_CTRL_ACK);
1007 if (!desc) {
1008 dev_err(dai->dev, "device_prep_slave_sg() fail\n");
1009 return;
1010 }
1011
1012 desc->callback = fsi_dma_complete;
1013 desc->callback_param = io;
1014
1015 cookie = desc->tx_submit(desc);
1016 if (cookie < 0) {
1017 dev_err(dai->dev, "tx_submit() fail\n");
1018 return;
1019 }
1020
1021 dma_async_issue_pending(chan);
1022
1023 /*
1024 * FIXME
1025 *
1026 * In DMAEngine case, codec and FSI cannot be started simultaneously
1027 * since FSI is using tasklet.
1028 * Therefore, in capture case, probably FSI FIFO will have got
1029 * overflow error in this point.
1030 * in that case, DMA cannot start transfer until error was cleared.
1031 */
1032 if (!is_play) {
1033 if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) {
1034 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
1035 fsi_reg_write(fsi, DIFF_ST, 0);
1036 }
1037 }
1038}
1039
1040static bool fsi_dma_filter(struct dma_chan *chan, void *param)
1041{
1042 struct sh_dmae_slave *slave = param;
1043
1044 chan->private = slave;
1045
1046 return true;
1047}
1048
1049static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
1050{
1051 tasklet_schedule(&io->tasklet);
1052
1053 return 0;
1054}
1055
1056static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1057 int start)
1058{
1059 u32 bws;
1060 u32 dma;
1061
1062 switch (io->sample_width * start) {
1063 case 2:
1064 bws = CR_BWS_16;
1065 dma = VDMD_STREAM | DMA_ON;
1066 break;
1067 case 4:
1068 bws = CR_BWS_24;
1069 dma = VDMD_BACK | DMA_ON;
1070 break;
1071 default:
1072 bws = 0;
1073 dma = 0;
1074 }
1075
1076 fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
1077 fsi_reg_write(fsi, OUT_DMAC, dma);
1078}
1079
1080static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
1081{
1082 dma_cap_mask_t mask;
1083
1084 dma_cap_zero(mask);
1085 dma_cap_set(DMA_SLAVE, mask);
1086
1087 io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
1088 if (!io->chan)
1089 return -EIO;
1090
1091 tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
1092
1093 return 0;
1094}
1095
1096static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io)
1097{
1098 tasklet_kill(&io->tasklet);
1099
1100 fsi_stream_stop(fsi, io);
1101
1102 if (io->chan)
1103 dma_release_channel(io->chan);
1104
1105 io->chan = NULL;
1106 return 0;
1107}
1108
1109static struct fsi_stream_handler fsi_dma_push_handler = {
1110 .init = fsi_dma_init,
1111 .quit = fsi_dma_quit,
1112 .probe = fsi_dma_probe,
1113 .transfer = fsi_dma_transfer,
1114 .remove = fsi_dma_remove,
1115 .start_stop = fsi_dma_push_start_stop,
1116};
1117
1118/*
884 * dai ops 1119 * dai ops
885 */ 1120 */
1121static void fsi_fifo_init(struct fsi_priv *fsi,
1122 struct fsi_stream *io,
1123 struct device *dev)
1124{
1125 struct fsi_master *master = fsi_get_master(fsi);
1126 int is_play = fsi_stream_is_play(fsi, io);
1127 u32 shift, i;
1128 int frame_capa;
1129
1130 /* get on-chip RAM capacity */
1131 shift = fsi_master_read(master, FIFO_SZ);
1132 shift >>= fsi_get_port_shift(fsi, io);
1133 shift &= FIFO_SZ_MASK;
1134 frame_capa = 256 << shift;
1135 dev_dbg(dev, "fifo = %d words\n", frame_capa);
1136
1137 /*
1138 * The maximum number of sample data varies depending
1139 * on the number of channels selected for the format.
1140 *
1141 * FIFOs are used in 4-channel units in 3-channel mode
1142 * and in 8-channel units in 5- to 7-channel mode
1143 * meaning that more FIFOs than the required size of DPRAM
1144 * are used.
1145 *
1146 * ex) if 256 words of DP-RAM is connected
1147 * 1 channel: 256 (256 x 1 = 256)
1148 * 2 channels: 128 (128 x 2 = 256)
1149 * 3 channels: 64 ( 64 x 3 = 192)
1150 * 4 channels: 64 ( 64 x 4 = 256)
1151 * 5 channels: 32 ( 32 x 5 = 160)
1152 * 6 channels: 32 ( 32 x 6 = 192)
1153 * 7 channels: 32 ( 32 x 7 = 224)
1154 * 8 channels: 32 ( 32 x 8 = 256)
1155 */
1156 for (i = 1; i < fsi->chan_num; i <<= 1)
1157 frame_capa >>= 1;
1158 dev_dbg(dev, "%d channel %d store\n",
1159 fsi->chan_num, frame_capa);
1160
1161 io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
1162
1163 /*
1164 * set interrupt generation factor
1165 * clear FIFO
1166 */
1167 if (is_play) {
1168 fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
1169 fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
1170 } else {
1171 fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
1172 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
1173 }
1174}
886 1175
887static int fsi_hw_startup(struct fsi_priv *fsi, 1176static int fsi_hw_startup(struct fsi_priv *fsi,
888 int is_play, 1177 struct fsi_stream *io,
889 struct device *dev) 1178 struct device *dev)
890{ 1179{
891 struct fsi_master *master = fsi_get_master(fsi); 1180 struct fsi_master *master = fsi_get_master(fsi);
@@ -934,17 +1223,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
934 } 1223 }
935 1224
936 /* irq clear */ 1225 /* irq clear */
937 fsi_irq_disable(fsi, is_play); 1226 fsi_irq_disable(fsi, io);
938 fsi_irq_clear_status(fsi); 1227 fsi_irq_clear_status(fsi);
939 1228
940 /* fifo init */ 1229 /* fifo init */
941 fsi_fifo_init(fsi, is_play, dev); 1230 fsi_fifo_init(fsi, io, dev);
942 1231
943 return 0; 1232 return 0;
944} 1233}
945 1234
946static void fsi_hw_shutdown(struct fsi_priv *fsi, 1235static void fsi_hw_shutdown(struct fsi_priv *fsi,
947 int is_play,
948 struct device *dev) 1236 struct device *dev)
949{ 1237{
950 if (fsi_is_clk_master(fsi)) 1238 if (fsi_is_clk_master(fsi))
@@ -955,18 +1243,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
955 struct snd_soc_dai *dai) 1243 struct snd_soc_dai *dai)
956{ 1244{
957 struct fsi_priv *fsi = fsi_get_priv(substream); 1245 struct fsi_priv *fsi = fsi_get_priv(substream);
958 int is_play = fsi_is_play(substream);
959 1246
960 return fsi_hw_startup(fsi, is_play, dai->dev); 1247 return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
961} 1248}
962 1249
963static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 1250static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
964 struct snd_soc_dai *dai) 1251 struct snd_soc_dai *dai)
965{ 1252{
966 struct fsi_priv *fsi = fsi_get_priv(substream); 1253 struct fsi_priv *fsi = fsi_get_priv(substream);
967 int is_play = fsi_is_play(substream);
968 1254
969 fsi_hw_shutdown(fsi, is_play, dai->dev); 1255 fsi_hw_shutdown(fsi, dai->dev);
970 fsi->rate = 0; 1256 fsi->rate = 0;
971} 1257}
972 1258
@@ -974,18 +1260,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
974 struct snd_soc_dai *dai) 1260 struct snd_soc_dai *dai)
975{ 1261{
976 struct fsi_priv *fsi = fsi_get_priv(substream); 1262 struct fsi_priv *fsi = fsi_get_priv(substream);
977 int is_play = fsi_is_play(substream); 1263 struct fsi_stream *io = fsi_stream_get(fsi, substream);
978 int ret = 0; 1264 int ret = 0;
979 1265
980 switch (cmd) { 1266 switch (cmd) {
981 case SNDRV_PCM_TRIGGER_START: 1267 case SNDRV_PCM_TRIGGER_START:
982 fsi_stream_push(fsi, is_play, substream); 1268 fsi_stream_init(fsi, io, substream);
983 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 1269 ret = fsi_stream_transfer(io);
984 fsi_port_start(fsi, is_play); 1270 if (0 == ret)
1271 fsi_stream_start(fsi, io);
985 break; 1272 break;
986 case SNDRV_PCM_TRIGGER_STOP: 1273 case SNDRV_PCM_TRIGGER_STOP:
987 fsi_port_stop(fsi, is_play); 1274 fsi_stream_stop(fsi, io);
988 fsi_stream_pop(fsi, is_play); 1275 fsi_stream_quit(fsi, io);
989 break; 1276 break;
990 } 1277 }
991 1278
@@ -1036,8 +1323,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
1036static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1323static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1037{ 1324{
1038 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 1325 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
1039 struct fsi_master *master = fsi_get_master(fsi); 1326 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
1040 set_rate_func set_rate = fsi_get_info_set_rate(master);
1041 u32 flags = fsi_get_info_flags(fsi); 1327 u32 flags = fsi_get_info_flags(fsi);
1042 int ret; 1328 int ret;
1043 1329
@@ -1151,7 +1437,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
1151static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 1437static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
1152{ 1438{
1153 struct fsi_priv *fsi = fsi_get_priv(substream); 1439 struct fsi_priv *fsi = fsi_get_priv(substream);
1154 struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); 1440 struct fsi_stream *io = fsi_stream_get(fsi, substream);
1155 1441
1156 return fsi_sample2frame(fsi, io->buff_sample_pos); 1442 return fsi_sample2frame(fsi, io->buff_sample_pos);
1157} 1443}
@@ -1239,11 +1525,24 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
1239/* 1525/*
1240 * platform function 1526 * platform function
1241 */ 1527 */
1528static void fsi_handler_init(struct fsi_priv *fsi)
1529{
1530 fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */
1531 fsi->playback.priv = fsi;
1532 fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
1533 fsi->capture.priv = fsi;
1534
1535 if (fsi->info->tx_id) {
1536 fsi->playback.slave.slave_id = fsi->info->tx_id;
1537 fsi->playback.handler = &fsi_dma_push_handler;
1538 }
1539}
1242 1540
1243static int fsi_probe(struct platform_device *pdev) 1541static int fsi_probe(struct platform_device *pdev)
1244{ 1542{
1245 struct fsi_master *master; 1543 struct fsi_master *master;
1246 const struct platform_device_id *id_entry; 1544 const struct platform_device_id *id_entry;
1545 struct sh_fsi_platform_info *info = pdev->dev.platform_data;
1247 struct resource *res; 1546 struct resource *res;
1248 unsigned int irq; 1547 unsigned int irq;
1249 int ret; 1548 int ret;
@@ -1278,17 +1577,30 @@ static int fsi_probe(struct platform_device *pdev)
1278 1577
1279 /* master setting */ 1578 /* master setting */
1280 master->irq = irq; 1579 master->irq = irq;
1281 master->info = pdev->dev.platform_data;
1282 master->core = (struct fsi_core *)id_entry->driver_data; 1580 master->core = (struct fsi_core *)id_entry->driver_data;
1283 spin_lock_init(&master->lock); 1581 spin_lock_init(&master->lock);
1284 1582
1285 /* FSI A setting */ 1583 /* FSI A setting */
1286 master->fsia.base = master->base; 1584 master->fsia.base = master->base;
1287 master->fsia.master = master; 1585 master->fsia.master = master;
1586 master->fsia.info = &info->port_a;
1587 fsi_handler_init(&master->fsia);
1588 ret = fsi_stream_probe(&master->fsia);
1589 if (ret < 0) {
1590 dev_err(&pdev->dev, "FSIA stream probe failed\n");
1591 goto exit_iounmap;
1592 }
1288 1593
1289 /* FSI B setting */ 1594 /* FSI B setting */
1290 master->fsib.base = master->base + 0x40; 1595 master->fsib.base = master->base + 0x40;
1291 master->fsib.master = master; 1596 master->fsib.master = master;
1597 master->fsib.info = &info->port_b;
1598 fsi_handler_init(&master->fsib);
1599 ret = fsi_stream_probe(&master->fsib);
1600 if (ret < 0) {
1601 dev_err(&pdev->dev, "FSIB stream probe failed\n");
1602 goto exit_fsia;
1603 }
1292 1604
1293 pm_runtime_enable(&pdev->dev); 1605 pm_runtime_enable(&pdev->dev);
1294 dev_set_drvdata(&pdev->dev, master); 1606 dev_set_drvdata(&pdev->dev, master);
@@ -1297,7 +1609,7 @@ static int fsi_probe(struct platform_device *pdev)
1297 id_entry->name, master); 1609 id_entry->name, master);
1298 if (ret) { 1610 if (ret) {
1299 dev_err(&pdev->dev, "irq request err\n"); 1611 dev_err(&pdev->dev, "irq request err\n");
1300 goto exit_iounmap; 1612 goto exit_fsib;
1301 } 1613 }
1302 1614
1303 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); 1615 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
@@ -1319,6 +1631,10 @@ exit_snd_soc:
1319 snd_soc_unregister_platform(&pdev->dev); 1631 snd_soc_unregister_platform(&pdev->dev);
1320exit_free_irq: 1632exit_free_irq:
1321 free_irq(irq, master); 1633 free_irq(irq, master);
1634exit_fsib:
1635 fsi_stream_remove(&master->fsib);
1636exit_fsia:
1637 fsi_stream_remove(&master->fsia);
1322exit_iounmap: 1638exit_iounmap:
1323 iounmap(master->base); 1639 iounmap(master->base);
1324 pm_runtime_disable(&pdev->dev); 1640 pm_runtime_disable(&pdev->dev);
@@ -1341,6 +1657,9 @@ static int fsi_remove(struct platform_device *pdev)
1341 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); 1657 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
1342 snd_soc_unregister_platform(&pdev->dev); 1658 snd_soc_unregister_platform(&pdev->dev);
1343 1659
1660 fsi_stream_remove(&master->fsia);
1661 fsi_stream_remove(&master->fsib);
1662
1344 iounmap(master->base); 1663 iounmap(master->base);
1345 kfree(master); 1664 kfree(master);
1346 1665
@@ -1348,30 +1667,29 @@ static int fsi_remove(struct platform_device *pdev)
1348} 1667}
1349 1668
1350static void __fsi_suspend(struct fsi_priv *fsi, 1669static void __fsi_suspend(struct fsi_priv *fsi,
1351 int is_play, 1670 struct fsi_stream *io,
1352 struct device *dev) 1671 struct device *dev)
1353{ 1672{
1354 if (!fsi_stream_is_working(fsi, is_play)) 1673 if (!fsi_stream_is_working(fsi, io))
1355 return; 1674 return;
1356 1675
1357 fsi_port_stop(fsi, is_play); 1676 fsi_stream_stop(fsi, io);
1358 fsi_hw_shutdown(fsi, is_play, dev); 1677 fsi_hw_shutdown(fsi, dev);
1359} 1678}
1360 1679
1361static void __fsi_resume(struct fsi_priv *fsi, 1680static void __fsi_resume(struct fsi_priv *fsi,
1362 int is_play, 1681 struct fsi_stream *io,
1363 struct device *dev) 1682 struct device *dev)
1364{ 1683{
1365 if (!fsi_stream_is_working(fsi, is_play)) 1684 if (!fsi_stream_is_working(fsi, io))
1366 return; 1685 return;
1367 1686
1368 fsi_hw_startup(fsi, is_play, dev); 1687 fsi_hw_startup(fsi, io, dev);
1369 1688
1370 if (fsi_is_clk_master(fsi) && fsi->rate) 1689 if (fsi_is_clk_master(fsi) && fsi->rate)
1371 fsi_set_master_clk(dev, fsi, fsi->rate, 1); 1690 fsi_set_master_clk(dev, fsi, fsi->rate, 1);
1372 1691
1373 fsi_port_start(fsi, is_play); 1692 fsi_stream_start(fsi, io);
1374
1375} 1693}
1376 1694
1377static int fsi_suspend(struct device *dev) 1695static int fsi_suspend(struct device *dev)
@@ -1380,11 +1698,11 @@ static int fsi_suspend(struct device *dev)
1380 struct fsi_priv *fsia = &master->fsia; 1698 struct fsi_priv *fsia = &master->fsia;
1381 struct fsi_priv *fsib = &master->fsib; 1699 struct fsi_priv *fsib = &master->fsib;
1382 1700
1383 __fsi_suspend(fsia, 1, dev); 1701 __fsi_suspend(fsia, &fsia->playback, dev);
1384 __fsi_suspend(fsia, 0, dev); 1702 __fsi_suspend(fsia, &fsia->capture, dev);
1385 1703
1386 __fsi_suspend(fsib, 1, dev); 1704 __fsi_suspend(fsib, &fsib->playback, dev);
1387 __fsi_suspend(fsib, 0, dev); 1705 __fsi_suspend(fsib, &fsib->capture, dev);
1388 1706
1389 return 0; 1707 return 0;
1390} 1708}
@@ -1395,32 +1713,18 @@ static int fsi_resume(struct device *dev)
1395 struct fsi_priv *fsia = &master->fsia; 1713 struct fsi_priv *fsia = &master->fsia;
1396 struct fsi_priv *fsib = &master->fsib; 1714 struct fsi_priv *fsib = &master->fsib;
1397 1715
1398 __fsi_resume(fsia, 1, dev); 1716 __fsi_resume(fsia, &fsia->playback, dev);
1399 __fsi_resume(fsia, 0, dev); 1717 __fsi_resume(fsia, &fsia->capture, dev);
1400 1718
1401 __fsi_resume(fsib, 1, dev); 1719 __fsi_resume(fsib, &fsib->playback, dev);
1402 __fsi_resume(fsib, 0, dev); 1720 __fsi_resume(fsib, &fsib->capture, dev);
1403 1721
1404 return 0; 1722 return 0;
1405} 1723}
1406 1724
1407static int fsi_runtime_nop(struct device *dev)
1408{
1409 /* Runtime PM callback shared between ->runtime_suspend()
1410 * and ->runtime_resume(). Simply returns success.
1411 *
1412 * This driver re-initializes all registers after
1413 * pm_runtime_get_sync() anyway so there is no need
1414 * to save and restore registers here.
1415 */
1416 return 0;
1417}
1418
1419static struct dev_pm_ops fsi_pm_ops = { 1725static struct dev_pm_ops fsi_pm_ops = {
1420 .suspend = fsi_suspend, 1726 .suspend = fsi_suspend,
1421 .resume = fsi_resume, 1727 .resume = fsi_resume,
1422 .runtime_suspend = fsi_runtime_nop,
1423 .runtime_resume = fsi_runtime_nop,
1424}; 1728};
1425 1729
1426static struct fsi_core fsi1_core = { 1730static struct fsi_core fsi1_core = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 92cee24ed2dc..a4deebc0801a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -277,8 +277,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
277 codec->debugfs_codec_root = debugfs_create_dir(codec->name, 277 codec->debugfs_codec_root = debugfs_create_dir(codec->name,
278 debugfs_card_root); 278 debugfs_card_root);
279 if (!codec->debugfs_codec_root) { 279 if (!codec->debugfs_codec_root) {
280 printk(KERN_WARNING 280 dev_warn(codec->dev, "Failed to create codec debugfs directory\n");
281 "ASoC: Failed to create codec debugfs directory\n");
282 return; 281 return;
283 } 282 }
284 283
@@ -291,8 +290,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
291 codec->debugfs_codec_root, 290 codec->debugfs_codec_root,
292 codec, &codec_reg_fops); 291 codec, &codec_reg_fops);
293 if (!codec->debugfs_reg) 292 if (!codec->debugfs_reg)
294 printk(KERN_WARNING 293 dev_warn(codec->dev, "Failed to create codec register debugfs file\n");
295 "ASoC: Failed to create codec register debugfs file\n");
296 294
297 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); 295 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
298} 296}
@@ -302,6 +300,27 @@ static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
302 debugfs_remove_recursive(codec->debugfs_codec_root); 300 debugfs_remove_recursive(codec->debugfs_codec_root);
303} 301}
304 302
303static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
304{
305 struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
306
307 platform->debugfs_platform_root = debugfs_create_dir(platform->name,
308 debugfs_card_root);
309 if (!platform->debugfs_platform_root) {
310 dev_warn(platform->dev,
311 "Failed to create platform debugfs directory\n");
312 return;
313 }
314
315 snd_soc_dapm_debugfs_init(&platform->dapm,
316 platform->debugfs_platform_root);
317}
318
319static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
320{
321 debugfs_remove_recursive(platform->debugfs_platform_root);
322}
323
305static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, 324static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
306 size_t count, loff_t *ppos) 325 size_t count, loff_t *ppos)
307{ 326{
@@ -435,6 +454,14 @@ static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
435{ 454{
436} 455}
437 456
457static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform)
458{
459}
460
461static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
462{
463}
464
438static inline void soc_init_card_debugfs(struct snd_soc_card *card) 465static inline void soc_init_card_debugfs(struct snd_soc_card *card)
439{ 466{
440} 467}
@@ -546,18 +573,20 @@ int snd_soc_suspend(struct device *dev)
546 } 573 }
547 574
548 for (i = 0; i < card->num_rtd; i++) { 575 for (i = 0; i < card->num_rtd; i++) {
549 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; 576 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
550 577
551 if (card->rtd[i].dai_link->ignore_suspend) 578 if (card->rtd[i].dai_link->ignore_suspend)
552 continue; 579 continue;
553 580
554 if (driver->playback.stream_name != NULL) 581 snd_soc_dapm_stream_event(&card->rtd[i],
555 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, 582 SNDRV_PCM_STREAM_PLAYBACK,
556 SND_SOC_DAPM_STREAM_SUSPEND); 583 codec_dai,
584 SND_SOC_DAPM_STREAM_SUSPEND);
557 585
558 if (driver->capture.stream_name != NULL) 586 snd_soc_dapm_stream_event(&card->rtd[i],
559 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, 587 SNDRV_PCM_STREAM_CAPTURE,
560 SND_SOC_DAPM_STREAM_SUSPEND); 588 codec_dai,
589 SND_SOC_DAPM_STREAM_SUSPEND);
561 } 590 }
562 591
563 /* suspend all CODECs */ 592 /* suspend all CODECs */
@@ -660,18 +689,18 @@ static void soc_resume_deferred(struct work_struct *work)
660 } 689 }
661 690
662 for (i = 0; i < card->num_rtd; i++) { 691 for (i = 0; i < card->num_rtd; i++) {
663 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; 692 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
664 693
665 if (card->rtd[i].dai_link->ignore_suspend) 694 if (card->rtd[i].dai_link->ignore_suspend)
666 continue; 695 continue;
667 696
668 if (driver->playback.stream_name != NULL) 697 snd_soc_dapm_stream_event(&card->rtd[i],
669 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, 698 SNDRV_PCM_STREAM_PLAYBACK, codec_dai,
670 SND_SOC_DAPM_STREAM_RESUME); 699 SND_SOC_DAPM_STREAM_RESUME);
671 700
672 if (driver->capture.stream_name != NULL) 701 snd_soc_dapm_stream_event(&card->rtd[i],
673 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, 702 SNDRV_PCM_STREAM_CAPTURE, codec_dai,
674 SND_SOC_DAPM_STREAM_RESUME); 703 SND_SOC_DAPM_STREAM_RESUME);
675 } 704 }
676 705
677 /* unmute any active DACs */ 706 /* unmute any active DACs */
@@ -904,7 +933,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
904 if (codec_dai->driver->remove) { 933 if (codec_dai->driver->remove) {
905 err = codec_dai->driver->remove(codec_dai); 934 err = codec_dai->driver->remove(codec_dai);
906 if (err < 0) 935 if (err < 0)
907 printk(KERN_ERR "asoc: failed to remove %s\n", codec_dai->name); 936 pr_err("asoc: failed to remove %s: %d\n",
937 codec_dai->name, err);
908 } 938 }
909 codec_dai->probed = 0; 939 codec_dai->probed = 0;
910 list_del(&codec_dai->card_list); 940 list_del(&codec_dai->card_list);
@@ -916,12 +946,14 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
916 if (platform->driver->remove) { 946 if (platform->driver->remove) {
917 err = platform->driver->remove(platform); 947 err = platform->driver->remove(platform);
918 if (err < 0) 948 if (err < 0)
919 printk(KERN_ERR "asoc: failed to remove %s\n", platform->name); 949 pr_err("asoc: failed to remove %s: %d\n",
950 platform->name, err);
920 } 951 }
921 952
922 /* Make sure all DAPM widgets are freed */ 953 /* Make sure all DAPM widgets are freed */
923 snd_soc_dapm_free(&platform->dapm); 954 snd_soc_dapm_free(&platform->dapm);
924 955
956 soc_cleanup_platform_debugfs(platform);
925 platform->probed = 0; 957 platform->probed = 0;
926 list_del(&platform->card_list); 958 list_del(&platform->card_list);
927 module_put(platform->dev->driver->owner); 959 module_put(platform->dev->driver->owner);
@@ -938,7 +970,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
938 if (cpu_dai->driver->remove) { 970 if (cpu_dai->driver->remove) {
939 err = cpu_dai->driver->remove(cpu_dai); 971 err = cpu_dai->driver->remove(cpu_dai);
940 if (err < 0) 972 if (err < 0)
941 printk(KERN_ERR "asoc: failed to remove %s\n", cpu_dai->name); 973 pr_err("asoc: failed to remove %s: %d\n",
974 cpu_dai->name, err);
942 } 975 }
943 cpu_dai->probed = 0; 976 cpu_dai->probed = 0;
944 list_del(&cpu_dai->card_list); 977 list_del(&cpu_dai->card_list);
@@ -980,6 +1013,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
980{ 1013{
981 int ret = 0; 1014 int ret = 0;
982 const struct snd_soc_codec_driver *driver = codec->driver; 1015 const struct snd_soc_codec_driver *driver = codec->driver;
1016 struct snd_soc_dai *dai;
983 1017
984 codec->card = card; 1018 codec->card = card;
985 codec->dapm.card = card; 1019 codec->dapm.card = card;
@@ -994,6 +1028,14 @@ static int soc_probe_codec(struct snd_soc_card *card,
994 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 1028 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
995 driver->num_dapm_widgets); 1029 driver->num_dapm_widgets);
996 1030
1031 /* Create DAPM widgets for each DAI stream */
1032 list_for_each_entry(dai, &dai_list, list) {
1033 if (dai->dev != codec->dev)
1034 continue;
1035
1036 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1037 }
1038
997 codec->dapm.idle_bias_off = driver->idle_bias_off; 1039 codec->dapm.idle_bias_off = driver->idle_bias_off;
998 1040
999 if (driver->probe) { 1041 if (driver->probe) {
@@ -1007,7 +1049,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
1007 } 1049 }
1008 1050
1009 if (driver->controls) 1051 if (driver->controls)
1010 snd_soc_add_controls(codec, driver->controls, 1052 snd_soc_add_codec_controls(codec, driver->controls,
1011 driver->num_controls); 1053 driver->num_controls);
1012 if (driver->dapm_routes) 1054 if (driver->dapm_routes)
1013 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1055 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
@@ -1039,6 +1081,8 @@ static int soc_probe_platform(struct snd_soc_card *card,
1039 if (!try_module_get(platform->dev->driver->owner)) 1081 if (!try_module_get(platform->dev->driver->owner))
1040 return -ENODEV; 1082 return -ENODEV;
1041 1083
1084 soc_init_platform_debugfs(platform);
1085
1042 if (driver->dapm_widgets) 1086 if (driver->dapm_widgets)
1043 snd_soc_dapm_new_controls(&platform->dapm, 1087 snd_soc_dapm_new_controls(&platform->dapm,
1044 driver->dapm_widgets, driver->num_dapm_widgets); 1088 driver->dapm_widgets, driver->num_dapm_widgets);
@@ -1068,6 +1112,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1068 return 0; 1112 return 0;
1069 1113
1070err_probe: 1114err_probe:
1115 soc_cleanup_platform_debugfs(platform);
1071 module_put(platform->dev->driver->owner); 1116 module_put(platform->dev->driver->owner);
1072 1117
1073 return ret; 1118 return ret;
@@ -1183,8 +1228,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1183 if (cpu_dai->driver->probe) { 1228 if (cpu_dai->driver->probe) {
1184 ret = cpu_dai->driver->probe(cpu_dai); 1229 ret = cpu_dai->driver->probe(cpu_dai);
1185 if (ret < 0) { 1230 if (ret < 0) {
1186 printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", 1231 pr_err("asoc: failed to probe CPU DAI %s: %d\n",
1187 cpu_dai->name); 1232 cpu_dai->name, ret);
1188 module_put(cpu_dai->dev->driver->owner); 1233 module_put(cpu_dai->dev->driver->owner);
1189 return ret; 1234 return ret;
1190 } 1235 }
@@ -1215,8 +1260,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1215 if (codec_dai->driver->probe) { 1260 if (codec_dai->driver->probe) {
1216 ret = codec_dai->driver->probe(codec_dai); 1261 ret = codec_dai->driver->probe(codec_dai);
1217 if (ret < 0) { 1262 if (ret < 0) {
1218 printk(KERN_ERR "asoc: failed to probe CODEC DAI %s\n", 1263 pr_err("asoc: failed to probe CODEC DAI %s: %d\n",
1219 codec_dai->name); 1264 codec_dai->name, ret);
1220 return ret; 1265 return ret;
1221 } 1266 }
1222 } 1267 }
@@ -1236,12 +1281,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1236 1281
1237 ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); 1282 ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
1238 if (ret < 0) 1283 if (ret < 0)
1239 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); 1284 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
1240 1285
1241 /* create the pcm */ 1286 /* create the pcm */
1242 ret = soc_new_pcm(rtd, num); 1287 ret = soc_new_pcm(rtd, num);
1243 if (ret < 0) { 1288 if (ret < 0) {
1244 printk(KERN_ERR "asoc: can't create pcm %s\n", dai_link->stream_name); 1289 pr_err("asoc: can't create pcm %s :%d\n",
1290 dai_link->stream_name, ret);
1245 return ret; 1291 return ret;
1246 } 1292 }
1247 1293
@@ -1274,7 +1320,7 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
1274 1320
1275 ret = soc_ac97_dev_register(rtd->codec); 1321 ret = soc_ac97_dev_register(rtd->codec);
1276 if (ret < 0) { 1322 if (ret < 0) {
1277 printk(KERN_ERR "asoc: AC97 device register failed\n"); 1323 pr_err("asoc: AC97 device register failed:%d\n", ret);
1278 return ret; 1324 return ret;
1279 } 1325 }
1280 1326
@@ -1414,8 +1460,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1414 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1460 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1415 card->owner, 0, &card->snd_card); 1461 card->owner, 0, &card->snd_card);
1416 if (ret < 0) { 1462 if (ret < 0) {
1417 printk(KERN_ERR "asoc: can't create sound card for card %s\n", 1463 pr_err("asoc: can't create sound card for card %s: %d\n",
1418 card->name); 1464 card->name, ret);
1419 mutex_unlock(&card->mutex); 1465 mutex_unlock(&card->mutex);
1420 return; 1466 return;
1421 } 1467 }
@@ -1468,13 +1514,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1468 } 1514 }
1469 } 1515 }
1470 1516
1471 /* We should have a non-codec control add function but we don't */ 1517 snd_soc_dapm_link_dai_widgets(card);
1518
1472 if (card->controls) 1519 if (card->controls)
1473 snd_soc_add_controls(list_first_entry(&card->codec_dev_list, 1520 snd_soc_add_card_controls(card, card->controls, card->num_controls);
1474 struct snd_soc_codec,
1475 card_list),
1476 card->controls,
1477 card->num_controls);
1478 1521
1479 if (card->dapm_routes) 1522 if (card->dapm_routes)
1480 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1523 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
@@ -1488,14 +1531,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1488 if (dai_link->dai_fmt) { 1531 if (dai_link->dai_fmt) {
1489 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, 1532 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
1490 dai_link->dai_fmt); 1533 dai_link->dai_fmt);
1491 if (ret != 0) 1534 if (ret != 0 && ret != -ENOTSUPP)
1492 dev_warn(card->rtd[i].codec_dai->dev, 1535 dev_warn(card->rtd[i].codec_dai->dev,
1493 "Failed to set DAI format: %d\n", 1536 "Failed to set DAI format: %d\n",
1494 ret); 1537 ret);
1495 1538
1496 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, 1539 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1497 dai_link->dai_fmt); 1540 dai_link->dai_fmt);
1498 if (ret != 0) 1541 if (ret != 0 && ret != -ENOTSUPP)
1499 dev_warn(card->rtd[i].cpu_dai->dev, 1542 dev_warn(card->rtd[i].cpu_dai->dev,
1500 "Failed to set DAI format: %d\n", 1543 "Failed to set DAI format: %d\n",
1501 ret); 1544 ret);
@@ -1538,7 +1581,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1538 1581
1539 ret = snd_card_register(card->snd_card); 1582 ret = snd_card_register(card->snd_card);
1540 if (ret < 0) { 1583 if (ret < 0) {
1541 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1584 pr_err("asoc: failed to register soundcard for %s: %d\n",
1585 card->name, ret);
1542 goto probe_aux_dev_err; 1586 goto probe_aux_dev_err;
1543 } 1587 }
1544 1588
@@ -1547,7 +1591,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1547 for (i = 0; i < card->num_rtd; i++) { 1591 for (i = 0; i < card->num_rtd; i++) {
1548 ret = soc_register_ac97_dai_link(&card->rtd[i]); 1592 ret = soc_register_ac97_dai_link(&card->rtd[i]);
1549 if (ret < 0) { 1593 if (ret < 0) {
1550 printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); 1594 pr_err("asoc: failed to register AC97 %s: %d\n",
1595 card->name, ret);
1551 while (--i >= 0) 1596 while (--i >= 0)
1552 soc_unregister_ac97_dai_link(card->rtd[i].codec); 1597 soc_unregister_ac97_dai_link(card->rtd[i].codec);
1553 goto probe_aux_dev_err; 1598 goto probe_aux_dev_err;
@@ -1600,6 +1645,10 @@ static int soc_probe(struct platform_device *pdev)
1600 if (!card) 1645 if (!card)
1601 return -EINVAL; 1646 return -EINVAL;
1602 1647
1648 dev_warn(&pdev->dev,
1649 "ASoC machine %s should use snd_soc_register_card()\n",
1650 card->name);
1651
1603 /* Bodge while we unpick instantiation */ 1652 /* Bodge while we unpick instantiation */
1604 card->dev = &pdev->dev; 1653 card->dev = &pdev->dev;
1605 1654
@@ -1637,7 +1686,6 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1637 1686
1638 snd_soc_dapm_free(&card->dapm); 1687 snd_soc_dapm_free(&card->dapm);
1639 1688
1640 kfree(card->rtd);
1641 snd_card_free(card->snd_card); 1689 snd_card_free(card->snd_card);
1642 return 0; 1690 return 0;
1643 1691
@@ -1676,7 +1724,10 @@ EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1676const struct dev_pm_ops snd_soc_pm_ops = { 1724const struct dev_pm_ops snd_soc_pm_ops = {
1677 .suspend = snd_soc_suspend, 1725 .suspend = snd_soc_suspend,
1678 .resume = snd_soc_resume, 1726 .resume = snd_soc_resume,
1727 .freeze = snd_soc_suspend,
1728 .thaw = snd_soc_resume,
1679 .poweroff = snd_soc_poweroff, 1729 .poweroff = snd_soc_poweroff,
1730 .restore = snd_soc_resume,
1680}; 1731};
1681EXPORT_SYMBOL_GPL(snd_soc_pm_ops); 1732EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
1682 1733
@@ -1880,23 +1931,28 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
1880int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 1931int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1881 unsigned int mask, unsigned int value) 1932 unsigned int mask, unsigned int value)
1882{ 1933{
1883 int change; 1934 bool change;
1884 unsigned int old, new; 1935 unsigned int old, new;
1885 int ret; 1936 int ret;
1886 1937
1887 ret = snd_soc_read(codec, reg); 1938 if (codec->using_regmap) {
1888 if (ret < 0) 1939 ret = regmap_update_bits_check(codec->control_data, reg,
1889 return ret; 1940 mask, value, &change);
1890 1941 } else {
1891 old = ret; 1942 ret = snd_soc_read(codec, reg);
1892 new = (old & ~mask) | (value & mask);
1893 change = old != new;
1894 if (change) {
1895 ret = snd_soc_write(codec, reg, new);
1896 if (ret < 0) 1943 if (ret < 0)
1897 return ret; 1944 return ret;
1945
1946 old = ret;
1947 new = (old & ~mask) | (value & mask);
1948 change = old != new;
1949 if (change)
1950 ret = snd_soc_write(codec, reg, new);
1898 } 1951 }
1899 1952
1953 if (ret < 0)
1954 return ret;
1955
1900 return change; 1956 return change;
1901} 1957}
1902EXPORT_SYMBOL_GPL(snd_soc_update_bits); 1958EXPORT_SYMBOL_GPL(snd_soc_update_bits);
@@ -1987,7 +2043,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
1987 * Returns 0 for success, else error. 2043 * Returns 0 for success, else error.
1988 */ 2044 */
1989struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2045struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
1990 void *data, char *long_name, 2046 void *data, const char *long_name,
1991 const char *prefix) 2047 const char *prefix)
1992{ 2048{
1993 struct snd_kcontrol_new template; 2049 struct snd_kcontrol_new template;
@@ -2022,9 +2078,28 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2022} 2078}
2023EXPORT_SYMBOL_GPL(snd_soc_cnew); 2079EXPORT_SYMBOL_GPL(snd_soc_cnew);
2024 2080
2081static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
2082 const struct snd_kcontrol_new *controls, int num_controls,
2083 const char *prefix, void *data)
2084{
2085 int err, i;
2086
2087 for (i = 0; i < num_controls; i++) {
2088 const struct snd_kcontrol_new *control = &controls[i];
2089 err = snd_ctl_add(card, snd_soc_cnew(control, data,
2090 control->name, prefix));
2091 if (err < 0) {
2092 dev_err(dev, "Failed to add %s: %d\n", control->name, err);
2093 return err;
2094 }
2095 }
2096
2097 return 0;
2098}
2099
2025/** 2100/**
2026 * snd_soc_add_controls - add an array of controls to a codec. 2101 * snd_soc_add_codec_controls - add an array of controls to a codec.
2027 * Convienience function to add a list of controls. Many codecs were 2102 * Convenience function to add a list of controls. Many codecs were
2028 * duplicating this code. 2103 * duplicating this code.
2029 * 2104 *
2030 * @codec: codec to add controls to 2105 * @codec: codec to add controls to
@@ -2033,31 +2108,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew);
2033 * 2108 *
2034 * Return 0 for success, else error. 2109 * Return 0 for success, else error.
2035 */ 2110 */
2036int snd_soc_add_controls(struct snd_soc_codec *codec, 2111int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
2037 const struct snd_kcontrol_new *controls, int num_controls) 2112 const struct snd_kcontrol_new *controls, int num_controls)
2038{ 2113{
2039 struct snd_card *card = codec->card->snd_card; 2114 struct snd_card *card = codec->card->snd_card;
2040 int err, i;
2041
2042 for (i = 0; i < num_controls; i++) {
2043 const struct snd_kcontrol_new *control = &controls[i];
2044 err = snd_ctl_add(card, snd_soc_cnew(control, codec,
2045 control->name,
2046 codec->name_prefix));
2047 if (err < 0) {
2048 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2049 codec->name, control->name, err);
2050 return err;
2051 }
2052 }
2053 2115
2054 return 0; 2116 return snd_soc_add_controls(card, codec->dev, controls, num_controls,
2117 codec->name_prefix, codec);
2055} 2118}
2056EXPORT_SYMBOL_GPL(snd_soc_add_controls); 2119EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
2057 2120
2058/** 2121/**
2059 * snd_soc_add_platform_controls - add an array of controls to a platform. 2122 * snd_soc_add_platform_controls - add an array of controls to a platform.
2060 * Convienience function to add a list of controls. 2123 * Convenience function to add a list of controls.
2061 * 2124 *
2062 * @platform: platform to add controls to 2125 * @platform: platform to add controls to
2063 * @controls: array of controls to add 2126 * @controls: array of controls to add
@@ -2069,23 +2132,53 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
2069 const struct snd_kcontrol_new *controls, int num_controls) 2132 const struct snd_kcontrol_new *controls, int num_controls)
2070{ 2133{
2071 struct snd_card *card = platform->card->snd_card; 2134 struct snd_card *card = platform->card->snd_card;
2072 int err, i;
2073
2074 for (i = 0; i < num_controls; i++) {
2075 const struct snd_kcontrol_new *control = &controls[i];
2076 err = snd_ctl_add(card, snd_soc_cnew(control, platform,
2077 control->name, NULL));
2078 if (err < 0) {
2079 dev_err(platform->dev, "Failed to add %s %d\n",control->name, err);
2080 return err;
2081 }
2082 }
2083 2135
2084 return 0; 2136 return snd_soc_add_controls(card, platform->dev, controls, num_controls,
2137 NULL, platform);
2085} 2138}
2086EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); 2139EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
2087 2140
2088/** 2141/**
2142 * snd_soc_add_card_controls - add an array of controls to a SoC card.
2143 * Convenience function to add a list of controls.
2144 *
2145 * @soc_card: SoC card to add controls to
2146 * @controls: array of controls to add
2147 * @num_controls: number of elements in the array
2148 *
2149 * Return 0 for success, else error.
2150 */
2151int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
2152 const struct snd_kcontrol_new *controls, int num_controls)
2153{
2154 struct snd_card *card = soc_card->snd_card;
2155
2156 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
2157 NULL, soc_card);
2158}
2159EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
2160
2161/**
2162 * snd_soc_add_dai_controls - add an array of controls to a DAI.
2163 * Convienience function to add a list of controls.
2164 *
2165 * @dai: DAI to add controls to
2166 * @controls: array of controls to add
2167 * @num_controls: number of elements in the array
2168 *
2169 * Return 0 for success, else error.
2170 */
2171int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
2172 const struct snd_kcontrol_new *controls, int num_controls)
2173{
2174 struct snd_card *card = dai->card->snd_card;
2175
2176 return snd_soc_add_controls(card, dai->dev, controls, num_controls,
2177 NULL, dai);
2178}
2179EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
2180
2181/**
2089 * snd_soc_info_enum_double - enumerated double mixer info callback 2182 * snd_soc_info_enum_double - enumerated double mixer info callback
2090 * @kcontrol: mixer control 2183 * @kcontrol: mixer control
2091 * @uinfo: control element information 2184 * @uinfo: control element information
@@ -2651,6 +2744,115 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2651} 2744}
2652EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); 2745EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2653 2746
2747int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2748 struct snd_ctl_elem_info *uinfo)
2749{
2750 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2751 struct soc_bytes *params = (void *)kcontrol->private_value;
2752
2753 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2754 uinfo->count = params->num_regs * codec->val_bytes;
2755
2756 return 0;
2757}
2758EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
2759
2760int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
2761 struct snd_ctl_elem_value *ucontrol)
2762{
2763 struct soc_bytes *params = (void *)kcontrol->private_value;
2764 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2765 int ret;
2766
2767 if (codec->using_regmap)
2768 ret = regmap_raw_read(codec->control_data, params->base,
2769 ucontrol->value.bytes.data,
2770 params->num_regs * codec->val_bytes);
2771 else
2772 ret = -EINVAL;
2773
2774 /* Hide any masked bytes to ensure consistent data reporting */
2775 if (ret == 0 && params->mask) {
2776 switch (codec->val_bytes) {
2777 case 1:
2778 ucontrol->value.bytes.data[0] &= ~params->mask;
2779 break;
2780 case 2:
2781 ((u16 *)(&ucontrol->value.bytes.data))[0]
2782 &= ~params->mask;
2783 break;
2784 case 4:
2785 ((u32 *)(&ucontrol->value.bytes.data))[0]
2786 &= ~params->mask;
2787 break;
2788 default:
2789 return -EINVAL;
2790 }
2791 }
2792
2793 return ret;
2794}
2795EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
2796
2797int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
2798 struct snd_ctl_elem_value *ucontrol)
2799{
2800 struct soc_bytes *params = (void *)kcontrol->private_value;
2801 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2802 int ret, len;
2803 unsigned int val;
2804 void *data;
2805
2806 if (!codec->using_regmap)
2807 return -EINVAL;
2808
2809 data = ucontrol->value.bytes.data;
2810 len = params->num_regs * codec->val_bytes;
2811
2812 /*
2813 * If we've got a mask then we need to preserve the register
2814 * bits. We shouldn't modify the incoming data so take a
2815 * copy.
2816 */
2817 if (params->mask) {
2818 ret = regmap_read(codec->control_data, params->base, &val);
2819 if (ret != 0)
2820 return ret;
2821
2822 val &= params->mask;
2823
2824 data = kmemdup(data, len, GFP_KERNEL);
2825 if (!data)
2826 return -ENOMEM;
2827
2828 switch (codec->val_bytes) {
2829 case 1:
2830 ((u8 *)data)[0] &= ~params->mask;
2831 ((u8 *)data)[0] |= val;
2832 break;
2833 case 2:
2834 ((u16 *)data)[0] &= cpu_to_be16(~params->mask);
2835 ((u16 *)data)[0] |= cpu_to_be16(val);
2836 break;
2837 case 4:
2838 ((u32 *)data)[0] &= cpu_to_be32(~params->mask);
2839 ((u32 *)data)[0] |= cpu_to_be32(val);
2840 break;
2841 default:
2842 return -EINVAL;
2843 }
2844 }
2845
2846 ret = regmap_raw_write(codec->control_data, params->base,
2847 data, len);
2848
2849 if (params->mask)
2850 kfree(data);
2851
2852 return ret;
2853}
2854EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
2855
2654/** 2856/**
2655 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2857 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2656 * @dai: DAI 2858 * @dai: DAI
@@ -2768,10 +2970,11 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
2768 */ 2970 */
2769int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2971int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2770{ 2972{
2771 if (dai->driver && dai->driver->ops->set_fmt) 2973 if (dai->driver == NULL)
2772 return dai->driver->ops->set_fmt(dai, fmt);
2773 else
2774 return -EINVAL; 2974 return -EINVAL;
2975 if (dai->driver->ops->set_fmt == NULL)
2976 return -ENOTSUPP;
2977 return dai->driver->ops->set_fmt(dai, fmt);
2775} 2978}
2776EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); 2979EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2777 2980
@@ -2875,7 +3078,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
2875 */ 3078 */
2876 if (!!link->codec_name == !!link->codec_of_node) { 3079 if (!!link->codec_name == !!link->codec_of_node) {
2877 dev_err(card->dev, 3080 dev_err(card->dev,
2878 "Neither/both codec name/of_node are set\n"); 3081 "Neither/both codec name/of_node are set for %s\n",
3082 link->name);
2879 return -EINVAL; 3083 return -EINVAL;
2880 } 3084 }
2881 3085
@@ -2885,7 +3089,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2885 */ 3089 */
2886 if (link->platform_name && link->platform_of_node) { 3090 if (link->platform_name && link->platform_of_node) {
2887 dev_err(card->dev, 3091 dev_err(card->dev,
2888 "Both platform name/of_node are set\n"); 3092 "Both platform name/of_node are set for %s\n", link->name);
2889 return -EINVAL; 3093 return -EINVAL;
2890 } 3094 }
2891 3095
@@ -2895,7 +3099,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
2895 */ 3099 */
2896 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { 3100 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
2897 dev_err(card->dev, 3101 dev_err(card->dev,
2898 "Neither/both cpu_dai name/of_node are set\n"); 3102 "Neither/both cpu_dai name/of_node are set for %s\n",
3103 link->name);
2899 return -EINVAL; 3104 return -EINVAL;
2900 } 3105 }
2901 } 3106 }
@@ -2906,9 +3111,10 @@ int snd_soc_register_card(struct snd_soc_card *card)
2906 3111
2907 soc_init_card_debugfs(card); 3112 soc_init_card_debugfs(card);
2908 3113
2909 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * 3114 card->rtd = devm_kzalloc(card->dev,
2910 (card->num_links + card->num_aux_devs), 3115 sizeof(struct snd_soc_pcm_runtime) *
2911 GFP_KERNEL); 3116 (card->num_links + card->num_aux_devs),
3117 GFP_KERNEL);
2912 if (card->rtd == NULL) 3118 if (card->rtd == NULL)
2913 return -ENOMEM; 3119 return -ENOMEM;
2914 card->rtd_aux = &card->rtd[card->num_links]; 3120 card->rtd_aux = &card->rtd[card->num_links];
@@ -3002,7 +3208,7 @@ static inline char *fmt_multiple_name(struct device *dev,
3002 struct snd_soc_dai_driver *dai_drv) 3208 struct snd_soc_dai_driver *dai_drv)
3003{ 3209{
3004 if (dai_drv->name == NULL) { 3210 if (dai_drv->name == NULL) {
3005 printk(KERN_ERR "asoc: error - multiple DAI %s registered with no name\n", 3211 pr_err("asoc: error - multiple DAI %s registered with no name\n",
3006 dev_name(dev)); 3212 dev_name(dev));
3007 return NULL; 3213 return NULL;
3008 } 3214 }
@@ -3177,6 +3383,7 @@ int snd_soc_register_platform(struct device *dev,
3177 platform->dapm.dev = dev; 3383 platform->dapm.dev = dev;
3178 platform->dapm.platform = platform; 3384 platform->dapm.platform = platform;
3179 platform->dapm.stream_event = platform_drv->stream_event; 3385 platform->dapm.stream_event = platform_drv->stream_event;
3386 mutex_init(&platform->mutex);
3180 3387
3181 mutex_lock(&client_mutex); 3388 mutex_lock(&client_mutex);
3182 list_add(&platform->list, &platform_list); 3389 list_add(&platform->list, &platform_list);
@@ -3285,6 +3492,7 @@ int snd_soc_register_codec(struct device *dev,
3285 codec->volatile_register = codec_drv->volatile_register; 3492 codec->volatile_register = codec_drv->volatile_register;
3286 codec->readable_register = codec_drv->readable_register; 3493 codec->readable_register = codec_drv->readable_register;
3287 codec->writable_register = codec_drv->writable_register; 3494 codec->writable_register = codec_drv->writable_register;
3495 codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time;
3288 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3496 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3289 codec->dapm.dev = dev; 3497 codec->dapm.dev = dev;
3290 codec->dapm.codec = codec; 3498 codec->dapm.codec = codec;
@@ -3473,8 +3681,7 @@ static int __init snd_soc_init(void)
3473#ifdef CONFIG_DEBUG_FS 3681#ifdef CONFIG_DEBUG_FS
3474 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); 3682 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3475 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { 3683 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3476 printk(KERN_WARNING 3684 pr_warn("ASoC: Failed to create debugfs directory\n");
3477 "ASoC: Failed to create debugfs directory\n");
3478 snd_soc_debugfs_root = NULL; 3685 snd_soc_debugfs_root = NULL;
3479 } 3686 }
3480 3687
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1315663c1c09..6241490fff30 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -14,19 +14,13 @@
14 * dynamic configuration of codec internal audio paths and active 14 * dynamic configuration of codec internal audio paths and active
15 * DACs/ADCs. 15 * DACs/ADCs.
16 * o Platform power domain - can support external components i.e. amps and 16 * o Platform power domain - can support external components i.e. amps and
17 * mic/meadphone insertion events. 17 * mic/headphone insertion events.
18 * o Automatic Mic Bias support 18 * o Automatic Mic Bias support
19 * o Jack insertion power event initiation - e.g. hp insertion will enable 19 * o Jack insertion power event initiation - e.g. hp insertion will enable
20 * sinks, dacs, etc 20 * sinks, dacs, etc
21 * o Delayed powerdown of audio susbsystem to reduce pops between a quick 21 * o Delayed power down of audio subsystem to reduce pops between a quick
22 * device reopen. 22 * device reopen.
23 * 23 *
24 * Todo:
25 * o DAPM power change sequencing - allow for configurable per
26 * codec sequences.
27 * o Support for analogue bias optimisation.
28 * o Support for reduced codec oversampling rates.
29 * o Support for reduced codec bias currents.
30 */ 24 */
31 25
32#include <linux/module.h> 26#include <linux/module.h>
@@ -40,6 +34,7 @@
40#include <linux/jiffies.h> 34#include <linux/jiffies.h>
41#include <linux/debugfs.h> 35#include <linux/debugfs.h>
42#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/regulator/consumer.h>
43#include <linux/slab.h> 38#include <linux/slab.h>
44#include <sound/core.h> 39#include <sound/core.h>
45#include <sound/pcm.h> 40#include <sound/pcm.h>
@@ -55,7 +50,9 @@
55static int dapm_up_seq[] = { 50static int dapm_up_seq[] = {
56 [snd_soc_dapm_pre] = 0, 51 [snd_soc_dapm_pre] = 0,
57 [snd_soc_dapm_supply] = 1, 52 [snd_soc_dapm_supply] = 1,
53 [snd_soc_dapm_regulator_supply] = 1,
58 [snd_soc_dapm_micbias] = 2, 54 [snd_soc_dapm_micbias] = 2,
55 [snd_soc_dapm_dai] = 3,
59 [snd_soc_dapm_aif_in] = 3, 56 [snd_soc_dapm_aif_in] = 3,
60 [snd_soc_dapm_aif_out] = 3, 57 [snd_soc_dapm_aif_out] = 3,
61 [snd_soc_dapm_mic] = 4, 58 [snd_soc_dapm_mic] = 4,
@@ -90,6 +87,8 @@ static int dapm_down_seq[] = {
90 [snd_soc_dapm_value_mux] = 9, 87 [snd_soc_dapm_value_mux] = 9,
91 [snd_soc_dapm_aif_in] = 10, 88 [snd_soc_dapm_aif_in] = 10,
92 [snd_soc_dapm_aif_out] = 10, 89 [snd_soc_dapm_aif_out] = 10,
90 [snd_soc_dapm_dai] = 10,
91 [snd_soc_dapm_regulator_supply] = 11,
93 [snd_soc_dapm_supply] = 11, 92 [snd_soc_dapm_supply] = 11,
94 [snd_soc_dapm_post] = 12, 93 [snd_soc_dapm_post] = 12,
95}; 94};
@@ -172,6 +171,19 @@ static inline struct snd_soc_card *dapm_get_soc_card(
172 return NULL; 171 return NULL;
173} 172}
174 173
174static void dapm_reset(struct snd_soc_card *card)
175{
176 struct snd_soc_dapm_widget *w;
177
178 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
179
180 list_for_each_entry(w, &card->widgets, list) {
181 w->power_checked = false;
182 w->inputs = -1;
183 w->outputs = -1;
184 }
185}
186
175static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) 187static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
176{ 188{
177 if (w->codec) 189 if (w->codec)
@@ -197,21 +209,28 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
197static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, 209static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
198 unsigned short reg, unsigned int mask, unsigned int value) 210 unsigned short reg, unsigned int mask, unsigned int value)
199{ 211{
200 int change; 212 bool change;
201 unsigned int old, new; 213 unsigned int old, new;
202 int ret; 214 int ret;
203 215
204 ret = soc_widget_read(w, reg); 216 if (w->codec && w->codec->using_regmap) {
205 if (ret < 0) 217 ret = regmap_update_bits_check(w->codec->control_data,
206 return ret; 218 reg, mask, value, &change);
207 219 if (ret != 0)
208 old = ret; 220 return ret;
209 new = (old & ~mask) | (value & mask); 221 } else {
210 change = old != new; 222 ret = soc_widget_read(w, reg);
211 if (change) {
212 ret = soc_widget_write(w, reg, new);
213 if (ret < 0) 223 if (ret < 0)
214 return ret; 224 return ret;
225
226 old = ret;
227 new = (old & ~mask) | (value & mask);
228 change = old != new;
229 if (change) {
230 ret = soc_widget_write(w, reg, new);
231 if (ret < 0)
232 return ret;
233 }
215 } 234 }
216 235
217 return change; 236 return change;
@@ -345,8 +364,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
345 case snd_soc_dapm_micbias: 364 case snd_soc_dapm_micbias:
346 case snd_soc_dapm_vmid: 365 case snd_soc_dapm_vmid:
347 case snd_soc_dapm_supply: 366 case snd_soc_dapm_supply:
367 case snd_soc_dapm_regulator_supply:
348 case snd_soc_dapm_aif_in: 368 case snd_soc_dapm_aif_in:
349 case snd_soc_dapm_aif_out: 369 case snd_soc_dapm_aif_out:
370 case snd_soc_dapm_dai:
350 case snd_soc_dapm_hp: 371 case snd_soc_dapm_hp:
351 case snd_soc_dapm_mic: 372 case snd_soc_dapm_mic:
352 case snd_soc_dapm_spk: 373 case snd_soc_dapm_spk:
@@ -504,17 +525,17 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
504 * for widgets so cut the prefix off 525 * for widgets so cut the prefix off
505 * the front of the widget name. 526 * the front of the widget name.
506 */ 527 */
507 snprintf(path->long_name, name_len, "%s %s", 528 snprintf((char *)path->long_name, name_len,
508 w->name + prefix_len, 529 "%s %s", w->name + prefix_len,
509 w->kcontrol_news[i].name); 530 w->kcontrol_news[i].name);
510 break; 531 break;
511 case snd_soc_dapm_mixer_named_ctl: 532 case snd_soc_dapm_mixer_named_ctl:
512 snprintf(path->long_name, name_len, "%s", 533 snprintf((char *)path->long_name, name_len,
513 w->kcontrol_news[i].name); 534 "%s", w->kcontrol_news[i].name);
514 break; 535 break;
515 } 536 }
516 537
517 path->long_name[name_len - 1] = '\0'; 538 ((char *)path->long_name)[name_len - 1] = '\0';
518 539
519 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], 540 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
520 wlist, path->long_name, 541 wlist, path->long_name,
@@ -548,7 +569,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
548 struct snd_soc_dapm_widget_list *wlist; 569 struct snd_soc_dapm_widget_list *wlist;
549 int shared, wlistentries; 570 int shared, wlistentries;
550 size_t wlistsize; 571 size_t wlistsize;
551 char *name; 572 const char *name;
552 573
553 if (w->num_kcontrols != 1) { 574 if (w->num_kcontrols != 1) {
554 dev_err(dapm->dev, 575 dev_err(dapm->dev,
@@ -673,12 +694,18 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
673 694
674 DAPM_UPDATE_STAT(widget, path_checks); 695 DAPM_UPDATE_STAT(widget, path_checks);
675 696
676 if (widget->id == snd_soc_dapm_supply) 697 switch (widget->id) {
698 case snd_soc_dapm_supply:
699 case snd_soc_dapm_regulator_supply:
677 return 0; 700 return 0;
701 default:
702 break;
703 }
678 704
679 switch (widget->id) { 705 switch (widget->id) {
680 case snd_soc_dapm_adc: 706 case snd_soc_dapm_adc:
681 case snd_soc_dapm_aif_out: 707 case snd_soc_dapm_aif_out:
708 case snd_soc_dapm_dai:
682 if (widget->active) { 709 if (widget->active) {
683 widget->outputs = snd_soc_dapm_suspend_check(widget); 710 widget->outputs = snd_soc_dapm_suspend_check(widget);
684 return widget->outputs; 711 return widget->outputs;
@@ -738,13 +765,19 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
738 765
739 DAPM_UPDATE_STAT(widget, path_checks); 766 DAPM_UPDATE_STAT(widget, path_checks);
740 767
741 if (widget->id == snd_soc_dapm_supply) 768 switch (widget->id) {
769 case snd_soc_dapm_supply:
770 case snd_soc_dapm_regulator_supply:
742 return 0; 771 return 0;
772 default:
773 break;
774 }
743 775
744 /* active stream ? */ 776 /* active stream ? */
745 switch (widget->id) { 777 switch (widget->id) {
746 case snd_soc_dapm_dac: 778 case snd_soc_dapm_dac:
747 case snd_soc_dapm_aif_in: 779 case snd_soc_dapm_aif_in:
780 case snd_soc_dapm_dai:
748 if (widget->active) { 781 if (widget->active) {
749 widget->inputs = snd_soc_dapm_suspend_check(widget); 782 widget->inputs = snd_soc_dapm_suspend_check(widget);
750 return widget->inputs; 783 return widget->inputs;
@@ -821,6 +854,19 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
821} 854}
822EXPORT_SYMBOL_GPL(dapm_reg_event); 855EXPORT_SYMBOL_GPL(dapm_reg_event);
823 856
857/*
858 * Handler for regulator supply widget.
859 */
860int dapm_regulator_event(struct snd_soc_dapm_widget *w,
861 struct snd_kcontrol *kcontrol, int event)
862{
863 if (SND_SOC_DAPM_EVENT_ON(event))
864 return regulator_enable(w->priv);
865 else
866 return regulator_disable_deferred(w->priv, w->shift);
867}
868EXPORT_SYMBOL_GPL(dapm_regulator_event);
869
824static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) 870static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
825{ 871{
826 if (w->power_checked) 872 if (w->power_checked)
@@ -851,6 +897,13 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
851 return out != 0 && in != 0; 897 return out != 0 && in != 0;
852} 898}
853 899
900static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
901{
902 DAPM_UPDATE_STAT(w, power_checks);
903
904 return w->active;
905}
906
854/* Check to see if an ADC has power */ 907/* Check to see if an ADC has power */
855static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 908static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
856{ 909{
@@ -1251,7 +1304,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1251 dev_err(d->dev, "Failed to turn off bias: %d\n", ret); 1304 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1252 1305
1253 if (d->dev) 1306 if (d->dev)
1254 pm_runtime_put_sync(d->dev); 1307 pm_runtime_put(d->dev);
1255 } 1308 }
1256 1309
1257 /* If we just powered up then move to active bias */ 1310 /* If we just powered up then move to active bias */
@@ -1301,6 +1354,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1301 } 1354 }
1302 switch (w->id) { 1355 switch (w->id) {
1303 case snd_soc_dapm_supply: 1356 case snd_soc_dapm_supply:
1357 case snd_soc_dapm_regulator_supply:
1304 /* Supplies can't affect their outputs, only their inputs */ 1358 /* Supplies can't affect their outputs, only their inputs */
1305 break; 1359 break;
1306 default: 1360 default:
@@ -1373,13 +1427,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1373 } 1427 }
1374 } 1428 }
1375 1429
1376 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 1430 dapm_reset(card);
1377
1378 list_for_each_entry(w, &card->widgets, list) {
1379 w->power_checked = false;
1380 w->inputs = -1;
1381 w->outputs = -1;
1382 }
1383 1431
1384 /* Check which widgets we need to power and store them in 1432 /* Check which widgets we need to power and store them in
1385 * lists indicating if they should be powered up or down. We 1433 * lists indicating if they should be powered up or down. We
@@ -1400,10 +1448,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1400 /* Supplies and micbiases only bring the 1448 /* Supplies and micbiases only bring the
1401 * context up to STANDBY as unless something 1449 * context up to STANDBY as unless something
1402 * else is active and passing audio they 1450 * else is active and passing audio they
1403 * generally don't require full power. 1451 * generally don't require full power. Signal
1452 * generators are virtual pins and have no
1453 * power impact themselves.
1404 */ 1454 */
1405 switch (w->id) { 1455 switch (w->id) {
1456 case snd_soc_dapm_siggen:
1457 break;
1406 case snd_soc_dapm_supply: 1458 case snd_soc_dapm_supply:
1459 case snd_soc_dapm_regulator_supply:
1407 case snd_soc_dapm_micbias: 1460 case snd_soc_dapm_micbias:
1408 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1461 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1409 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1462 d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1475,6 +1528,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1475 &async_domain); 1528 &async_domain);
1476 async_synchronize_full_domain(&async_domain); 1529 async_synchronize_full_domain(&async_domain);
1477 1530
1531 /* do we need to notify any clients that DAPM event is complete */
1532 list_for_each_entry(d, &card->dapm_list, list) {
1533 if (d->stream_event)
1534 d->stream_event(d, event);
1535 }
1536
1478 pop_dbg(dapm->dev, card->pop_time, 1537 pop_dbg(dapm->dev, card->pop_time,
1479 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1538 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
1480 pop_wait(card->pop_time); 1539 pop_wait(card->pop_time);
@@ -1510,8 +1569,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1510 out = is_connected_output_ep(w); 1569 out = is_connected_output_ep(w);
1511 dapm_clear_walk(w->dapm); 1570 dapm_clear_walk(w->dapm);
1512 1571
1513 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", 1572 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1514 w->name, w->power ? "On" : "Off", in, out); 1573 w->name, w->power ? "On" : "Off",
1574 w->force ? " (forced)" : "", in, out);
1515 1575
1516 if (w->reg >= 0) 1576 if (w->reg >= 0)
1517 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1577 ret += snprintf(buf + ret, PAGE_SIZE - ret,
@@ -1607,7 +1667,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1607 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 1667 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1608 1668
1609 if (!dapm->debugfs_dapm) { 1669 if (!dapm->debugfs_dapm) {
1610 printk(KERN_WARNING 1670 dev_warn(dapm->dev,
1611 "Failed to create DAPM debugfs directory\n"); 1671 "Failed to create DAPM debugfs directory\n");
1612 return; 1672 return;
1613 } 1673 }
@@ -1659,9 +1719,8 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1659#endif 1719#endif
1660 1720
1661/* test and update the power status of a mux widget */ 1721/* test and update the power status of a mux widget */
1662static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1722int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1663 struct snd_kcontrol *kcontrol, int change, 1723 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1664 int mux, struct soc_enum *e)
1665{ 1724{
1666 struct snd_soc_dapm_path *path; 1725 struct snd_soc_dapm_path *path;
1667 int found = 0; 1726 int found = 0;
@@ -1671,9 +1730,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1671 widget->id != snd_soc_dapm_value_mux) 1730 widget->id != snd_soc_dapm_value_mux)
1672 return -ENODEV; 1731 return -ENODEV;
1673 1732
1674 if (!change)
1675 return 0;
1676
1677 /* find dapm widget path assoc with kcontrol */ 1733 /* find dapm widget path assoc with kcontrol */
1678 list_for_each_entry(path, &widget->dapm->card->paths, list) { 1734 list_for_each_entry(path, &widget->dapm->card->paths, list) {
1679 if (path->kcontrol != kcontrol) 1735 if (path->kcontrol != kcontrol)
@@ -1702,9 +1758,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1702 1758
1703 return 0; 1759 return 0;
1704} 1760}
1761EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
1705 1762
1706/* test and update the power status of a mixer or switch widget */ 1763/* test and update the power status of a mixer or switch widget */
1707static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1764int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1708 struct snd_kcontrol *kcontrol, int connect) 1765 struct snd_kcontrol *kcontrol, int connect)
1709{ 1766{
1710 struct snd_soc_dapm_path *path; 1767 struct snd_soc_dapm_path *path;
@@ -1733,6 +1790,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1733 1790
1734 return 0; 1791 return 0;
1735} 1792}
1793EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
1736 1794
1737/* show dapm widget status in sys fs */ 1795/* show dapm widget status in sys fs */
1738static ssize_t dapm_widget_show(struct device *dev, 1796static ssize_t dapm_widget_show(struct device *dev,
@@ -1762,6 +1820,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1762 case snd_soc_dapm_mixer: 1820 case snd_soc_dapm_mixer:
1763 case snd_soc_dapm_mixer_named_ctl: 1821 case snd_soc_dapm_mixer_named_ctl:
1764 case snd_soc_dapm_supply: 1822 case snd_soc_dapm_supply:
1823 case snd_soc_dapm_regulator_supply:
1765 if (w->name) 1824 if (w->name)
1766 count += sprintf(buf + count, "%s: %s\n", 1825 count += sprintf(buf + count, "%s: %s\n",
1767 w->name, w->power ? "On":"Off"); 1826 w->name, w->power ? "On":"Off");
@@ -1869,10 +1928,12 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1869 return -EINVAL; 1928 return -EINVAL;
1870 } 1929 }
1871 1930
1931 if (w->connected != status)
1932 dapm_mark_dirty(w, "pin configuration");
1933
1872 w->connected = status; 1934 w->connected = status;
1873 if (status == 0) 1935 if (status == 0)
1874 w->force = 0; 1936 w->force = 0;
1875 dapm_mark_dirty(w, "pin configuration");
1876 1937
1877 return 0; 1938 return 0;
1878} 1939}
@@ -2000,8 +2061,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2000 case snd_soc_dapm_pre: 2061 case snd_soc_dapm_pre:
2001 case snd_soc_dapm_post: 2062 case snd_soc_dapm_post:
2002 case snd_soc_dapm_supply: 2063 case snd_soc_dapm_supply:
2064 case snd_soc_dapm_regulator_supply:
2003 case snd_soc_dapm_aif_in: 2065 case snd_soc_dapm_aif_in:
2004 case snd_soc_dapm_aif_out: 2066 case snd_soc_dapm_aif_out:
2067 case snd_soc_dapm_dai:
2005 list_add(&path->list, &dapm->card->paths); 2068 list_add(&path->list, &dapm->card->paths);
2006 list_add(&path->list_sink, &wsink->sources); 2069 list_add(&path->list_sink, &wsink->sources);
2007 list_add(&path->list_source, &wsource->sinks); 2070 list_add(&path->list_source, &wsource->sinks);
@@ -2315,7 +2378,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2315 update.val = val; 2378 update.val = val;
2316 widget->dapm->update = &update; 2379 widget->dapm->update = &update;
2317 2380
2318 dapm_mixer_update_power(widget, kcontrol, connect); 2381 snd_soc_dapm_mixer_update_power(widget, kcontrol, connect);
2319 2382
2320 widget->dapm->update = NULL; 2383 widget->dapm->update = NULL;
2321 } 2384 }
@@ -2406,7 +2469,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2406 update.val = val; 2469 update.val = val;
2407 widget->dapm->update = &update; 2470 widget->dapm->update = &update;
2408 2471
2409 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2472 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2410 2473
2411 widget->dapm->update = NULL; 2474 widget->dapm->update = NULL;
2412 } 2475 }
@@ -2467,8 +2530,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2467 2530
2468 widget->value = ucontrol->value.enumerated.item[0]; 2531 widget->value = ucontrol->value.enumerated.item[0];
2469 2532
2470 dapm_mux_update_power(widget, kcontrol, change, 2533 snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
2471 widget->value, e);
2472 } 2534 }
2473 } 2535 }
2474 2536
@@ -2571,7 +2633,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2571 update.val = val; 2633 update.val = val;
2572 widget->dapm->update = &update; 2634 widget->dapm->update = &update;
2573 2635
2574 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2636 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2575 2637
2576 widget->dapm->update = NULL; 2638 widget->dapm->update = NULL;
2577 } 2639 }
@@ -2611,15 +2673,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
2611int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 2673int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2612 struct snd_ctl_elem_value *ucontrol) 2674 struct snd_ctl_elem_value *ucontrol)
2613{ 2675{
2614 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2676 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2615 const char *pin = (const char *)kcontrol->private_value; 2677 const char *pin = (const char *)kcontrol->private_value;
2616 2678
2617 mutex_lock(&codec->mutex); 2679 mutex_lock(&card->mutex);
2618 2680
2619 ucontrol->value.integer.value[0] = 2681 ucontrol->value.integer.value[0] =
2620 snd_soc_dapm_get_pin_status(&codec->dapm, pin); 2682 snd_soc_dapm_get_pin_status(&card->dapm, pin);
2621 2683
2622 mutex_unlock(&codec->mutex); 2684 mutex_unlock(&card->mutex);
2623 2685
2624 return 0; 2686 return 0;
2625} 2687}
@@ -2634,41 +2696,48 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
2634int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 2696int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2635 struct snd_ctl_elem_value *ucontrol) 2697 struct snd_ctl_elem_value *ucontrol)
2636{ 2698{
2637 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2699 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2638 const char *pin = (const char *)kcontrol->private_value; 2700 const char *pin = (const char *)kcontrol->private_value;
2639 2701
2640 mutex_lock(&codec->mutex); 2702 mutex_lock(&card->mutex);
2641 2703
2642 if (ucontrol->value.integer.value[0]) 2704 if (ucontrol->value.integer.value[0])
2643 snd_soc_dapm_enable_pin(&codec->dapm, pin); 2705 snd_soc_dapm_enable_pin(&card->dapm, pin);
2644 else 2706 else
2645 snd_soc_dapm_disable_pin(&codec->dapm, pin); 2707 snd_soc_dapm_disable_pin(&card->dapm, pin);
2646 2708
2647 snd_soc_dapm_sync(&codec->dapm); 2709 snd_soc_dapm_sync(&card->dapm);
2648 2710
2649 mutex_unlock(&codec->mutex); 2711 mutex_unlock(&card->mutex);
2650 2712
2651 return 0; 2713 return 0;
2652} 2714}
2653EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 2715EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
2654 2716
2655/** 2717static struct snd_soc_dapm_widget *
2656 * snd_soc_dapm_new_control - create new dapm control 2718snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2657 * @dapm: DAPM context 2719 const struct snd_soc_dapm_widget *widget)
2658 * @widget: widget template
2659 *
2660 * Creates a new dapm control based upon the template.
2661 *
2662 * Returns 0 for success else error.
2663 */
2664int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2665 const struct snd_soc_dapm_widget *widget)
2666{ 2720{
2667 struct snd_soc_dapm_widget *w; 2721 struct snd_soc_dapm_widget *w;
2668 size_t name_len; 2722 size_t name_len;
2723 int ret;
2669 2724
2670 if ((w = dapm_cnew_widget(widget)) == NULL) 2725 if ((w = dapm_cnew_widget(widget)) == NULL)
2671 return -ENOMEM; 2726 return NULL;
2727
2728 switch (w->id) {
2729 case snd_soc_dapm_regulator_supply:
2730 w->priv = devm_regulator_get(dapm->dev, w->name);
2731 if (IS_ERR(w->priv)) {
2732 ret = PTR_ERR(w->priv);
2733 dev_err(dapm->dev, "Failed to request %s: %d\n",
2734 w->name, ret);
2735 return NULL;
2736 }
2737 break;
2738 default:
2739 break;
2740 }
2672 2741
2673 name_len = strlen(widget->name) + 1; 2742 name_len = strlen(widget->name) + 1;
2674 if (dapm->codec && dapm->codec->name_prefix) 2743 if (dapm->codec && dapm->codec->name_prefix)
@@ -2676,13 +2745,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2676 w->name = kmalloc(name_len, GFP_KERNEL); 2745 w->name = kmalloc(name_len, GFP_KERNEL);
2677 if (w->name == NULL) { 2746 if (w->name == NULL) {
2678 kfree(w); 2747 kfree(w);
2679 return -ENOMEM; 2748 return NULL;
2680 } 2749 }
2681 if (dapm->codec && dapm->codec->name_prefix) 2750 if (dapm->codec && dapm->codec->name_prefix)
2682 snprintf(w->name, name_len, "%s %s", 2751 snprintf((char *)w->name, name_len, "%s %s",
2683 dapm->codec->name_prefix, widget->name); 2752 dapm->codec->name_prefix, widget->name);
2684 else 2753 else
2685 snprintf(w->name, name_len, "%s", widget->name); 2754 snprintf((char *)w->name, name_len, "%s", widget->name);
2686 2755
2687 switch (w->id) { 2756 switch (w->id) {
2688 case snd_soc_dapm_switch: 2757 case snd_soc_dapm_switch:
@@ -2715,8 +2784,12 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2715 w->power_check = dapm_generic_check_power; 2784 w->power_check = dapm_generic_check_power;
2716 break; 2785 break;
2717 case snd_soc_dapm_supply: 2786 case snd_soc_dapm_supply:
2787 case snd_soc_dapm_regulator_supply:
2718 w->power_check = dapm_supply_check_power; 2788 w->power_check = dapm_supply_check_power;
2719 break; 2789 break;
2790 case snd_soc_dapm_dai:
2791 w->power_check = dapm_dai_check_power;
2792 break;
2720 default: 2793 default:
2721 w->power_check = dapm_always_on_check_power; 2794 w->power_check = dapm_always_on_check_power;
2722 break; 2795 break;
@@ -2734,9 +2807,8 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2734 2807
2735 /* machine layer set ups unconnected pins and insertions */ 2808 /* machine layer set ups unconnected pins and insertions */
2736 w->connected = 1; 2809 w->connected = 1;
2737 return 0; 2810 return w;
2738} 2811}
2739EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
2740 2812
2741/** 2813/**
2742 * snd_soc_dapm_new_controls - create new dapm controls 2814 * snd_soc_dapm_new_controls - create new dapm controls
@@ -2752,15 +2824,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2752 const struct snd_soc_dapm_widget *widget, 2824 const struct snd_soc_dapm_widget *widget,
2753 int num) 2825 int num)
2754{ 2826{
2755 int i, ret; 2827 struct snd_soc_dapm_widget *w;
2828 int i;
2756 2829
2757 for (i = 0; i < num; i++) { 2830 for (i = 0; i < num; i++) {
2758 ret = snd_soc_dapm_new_control(dapm, widget); 2831 w = snd_soc_dapm_new_control(dapm, widget);
2759 if (ret < 0) { 2832 if (!w) {
2760 dev_err(dapm->dev, 2833 dev_err(dapm->dev,
2761 "ASoC: Failed to create DAPM control %s: %d\n", 2834 "ASoC: Failed to create DAPM control %s\n",
2762 widget->name, ret); 2835 widget->name);
2763 return ret; 2836 return -ENOMEM;
2764 } 2837 }
2765 widget++; 2838 widget++;
2766 } 2839 }
@@ -2768,40 +2841,140 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2768} 2841}
2769EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2842EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
2770 2843
2771static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, 2844int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
2772 const char *stream, int event) 2845 struct snd_soc_dai *dai)
2773{ 2846{
2847 struct snd_soc_dapm_widget template;
2774 struct snd_soc_dapm_widget *w; 2848 struct snd_soc_dapm_widget *w;
2775 2849
2776 list_for_each_entry(w, &dapm->card->widgets, list) 2850 WARN_ON(dapm->dev != dai->dev);
2777 { 2851
2778 if (!w->sname || w->dapm != dapm) 2852 memset(&template, 0, sizeof(template));
2853 template.reg = SND_SOC_NOPM;
2854
2855 if (dai->driver->playback.stream_name) {
2856 template.id = snd_soc_dapm_dai;
2857 template.name = dai->driver->playback.stream_name;
2858 template.sname = dai->driver->playback.stream_name;
2859
2860 dev_dbg(dai->dev, "adding %s widget\n",
2861 template.name);
2862
2863 w = snd_soc_dapm_new_control(dapm, &template);
2864 if (!w) {
2865 dev_err(dapm->dev, "Failed to create %s widget\n",
2866 dai->driver->playback.stream_name);
2867 }
2868
2869 w->priv = dai;
2870 dai->playback_widget = w;
2871 }
2872
2873 if (dai->driver->capture.stream_name) {
2874 template.id = snd_soc_dapm_dai;
2875 template.name = dai->driver->capture.stream_name;
2876 template.sname = dai->driver->capture.stream_name;
2877
2878 dev_dbg(dai->dev, "adding %s widget\n",
2879 template.name);
2880
2881 w = snd_soc_dapm_new_control(dapm, &template);
2882 if (!w) {
2883 dev_err(dapm->dev, "Failed to create %s widget\n",
2884 dai->driver->capture.stream_name);
2885 }
2886
2887 w->priv = dai;
2888 dai->capture_widget = w;
2889 }
2890
2891 return 0;
2892}
2893
2894int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
2895{
2896 struct snd_soc_dapm_widget *dai_w, *w;
2897 struct snd_soc_dai *dai;
2898 struct snd_soc_dapm_route r;
2899
2900 memset(&r, 0, sizeof(r));
2901
2902 /* For each DAI widget... */
2903 list_for_each_entry(dai_w, &card->widgets, list) {
2904 if (dai_w->id != snd_soc_dapm_dai)
2779 continue; 2905 continue;
2780 dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2906
2781 w->name, w->sname, stream, event); 2907 dai = dai_w->priv;
2782 if (strstr(w->sname, stream)) { 2908
2783 dapm_mark_dirty(w, "stream event"); 2909 /* ...find all widgets with the same stream and link them */
2784 switch(event) { 2910 list_for_each_entry(w, &card->widgets, list) {
2785 case SND_SOC_DAPM_STREAM_START: 2911 if (w->dapm != dai_w->dapm)
2786 w->active = 1; 2912 continue;
2787 break; 2913
2788 case SND_SOC_DAPM_STREAM_STOP: 2914 if (w->id == snd_soc_dapm_dai)
2789 w->active = 0; 2915 continue;
2790 break; 2916
2791 case SND_SOC_DAPM_STREAM_SUSPEND: 2917 if (!w->sname)
2792 case SND_SOC_DAPM_STREAM_RESUME: 2918 continue;
2793 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2919
2794 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2920 if (dai->driver->playback.stream_name &&
2795 break; 2921 strstr(w->sname,
2922 dai->driver->playback.stream_name)) {
2923 r.source = dai->playback_widget->name;
2924 r.sink = w->name;
2925 dev_dbg(dai->dev, "%s -> %s\n",
2926 r.source, r.sink);
2927
2928 snd_soc_dapm_add_route(w->dapm, &r);
2929 }
2930
2931 if (dai->driver->capture.stream_name &&
2932 strstr(w->sname,
2933 dai->driver->capture.stream_name)) {
2934 r.source = w->name;
2935 r.sink = dai->capture_widget->name;
2936 dev_dbg(dai->dev, "%s -> %s\n",
2937 r.source, r.sink);
2938
2939 snd_soc_dapm_add_route(w->dapm, &r);
2796 } 2940 }
2797 } 2941 }
2798 } 2942 }
2799 2943
2800 dapm_power_widgets(dapm, event); 2944 return 0;
2945}
2801 2946
2802 /* do we need to notify any clients that DAPM stream is complete */ 2947static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2803 if (dapm->stream_event) 2948 int stream, struct snd_soc_dai *dai,
2804 dapm->stream_event(dapm, event); 2949 int event)
2950{
2951 struct snd_soc_dapm_widget *w;
2952
2953 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2954 w = dai->playback_widget;
2955 else
2956 w = dai->capture_widget;
2957
2958 if (!w)
2959 return;
2960
2961 dapm_mark_dirty(w, "stream event");
2962
2963 switch (event) {
2964 case SND_SOC_DAPM_STREAM_START:
2965 w->active = 1;
2966 break;
2967 case SND_SOC_DAPM_STREAM_STOP:
2968 w->active = 0;
2969 break;
2970 case SND_SOC_DAPM_STREAM_SUSPEND:
2971 case SND_SOC_DAPM_STREAM_RESUME:
2972 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2973 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2974 break;
2975 }
2976
2977 dapm_power_widgets(dapm, event);
2805} 2978}
2806 2979
2807/** 2980/**
@@ -2815,16 +2988,13 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2815 * 2988 *
2816 * Returns 0 for success else error. 2989 * Returns 0 for success else error.
2817 */ 2990 */
2818int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, 2991int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2819 const char *stream, int event) 2992 struct snd_soc_dai *dai, int event)
2820{ 2993{
2821 struct snd_soc_codec *codec = rtd->codec; 2994 struct snd_soc_codec *codec = rtd->codec;
2822 2995
2823 if (stream == NULL)
2824 return 0;
2825
2826 mutex_lock(&codec->mutex); 2996 mutex_lock(&codec->mutex);
2827 soc_dapm_stream_event(&codec->dapm, stream, event); 2997 soc_dapm_stream_event(&codec->dapm, stream, dai, event);
2828 mutex_unlock(&codec->mutex); 2998 mutex_unlock(&codec->mutex);
2829 return 0; 2999 return 0;
2830} 3000}
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
new file mode 100644
index 000000000000..4420b7030c83
--- /dev/null
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (C) 2012, Analog Devices Inc.
3 * Author: Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * Based on:
6 * imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
7 * mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc.
8 * ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
9 * Copyright (C) 2006 Applied Data Systems
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/dmaengine.h>
24#include <linux/slab.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <sound/dmaengine_pcm.h>
30
31struct dmaengine_pcm_runtime_data {
32 struct dma_chan *dma_chan;
33
34 unsigned int pos;
35
36 void *data;
37};
38
39static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
40 const struct snd_pcm_substream *substream)
41{
42 return substream->runtime->private_data;
43}
44
45/**
46 * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
47 * @substream: PCM substream
48 * @data: Data to set
49 */
50void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
51{
52 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
53
54 prtd->data = data;
55}
56EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
57
58/**
59 * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
60 * @substream: PCM substream
61 *
62 * Returns the data previously set with snd_dmaengine_pcm_set_data
63 */
64void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
65{
66 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
67
68 return prtd->data;
69}
70EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
71
72struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
73{
74 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
75
76 return prtd->dma_chan;
77}
78EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_chan);
79
80/**
81 * snd_hwparams_to_dma_slave_config - Convert hw_params to dma_slave_config
82 * @substream: PCM substream
83 * @params: hw_params
84 * @slave_config: DMA slave config
85 *
86 * This function can be used to initialize a dma_slave_config from a substream
87 * and hw_params in a dmaengine based PCM driver implementation.
88 */
89int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
90 const struct snd_pcm_hw_params *params,
91 struct dma_slave_config *slave_config)
92{
93 enum dma_slave_buswidth buswidth;
94
95 switch (params_format(params)) {
96 case SNDRV_PCM_FORMAT_S8:
97 buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
98 break;
99 case SNDRV_PCM_FORMAT_S16_LE:
100 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
101 break;
102 case SNDRV_PCM_FORMAT_S18_3LE:
103 case SNDRV_PCM_FORMAT_S20_3LE:
104 case SNDRV_PCM_FORMAT_S24_LE:
105 case SNDRV_PCM_FORMAT_S32_LE:
106 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
107 break;
108 default:
109 return -EINVAL;
110 }
111
112 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
113 slave_config->direction = DMA_MEM_TO_DEV;
114 slave_config->dst_addr_width = buswidth;
115 } else {
116 slave_config->direction = DMA_DEV_TO_MEM;
117 slave_config->src_addr_width = buswidth;
118 }
119
120 return 0;
121}
122EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
123
124static void dmaengine_pcm_dma_complete(void *arg)
125{
126 struct snd_pcm_substream *substream = arg;
127 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
128
129 prtd->pos += snd_pcm_lib_period_bytes(substream);
130 if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
131 prtd->pos = 0;
132
133 snd_pcm_period_elapsed(substream);
134}
135
136static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
137{
138 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
139 struct dma_chan *chan = prtd->dma_chan;
140 struct dma_async_tx_descriptor *desc;
141 enum dma_transfer_direction direction;
142
143 direction = snd_pcm_substream_to_dma_direction(substream);
144
145 prtd->pos = 0;
146 desc = chan->device->device_prep_dma_cyclic(chan,
147 substream->runtime->dma_addr,
148 snd_pcm_lib_buffer_bytes(substream),
149 snd_pcm_lib_period_bytes(substream), direction);
150
151 if (!desc)
152 return -ENOMEM;
153
154 desc->callback = dmaengine_pcm_dma_complete;
155 desc->callback_param = substream;
156 dmaengine_submit(desc);
157
158 return 0;
159}
160
161/**
162 * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
163 * @substream: PCM substream
164 * @cmd: Trigger command
165 *
166 * Returns 0 on success, a negative error code otherwise.
167 *
168 * This function can be used as the PCM trigger callback for dmaengine based PCM
169 * driver implementations.
170 */
171int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
172{
173 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
174 int ret;
175
176 switch (cmd) {
177 case SNDRV_PCM_TRIGGER_START:
178 ret = dmaengine_pcm_prepare_and_submit(substream);
179 if (ret)
180 return ret;
181 dma_async_issue_pending(prtd->dma_chan);
182 break;
183 case SNDRV_PCM_TRIGGER_RESUME:
184 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
185 dmaengine_resume(prtd->dma_chan);
186 break;
187 case SNDRV_PCM_TRIGGER_SUSPEND:
188 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
189 dmaengine_pause(prtd->dma_chan);
190 break;
191 case SNDRV_PCM_TRIGGER_STOP:
192 dmaengine_terminate_all(prtd->dma_chan);
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 return 0;
199}
200EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
201
202/**
203 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
204 * @substream: PCM substream
205 *
206 * This function can be used as the PCM pointer callback for dmaengine based PCM
207 * driver implementations.
208 */
209snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
210{
211 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
212 return bytes_to_frames(substream->runtime, prtd->pos);
213}
214EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
215
216static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd,
217 dma_filter_fn filter_fn, void *filter_data)
218{
219 dma_cap_mask_t mask;
220
221 dma_cap_zero(mask);
222 dma_cap_set(DMA_SLAVE, mask);
223 dma_cap_set(DMA_CYCLIC, mask);
224 prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data);
225
226 if (!prtd->dma_chan)
227 return -ENXIO;
228
229 return 0;
230}
231
232/**
233 * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
234 * @substream: PCM substream
235 * @filter_fn: Filter function used to request the DMA channel
236 * @filter_data: Data passed to the DMA filter function
237 *
238 * Returns 0 on success, a negative error code otherwise.
239 *
240 * This function will request a DMA channel using the passed filter function and
241 * data. The function should usually be called from the pcm open callback.
242 *
243 * Note that this function will use private_data field of the substream's
244 * runtime. So it is not availabe to your pcm driver implementation. If you need
245 * to keep additional data attached to a substream use
246 * snd_dmaeinge_pcm_{set,get}_data.
247 */
248int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
249 dma_filter_fn filter_fn, void *filter_data)
250{
251 struct dmaengine_pcm_runtime_data *prtd;
252 int ret;
253
254 ret = snd_pcm_hw_constraint_integer(substream->runtime,
255 SNDRV_PCM_HW_PARAM_PERIODS);
256 if (ret < 0)
257 return ret;
258
259 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
260 if (!prtd)
261 return -ENOMEM;
262
263 ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data);
264 if (ret < 0) {
265 kfree(prtd);
266 return ret;
267 }
268
269 substream->runtime->private_data = prtd;
270
271 return 0;
272}
273EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open);
274
275/**
276 * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
277 * @substream: PCM substream
278 */
279int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
280{
281 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
282
283 dma_release_channel(prtd->dma_chan);
284 kfree(prtd);
285
286 return 0;
287}
288EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index c8610cbf34a5..4d8dc6a27d4d 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -114,6 +114,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
114 enum snd_soc_control_type control) 114 enum snd_soc_control_type control)
115{ 115{
116 struct regmap_config config; 116 struct regmap_config config;
117 int ret;
117 118
118 memset(&config, 0, sizeof(config)); 119 memset(&config, 0, sizeof(config));
119 codec->write = hw_write; 120 codec->write = hw_write;
@@ -140,6 +141,12 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
140 141
141 case SND_SOC_REGMAP: 142 case SND_SOC_REGMAP:
142 /* Device has made its own regmap arrangements */ 143 /* Device has made its own regmap arrangements */
144 codec->using_regmap = true;
145
146 ret = regmap_get_val_bytes(codec->control_data);
147 /* Errors are legitimate for non-integer byte multiples */
148 if (ret > 0)
149 codec->val_bytes = ret;
143 break; 150 break;
144 151
145 default: 152 default:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index cdc860a5ff37..0ad8dcacd2f3 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -63,6 +63,41 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
63} 63}
64 64
65/* 65/*
66 * List of sample sizes that might go over the bus for parameter
67 * application. There ought to be a wildcard sample size for things
68 * like the DAC/ADC resolution to use but there isn't right now.
69 */
70static int sample_sizes[] = {
71 24, 32,
72};
73
74static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
75 struct snd_soc_dai *dai)
76{
77 int ret, i, bits;
78
79 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
80 bits = dai->driver->playback.sig_bits;
81 else
82 bits = dai->driver->capture.sig_bits;
83
84 if (!bits)
85 return;
86
87 for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) {
88 if (bits >= sample_sizes[i])
89 continue;
90
91 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
92 sample_sizes[i], bits);
93 if (ret != 0)
94 dev_warn(dai->dev,
95 "Failed to set MSB %d/%d: %d\n",
96 bits, sample_sizes[i], ret);
97 }
98}
99
100/*
66 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 101 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
67 * then initialized and any private data can be allocated. This also calls 102 * then initialized and any private data can be allocated. This also calls
68 * startup for the cpu DAI, platform, machine and codec DAI. 103 * startup for the cpu DAI, platform, machine and codec DAI.
@@ -88,8 +123,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
88 if (cpu_dai->driver->ops->startup) { 123 if (cpu_dai->driver->ops->startup) {
89 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 124 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
90 if (ret < 0) { 125 if (ret < 0) {
91 printk(KERN_ERR "asoc: can't open interface %s\n", 126 dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
92 cpu_dai->name); 127 cpu_dai->name, ret);
93 goto out; 128 goto out;
94 } 129 }
95 } 130 }
@@ -97,7 +132,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
97 if (platform->driver->ops && platform->driver->ops->open) { 132 if (platform->driver->ops && platform->driver->ops->open) {
98 ret = platform->driver->ops->open(substream); 133 ret = platform->driver->ops->open(substream);
99 if (ret < 0) { 134 if (ret < 0) {
100 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 135 dev_err(platform->dev, "can't open platform %s: %d\n",
136 platform->name, ret);
101 goto platform_err; 137 goto platform_err;
102 } 138 }
103 } 139 }
@@ -105,8 +141,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
105 if (codec_dai->driver->ops->startup) { 141 if (codec_dai->driver->ops->startup) {
106 ret = codec_dai->driver->ops->startup(substream, codec_dai); 142 ret = codec_dai->driver->ops->startup(substream, codec_dai);
107 if (ret < 0) { 143 if (ret < 0) {
108 printk(KERN_ERR "asoc: can't open codec %s\n", 144 dev_err(codec_dai->dev, "can't open codec %s: %d\n",
109 codec_dai->name); 145 codec_dai->name, ret);
110 goto codec_dai_err; 146 goto codec_dai_err;
111 } 147 }
112 } 148 }
@@ -114,7 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
114 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { 150 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
115 ret = rtd->dai_link->ops->startup(substream); 151 ret = rtd->dai_link->ops->startup(substream);
116 if (ret < 0) { 152 if (ret < 0) {
117 printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name); 153 pr_err("asoc: %s startup failed: %d\n",
154 rtd->dai_link->name, ret);
118 goto machine_err; 155 goto machine_err;
119 } 156 }
120 } 157 }
@@ -187,6 +224,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
187 goto config_err; 224 goto config_err;
188 } 225 }
189 226
227 soc_pcm_apply_msb(substream, codec_dai);
228 soc_pcm_apply_msb(substream, cpu_dai);
229
190 /* Symmetry only applies if we've already got an active stream. */ 230 /* Symmetry only applies if we've already got an active stream. */
191 if (cpu_dai->active) { 231 if (cpu_dai->active) {
192 ret = soc_pcm_apply_symmetry(substream, cpu_dai); 232 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
@@ -267,9 +307,8 @@ static void close_delayed_work(struct work_struct *work)
267 /* are we waiting on this codec DAI stream */ 307 /* are we waiting on this codec DAI stream */
268 if (codec_dai->pop_wait == 1) { 308 if (codec_dai->pop_wait == 1) {
269 codec_dai->pop_wait = 0; 309 codec_dai->pop_wait = 0;
270 snd_soc_dapm_stream_event(rtd, 310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
271 codec_dai->driver->playback.stream_name, 311 codec_dai, SND_SOC_DAPM_STREAM_STOP);
272 SND_SOC_DAPM_STREAM_STOP);
273 } 312 }
274 313
275 mutex_unlock(&rtd->pcm_mutex); 314 mutex_unlock(&rtd->pcm_mutex);
@@ -329,12 +368,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
329 cpu_dai->runtime = NULL; 368 cpu_dai->runtime = NULL;
330 369
331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
332 if (codec->ignore_pmdown_time || 371 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
333 rtd->dai_link->ignore_pmdown_time) { 372 rtd->dai_link->ignore_pmdown_time) {
334 /* powered down playback stream now */ 373 /* powered down playback stream now */
335 snd_soc_dapm_stream_event(rtd, 374 snd_soc_dapm_stream_event(rtd,
336 codec_dai->driver->playback.stream_name, 375 SNDRV_PCM_STREAM_PLAYBACK,
337 SND_SOC_DAPM_STREAM_STOP); 376 codec_dai,
377 SND_SOC_DAPM_STREAM_STOP);
338 } else { 378 } else {
339 /* start delayed pop wq here for playback streams */ 379 /* start delayed pop wq here for playback streams */
340 codec_dai->pop_wait = 1; 380 codec_dai->pop_wait = 1;
@@ -343,9 +383,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
343 } 383 }
344 } else { 384 } else {
345 /* capture streams can be powered down now */ 385 /* capture streams can be powered down now */
346 snd_soc_dapm_stream_event(rtd, 386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
347 codec_dai->driver->capture.stream_name, 387 codec_dai, SND_SOC_DAPM_STREAM_STOP);
348 SND_SOC_DAPM_STREAM_STOP);
349 } 388 }
350 389
351 mutex_unlock(&rtd->pcm_mutex); 390 mutex_unlock(&rtd->pcm_mutex);
@@ -375,7 +414,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
375 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { 414 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
376 ret = rtd->dai_link->ops->prepare(substream); 415 ret = rtd->dai_link->ops->prepare(substream);
377 if (ret < 0) { 416 if (ret < 0) {
378 printk(KERN_ERR "asoc: machine prepare error\n"); 417 pr_err("asoc: machine prepare error: %d\n", ret);
379 goto out; 418 goto out;
380 } 419 }
381 } 420 }
@@ -383,7 +422,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
383 if (platform->driver->ops && platform->driver->ops->prepare) { 422 if (platform->driver->ops && platform->driver->ops->prepare) {
384 ret = platform->driver->ops->prepare(substream); 423 ret = platform->driver->ops->prepare(substream);
385 if (ret < 0) { 424 if (ret < 0) {
386 printk(KERN_ERR "asoc: platform prepare error\n"); 425 dev_err(platform->dev, "platform prepare error: %d\n",
426 ret);
387 goto out; 427 goto out;
388 } 428 }
389 } 429 }
@@ -391,7 +431,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
391 if (codec_dai->driver->ops->prepare) { 431 if (codec_dai->driver->ops->prepare) {
392 ret = codec_dai->driver->ops->prepare(substream, codec_dai); 432 ret = codec_dai->driver->ops->prepare(substream, codec_dai);
393 if (ret < 0) { 433 if (ret < 0) {
394 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 434 dev_err(codec_dai->dev, "DAI prepare error: %d\n",
435 ret);
395 goto out; 436 goto out;
396 } 437 }
397 } 438 }
@@ -399,7 +440,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
399 if (cpu_dai->driver->ops->prepare) { 440 if (cpu_dai->driver->ops->prepare) {
400 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); 441 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
401 if (ret < 0) { 442 if (ret < 0) {
402 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 443 dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
444 ret);
403 goto out; 445 goto out;
404 } 446 }
405 } 447 }
@@ -411,14 +453,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
411 cancel_delayed_work(&rtd->delayed_work); 453 cancel_delayed_work(&rtd->delayed_work);
412 } 454 }
413 455
414 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai,
415 snd_soc_dapm_stream_event(rtd, 457 SND_SOC_DAPM_STREAM_START);
416 codec_dai->driver->playback.stream_name,
417 SND_SOC_DAPM_STREAM_START);
418 else
419 snd_soc_dapm_stream_event(rtd,
420 codec_dai->driver->capture.stream_name,
421 SND_SOC_DAPM_STREAM_START);
422 458
423 snd_soc_dai_digital_mute(codec_dai, 0); 459 snd_soc_dai_digital_mute(codec_dai, 0);
424 460
@@ -446,7 +482,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
446 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { 482 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
447 ret = rtd->dai_link->ops->hw_params(substream, params); 483 ret = rtd->dai_link->ops->hw_params(substream, params);
448 if (ret < 0) { 484 if (ret < 0) {
449 printk(KERN_ERR "asoc: machine hw_params failed\n"); 485 pr_err("asoc: machine hw_params failed: %d\n", ret);
450 goto out; 486 goto out;
451 } 487 }
452 } 488 }
@@ -454,8 +490,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
454 if (codec_dai->driver->ops->hw_params) { 490 if (codec_dai->driver->ops->hw_params) {
455 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); 491 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
456 if (ret < 0) { 492 if (ret < 0) {
457 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 493 dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
458 codec_dai->name); 494 codec_dai->name, ret);
459 goto codec_err; 495 goto codec_err;
460 } 496 }
461 } 497 }
@@ -463,8 +499,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
463 if (cpu_dai->driver->ops->hw_params) { 499 if (cpu_dai->driver->ops->hw_params) {
464 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); 500 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
465 if (ret < 0) { 501 if (ret < 0) {
466 printk(KERN_ERR "asoc: interface %s hw params failed\n", 502 dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
467 cpu_dai->name); 503 cpu_dai->name, ret);
468 goto interface_err; 504 goto interface_err;
469 } 505 }
470 } 506 }
@@ -472,8 +508,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
472 if (platform->driver->ops && platform->driver->ops->hw_params) { 508 if (platform->driver->ops && platform->driver->ops->hw_params) {
473 ret = platform->driver->ops->hw_params(substream, params); 509 ret = platform->driver->ops->hw_params(substream, params);
474 if (ret < 0) { 510 if (ret < 0) {
475 printk(KERN_ERR "asoc: platform %s hw params failed\n", 511 dev_err(platform->dev, "%s hw params failed: %d\n",
476 platform->name); 512 platform->name, ret);
477 goto platform_err; 513 goto platform_err;
478 } 514 }
479 } 515 }
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 4220bb0f2730..60053709e417 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -89,14 +89,32 @@ static struct snd_soc_platform_driver dummy_platform = {
89 .ops = &dummy_dma_ops, 89 .ops = &dummy_dma_ops,
90}; 90};
91 91
92static struct snd_soc_codec_driver dummy_codec;
93static struct snd_soc_dai_driver dummy_dai = {
94 .name = "snd-soc-dummy-dai",
95};
96
92static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) 97static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
93{ 98{
94 return snd_soc_register_platform(&pdev->dev, &dummy_platform); 99 int ret;
100
101 ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1);
102 if (ret < 0)
103 return ret;
104
105 ret = snd_soc_register_platform(&pdev->dev, &dummy_platform);
106 if (ret < 0) {
107 snd_soc_unregister_codec(&pdev->dev);
108 return ret;
109 }
110
111 return ret;
95} 112}
96 113
97static __devexit int snd_soc_dummy_remove(struct platform_device *pdev) 114static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
98{ 115{
99 snd_soc_unregister_platform(&pdev->dev); 116 snd_soc_unregister_platform(&pdev->dev);
117 snd_soc_unregister_codec(&pdev->dev);
100 118
101 return 0; 119 return 0;
102} 120}
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 4a0e805c4edd..e45ccd851f6a 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -18,6 +18,7 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/of_gpio.h>
21 22
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/jack.h> 24#include <sound/jack.h>
@@ -34,8 +35,13 @@
34 35
35#define DRV_NAME "tegra-alc5632" 36#define DRV_NAME "tegra-alc5632"
36 37
38#define GPIO_HP_DET BIT(0)
39
37struct tegra_alc5632 { 40struct tegra_alc5632 {
38 struct tegra_asoc_utils_data util_data; 41 struct tegra_asoc_utils_data util_data;
42 struct platform_device *pcm_dev;
43 int gpio_requested;
44 int gpio_hp_det;
39}; 45};
40 46
41static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, 47static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
@@ -85,24 +91,18 @@ static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = {
85 }, 91 },
86}; 92};
87 93
94static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
95 .name = "Headset detection",
96 .report = SND_JACK_HEADSET,
97 .debounce_time = 150,
98 .invert = 1,
99};
100
88static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { 101static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
89 SND_SOC_DAPM_SPK("Int Spk", NULL), 102 SND_SOC_DAPM_SPK("Int Spk", NULL),
90 SND_SOC_DAPM_HP("Headset Stereophone", NULL), 103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
91 SND_SOC_DAPM_MIC("Headset Mic", NULL), 104 SND_SOC_DAPM_MIC("Headset Mic", NULL),
92}; 105 SND_SOC_DAPM_MIC("Digital Mic", NULL),
93
94static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = {
95 /* Internal Speaker */
96 {"Int Spk", NULL, "SPKOUT"},
97 {"Int Spk", NULL, "SPKOUTN"},
98
99 /* Headset Mic */
100 {"MIC1", NULL, "MICBIAS1"},
101 {"MICBIAS1", NULL, "Headset Mic"},
102
103 /* Headset Stereophone */
104 {"Headset Stereophone", NULL, "HPR"},
105 {"Headset Stereophone", NULL, "HPL"},
106}; 106};
107 107
108static const struct snd_kcontrol_new tegra_alc5632_controls[] = { 108static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
@@ -113,6 +113,8 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
113{ 113{
114 struct snd_soc_codec *codec = rtd->codec; 114 struct snd_soc_codec *codec = rtd->codec;
115 struct snd_soc_dapm_context *dapm = &codec->dapm; 115 struct snd_soc_dapm_context *dapm = &codec->dapm;
116 struct device_node *np = codec->card->dev->of_node;
117 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
116 118
117 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 119 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
118 &tegra_alc5632_hs_jack); 120 &tegra_alc5632_hs_jack);
@@ -120,6 +122,16 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
120 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 122 ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
121 tegra_alc5632_hs_jack_pins); 123 tegra_alc5632_hs_jack_pins);
122 124
125 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
126
127 if (gpio_is_valid(machine->gpio_hp_det)) {
128 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
129 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
130 1,
131 &tegra_alc5632_hp_jack_gpio);
132 machine->gpio_requested |= GPIO_HP_DET;
133 }
134
123 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 135 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
124 136
125 return 0; 137 return 0;
@@ -128,9 +140,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
128static struct snd_soc_dai_link tegra_alc5632_dai = { 140static struct snd_soc_dai_link tegra_alc5632_dai = {
129 .name = "ALC5632", 141 .name = "ALC5632",
130 .stream_name = "ALC5632 PCM", 142 .stream_name = "ALC5632 PCM",
131 .codec_name = "alc5632.0-001e",
132 .platform_name = "tegra-pcm-audio", 143 .platform_name = "tegra-pcm-audio",
133 .cpu_dai_name = "tegra-i2s.0",
134 .codec_dai_name = "alc5632-hifi", 144 .codec_dai_name = "alc5632-hifi",
135 .init = tegra_alc5632_asoc_init, 145 .init = tegra_alc5632_asoc_init,
136 .ops = &tegra_alc5632_asoc_ops, 146 .ops = &tegra_alc5632_asoc_ops,
@@ -148,8 +158,6 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
148 .num_controls = ARRAY_SIZE(tegra_alc5632_controls), 158 .num_controls = ARRAY_SIZE(tegra_alc5632_controls),
149 .dapm_widgets = tegra_alc5632_dapm_widgets, 159 .dapm_widgets = tegra_alc5632_dapm_widgets,
150 .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets), 160 .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets),
151 .dapm_routes = tegra_alc5632_audio_map,
152 .num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map),
153 .fully_routed = true, 161 .fully_routed = true,
154}; 162};
155 163
@@ -163,45 +171,111 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
163 sizeof(struct tegra_alc5632), GFP_KERNEL); 171 sizeof(struct tegra_alc5632), GFP_KERNEL);
164 if (!alc5632) { 172 if (!alc5632) {
165 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); 173 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
166 return -ENOMEM; 174 ret = -ENOMEM;
175 goto err;
167 } 176 }
168 177
169 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
170 if (ret)
171 return ret;
172
173 card->dev = &pdev->dev; 178 card->dev = &pdev->dev;
174 platform_set_drvdata(pdev, card); 179 platform_set_drvdata(pdev, card);
175 snd_soc_card_set_drvdata(card, alc5632); 180 snd_soc_card_set_drvdata(card, alc5632);
176 181
182 alc5632->pcm_dev = ERR_PTR(-EINVAL);
183
184 if (!(pdev->dev.of_node)) {
185 dev_err(&pdev->dev, "Must be instantiated using device tree\n");
186 ret = -EINVAL;
187 goto err;
188 }
189
190 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
191 if (ret)
192 goto err;
193
194 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
195 if (ret)
196 goto err;
197
198 tegra_alc5632_dai.codec_of_node = of_parse_phandle(
199 pdev->dev.of_node, "nvidia,audio-codec", 0);
200
201 if (!tegra_alc5632_dai.codec_of_node) {
202 dev_err(&pdev->dev,
203 "Property 'nvidia,audio-codec' missing or invalid\n");
204 ret = -EINVAL;
205 goto err;
206 }
207
208 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle(
209 pdev->dev.of_node, "nvidia,i2s-controller", 0);
210 if (!tegra_alc5632_dai.cpu_dai_of_node) {
211 dev_err(&pdev->dev,
212 "Property 'nvidia,i2s-controller' missing or invalid\n");
213 ret = -EINVAL;
214 goto err;
215 }
216
217 alc5632->pcm_dev = platform_device_register_simple(
218 "tegra-pcm-audio", -1, NULL, 0);
219 if (IS_ERR(alc5632->pcm_dev)) {
220 dev_err(&pdev->dev,
221 "Can't instantiate tegra-pcm-audio\n");
222 ret = PTR_ERR(alc5632->pcm_dev);
223 goto err;
224 }
225
226 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
227 if (ret)
228 goto err_unregister;
229
177 ret = snd_soc_register_card(card); 230 ret = snd_soc_register_card(card);
178 if (ret) { 231 if (ret) {
179 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 232 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
180 ret); 233 ret);
181 tegra_asoc_utils_fini(&alc5632->util_data); 234 goto err_fini_utils;
182 return ret;
183 } 235 }
184 236
185 return 0; 237 return 0;
238
239err_fini_utils:
240 tegra_asoc_utils_fini(&alc5632->util_data);
241err_unregister:
242 if (!IS_ERR(alc5632->pcm_dev))
243 platform_device_unregister(alc5632->pcm_dev);
244err:
245 return ret;
186} 246}
187 247
188static int __devexit tegra_alc5632_remove(struct platform_device *pdev) 248static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
189{ 249{
190 struct snd_soc_card *card = platform_get_drvdata(pdev); 250 struct snd_soc_card *card = platform_get_drvdata(pdev);
191 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 251 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
252
253 if (machine->gpio_requested & GPIO_HP_DET)
254 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack,
255 1,
256 &tegra_alc5632_hp_jack_gpio);
257 machine->gpio_requested = 0;
192 258
193 snd_soc_unregister_card(card); 259 snd_soc_unregister_card(card);
194 260
195 tegra_asoc_utils_fini(&alc5632->util_data); 261 tegra_asoc_utils_fini(&machine->util_data);
262 if (!IS_ERR(machine->pcm_dev))
263 platform_device_unregister(machine->pcm_dev);
196 264
197 return 0; 265 return 0;
198} 266}
199 267
268static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = {
269 { .compatible = "nvidia,tegra-audio-alc5632", },
270 {},
271};
272
200static struct platform_driver tegra_alc5632_driver = { 273static struct platform_driver tegra_alc5632_driver = {
201 .driver = { 274 .driver = {
202 .name = DRV_NAME, 275 .name = DRV_NAME,
203 .owner = THIS_MODULE, 276 .owner = THIS_MODULE,
204 .pm = &snd_soc_pm_ops, 277 .pm = &snd_soc_pm_ops,
278 .of_match_table = tegra_alc5632_of_match,
205 }, 279 },
206 .probe = tegra_alc5632_probe, 280 .probe = tegra_alc5632_probe,
207 .remove = __devexit_p(tegra_alc5632_remove), 281 .remove = __devexit_p(tegra_alc5632_remove),
@@ -212,3 +286,4 @@ MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
212MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); 286MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver");
213MODULE_LICENSE("GPL"); 287MODULE_LICENSE("GPL");
214MODULE_ALIAS("platform:" DRV_NAME); 288MODULE_ALIAS("platform:" DRV_NAME);
289MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match);
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c22431516ab2..8b4457137c7c 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -336,7 +336,7 @@ static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
336 if (!card->dev->dma_mask) 336 if (!card->dev->dma_mask)
337 card->dev->dma_mask = &tegra_dma_mask; 337 card->dev->dma_mask = &tegra_dma_mask;
338 if (!card->dev->coherent_dma_mask) 338 if (!card->dev->coherent_dma_mask)
339 card->dev->coherent_dma_mask = 0xffffffff; 339 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
340 340
341 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 341 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
342 ret = tegra_pcm_preallocate_dma_buffer(pcm, 342 ret = tegra_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 4dd051bdf4fd..c6500d00053b 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -1112,17 +1112,7 @@ static struct spi_driver at73c213_driver = {
1112 .remove = __devexit_p(snd_at73c213_remove), 1112 .remove = __devexit_p(snd_at73c213_remove),
1113}; 1113};
1114 1114
1115static int __init at73c213_init(void) 1115module_spi_driver(at73c213_driver);
1116{
1117 return spi_register_driver(&at73c213_driver);
1118}
1119module_init(at73c213_init);
1120
1121static void __exit at73c213_exit(void)
1122{
1123 spi_unregister_driver(&at73c213_driver);
1124}
1125module_exit(at73c213_exit);
1126 1116
1127MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); 1117MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
1128MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); 1118MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 8af92e3e9c18..fc8cc823e438 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -29,7 +28,7 @@
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); 30MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
32MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver, version 0.3.0"); 31MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver");
33MODULE_LICENSE("GPL v2"); 32MODULE_LICENSE("GPL v2");
34MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); 33MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}");
35 34
diff --git a/sound/usb/6fire/chip.h b/sound/usb/6fire/chip.h
index d11e5cb520f0..bde02d105a51 100644
--- a/sound/usb/6fire/chip.h
+++ b/sound/usb/6fire/chip.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
index c994daa57af2..6c3d531a250e 100644
--- a/sound/usb/6fire/comm.c
+++ b/sound/usb/6fire/comm.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
index edc5dc84b888..d2af0a5ddcf3 100644
--- a/sound/usb/6fire/comm.h
+++ b/sound/usb/6fire/comm.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/common.h b/sound/usb/6fire/common.h
index 7dbeb4a37831..b6eb03ed1c2c 100644
--- a/sound/usb/6fire/common.h
+++ b/sound/usb/6fire/common.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index ac828eff1a63..07ed914d5e71 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -5,9 +5,12 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
10 * Thanks to:
11 * - Holger Ruckdeschel: he found out how to control individual channel
12 * volumes and introduced mute switch
13 *
11 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -16,6 +19,7 @@
16 19
17#include <linux/interrupt.h> 20#include <linux/interrupt.h>
18#include <sound/control.h> 21#include <sound/control.h>
22#include <sound/tlv.h>
19 23
20#include "control.h" 24#include "control.h"
21#include "comm.h" 25#include "comm.h"
@@ -25,26 +29,6 @@ static char *opt_coax_texts[2] = { "Optical", "Coax" };
25static char *line_phono_texts[2] = { "Line", "Phono" }; 29static char *line_phono_texts[2] = { "Line", "Phono" };
26 30
27/* 31/*
28 * calculated with $value\[i\] = 128 \cdot sqrt[3]{\frac{i}{128}}$
29 * this is done because the linear values cause rapid degredation
30 * of volume in the uppermost region.
31 */
32static const u8 log_volume_table[128] = {
33 0x00, 0x19, 0x20, 0x24, 0x28, 0x2b, 0x2e, 0x30, 0x32, 0x34,
34 0x36, 0x38, 0x3a, 0x3b, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43,
35 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
36 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56,
37 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c,
38 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62,
39 0x63, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68,
40 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c,
41 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71,
42 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75,
43 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79,
44 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
45 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f };
46
47/*
48 * data that needs to be sent to device. sets up card internal stuff. 32 * data that needs to be sent to device. sets up card internal stuff.
49 * values dumped from windows driver and filtered by trial'n'error. 33 * values dumped from windows driver and filtered by trial'n'error.
50 */ 34 */
@@ -59,7 +43,7 @@ init_data[] = {
59 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, 43 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
60 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, 44 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
61 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, 45 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
62 { 0x12, 0x0d, 0x78 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, 46 { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
63 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, 47 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
64 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, 48 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
65 { 0 } /* TERMINATING ENTRY */ 49 { 0 } /* TERMINATING ENTRY */
@@ -70,20 +54,47 @@ static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; 54static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; 55static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72 56
57static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0);
58static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500);
59
73enum { 60enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3 61 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75}; 62};
76 63
77static void usb6fire_control_master_vol_update(struct control_runtime *rt) 64static void usb6fire_control_output_vol_update(struct control_runtime *rt)
78{ 65{
79 struct comm_runtime *comm_rt = rt->chip->comm; 66 struct comm_runtime *comm_rt = rt->chip->comm;
80 if (comm_rt) { 67 int i;
81 /* set volume */ 68
82 comm_rt->write8(comm_rt, 0x12, 0x0f, 0x7f - 69 if (comm_rt)
83 log_volume_table[rt->master_vol]); 70 for (i = 0; i < 6; i++)
84 /* unmute */ 71 if (!(rt->ovol_updated & (1 << i))) {
85 comm_rt->write8(comm_rt, 0x12, 0x0e, 0x00); 72 comm_rt->write8(comm_rt, 0x12, 0x0f + i,
86 } 73 180 - rt->output_vol[i]);
74 rt->ovol_updated |= 1 << i;
75 }
76}
77
78static void usb6fire_control_output_mute_update(struct control_runtime *rt)
79{
80 struct comm_runtime *comm_rt = rt->chip->comm;
81
82 if (comm_rt)
83 comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute);
84}
85
86static void usb6fire_control_input_vol_update(struct control_runtime *rt)
87{
88 struct comm_runtime *comm_rt = rt->chip->comm;
89 int i;
90
91 if (comm_rt)
92 for (i = 0; i < 2; i++)
93 if (!(rt->ivol_updated & (1 << i))) {
94 comm_rt->write8(comm_rt, 0x12, 0x1c + i,
95 rt->input_vol[i] & 0x3f);
96 rt->ivol_updated |= 1 << i;
97 }
87} 98}
88 99
89static void usb6fire_control_line_phono_update(struct control_runtime *rt) 100static void usb6fire_control_line_phono_update(struct control_runtime *rt)
@@ -165,34 +176,147 @@ static int usb6fire_control_streaming_update(struct control_runtime *rt)
165 return -EINVAL; 176 return -EINVAL;
166} 177}
167 178
168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 179static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol,
169 struct snd_ctl_elem_info *uinfo) 180 struct snd_ctl_elem_info *uinfo)
170{ 181{
171 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
172 uinfo->count = 1; 183 uinfo->count = 2;
173 uinfo->value.integer.min = 0; 184 uinfo->value.integer.min = 0;
174 uinfo->value.integer.max = 127; 185 uinfo->value.integer.max = 180;
175 return 0; 186 return 0;
176} 187}
177 188
178static int usb6fire_control_master_vol_put(struct snd_kcontrol *kcontrol, 189static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol,
179 struct snd_ctl_elem_value *ucontrol) 190 struct snd_ctl_elem_value *ucontrol)
180{ 191{
181 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 192 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
193 unsigned int ch = kcontrol->private_value;
182 int changed = 0; 194 int changed = 0;
183 if (rt->master_vol != ucontrol->value.integer.value[0]) { 195
184 rt->master_vol = ucontrol->value.integer.value[0]; 196 if (ch > 4) {
185 usb6fire_control_master_vol_update(rt); 197 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
198 return -EINVAL;
199 }
200
201 if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) {
202 rt->output_vol[ch] = ucontrol->value.integer.value[0];
203 rt->ovol_updated &= ~(1 << ch);
186 changed = 1; 204 changed = 1;
187 } 205 }
206 if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) {
207 rt->output_vol[ch + 1] = ucontrol->value.integer.value[1];
208 rt->ovol_updated &= ~(2 << ch);
209 changed = 1;
210 }
211
212 if (changed)
213 usb6fire_control_output_vol_update(rt);
214
188 return changed; 215 return changed;
189} 216}
190 217
191static int usb6fire_control_master_vol_get(struct snd_kcontrol *kcontrol, 218static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol,
192 struct snd_ctl_elem_value *ucontrol) 219 struct snd_ctl_elem_value *ucontrol)
193{ 220{
194 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 221 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
195 ucontrol->value.integer.value[0] = rt->master_vol; 222 unsigned int ch = kcontrol->private_value;
223
224 if (ch > 4) {
225 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
226 return -EINVAL;
227 }
228
229 ucontrol->value.integer.value[0] = rt->output_vol[ch];
230 ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
231 return 0;
232}
233
234static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
236{
237 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
238 unsigned int ch = kcontrol->private_value;
239 u8 old = rt->output_mute;
240 u8 value = 0;
241
242 if (ch > 4) {
243 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
244 return -EINVAL;
245 }
246
247 rt->output_mute &= ~(3 << ch);
248 if (ucontrol->value.integer.value[0])
249 value |= 1;
250 if (ucontrol->value.integer.value[1])
251 value |= 2;
252 rt->output_mute |= value << ch;
253
254 if (rt->output_mute != old)
255 usb6fire_control_output_mute_update(rt);
256
257 return rt->output_mute != old;
258}
259
260static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,
261 struct snd_ctl_elem_value *ucontrol)
262{
263 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
264 unsigned int ch = kcontrol->private_value;
265 u8 value = rt->output_mute >> ch;
266
267 if (ch > 4) {
268 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
269 return -EINVAL;
270 }
271
272 ucontrol->value.integer.value[0] = 1 & value;
273 value >>= 1;
274 ucontrol->value.integer.value[1] = 1 & value;
275
276 return 0;
277}
278
279static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_info *uinfo)
281{
282 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
283 uinfo->count = 2;
284 uinfo->value.integer.min = 0;
285 uinfo->value.integer.max = 30;
286 return 0;
287}
288
289static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol,
290 struct snd_ctl_elem_value *ucontrol)
291{
292 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
293 int changed = 0;
294
295 if (rt->input_vol[0] != ucontrol->value.integer.value[0]) {
296 rt->input_vol[0] = ucontrol->value.integer.value[0] - 15;
297 rt->ivol_updated &= ~(1 << 0);
298 changed = 1;
299 }
300 if (rt->input_vol[1] != ucontrol->value.integer.value[1]) {
301 rt->input_vol[1] = ucontrol->value.integer.value[1] - 15;
302 rt->ivol_updated &= ~(1 << 1);
303 changed = 1;
304 }
305
306 if (changed)
307 usb6fire_control_input_vol_update(rt);
308
309 return changed;
310}
311
312static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
316
317 ucontrol->value.integer.value[0] = rt->input_vol[0] + 15;
318 ucontrol->value.integer.value[1] = rt->input_vol[1] + 15;
319
196 return 0; 320 return 0;
197} 321}
198 322
@@ -287,18 +411,83 @@ static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
287 return 0; 411 return 0;
288} 412}
289 413
290static struct __devinitdata snd_kcontrol_new elements[] = { 414static struct __devinitdata snd_kcontrol_new vol_elements[] = {
291 { 415 {
292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
293 .name = "Master Playback Volume", 417 .name = "Analog Playback Volume",
294 .index = 0, 418 .index = 0,
419 .private_value = 0,
420 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
421 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
422 .info = usb6fire_control_output_vol_info,
423 .get = usb6fire_control_output_vol_get,
424 .put = usb6fire_control_output_vol_put,
425 .tlv = { .p = tlv_output }
426 },
427 {
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "Analog Playback Volume",
430 .index = 1,
431 .private_value = 2,
432 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
433 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
434 .info = usb6fire_control_output_vol_info,
435 .get = usb6fire_control_output_vol_get,
436 .put = usb6fire_control_output_vol_put,
437 .tlv = { .p = tlv_output }
438 },
439 {
440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
441 .name = "Analog Playback Volume",
442 .index = 2,
443 .private_value = 4,
444 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
445 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
446 .info = usb6fire_control_output_vol_info,
447 .get = usb6fire_control_output_vol_get,
448 .put = usb6fire_control_output_vol_put,
449 .tlv = { .p = tlv_output }
450 },
451 {}
452};
453
454static struct __devinitdata snd_kcontrol_new mute_elements[] = {
455 {
456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
457 .name = "Analog Playback Switch",
458 .index = 0,
459 .private_value = 0,
460 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
461 .info = snd_ctl_boolean_stereo_info,
462 .get = usb6fire_control_output_mute_get,
463 .put = usb6fire_control_output_mute_put,
464 },
465 {
466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
467 .name = "Analog Playback Switch",
468 .index = 1,
469 .private_value = 2,
295 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 470 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
296 .info = usb6fire_control_master_vol_info, 471 .info = snd_ctl_boolean_stereo_info,
297 .get = usb6fire_control_master_vol_get, 472 .get = usb6fire_control_output_mute_get,
298 .put = usb6fire_control_master_vol_put 473 .put = usb6fire_control_output_mute_put,
299 }, 474 },
300 { 475 {
301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
477 .name = "Analog Playback Switch",
478 .index = 2,
479 .private_value = 4,
480 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
481 .info = snd_ctl_boolean_stereo_info,
482 .get = usb6fire_control_output_mute_get,
483 .put = usb6fire_control_output_mute_put,
484 },
485 {}
486};
487
488static struct __devinitdata snd_kcontrol_new elements[] = {
489 {
490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
302 .name = "Line/Phono Capture Route", 491 .name = "Line/Phono Capture Route",
303 .index = 0, 492 .index = 0,
304 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 493 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -324,9 +513,54 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
324 .get = usb6fire_control_digital_thru_get, 513 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put 514 .put = usb6fire_control_digital_thru_put
326 }, 515 },
516 {
517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
518 .name = "Analog Capture Volume",
519 .index = 0,
520 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
521 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
522 .info = usb6fire_control_input_vol_info,
523 .get = usb6fire_control_input_vol_get,
524 .put = usb6fire_control_input_vol_put,
525 .tlv = { .p = tlv_input }
526 },
327 {} 527 {}
328}; 528};
329 529
530static int usb6fire_control_add_virtual(
531 struct control_runtime *rt,
532 struct snd_card *card,
533 char *name,
534 struct snd_kcontrol_new *elems)
535{
536 int ret;
537 int i;
538 struct snd_kcontrol *vmaster =
539 snd_ctl_make_virtual_master(name, tlv_output);
540 struct snd_kcontrol *control;
541
542 if (!vmaster)
543 return -ENOMEM;
544 ret = snd_ctl_add(card, vmaster);
545 if (ret < 0)
546 return ret;
547
548 i = 0;
549 while (elems[i].name) {
550 control = snd_ctl_new1(&elems[i], rt);
551 if (!control)
552 return -ENOMEM;
553 ret = snd_ctl_add(card, control);
554 if (ret < 0)
555 return ret;
556 ret = snd_ctl_add_slave(vmaster, control);
557 if (ret < 0)
558 return ret;
559 i++;
560 }
561 return 0;
562}
563
330int __devinit usb6fire_control_init(struct sfire_chip *chip) 564int __devinit usb6fire_control_init(struct sfire_chip *chip)
331{ 565{
332 int i; 566 int i;
@@ -352,9 +586,26 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
352 586
353 usb6fire_control_opt_coax_update(rt); 587 usb6fire_control_opt_coax_update(rt);
354 usb6fire_control_line_phono_update(rt); 588 usb6fire_control_line_phono_update(rt);
355 usb6fire_control_master_vol_update(rt); 589 usb6fire_control_output_vol_update(rt);
590 usb6fire_control_output_mute_update(rt);
591 usb6fire_control_input_vol_update(rt);
356 usb6fire_control_streaming_update(rt); 592 usb6fire_control_streaming_update(rt);
357 593
594 ret = usb6fire_control_add_virtual(rt, chip->card,
595 "Master Playback Volume", vol_elements);
596 if (ret) {
597 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
598 kfree(rt);
599 return ret;
600 }
601 ret = usb6fire_control_add_virtual(rt, chip->card,
602 "Master Playback Switch", mute_elements);
603 if (ret) {
604 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
605 kfree(rt);
606 return ret;
607 }
608
358 i = 0; 609 i = 0;
359 while (elements[i].name) { 610 while (elements[i].name) {
360 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); 611 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index 8f5aeead2e3d..9a596d95474a 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -44,7 +43,11 @@ struct control_runtime {
44 bool line_phono_switch; 43 bool line_phono_switch;
45 bool digital_thru_switch; 44 bool digital_thru_switch;
46 bool usb_streaming; 45 bool usb_streaming;
47 u8 master_vol; 46 u8 output_vol[6];
47 u8 ovol_updated;
48 u8 output_mute;
49 s8 input_vol[2];
50 u8 ivol_updated;
48}; 51};
49 52
50int __devinit usb6fire_control_init(struct sfire_chip *chip); 53int __devinit usb6fire_control_init(struct sfire_chip *chip);
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 3b5f517a3972..6f9715ab32fe 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index 13f4509dce2b..f0e5179b242b 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
index 97a7bf669135..5114eccc1d8e 100644
--- a/sound/usb/6fire/midi.h
+++ b/sound/usb/6fire/midi.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index d144cdb2f159..c97d05f0e966 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
index 2bee81374002..3104301b257d 100644
--- a/sound/usb/6fire/pcm.h
+++ b/sound/usb/6fire/pcm.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 3efc21c3d67c..ff77b28f3da1 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -106,6 +106,7 @@ config SND_USB_6FIRE
106 select BITREVERSE 106 select BITREVERSE
107 select SND_RAWMIDI 107 select SND_RAWMIDI
108 select SND_PCM 108 select SND_PCM
109 select SND_VMASTER
109 help 110 help
110 Say Y here to include support for TerraTec 6fire DMX USB interface. 111 Say Y here to include support for TerraTec 6fire DMX USB interface.
111 112
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 0220b0f335b9..0eed6115c2d4 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -695,6 +695,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
695 struct snd_usb_substream *subs) 695 struct snd_usb_substream *subs)
696{ 696{
697 struct audioformat *fp; 697 struct audioformat *fp;
698 int *rate_list;
698 int count = 0, needs_knot = 0; 699 int count = 0, needs_knot = 0;
699 int err; 700 int err;
700 701
@@ -708,7 +709,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
708 if (!needs_knot) 709 if (!needs_knot)
709 return 0; 710 return 0;
710 711
711 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); 712 subs->rate_list.list = rate_list =
713 kmalloc(sizeof(int) * count, GFP_KERNEL);
712 if (!subs->rate_list.list) 714 if (!subs->rate_list.list)
713 return -ENOMEM; 715 return -ENOMEM;
714 subs->rate_list.count = count; 716 subs->rate_list.count = count;
@@ -717,7 +719,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
717 list_for_each_entry(fp, &subs->fmt_list, list) { 719 list_for_each_entry(fp, &subs->fmt_list, list) {
718 int i; 720 int i;
719 for (i = 0; i < fp->nr_rates; i++) 721 for (i = 0; i < fp->nr_rates; i++)
720 subs->rate_list.list[count++] = fp->rate_table[i]; 722 rate_list[count++] = fp->rate_table[i];
721 } 723 }
722 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 724 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
723 &subs->rate_list); 725 &subs->rate_list);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6ffb3713b60c..520ef96d7c75 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -80,7 +80,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
80 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; 80 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
81 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ 81 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
82 snd_printk(KERN_ERR "active frame status %i. " 82 snd_printk(KERN_ERR "active frame status %i. "
83 "Most propably some hardware problem.\n", 83 "Most probably some hardware problem.\n",
84 urb->iso_frame_desc[i].status); 84 urb->iso_frame_desc[i].status);
85 return urb->iso_frame_desc[i].status; 85 return urb->iso_frame_desc[i].status;
86 } 86 }
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
300{ 300{
301 snd_printk(KERN_ERR 301 snd_printk(KERN_ERR
302"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" 302"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
303"Most propably some urb of usb-frame %i is still missing.\n" 303"Most probably some urb of usb-frame %i is still missing.\n"
304"Cause could be too long delays in usb-hcd interrupt handling.\n", 304"Cause could be too long delays in usb-hcd interrupt handling.\n",
305 usb_get_current_frame_number(usX2Y->dev), 305 usb_get_current_frame_number(usX2Y->dev),
306 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 306 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index a51340f6f2db..8e40b6e67e9e 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -74,7 +74,7 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
74 } 74 }
75 for (i = 0; i < nr_of_packs(); i++) { 75 for (i = 0; i < nr_of_packs(); i++) {
76 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ 76 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
77 snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status); 77 snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
78 return urb->iso_frame_desc[i].status; 78 return urb->iso_frame_desc[i].status;
79 } 79 }
80 lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride; 80 lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;