aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:37 -0400
committerTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:37 -0400
commitcb3f2adc03ab055b19c677a6283523861fafebdd (patch)
tree59cfb6800f0635a4aec16c8e0da619f27e51ee79 /sound
parent44c76a960a62fcc46cbcaa0a22a34e666a729329 (diff)
parent828006de1bddf83b6ecf03ec459c15f7c7c22db7 (diff)
Merge branch 'topic/asoc' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm.c99
-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.c370
-rw-r--r--sound/soc/codecs/wm8994.h6
-rw-r--r--sound/soc/codecs/wm8995.c4
-rw-r--r--sound/soc/codecs/wm8996.c234
-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.c148
-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/edb93xx.c4
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c152
-rw-r--r--sound/soc/ep93xx/snappercl15.c4
-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.c36
-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.c3
-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.c14
-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.c391
-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
173 files changed, 14905 insertions, 6039 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 8928ca871c22..6e4bfcc14254 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
650 pstr->stream = stream; 650 pstr->stream = stream;
651 pstr->pcm = pcm; 651 pstr->pcm = pcm;
652 pstr->substream_count = substream_count; 652 pstr->substream_count = substream_count;
653 if (substream_count > 0) { 653 if (substream_count > 0 && !pcm->internal) {
654 err = snd_pcm_stream_proc_init(pstr); 654 err = snd_pcm_stream_proc_init(pstr);
655 if (err < 0) { 655 if (err < 0) {
656 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 656 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
@@ -674,15 +674,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
674 pstr->substream = substream; 674 pstr->substream = substream;
675 else 675 else
676 prev->next = substream; 676 prev->next = substream;
677 err = snd_pcm_substream_proc_init(substream); 677
678 if (err < 0) { 678 if (!pcm->internal) {
679 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); 679 err = snd_pcm_substream_proc_init(substream);
680 if (prev == NULL) 680 if (err < 0) {
681 pstr->substream = NULL; 681 snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
682 else 682 if (prev == NULL)
683 prev->next = NULL; 683 pstr->substream = NULL;
684 kfree(substream); 684 else
685 return err; 685 prev->next = NULL;
686 kfree(substream);
687 return err;
688 }
686 } 689 }
687 substream->group = &substream->self_group; 690 substream->group = &substream->self_group;
688 spin_lock_init(&substream->self_group.lock); 691 spin_lock_init(&substream->self_group.lock);
@@ -696,25 +699,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
696 699
697EXPORT_SYMBOL(snd_pcm_new_stream); 700EXPORT_SYMBOL(snd_pcm_new_stream);
698 701
699/** 702static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
700 * snd_pcm_new - create a new PCM instance 703 int playback_count, int capture_count, bool internal,
701 * @card: the card instance 704 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{ 705{
719 struct snd_pcm *pcm; 706 struct snd_pcm *pcm;
720 int err; 707 int err;
@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
735 } 722 }
736 pcm->card = card; 723 pcm->card = card;
737 pcm->device = device; 724 pcm->device = device;
725 pcm->internal = internal;
738 if (id) 726 if (id)
739 strlcpy(pcm->id, id, sizeof(pcm->id)); 727 strlcpy(pcm->id, id, sizeof(pcm->id));
740 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { 728 if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@@ -756,8 +744,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
756 return 0; 744 return 0;
757} 745}
758 746
747/**
748 * snd_pcm_new - create a new PCM instance
749 * @card: the card instance
750 * @id: the id string
751 * @device: the device index (zero based)
752 * @playback_count: the number of substreams for playback
753 * @capture_count: the number of substreams for capture
754 * @rpcm: the pointer to store the new pcm instance
755 *
756 * Creates a new PCM instance.
757 *
758 * The pcm operators have to be set afterwards to the new instance
759 * via snd_pcm_set_ops().
760 *
761 * Returns zero if successful, or a negative error code on failure.
762 */
763int snd_pcm_new(struct snd_card *card, const char *id, int device,
764 int playback_count, int capture_count, struct snd_pcm **rpcm)
765{
766 return _snd_pcm_new(card, id, device, playback_count, capture_count,
767 false, rpcm);
768}
759EXPORT_SYMBOL(snd_pcm_new); 769EXPORT_SYMBOL(snd_pcm_new);
760 770
771/**
772 * snd_pcm_new_internal - create a new internal PCM instance
773 * @card: the card instance
774 * @id: the id string
775 * @device: the device index (zero based - shared with normal PCMs)
776 * @playback_count: the number of substreams for playback
777 * @capture_count: the number of substreams for capture
778 * @rpcm: the pointer to store the new pcm instance
779 *
780 * Creates a new internal PCM instance with no userspace device or procfs
781 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
782 * will only be used internally by kernel drivers. i.e. it cannot be opened
783 * by userspace. It provides existing ASoC components drivers with a substream
784 * and access to any private data.
785 *
786 * The pcm operators have to be set afterwards to the new instance
787 * via snd_pcm_set_ops().
788 *
789 * Returns zero if successful, or a negative error code on failure.
790 */
791int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
792 int playback_count, int capture_count,
793 struct snd_pcm **rpcm)
794{
795 return _snd_pcm_new(card, id, device, playback_count, capture_count,
796 true, rpcm);
797}
798EXPORT_SYMBOL(snd_pcm_new_internal);
799
761static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 800static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
762{ 801{
763 struct snd_pcm_substream *substream, *substream_next; 802 struct snd_pcm_substream *substream, *substream_next;
@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
994 } 1033 }
995 for (cidx = 0; cidx < 2; cidx++) { 1034 for (cidx = 0; cidx < 2; cidx++) {
996 int devtype = -1; 1035 int devtype = -1;
997 if (pcm->streams[cidx].substream == NULL) 1036 if (pcm->streams[cidx].substream == NULL || pcm->internal)
998 continue; 1037 continue;
999 switch (cidx) { 1038 switch (cidx) {
1000 case SNDRV_PCM_STREAM_PLAYBACK: 1039 case SNDRV_PCM_STREAM_PLAYBACK:
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..15fcb1bb7148 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,19 +776,25 @@ 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) {
779 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
780 WM8994_LINEOUT_VMID_BUF_ENA |
781 WM8994_LINEOUT1_DISCH |
782 WM8994_LINEOUT2_DISCH,
783 WM8994_LINEOUT_VMID_BUF_ENA);
784
785 wm_hubs_vmid_ena(codec);
786
781 /* Startup bias, VMID ramp & buffer */ 787 /* Startup bias, VMID ramp & buffer */
782 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 788 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
789 WM8994_BIAS_SRC |
790 WM8994_VMID_DISCH |
783 WM8994_STARTUP_BIAS_ENA | 791 WM8994_STARTUP_BIAS_ENA |
784 WM8994_VMID_BUF_ENA | 792 WM8994_VMID_BUF_ENA |
785 WM8994_VMID_RAMP_MASK, 793 WM8994_VMID_RAMP_MASK,
794 WM8994_BIAS_SRC |
786 WM8994_STARTUP_BIAS_ENA | 795 WM8994_STARTUP_BIAS_ENA |
787 WM8994_VMID_BUF_ENA | 796 WM8994_VMID_BUF_ENA |
788 (0x3 << WM8994_VMID_RAMP_SHIFT)); 797 (0x2 << WM8994_VMID_RAMP_SHIFT));
789
790 /* Remove discharge for line out */
791 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
792 WM8994_LINEOUT1_DISCH |
793 WM8994_LINEOUT2_DISCH, 0);
794 798
795 /* Main bias enable, VMID=2x40k */ 799 /* Main bias enable, VMID=2x40k */
796 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, 800 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
@@ -798,7 +802,11 @@ static void vmid_reference(struct snd_soc_codec *codec)
798 WM8994_VMID_SEL_MASK, 802 WM8994_VMID_SEL_MASK,
799 WM8994_BIAS_ENA | 0x2); 803 WM8994_BIAS_ENA | 0x2);
800 804
801 msleep(20); 805 msleep(50);
806
807 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
808 WM8994_VMID_RAMP_MASK | WM8994_BIAS_SRC,
809 0);
802 } 810 }
803} 811}
804 812
@@ -828,6 +836,10 @@ static void vmid_dereference(struct snd_soc_codec *codec)
828 WM8994_BIAS_ENA | 836 WM8994_BIAS_ENA |
829 WM8994_VMID_SEL_MASK, 0); 837 WM8994_VMID_SEL_MASK, 0);
830 838
839 /* Discharge VMID */
840 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
841 WM8994_VMID_DISCH, WM8994_VMID_DISCH);
842
831 /* Discharge line */ 843 /* Discharge line */
832 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 844 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
833 WM8994_LINEOUT1_DISCH | 845 WM8994_LINEOUT1_DISCH |
@@ -1459,17 +1471,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1459 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, 1471 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
1460 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1472 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1461 1473
1462SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1474SND_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), 1475SND_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), 1476SND_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), 1477SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1466 1478
1467SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1479SND_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), 1480SND_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), 1481SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1470 1482
1471SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1483SND_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), 1484SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1473 1485
1474SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1486SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1475 1487
@@ -1584,6 +1596,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1584 1596
1585 { "TOCLK", NULL, "CLK_SYS" }, 1597 { "TOCLK", NULL, "CLK_SYS" },
1586 1598
1599 { "AIF1DACDAT", NULL, "AIF1 Playback" },
1600 { "AIF2DACDAT", NULL, "AIF2 Playback" },
1601 { "AIF3DACDAT", NULL, "AIF3 Playback" },
1602
1603 { "AIF1 Capture", NULL, "AIF1ADCDAT" },
1604 { "AIF2 Capture", NULL, "AIF2ADCDAT" },
1605 { "AIF3 Capture", NULL, "AIF3ADCDAT" },
1606
1587 /* AIF1 outputs */ 1607 /* AIF1 outputs */
1588 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, 1608 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
1589 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, 1609 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
@@ -1896,7 +1916,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1896 WM8994_FLL1_OUTDIV_MASK | 1916 WM8994_FLL1_OUTDIV_MASK |
1897 WM8994_FLL1_FRATIO_MASK, reg); 1917 WM8994_FLL1_FRATIO_MASK, reg);
1898 1918
1899 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); 1919 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
1920 WM8994_FLL1_K_MASK, fll.k);
1900 1921
1901 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, 1922 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
1902 WM8994_FLL1_N_MASK, 1923 WM8994_FLL1_N_MASK,
@@ -2074,6 +2095,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2074 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2095 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2075 struct wm8994 *control = wm8994->wm8994; 2096 struct wm8994 *control = wm8994->wm8994;
2076 2097
2098 wm_hubs_set_bias_level(codec, level);
2099
2077 switch (level) { 2100 switch (level) {
2078 case SND_SOC_BIAS_ON: 2101 case SND_SOC_BIAS_ON:
2079 break; 2102 break;
@@ -2168,6 +2191,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2168 wm8994->cur_fw = NULL; 2191 wm8994->cur_fw = NULL;
2169 break; 2192 break;
2170 } 2193 }
2194
2171 codec->dapm.bias_level = level; 2195 codec->dapm.bias_level = level;
2172 2196
2173 return 0; 2197 return 0;
@@ -2654,6 +2678,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2654 .channels_max = 2, 2678 .channels_max = 2,
2655 .rates = WM8994_RATES, 2679 .rates = WM8994_RATES,
2656 .formats = WM8994_FORMATS, 2680 .formats = WM8994_FORMATS,
2681 .sig_bits = 24,
2657 }, 2682 },
2658 .capture = { 2683 .capture = {
2659 .stream_name = "AIF1 Capture", 2684 .stream_name = "AIF1 Capture",
@@ -2661,6 +2686,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2661 .channels_max = 2, 2686 .channels_max = 2,
2662 .rates = WM8994_RATES, 2687 .rates = WM8994_RATES,
2663 .formats = WM8994_FORMATS, 2688 .formats = WM8994_FORMATS,
2689 .sig_bits = 24,
2664 }, 2690 },
2665 .ops = &wm8994_aif1_dai_ops, 2691 .ops = &wm8994_aif1_dai_ops,
2666 }, 2692 },
@@ -2673,6 +2699,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2673 .channels_max = 2, 2699 .channels_max = 2,
2674 .rates = WM8994_RATES, 2700 .rates = WM8994_RATES,
2675 .formats = WM8994_FORMATS, 2701 .formats = WM8994_FORMATS,
2702 .sig_bits = 24,
2676 }, 2703 },
2677 .capture = { 2704 .capture = {
2678 .stream_name = "AIF2 Capture", 2705 .stream_name = "AIF2 Capture",
@@ -2680,6 +2707,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2680 .channels_max = 2, 2707 .channels_max = 2,
2681 .rates = WM8994_RATES, 2708 .rates = WM8994_RATES,
2682 .formats = WM8994_FORMATS, 2709 .formats = WM8994_FORMATS,
2710 .sig_bits = 24,
2683 }, 2711 },
2684 .probe = wm8994_aif2_probe, 2712 .probe = wm8994_aif2_probe,
2685 .ops = &wm8994_aif2_dai_ops, 2713 .ops = &wm8994_aif2_dai_ops,
@@ -2693,6 +2721,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2693 .channels_max = 2, 2721 .channels_max = 2,
2694 .rates = WM8994_RATES, 2722 .rates = WM8994_RATES,
2695 .formats = WM8994_FORMATS, 2723 .formats = WM8994_FORMATS,
2724 .sig_bits = 24,
2696 }, 2725 },
2697 .capture = { 2726 .capture = {
2698 .stream_name = "AIF3 Capture", 2727 .stream_name = "AIF3 Capture",
@@ -2700,13 +2729,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2700 .channels_max = 2, 2729 .channels_max = 2,
2701 .rates = WM8994_RATES, 2730 .rates = WM8994_RATES,
2702 .formats = WM8994_FORMATS, 2731 .formats = WM8994_FORMATS,
2703 }, 2732 .sig_bits = 24,
2733 },
2704 .ops = &wm8994_aif3_dai_ops, 2734 .ops = &wm8994_aif3_dai_ops,
2705 } 2735 }
2706}; 2736};
2707 2737
2708#ifdef CONFIG_PM 2738#ifdef CONFIG_PM
2709static int wm8994_suspend(struct snd_soc_codec *codec) 2739static int wm8994_codec_suspend(struct snd_soc_codec *codec)
2710{ 2740{
2711 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2741 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2712 struct wm8994 *control = wm8994->wm8994; 2742 struct wm8994 *control = wm8994->wm8994;
@@ -2740,7 +2770,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec)
2740 return 0; 2770 return 0;
2741} 2771}
2742 2772
2743static int wm8994_resume(struct snd_soc_codec *codec) 2773static int wm8994_codec_resume(struct snd_soc_codec *codec)
2744{ 2774{
2745 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2775 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2746 struct wm8994 *control = wm8994->wm8994; 2776 struct wm8994 *control = wm8994->wm8994;
@@ -2762,8 +2792,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2762 codec->cache_only = 0; 2792 codec->cache_only = 0;
2763 } 2793 }
2764 2794
2765 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2766
2767 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2795 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2768 if (!wm8994->fll_suspend[i].out) 2796 if (!wm8994->fll_suspend[i].out)
2769 continue; 2797 continue;
@@ -2801,8 +2829,8 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2801 return 0; 2829 return 0;
2802} 2830}
2803#else 2831#else
2804#define wm8994_suspend NULL 2832#define wm8994_codec_suspend NULL
2805#define wm8994_resume NULL 2833#define wm8994_codec_resume NULL
2806#endif 2834#endif
2807 2835
2808static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 2836static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
@@ -2865,7 +2893,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
2865 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 2893 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
2866 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 2894 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
2867 2895
2868 ret = snd_soc_add_controls(wm8994->codec, controls, 2896 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2869 ARRAY_SIZE(controls)); 2897 ARRAY_SIZE(controls));
2870 if (ret != 0) 2898 if (ret != 0)
2871 dev_err(wm8994->codec->dev, 2899 dev_err(wm8994->codec->dev,
@@ -2918,7 +2946,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2918 wm8994->drc_enum.max = pdata->num_drc_cfgs; 2946 wm8994->drc_enum.max = pdata->num_drc_cfgs;
2919 wm8994->drc_enum.texts = wm8994->drc_texts; 2947 wm8994->drc_enum.texts = wm8994->drc_texts;
2920 2948
2921 ret = snd_soc_add_controls(wm8994->codec, controls, 2949 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2922 ARRAY_SIZE(controls)); 2950 ARRAY_SIZE(controls));
2923 if (ret != 0) 2951 if (ret != 0)
2924 dev_err(wm8994->codec->dev, 2952 dev_err(wm8994->codec->dev,
@@ -2934,7 +2962,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2934 if (pdata->num_retune_mobile_cfgs) 2962 if (pdata->num_retune_mobile_cfgs)
2935 wm8994_handle_retune_mobile_pdata(wm8994); 2963 wm8994_handle_retune_mobile_pdata(wm8994);
2936 else 2964 else
2937 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 2965 snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
2938 ARRAY_SIZE(wm8994_eq_controls)); 2966 ARRAY_SIZE(wm8994_eq_controls));
2939 2967
2940 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { 2968 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -2951,8 +2979,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2951 * @codec: WM8994 codec 2979 * @codec: WM8994 codec
2952 * @jack: jack to report detection events on 2980 * @jack: jack to report detection events on
2953 * @micbias: microphone bias to detect on 2981 * @micbias: microphone bias to detect on
2954 * @det: value to report for presence detection
2955 * @shrt: value to report for short detection
2956 * 2982 *
2957 * Enable microphone detection via IRQ on the WM8994. If GPIOs are 2983 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
2958 * being used to bring out signals to the processor then only platform 2984 * being used to bring out signals to the processor then only platform
@@ -2963,43 +2989,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2963 * and micbias2_lvl platform data members. 2989 * and micbias2_lvl platform data members.
2964 */ 2990 */
2965int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 2991int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2966 int micbias, int det, int shrt) 2992 int micbias)
2967{ 2993{
2968 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2994 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2969 struct wm8994_micdet *micdet; 2995 struct wm8994_micdet *micdet;
2970 struct wm8994 *control = wm8994->wm8994; 2996 struct wm8994 *control = wm8994->wm8994;
2971 int reg; 2997 int reg, ret;
2972 2998
2973 if (control->type != WM8994) 2999 if (control->type != WM8994) {
3000 dev_warn(codec->dev, "Not a WM8994\n");
2974 return -EINVAL; 3001 return -EINVAL;
3002 }
2975 3003
2976 switch (micbias) { 3004 switch (micbias) {
2977 case 1: 3005 case 1:
2978 micdet = &wm8994->micdet[0]; 3006 micdet = &wm8994->micdet[0];
3007 if (jack)
3008 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3009 "MICBIAS1");
3010 else
3011 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3012 "MICBIAS1");
2979 break; 3013 break;
2980 case 2: 3014 case 2:
2981 micdet = &wm8994->micdet[1]; 3015 micdet = &wm8994->micdet[1];
3016 if (jack)
3017 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3018 "MICBIAS1");
3019 else
3020 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3021 "MICBIAS1");
2982 break; 3022 break;
2983 default: 3023 default:
3024 dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
2984 return -EINVAL; 3025 return -EINVAL;
2985 } 3026 }
2986 3027
2987 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", 3028 if (ret != 0)
2988 micbias, det, shrt); 3029 dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
3030 micbias, ret);
3031
3032 dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
3033 micbias, jack);
2989 3034
2990 /* Store the configuration */ 3035 /* Store the configuration */
2991 micdet->jack = jack; 3036 micdet->jack = jack;
2992 micdet->det = det; 3037 micdet->detecting = true;
2993 micdet->shrt = shrt;
2994 3038
2995 /* If either of the jacks is set up then enable detection */ 3039 /* If either of the jacks is set up then enable detection */
2996 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) 3040 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2997 reg = WM8994_MICD_ENA; 3041 reg = WM8994_MICD_ENA;
2998 else 3042 else
2999 reg = 0; 3043 reg = 0;
3000 3044
3001 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); 3045 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3002 3046
3047 snd_soc_dapm_sync(&codec->dapm);
3048
3003 return 0; 3049 return 0;
3004} 3050}
3005EXPORT_SYMBOL_GPL(wm8994_mic_detect); 3051EXPORT_SYMBOL_GPL(wm8994_mic_detect);
@@ -3025,20 +3071,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3025 dev_dbg(codec->dev, "Microphone status: %x\n", reg); 3071 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3026 3072
3027 report = 0; 3073 report = 0;
3028 if (reg & WM8994_MIC1_DET_STS) 3074 if (reg & WM8994_MIC1_DET_STS) {
3029 report |= priv->micdet[0].det; 3075 if (priv->micdet[0].detecting)
3030 if (reg & WM8994_MIC1_SHRT_STS) 3076 report = SND_JACK_HEADSET;
3031 report |= priv->micdet[0].shrt; 3077 }
3078 if (reg & WM8994_MIC1_SHRT_STS) {
3079 if (priv->micdet[0].detecting)
3080 report = SND_JACK_HEADPHONE;
3081 else
3082 report |= SND_JACK_BTN_0;
3083 }
3084 if (report)
3085 priv->micdet[0].detecting = false;
3086 else
3087 priv->micdet[0].detecting = true;
3088
3032 snd_soc_jack_report(priv->micdet[0].jack, report, 3089 snd_soc_jack_report(priv->micdet[0].jack, report,
3033 priv->micdet[0].det | priv->micdet[0].shrt); 3090 SND_JACK_HEADSET | SND_JACK_BTN_0);
3034 3091
3035 report = 0; 3092 report = 0;
3036 if (reg & WM8994_MIC2_DET_STS) 3093 if (reg & WM8994_MIC2_DET_STS) {
3037 report |= priv->micdet[1].det; 3094 if (priv->micdet[1].detecting)
3038 if (reg & WM8994_MIC2_SHRT_STS) 3095 report = SND_JACK_HEADSET;
3039 report |= priv->micdet[1].shrt; 3096 }
3097 if (reg & WM8994_MIC2_SHRT_STS) {
3098 if (priv->micdet[1].detecting)
3099 report = SND_JACK_HEADPHONE;
3100 else
3101 report |= SND_JACK_BTN_0;
3102 }
3103 if (report)
3104 priv->micdet[1].detecting = false;
3105 else
3106 priv->micdet[1].detecting = true;
3107
3040 snd_soc_jack_report(priv->micdet[1].jack, report, 3108 snd_soc_jack_report(priv->micdet[1].jack, report,
3041 priv->micdet[1].det | priv->micdet[1].shrt); 3109 SND_JACK_HEADSET | SND_JACK_BTN_0);
3042 3110
3043 return IRQ_HANDLED; 3111 return IRQ_HANDLED;
3044} 3112}
@@ -3087,7 +3155,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3087 } 3155 }
3088 3156
3089 3157
3090 if (wm8994->mic_detecting && status & 0x4) { 3158 if (wm8994->mic_detecting && status & 0xfc) {
3091 dev_dbg(codec->dev, "Detected headphone\n"); 3159 dev_dbg(codec->dev, "Detected headphone\n");
3092 wm8994->mic_detecting = false; 3160 wm8994->mic_detecting = false;
3093 3161
@@ -3098,11 +3166,23 @@ static void wm8958_default_micdet(u16 status, void *data)
3098 3166
3099 /* If we have jackdet that will detect removal */ 3167 /* If we have jackdet that will detect removal */
3100 if (wm8994->jackdet) { 3168 if (wm8994->jackdet) {
3169 mutex_lock(&wm8994->accdet_lock);
3170
3101 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3171 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3102 WM8958_MICD_ENA, 0); 3172 WM8958_MICD_ENA, 0);
3103 3173
3104 wm1811_jackdet_set_mode(codec, 3174 wm1811_jackdet_set_mode(codec,
3105 WM1811_JACKDET_MODE_JACK); 3175 WM1811_JACKDET_MODE_JACK);
3176
3177 mutex_unlock(&wm8994->accdet_lock);
3178
3179 if (wm8994->pdata->jd_ext_cap) {
3180 mutex_lock(&codec->mutex);
3181 snd_soc_dapm_disable_pin(&codec->dapm,
3182 "MICBIAS2");
3183 snd_soc_dapm_sync(&codec->dapm);
3184 mutex_unlock(&codec->mutex);
3185 }
3106 } 3186 }
3107 } 3187 }
3108 3188
@@ -3137,6 +3217,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3137 struct wm8994_priv *wm8994 = data; 3217 struct wm8994_priv *wm8994 = data;
3138 struct snd_soc_codec *codec = wm8994->codec; 3218 struct snd_soc_codec *codec = wm8994->codec;
3139 int reg; 3219 int reg;
3220 bool present;
3140 3221
3141 mutex_lock(&wm8994->accdet_lock); 3222 mutex_lock(&wm8994->accdet_lock);
3142 3223
@@ -3149,11 +3230,17 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3149 3230
3150 dev_dbg(codec->dev, "JACKDET %x\n", reg); 3231 dev_dbg(codec->dev, "JACKDET %x\n", reg);
3151 3232
3152 if (reg & WM1811_JACKDET_LVL) { 3233 present = reg & WM1811_JACKDET_LVL;
3234
3235 if (present) {
3153 dev_dbg(codec->dev, "Jack detected\n"); 3236 dev_dbg(codec->dev, "Jack detected\n");
3154 3237
3155 snd_soc_jack_report(wm8994->micdet[0].jack, 3238 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3156 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); 3239 WM8958_MICB2_DISCH, 0);
3240
3241 /* Disable debounce while inserted */
3242 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3243 WM1811_JACKDET_DB, 0);
3157 3244
3158 /* 3245 /*
3159 * Start off measument of microphone impedence to find 3246 * Start off measument of microphone impedence to find
@@ -3161,14 +3248,18 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3161 */ 3248 */
3162 wm8994->mic_detecting = true; 3249 wm8994->mic_detecting = true;
3163 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); 3250 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
3251
3164 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3252 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3165 WM8958_MICD_ENA, WM8958_MICD_ENA); 3253 WM8958_MICD_ENA, WM8958_MICD_ENA);
3166 } else { 3254 } else {
3167 dev_dbg(codec->dev, "Jack not detected\n"); 3255 dev_dbg(codec->dev, "Jack not detected\n");
3168 3256
3169 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 3257 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3170 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3258 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
3171 wm8994->btn_mask); 3259
3260 /* Enable debounce while removed */
3261 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3262 WM1811_JACKDET_DB, WM1811_JACKDET_DB);
3172 3263
3173 wm8994->mic_detecting = false; 3264 wm8994->mic_detecting = false;
3174 wm8994->jack_mic = false; 3265 wm8994->jack_mic = false;
@@ -3179,6 +3270,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3179 3270
3180 mutex_unlock(&wm8994->accdet_lock); 3271 mutex_unlock(&wm8994->accdet_lock);
3181 3272
3273 /* If required for an external cap force MICBIAS on */
3274 if (wm8994->pdata->jd_ext_cap) {
3275 mutex_lock(&codec->mutex);
3276
3277 if (present)
3278 snd_soc_dapm_force_enable_pin(&codec->dapm,
3279 "MICBIAS2");
3280 else
3281 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3282
3283 snd_soc_dapm_sync(&codec->dapm);
3284 mutex_unlock(&codec->mutex);
3285 }
3286
3287 if (present)
3288 snd_soc_jack_report(wm8994->micdet[0].jack,
3289 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
3290 else
3291 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3292 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3293 wm8994->btn_mask);
3294
3182 return IRQ_HANDLED; 3295 return IRQ_HANDLED;
3183} 3296}
3184 3297
@@ -3221,6 +3334,7 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3221 } 3334 }
3222 3335
3223 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); 3336 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
3337 snd_soc_dapm_sync(&codec->dapm);
3224 3338
3225 wm8994->micdet[0].jack = jack; 3339 wm8994->micdet[0].jack = jack;
3226 wm8994->jack_cb = cb; 3340 wm8994->jack_cb = cb;
@@ -3251,6 +3365,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3251 * otherwise jump straight to microphone detection. 3365 * otherwise jump straight to microphone detection.
3252 */ 3366 */
3253 if (wm8994->jackdet) { 3367 if (wm8994->jackdet) {
3368 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3369 WM8958_MICB2_DISCH,
3370 WM8958_MICB2_DISCH);
3254 snd_soc_update_bits(codec, WM8994_LDO_1, 3371 snd_soc_update_bits(codec, WM8994_LDO_1,
3255 WM8994_LDO1_DISCH, 0); 3372 WM8994_LDO1_DISCH, 0);
3256 wm1811_jackdet_set_mode(codec, 3373 wm1811_jackdet_set_mode(codec,
@@ -3263,7 +3380,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3263 } else { 3380 } else {
3264 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3381 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3265 WM8958_MICD_ENA, 0); 3382 WM8958_MICD_ENA, 0);
3383 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE);
3266 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); 3384 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS");
3385 snd_soc_dapm_sync(&codec->dapm);
3267 } 3386 }
3268 3387
3269 return 0; 3388 return 0;
@@ -3276,17 +3395,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3276 struct snd_soc_codec *codec = wm8994->codec; 3395 struct snd_soc_codec *codec = wm8994->codec;
3277 int reg, count; 3396 int reg, count;
3278 3397
3279 mutex_lock(&wm8994->accdet_lock);
3280
3281 /* 3398 /*
3282 * Jack detection may have detected a removal simulataneously 3399 * Jack detection may have detected a removal simulataneously
3283 * with an update of the MICDET status; if so it will have 3400 * with an update of the MICDET status; if so it will have
3284 * stopped detection and we can ignore this interrupt. 3401 * stopped detection and we can ignore this interrupt.
3285 */ 3402 */
3286 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { 3403 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
3287 mutex_unlock(&wm8994->accdet_lock);
3288 return IRQ_HANDLED; 3404 return IRQ_HANDLED;
3289 }
3290 3405
3291 /* We may occasionally read a detection without an impedence 3406 /* We may occasionally read a detection without an impedence
3292 * range being provided - if that happens loop again. 3407 * range being provided - if that happens loop again.
@@ -3295,7 +3410,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3295 do { 3410 do {
3296 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); 3411 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
3297 if (reg < 0) { 3412 if (reg < 0) {
3298 mutex_unlock(&wm8994->accdet_lock);
3299 dev_err(codec->dev, 3413 dev_err(codec->dev,
3300 "Failed to read mic detect status: %d\n", 3414 "Failed to read mic detect status: %d\n",
3301 reg); 3415 reg);
@@ -3326,8 +3440,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3326 dev_warn(codec->dev, "Accessory detection with no callback\n"); 3440 dev_warn(codec->dev, "Accessory detection with no callback\n");
3327 3441
3328out: 3442out:
3329 mutex_unlock(&wm8994->accdet_lock);
3330
3331 return IRQ_HANDLED; 3443 return IRQ_HANDLED;
3332} 3444}
3333 3445
@@ -3361,23 +3473,16 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data)
3361static int wm8994_codec_probe(struct snd_soc_codec *codec) 3473static int wm8994_codec_probe(struct snd_soc_codec *codec)
3362{ 3474{
3363 struct wm8994 *control = dev_get_drvdata(codec->dev->parent); 3475 struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
3364 struct wm8994_priv *wm8994; 3476 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3365 struct snd_soc_dapm_context *dapm = &codec->dapm; 3477 struct snd_soc_dapm_context *dapm = &codec->dapm;
3366 unsigned int reg; 3478 unsigned int reg;
3367 int ret, i; 3479 int ret, i;
3368 3480
3481 wm8994->codec = codec;
3369 codec->control_data = control->regmap; 3482 codec->control_data = control->regmap;
3370 3483
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); 3484 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
3378 3485
3379 wm8994->wm8994 = dev_get_drvdata(codec->dev->parent);
3380 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3381 wm8994->codec = codec; 3486 wm8994->codec = codec;
3382 3487
3383 mutex_init(&wm8994->accdet_lock); 3488 mutex_init(&wm8994->accdet_lock);
@@ -3392,12 +3497,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3392 WM8994_IRQ_MIC1_DET; 3497 WM8994_IRQ_MIC1_DET;
3393 3498
3394 pm_runtime_enable(codec->dev); 3499 pm_runtime_enable(codec->dev);
3395 pm_runtime_resume(codec->dev); 3500 pm_runtime_idle(codec->dev);
3501
3502 /* By default use idle_bias_off, will override for WM8994 */
3503 codec->dapm.idle_bias_off = 1;
3396 3504
3397 /* Set revision-specific configuration */ 3505 /* Set revision-specific configuration */
3398 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 3506 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3399 switch (control->type) { 3507 switch (control->type) {
3400 case WM8994: 3508 case WM8994:
3509 /* Single ended line outputs should have VMID on. */
3510 if (!wm8994->pdata->lineout1_diff ||
3511 !wm8994->pdata->lineout2_diff)
3512 codec->dapm.idle_bias_off = 0;
3513
3401 switch (wm8994->revision) { 3514 switch (wm8994->revision) {
3402 case 2: 3515 case 2:
3403 case 3: 3516 case 3:
@@ -3415,11 +3528,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3415 3528
3416 case WM8958: 3529 case WM8958:
3417 wm8994->hubs.dcs_readback_mode = 1; 3530 wm8994->hubs.dcs_readback_mode = 1;
3531 wm8994->hubs.hp_startup_mode = 1;
3418 break; 3532 break;
3419 3533
3420 case WM1811: 3534 case WM1811:
3421 wm8994->hubs.dcs_readback_mode = 2; 3535 wm8994->hubs.dcs_readback_mode = 2;
3422 wm8994->hubs.no_series_update = 1; 3536 wm8994->hubs.no_series_update = 1;
3537 wm8994->hubs.hp_startup_mode = 1;
3538 wm8994->hubs.no_cache_class_w = true;
3423 3539
3424 switch (wm8994->revision) { 3540 switch (wm8994->revision) {
3425 case 0: 3541 case 0:
@@ -3536,6 +3652,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3536 wm8994->fll_locked_irq = false; 3652 wm8994->fll_locked_irq = false;
3537 } 3653 }
3538 3654
3655 /* Make sure we can read from the GPIOs if they're inputs */
3656 pm_runtime_get_sync(codec->dev);
3657
3539 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3658 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3540 * configured on init - if a system wants to do this dynamically 3659 * configured on init - if a system wants to do this dynamically
3541 * at runtime we can deal with that then. 3660 * at runtime we can deal with that then.
@@ -3564,7 +3683,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3564 wm8994->lrclk_shared[1] = 0; 3683 wm8994->lrclk_shared[1] = 0;
3565 } 3684 }
3566 3685
3567 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3686 pm_runtime_put(codec->dev);
3568 3687
3569 /* Latch volume updates (right only; we always do left then right). */ 3688 /* Latch volume updates (right only; we always do left then right). */
3570 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, 3689 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
@@ -3642,7 +3761,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3642 wm8994_handle_pdata(wm8994); 3761 wm8994_handle_pdata(wm8994);
3643 3762
3644 wm_hubs_add_analogue_controls(codec); 3763 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls, 3764 snd_soc_add_codec_controls(codec, wm8994_snd_controls,
3646 ARRAY_SIZE(wm8994_snd_controls)); 3765 ARRAY_SIZE(wm8994_snd_controls));
3647 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, 3766 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
3648 ARRAY_SIZE(wm8994_dapm_widgets)); 3767 ARRAY_SIZE(wm8994_dapm_widgets));
@@ -3668,7 +3787,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3668 } 3787 }
3669 break; 3788 break;
3670 case WM8958: 3789 case WM8958:
3671 snd_soc_add_controls(codec, wm8958_snd_controls, 3790 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3672 ARRAY_SIZE(wm8958_snd_controls)); 3791 ARRAY_SIZE(wm8958_snd_controls));
3673 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3792 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3674 ARRAY_SIZE(wm8958_dapm_widgets)); 3793 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3690,7 +3809,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3690 break; 3809 break;
3691 3810
3692 case WM1811: 3811 case WM1811:
3693 snd_soc_add_controls(codec, wm8958_snd_controls, 3812 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3694 ARRAY_SIZE(wm8958_snd_controls)); 3813 ARRAY_SIZE(wm8958_snd_controls));
3695 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3814 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3696 ARRAY_SIZE(wm8958_dapm_widgets)); 3815 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3819,24 +3938,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3819 return 0; 3938 return 0;
3820} 3939}
3821 3940
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 = { 3941static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
3829 .probe = wm8994_codec_probe, 3942 .probe = wm8994_codec_probe,
3830 .remove = wm8994_codec_remove, 3943 .remove = wm8994_codec_remove,
3831 .suspend = wm8994_suspend, 3944 .suspend = wm8994_codec_suspend,
3832 .resume = wm8994_resume, 3945 .resume = wm8994_codec_resume,
3833 .set_bias_level = wm8994_set_bias_level, 3946 .set_bias_level = wm8994_set_bias_level,
3834 .reg_cache_size = WM8994_MAX_REGISTER,
3835 .volatile_register = wm8994_soc_volatile,
3836}; 3947};
3837 3948
3838static int __devinit wm8994_probe(struct platform_device *pdev) 3949static int __devinit wm8994_probe(struct platform_device *pdev)
3839{ 3950{
3951 struct wm8994_priv *wm8994;
3952
3953 wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv),
3954 GFP_KERNEL);
3955 if (wm8994 == NULL)
3956 return -ENOMEM;
3957 platform_set_drvdata(pdev, wm8994);
3958
3959 wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
3960 wm8994->pdata = dev_get_platdata(pdev->dev.parent);
3961
3840 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, 3962 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
3841 wm8994_dai, ARRAY_SIZE(wm8994_dai)); 3963 wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842} 3964}
@@ -3847,11 +3969,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev)
3847 return 0; 3969 return 0;
3848} 3970}
3849 3971
3972#ifdef CONFIG_PM_SLEEP
3973static int wm8994_suspend(struct device *dev)
3974{
3975 struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
3976
3977 /* Drop down to power saving mode when system is suspended */
3978 if (wm8994->jackdet && !wm8994->active_refcount)
3979 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
3980 WM1811_JACKDET_MODE_MASK,
3981 wm8994->jackdet_mode);
3982
3983 return 0;
3984}
3985
3986static int wm8994_resume(struct device *dev)
3987{
3988 struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
3989
3990 if (wm8994->jackdet && wm8994->jack_cb)
3991 regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
3992 WM1811_JACKDET_MODE_MASK,
3993 WM1811_JACKDET_MODE_AUDIO);
3994
3995 return 0;
3996}
3997#endif
3998
3999static const struct dev_pm_ops wm8994_pm_ops = {
4000 SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
4001};
4002
3850static struct platform_driver wm8994_codec_driver = { 4003static struct platform_driver wm8994_codec_driver = {
3851 .driver = { 4004 .driver = {
3852 .name = "wm8994-codec", 4005 .name = "wm8994-codec",
3853 .owner = THIS_MODULE, 4006 .owner = THIS_MODULE,
3854 }, 4007 .pm = &wm8994_pm_ops,
4008 },
3855 .probe = wm8994_probe, 4009 .probe = wm8994_probe,
3856 .remove = __devexit_p(wm8994_remove), 4010 .remove = __devexit_p(wm8994_remove),
3857}; 4011};
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index c3a42474ab19..2f4d2d12a452 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -35,7 +35,7 @@
35typedef void (*wm8958_micdet_cb)(u16 status, void *data); 35typedef void (*wm8958_micdet_cb)(u16 status, void *data);
36 36
37int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 37int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
38 int micbias, int det, int shrt); 38 int micbias);
39int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 39int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
40 wm8958_micdet_cb cb, void *cb_data); 40 wm8958_micdet_cb cb, void *cb_data);
41 41
@@ -46,8 +46,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec);
46 46
47struct wm8994_micdet { 47struct wm8994_micdet {
48 struct snd_soc_jack *jack; 48 struct snd_soc_jack *jack;
49 int det; 49 bool detecting;
50 int shrt;
51}; 50};
52 51
53/* codec private data */ 52/* codec private data */
@@ -123,6 +122,7 @@ struct wm8994_priv {
123 bool jack_mic; 122 bool jack_mic;
124 int btn_mask; 123 int btn_mask;
125 bool jackdet; 124 bool jackdet;
125 int jackdet_mode;
126 126
127 wm8958_micdet_cb jack_cb; 127 wm8958_micdet_cb jack_cb;
128 void *jack_cb_data; 128 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..40a124c9f15d 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,
@@ -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,8 +3057,6 @@ 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 |\
@@ -3087,6 +3080,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3087 .channels_max = 6, 3080 .channels_max = 6,
3088 .rates = WM8996_RATES, 3081 .rates = WM8996_RATES,
3089 .formats = WM8996_FORMATS, 3082 .formats = WM8996_FORMATS,
3083 .sig_bits = 24,
3090 }, 3084 },
3091 .capture = { 3085 .capture = {
3092 .stream_name = "AIF1 Capture", 3086 .stream_name = "AIF1 Capture",
@@ -3094,6 +3088,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3094 .channels_max = 6, 3088 .channels_max = 6,
3095 .rates = WM8996_RATES, 3089 .rates = WM8996_RATES,
3096 .formats = WM8996_FORMATS, 3090 .formats = WM8996_FORMATS,
3091 .sig_bits = 24,
3097 }, 3092 },
3098 .ops = &wm8996_dai_ops, 3093 .ops = &wm8996_dai_ops,
3099 }, 3094 },
@@ -3105,6 +3100,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3105 .channels_max = 2, 3100 .channels_max = 2,
3106 .rates = WM8996_RATES, 3101 .rates = WM8996_RATES,
3107 .formats = WM8996_FORMATS, 3102 .formats = WM8996_FORMATS,
3103 .sig_bits = 24,
3108 }, 3104 },
3109 .capture = { 3105 .capture = {
3110 .stream_name = "AIF2 Capture", 3106 .stream_name = "AIF2 Capture",
@@ -3112,6 +3108,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
3112 .channels_max = 2, 3108 .channels_max = 2,
3113 .rates = WM8996_RATES, 3109 .rates = WM8996_RATES,
3114 .formats = WM8996_FORMATS, 3110 .formats = WM8996_FORMATS,
3111 .sig_bits = 24,
3115 }, 3112 },
3116 .ops = &wm8996_dai_ops, 3113 .ops = &wm8996_dai_ops,
3117 }, 3114 },
@@ -3149,25 +3146,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3149 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3146 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3150 wm8996->supplies[i].supply = wm8996_supply_names[i]; 3147 wm8996->supplies[i].supply = wm8996_supply_names[i];
3151 3148
3152 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), 3149 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
3153 wm8996->supplies); 3150 wm8996->supplies);
3154 if (ret != 0) { 3151 if (ret != 0) {
3155 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); 3152 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
3156 goto err_gpio; 3153 goto err_gpio;
3157 } 3154 }
3158 3155
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), 3156 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3167 wm8996->supplies); 3157 wm8996->supplies);
3168 if (ret != 0) { 3158 if (ret != 0) {
3169 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 3159 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
3170 goto err_cpvdd; 3160 goto err_gpio;
3171 } 3161 }
3172 3162
3173 if (wm8996->pdata.ldo_ena > 0) { 3163 if (wm8996->pdata.ldo_ena > 0) {
@@ -3188,7 +3178,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3188 goto err_regmap; 3178 goto err_regmap;
3189 } 3179 }
3190 if (reg != 0x8915) { 3180 if (reg != 0x8915) {
3191 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); 3181 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);
3192 ret = -EINVAL; 3182 ret = -EINVAL;
3193 goto err_regmap; 3183 goto err_regmap;
3194 } 3184 }
@@ -3229,10 +3219,6 @@ err_enable:
3229 if (wm8996->pdata.ldo_ena > 0) 3219 if (wm8996->pdata.ldo_ena > 0)
3230 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3220 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3231 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3221 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: 3222err_gpio:
3237 if (wm8996->pdata.ldo_ena > 0) 3223 if (wm8996->pdata.ldo_ena > 0)
3238 gpio_free(wm8996->pdata.ldo_ena); 3224 gpio_free(wm8996->pdata.ldo_ena);
@@ -3247,8 +3233,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3247 3233
3248 snd_soc_unregister_codec(&client->dev); 3234 snd_soc_unregister_codec(&client->dev);
3249 wm8996_free_gpio(wm8996); 3235 wm8996_free_gpio(wm8996);
3250 regulator_put(wm8996->cpvdd);
3251 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3252 regmap_exit(wm8996->regmap); 3236 regmap_exit(wm8996->regmap);
3253 if (wm8996->pdata.ldo_ena > 0) { 3237 if (wm8996->pdata.ldo_ena > 0) {
3254 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3238 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3273,25 +3257,7 @@ static struct i2c_driver wm8996_i2c_driver = {
3273 .id_table = wm8996_i2c_id, 3257 .id_table = wm8996_i2c_id,
3274}; 3258};
3275 3259
3276static int __init wm8996_modinit(void) 3260module_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 3261
3296MODULE_DESCRIPTION("ASoC WM8996 driver"); 3262MODULE_DESCRIPTION("ASoC WM8996 driver");
3297MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3263MODULE_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..c08d1c2f346f 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),
@@ -640,9 +670,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
640 670
641SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, 671SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
642 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 672 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
643SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 673SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
644 NULL, 0, 674 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 675
647SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 676SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
648 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), 677 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
@@ -656,10 +685,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
656 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), 685 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
657 686
658SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), 687SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
659SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, 688SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
660 NULL, 0), 689 NULL, 0),
661SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, 690SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
662 NULL, 0), 691 NULL, 0),
663 692
664SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, 693SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
665 line1_mix, ARRAY_SIZE(line1_mix)), 694 line1_mix, ARRAY_SIZE(line1_mix)),
@@ -675,14 +704,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
675SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, 704SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
676 line2p_mix, ARRAY_SIZE(line2p_mix)), 705 line2p_mix, ARRAY_SIZE(line2p_mix)),
677 706
678SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, 707SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
679 NULL, 0), 708 NULL, 0, lineout_event,
680SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, 709 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
681 NULL, 0), 710SND_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, 711 NULL, 0, lineout_event,
683 NULL, 0), 712 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
684SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, 713SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
685 NULL, 0), 714 NULL, 0, lineout_event,
715 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
716SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
717 NULL, 0, lineout_event,
718 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
686 719
687SND_SOC_DAPM_OUTPUT("SPKOUTLP"), 720SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
688SND_SOC_DAPM_OUTPUT("SPKOUTLN"), 721SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
@@ -901,7 +934,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
901 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 934 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
902 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 935 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
903 936
904 snd_soc_add_controls(codec, analogue_snd_controls, 937 snd_soc_add_codec_controls(codec, analogue_snd_controls,
905 ARRAY_SIZE(analogue_snd_controls)); 938 ARRAY_SIZE(analogue_snd_controls));
906 939
907 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, 940 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
@@ -949,6 +982,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
949 int jd_scthr, int jd_thr, int micbias1_lvl, 982 int jd_scthr, int jd_thr, int micbias1_lvl,
950 int micbias2_lvl) 983 int micbias2_lvl)
951{ 984{
985 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
986
987 hubs->lineout1_se = !lineout1_diff;
988 hubs->lineout2_se = !lineout2_diff;
989
952 if (!lineout1_diff) 990 if (!lineout1_diff)
953 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 991 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
954 WM8993_LINEOUT1_MODE, 992 WM8993_LINEOUT1_MODE,
@@ -958,12 +996,6 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
958 WM8993_LINEOUT2_MODE, 996 WM8993_LINEOUT2_MODE,
959 WM8993_LINEOUT2_MODE); 997 WM8993_LINEOUT2_MODE);
960 998
961 /* If the line outputs are differential then we aren't presenting
962 * VMID as an output and can disable it.
963 */
964 if (lineout1_diff && lineout2_diff)
965 codec->dapm.idle_bias_off = 1;
966
967 if (lineout1fb) 999 if (lineout1fb)
968 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 1000 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
969 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); 1001 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
@@ -984,6 +1016,74 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
984} 1016}
985EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); 1017EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
986 1018
1019void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
1020{
1021 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1022 int val = 0;
1023
1024 if (hubs->lineout1_se)
1025 val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
1026
1027 if (hubs->lineout2_se)
1028 val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
1029
1030 /* Enable the line outputs while we power up */
1031 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
1032}
1033EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
1034
1035void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
1036 enum snd_soc_bias_level level)
1037{
1038 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1039 int val;
1040
1041 switch (level) {
1042 case SND_SOC_BIAS_STANDBY:
1043 /* Clamp the inputs to VMID while we ramp to charge caps */
1044 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1045 WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
1046 break;
1047
1048 case SND_SOC_BIAS_ON:
1049 /* Turn off any unneded single ended outputs */
1050 val = 0;
1051
1052 if (hubs->lineout1_se && hubs->lineout1n_ena)
1053 val |= WM8993_LINEOUT1N_ENA;
1054
1055 if (hubs->lineout1_se && hubs->lineout1p_ena)
1056 val |= WM8993_LINEOUT1P_ENA;
1057
1058 if (hubs->lineout2_se && hubs->lineout2n_ena)
1059 val |= WM8993_LINEOUT2N_ENA;
1060
1061 if (hubs->lineout2_se && hubs->lineout2p_ena)
1062 val |= WM8993_LINEOUT2P_ENA;
1063
1064 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
1065 WM8993_LINEOUT1N_ENA |
1066 WM8993_LINEOUT1P_ENA |
1067 WM8993_LINEOUT2N_ENA |
1068 WM8993_LINEOUT2P_ENA,
1069 val);
1070
1071 if (!hubs->lineout1n_ena && !hubs->lineout1p_ena &&
1072 !hubs->lineout2n_ena && !hubs->lineout2p_ena)
1073 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1074 WM8993_LINEOUT_VMID_BUF_ENA, 0);
1075
1076 /* Remove the input clamps */
1077 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1078 WM8993_INPUTS_CLAMP, 0);
1079 break;
1080
1081 default:
1082 break;
1083 }
1084}
1085EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
1086
987MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 1087MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
988MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1088MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
989MODULE_LICENSE("GPL"); 1089MODULE_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/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index bae5cbbbd2b2..e01cb02abd3a 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -85,9 +85,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev)
85 struct snd_soc_card *card = &snd_soc_edb93xx; 85 struct snd_soc_card *card = &snd_soc_edb93xx;
86 int ret; 86 int ret;
87 87
88 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 88 ret = ep93xx_i2s_acquire();
89 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
90 EP93XX_SYSCON_I2SCLKDIV_SPOL);
91 if (ret) 89 if (ret)
92 return ret; 90 return ret;
93 91
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/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index ccae34a3f280..a193cea3cf3c 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -103,9 +103,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev)
103 struct snd_soc_card *card = &snd_soc_snappercl15; 103 struct snd_soc_card *card = &snd_soc_snappercl15;
104 int ret; 104 int ret;
105 105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 106 ret = ep93xx_i2s_acquire();
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret) 107 if (ret)
110 return ret; 108 return ret;
111 109
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..b88987083475 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;
@@ -543,6 +543,11 @@ static struct platform_driver p1022_ds_driver = {
543 .probe = p1022_ds_probe, 543 .probe = p1022_ds_probe,
544 .remove = __devexit_p(p1022_ds_remove), 544 .remove = __devexit_p(p1022_ds_remove),
545 .driver = { 545 .driver = {
546 /*
547 * The name must match 'compatible' property in the device tree,
548 * in lowercase letters.
549 */
550 .name = "snd-soc-p1022ds",
546 .owner = THIS_MODULE, 551 .owner = THIS_MODULE,
547 }, 552 },
548}; 553};
@@ -556,33 +561,6 @@ static int __init p1022_ds_init(void)
556{ 561{
557 struct device_node *guts_np; 562 struct device_node *guts_np;
558 struct resource res; 563 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 564
587 /* Get the physical address of the global utilities registers */ 565 /* Get the physical address of the global utilities registers */
588 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); 566 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..a16df0fa6eff 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -764,7 +764,8 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai)
764 764
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
766 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 766 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
767 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 767 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
768 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
768 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 769 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
769 770
770#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 771#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..6553b19c70c7 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
@@ -761,15 +761,13 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
761 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 761 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
762 local_irq_save(flags); 762 local_irq_save(flags);
763 763
764 if (capture) 764 if (capture) {
765 i2s_rxctrl(i2s, 0); 765 i2s_rxctrl(i2s, 0);
766 else
767 i2s_txctrl(i2s, 0);
768
769 if (capture)
770 i2s_fifo(i2s, FIC_RXFLUSH); 766 i2s_fifo(i2s, FIC_RXFLUSH);
771 else 767 } else {
768 i2s_txctrl(i2s, 0);
772 i2s_fifo(i2s, FIC_TXFLUSH); 769 i2s_fifo(i2s, FIC_TXFLUSH);
770 }
773 771
774 local_irq_restore(flags); 772 local_irq_restore(flags);
775 break; 773 break;
@@ -1143,7 +1141,7 @@ static struct platform_driver samsung_i2s_driver = {
1143module_platform_driver(samsung_i2s_driver); 1141module_platform_driver(samsung_i2s_driver);
1144 1142
1145/* Module information */ 1143/* Module information */
1146MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 1144MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
1147MODULE_DESCRIPTION("Samsung I2S Interface"); 1145MODULE_DESCRIPTION("Samsung I2S Interface");
1148MODULE_ALIAS("platform:samsung-i2s"); 1146MODULE_ALIAS("platform:samsung-i2s");
1149MODULE_LICENSE("GPL"); 1147MODULE_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..93a0daac5088 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
@@ -1676,7 +1725,10 @@ EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1676const struct dev_pm_ops snd_soc_pm_ops = { 1725const struct dev_pm_ops snd_soc_pm_ops = {
1677 .suspend = snd_soc_suspend, 1726 .suspend = snd_soc_suspend,
1678 .resume = snd_soc_resume, 1727 .resume = snd_soc_resume,
1728 .freeze = snd_soc_suspend,
1729 .thaw = snd_soc_resume,
1679 .poweroff = snd_soc_poweroff, 1730 .poweroff = snd_soc_poweroff,
1731 .restore = snd_soc_resume,
1680}; 1732};
1681EXPORT_SYMBOL_GPL(snd_soc_pm_ops); 1733EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
1682 1734
@@ -1880,23 +1932,28 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
1880int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 1932int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1881 unsigned int mask, unsigned int value) 1933 unsigned int mask, unsigned int value)
1882{ 1934{
1883 int change; 1935 bool change;
1884 unsigned int old, new; 1936 unsigned int old, new;
1885 int ret; 1937 int ret;
1886 1938
1887 ret = snd_soc_read(codec, reg); 1939 if (codec->using_regmap) {
1888 if (ret < 0) 1940 ret = regmap_update_bits_check(codec->control_data, reg,
1889 return ret; 1941 mask, value, &change);
1890 1942 } else {
1891 old = ret; 1943 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) 1944 if (ret < 0)
1897 return ret; 1945 return ret;
1946
1947 old = ret;
1948 new = (old & ~mask) | (value & mask);
1949 change = old != new;
1950 if (change)
1951 ret = snd_soc_write(codec, reg, new);
1898 } 1952 }
1899 1953
1954 if (ret < 0)
1955 return ret;
1956
1900 return change; 1957 return change;
1901} 1958}
1902EXPORT_SYMBOL_GPL(snd_soc_update_bits); 1959EXPORT_SYMBOL_GPL(snd_soc_update_bits);
@@ -1987,7 +2044,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
1987 * Returns 0 for success, else error. 2044 * Returns 0 for success, else error.
1988 */ 2045 */
1989struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2046struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
1990 void *data, char *long_name, 2047 void *data, const char *long_name,
1991 const char *prefix) 2048 const char *prefix)
1992{ 2049{
1993 struct snd_kcontrol_new template; 2050 struct snd_kcontrol_new template;
@@ -2022,9 +2079,28 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2022} 2079}
2023EXPORT_SYMBOL_GPL(snd_soc_cnew); 2080EXPORT_SYMBOL_GPL(snd_soc_cnew);
2024 2081
2082static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
2083 const struct snd_kcontrol_new *controls, int num_controls,
2084 const char *prefix, void *data)
2085{
2086 int err, i;
2087
2088 for (i = 0; i < num_controls; i++) {
2089 const struct snd_kcontrol_new *control = &controls[i];
2090 err = snd_ctl_add(card, snd_soc_cnew(control, data,
2091 control->name, prefix));
2092 if (err < 0) {
2093 dev_err(dev, "Failed to add %s: %d\n", control->name, err);
2094 return err;
2095 }
2096 }
2097
2098 return 0;
2099}
2100
2025/** 2101/**
2026 * snd_soc_add_controls - add an array of controls to a codec. 2102 * 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 2103 * Convenience function to add a list of controls. Many codecs were
2028 * duplicating this code. 2104 * duplicating this code.
2029 * 2105 *
2030 * @codec: codec to add controls to 2106 * @codec: codec to add controls to
@@ -2033,31 +2109,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew);
2033 * 2109 *
2034 * Return 0 for success, else error. 2110 * Return 0 for success, else error.
2035 */ 2111 */
2036int snd_soc_add_controls(struct snd_soc_codec *codec, 2112int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
2037 const struct snd_kcontrol_new *controls, int num_controls) 2113 const struct snd_kcontrol_new *controls, int num_controls)
2038{ 2114{
2039 struct snd_card *card = codec->card->snd_card; 2115 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 2116
2054 return 0; 2117 return snd_soc_add_controls(card, codec->dev, controls, num_controls,
2118 codec->name_prefix, codec);
2055} 2119}
2056EXPORT_SYMBOL_GPL(snd_soc_add_controls); 2120EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
2057 2121
2058/** 2122/**
2059 * snd_soc_add_platform_controls - add an array of controls to a platform. 2123 * snd_soc_add_platform_controls - add an array of controls to a platform.
2060 * Convienience function to add a list of controls. 2124 * Convenience function to add a list of controls.
2061 * 2125 *
2062 * @platform: platform to add controls to 2126 * @platform: platform to add controls to
2063 * @controls: array of controls to add 2127 * @controls: array of controls to add
@@ -2069,23 +2133,53 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
2069 const struct snd_kcontrol_new *controls, int num_controls) 2133 const struct snd_kcontrol_new *controls, int num_controls)
2070{ 2134{
2071 struct snd_card *card = platform->card->snd_card; 2135 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 2136
2084 return 0; 2137 return snd_soc_add_controls(card, platform->dev, controls, num_controls,
2138 NULL, platform);
2085} 2139}
2086EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); 2140EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
2087 2141
2088/** 2142/**
2143 * snd_soc_add_card_controls - add an array of controls to a SoC card.
2144 * Convenience function to add a list of controls.
2145 *
2146 * @soc_card: SoC card to add controls to
2147 * @controls: array of controls to add
2148 * @num_controls: number of elements in the array
2149 *
2150 * Return 0 for success, else error.
2151 */
2152int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
2153 const struct snd_kcontrol_new *controls, int num_controls)
2154{
2155 struct snd_card *card = soc_card->snd_card;
2156
2157 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
2158 NULL, soc_card);
2159}
2160EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
2161
2162/**
2163 * snd_soc_add_dai_controls - add an array of controls to a DAI.
2164 * Convienience function to add a list of controls.
2165 *
2166 * @dai: DAI to add controls to
2167 * @controls: array of controls to add
2168 * @num_controls: number of elements in the array
2169 *
2170 * Return 0 for success, else error.
2171 */
2172int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
2173 const struct snd_kcontrol_new *controls, int num_controls)
2174{
2175 struct snd_card *card = dai->card->snd_card;
2176
2177 return snd_soc_add_controls(card, dai->dev, controls, num_controls,
2178 NULL, dai);
2179}
2180EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
2181
2182/**
2089 * snd_soc_info_enum_double - enumerated double mixer info callback 2183 * snd_soc_info_enum_double - enumerated double mixer info callback
2090 * @kcontrol: mixer control 2184 * @kcontrol: mixer control
2091 * @uinfo: control element information 2185 * @uinfo: control element information
@@ -2651,6 +2745,115 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2651} 2745}
2652EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); 2746EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2653 2747
2748int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2749 struct snd_ctl_elem_info *uinfo)
2750{
2751 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2752 struct soc_bytes *params = (void *)kcontrol->private_value;
2753
2754 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2755 uinfo->count = params->num_regs * codec->val_bytes;
2756
2757 return 0;
2758}
2759EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
2760
2761int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
2762 struct snd_ctl_elem_value *ucontrol)
2763{
2764 struct soc_bytes *params = (void *)kcontrol->private_value;
2765 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2766 int ret;
2767
2768 if (codec->using_regmap)
2769 ret = regmap_raw_read(codec->control_data, params->base,
2770 ucontrol->value.bytes.data,
2771 params->num_regs * codec->val_bytes);
2772 else
2773 ret = -EINVAL;
2774
2775 /* Hide any masked bytes to ensure consistent data reporting */
2776 if (ret == 0 && params->mask) {
2777 switch (codec->val_bytes) {
2778 case 1:
2779 ucontrol->value.bytes.data[0] &= ~params->mask;
2780 break;
2781 case 2:
2782 ((u16 *)(&ucontrol->value.bytes.data))[0]
2783 &= ~params->mask;
2784 break;
2785 case 4:
2786 ((u32 *)(&ucontrol->value.bytes.data))[0]
2787 &= ~params->mask;
2788 break;
2789 default:
2790 return -EINVAL;
2791 }
2792 }
2793
2794 return ret;
2795}
2796EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
2797
2798int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
2799 struct snd_ctl_elem_value *ucontrol)
2800{
2801 struct soc_bytes *params = (void *)kcontrol->private_value;
2802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2803 int ret, len;
2804 unsigned int val;
2805 void *data;
2806
2807 if (!codec->using_regmap)
2808 return -EINVAL;
2809
2810 data = ucontrol->value.bytes.data;
2811 len = params->num_regs * codec->val_bytes;
2812
2813 /*
2814 * If we've got a mask then we need to preserve the register
2815 * bits. We shouldn't modify the incoming data so take a
2816 * copy.
2817 */
2818 if (params->mask) {
2819 ret = regmap_read(codec->control_data, params->base, &val);
2820 if (ret != 0)
2821 return ret;
2822
2823 val &= params->mask;
2824
2825 data = kmemdup(data, len, GFP_KERNEL);
2826 if (!data)
2827 return -ENOMEM;
2828
2829 switch (codec->val_bytes) {
2830 case 1:
2831 ((u8 *)data)[0] &= ~params->mask;
2832 ((u8 *)data)[0] |= val;
2833 break;
2834 case 2:
2835 ((u16 *)data)[0] &= cpu_to_be16(~params->mask);
2836 ((u16 *)data)[0] |= cpu_to_be16(val);
2837 break;
2838 case 4:
2839 ((u32 *)data)[0] &= cpu_to_be32(~params->mask);
2840 ((u32 *)data)[0] |= cpu_to_be32(val);
2841 break;
2842 default:
2843 return -EINVAL;
2844 }
2845 }
2846
2847 ret = regmap_raw_write(codec->control_data, params->base,
2848 data, len);
2849
2850 if (params->mask)
2851 kfree(data);
2852
2853 return ret;
2854}
2855EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
2856
2654/** 2857/**
2655 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2858 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2656 * @dai: DAI 2859 * @dai: DAI
@@ -2768,10 +2971,11 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
2768 */ 2971 */
2769int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2972int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2770{ 2973{
2771 if (dai->driver && dai->driver->ops->set_fmt) 2974 if (dai->driver == NULL)
2772 return dai->driver->ops->set_fmt(dai, fmt);
2773 else
2774 return -EINVAL; 2975 return -EINVAL;
2976 if (dai->driver->ops->set_fmt == NULL)
2977 return -ENOTSUPP;
2978 return dai->driver->ops->set_fmt(dai, fmt);
2775} 2979}
2776EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); 2980EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2777 2981
@@ -2875,7 +3079,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
2875 */ 3079 */
2876 if (!!link->codec_name == !!link->codec_of_node) { 3080 if (!!link->codec_name == !!link->codec_of_node) {
2877 dev_err(card->dev, 3081 dev_err(card->dev,
2878 "Neither/both codec name/of_node are set\n"); 3082 "Neither/both codec name/of_node are set for %s\n",
3083 link->name);
2879 return -EINVAL; 3084 return -EINVAL;
2880 } 3085 }
2881 3086
@@ -2885,7 +3090,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2885 */ 3090 */
2886 if (link->platform_name && link->platform_of_node) { 3091 if (link->platform_name && link->platform_of_node) {
2887 dev_err(card->dev, 3092 dev_err(card->dev,
2888 "Both platform name/of_node are set\n"); 3093 "Both platform name/of_node are set for %s\n", link->name);
2889 return -EINVAL; 3094 return -EINVAL;
2890 } 3095 }
2891 3096
@@ -2895,7 +3100,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
2895 */ 3100 */
2896 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { 3101 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
2897 dev_err(card->dev, 3102 dev_err(card->dev,
2898 "Neither/both cpu_dai name/of_node are set\n"); 3103 "Neither/both cpu_dai name/of_node are set for %s\n",
3104 link->name);
2899 return -EINVAL; 3105 return -EINVAL;
2900 } 3106 }
2901 } 3107 }
@@ -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,