aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:25:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:25:01 -0400
commit68d99b2c8efcb6ed3807a55569300c53b5f88be5 (patch)
treef189c8f2132d3668a2f0e503f5c3f8695b26a1c8 /sound/soc
parent0e59e7e7feb5a12938fbf9135147eeda3238c6c4 (diff)
parent8128c9f21509f9a8b6da94ac432d845dda458406 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (549 commits) ALSA: hda - Fix ADC input-amp handling for Cx20549 codec ALSA: hda - Keep EAPD turned on for old Conexant chips ALSA: hda/realtek - Fix missing volume controls with ALC260 ASoC: wm8940: Properly set codec->dapm.bias_level ALSA: hda - Fix pin-config for ASUS W90V ALSA: hda - Fix surround/CLFE headphone and speaker pins order ALSA: hda - Fix typo ALSA: Update the sound git tree URL ALSA: HDA: Add new revision for ALC662 ASoC: max98095: Convert codec->hw_write to snd_soc_write ASoC: keep pointer to resource so it can be freed ASoC: sgtl5000: Fix wrong mask in some snd_soc_update_bits calls ASoC: wm8996: Fix wrong mask for setting WM8996_AIF_CLOCKING_2 ASoC: da7210: Add support for line out and DAC ASoC: da7210: Add support for DAPM ALSA: hda/realtek - Fix DAC assignments of multiple speakers ASoC: Use SGTL5000_LINREG_VDDD_MASK instead of hardcoded mask value ASoC: Set sgtl5000->ldo in ldo_regulator_register ASoC: wm8996: Use SND_SOC_DAPM_AIF_OUT for AIF2 Capture ASoC: wm8994: Use SND_SOC_DAPM_AIF_OUT for AIF3 Capture ...
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c6
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c2
-rw-r--r--sound/soc/au1x/Kconfig28
-rw-r--r--sound/soc/au1x/Makefile10
-rw-r--r--sound/soc/au1x/ac97c.c366
-rw-r--r--sound/soc/au1x/db1000.c75
-rw-r--r--sound/soc/au1x/db1200.c64
-rw-r--r--sound/soc/au1x/dbdma2.c91
-rw-r--r--sound/soc/au1x/dma.c377
-rw-r--r--sound/soc/au1x/i2sc.c349
-rw-r--r--sound/soc/au1x/psc-ac97.c61
-rw-r--r--sound/soc/au1x/psc-i2s.c55
-rw-r--r--sound/soc/au1x/psc.h16
-rw-r--r--sound/soc/blackfin/Kconfig13
-rw-r--r--sound/soc/blackfin/Makefile2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c202
-rw-r--r--sound/soc/codecs/88pm860x-codec.c14
-rw-r--r--sound/soc/codecs/Kconfig16
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ad193x.c96
-rw-r--r--sound/soc/codecs/ad193x.h36
-rw-r--r--sound/soc/codecs/ad1980.c11
-rw-r--r--sound/soc/codecs/adau1373.c1414
-rw-r--r--sound/soc/codecs/adau1373.h29
-rw-r--r--sound/soc/codecs/adau1701.c3
-rw-r--r--sound/soc/codecs/adav80x.c3
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4535.c110
-rw-r--r--sound/soc/codecs/ak4641.c3
-rw-r--r--sound/soc/codecs/ak4642.c104
-rw-r--r--sound/soc/codecs/ak4671.c22
-rw-r--r--sound/soc/codecs/alc5623.c8
-rw-r--r--sound/soc/codecs/cs4270.c14
-rw-r--r--sound/soc/codecs/cs4271.c5
-rw-r--r--sound/soc/codecs/cs42l51.c15
-rw-r--r--sound/soc/codecs/da7210.c649
-rw-r--r--sound/soc/codecs/lm4857.c2
-rw-r--r--sound/soc/codecs/max98088.c36
-rw-r--r--sound/soc/codecs/max98095.c47
-rw-r--r--sound/soc/codecs/rt5631.c1773
-rw-r--r--sound/soc/codecs/rt5631.h701
-rw-r--r--sound/soc/codecs/sgtl5000.c37
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/codecs/sn95031.c16
-rw-r--r--sound/soc/codecs/ssm2602.c107
-rw-r--r--sound/soc/codecs/ssm2602.h6
-rw-r--r--sound/soc/codecs/sta32x.c54
-rw-r--r--sound/soc/codecs/tlv320aic23.c181
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c65
-rw-r--r--sound/soc/codecs/tlv320aic3x.c25
-rw-r--r--sound/soc/codecs/tlv320dac33.c31
-rw-r--r--sound/soc/codecs/tpa6130a2.c13
-rw-r--r--sound/soc/codecs/twl4030.c69
-rw-r--r--sound/soc/codecs/twl6040.c805
-rw-r--r--sound/soc/codecs/twl6040.h13
-rw-r--r--sound/soc/codecs/wl1273.c1
-rw-r--r--sound/soc/codecs/wm1250-ev1.c140
-rw-r--r--sound/soc/codecs/wm5100-tables.c1531
-rw-r--r--sound/soc/codecs/wm5100.c2809
-rw-r--r--sound/soc/codecs/wm5100.h5155
-rw-r--r--sound/soc/codecs/wm8350.c43
-rw-r--r--sound/soc/codecs/wm8400.c2
-rw-r--r--sound/soc/codecs/wm8510.c21
-rw-r--r--sound/soc/codecs/wm8523.c36
-rw-r--r--sound/soc/codecs/wm8580.c69
-rw-r--r--sound/soc/codecs/wm8711.c38
-rw-r--r--sound/soc/codecs/wm8728.c13
-rw-r--r--sound/soc/codecs/wm8731.c25
-rw-r--r--sound/soc/codecs/wm8737.c10
-rw-r--r--sound/soc/codecs/wm8741.c151
-rw-r--r--sound/soc/codecs/wm8750.c56
-rw-r--r--sound/soc/codecs/wm8753.c13
-rw-r--r--sound/soc/codecs/wm8770.c8
-rw-r--r--sound/soc/codecs/wm8776.c67
-rw-r--r--sound/soc/codecs/wm8782.c2
-rw-r--r--sound/soc/codecs/wm8804.c9
-rw-r--r--sound/soc/codecs/wm8900.c115
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8940.c51
-rw-r--r--sound/soc/codecs/wm8960.c18
-rw-r--r--sound/soc/codecs/wm8961.c4
-rw-r--r--sound/soc/codecs/wm8962.c222
-rw-r--r--sound/soc/codecs/wm8971.c42
-rw-r--r--sound/soc/codecs/wm8974.c15
-rw-r--r--sound/soc/codecs/wm8978.c3
-rw-r--r--sound/soc/codecs/wm8983.c2
-rw-r--r--sound/soc/codecs/wm8988.c33
-rw-r--r--sound/soc/codecs/wm8990.c105
-rw-r--r--sound/soc/codecs/wm8991.c24
-rw-r--r--sound/soc/codecs/wm8993.c7
-rw-r--r--sound/soc/codecs/wm8994-tables.c16
-rw-r--r--sound/soc/codecs/wm8994.c376
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm8995.c22
-rw-r--r--sound/soc/codecs/wm8996.c321
-rw-r--r--sound/soc/codecs/wm9081.c14
-rw-r--r--sound/soc/codecs/wm9090.c7
-rw-r--r--sound/soc/codecs/wm_hubs.c68
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c5
-rw-r--r--sound/soc/davinci/davinci-mcasp.c20
-rw-r--r--sound/soc/davinci/davinci-pcm.c123
-rw-r--r--sound/soc/ep93xx/edb93xx.c60
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c2
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c1
-rw-r--r--sound/soc/ep93xx/simone.c64
-rw-r--r--sound/soc/ep93xx/snappercl15.c53
-rw-r--r--sound/soc/fsl/fsl_dma.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c206
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c4
-rw-r--r--sound/soc/imx/Kconfig3
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c12
-rw-r--r--sound/soc/imx/imx-ssi.c9
-rw-r--r--sound/soc/imx/imx-ssi.h6
-rw-r--r--sound/soc/jz4740/jz4740-pcm.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c2
-rw-r--r--sound/soc/mid-x86/mfld_machine.c4
-rw-r--r--sound/soc/mid-x86/sst_platform.c19
-rw-r--r--sound/soc/mxs/Kconfig20
-rw-r--r--sound/soc/mxs/Makefile10
-rw-r--r--sound/soc/mxs/mxs-pcm.c359
-rw-r--r--sound/soc/mxs/mxs-pcm.h43
-rw-r--r--sound/soc/mxs/mxs-saif.c798
-rw-r--r--sound/soc/mxs/mxs-saif.h134
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c173
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c5
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/am3517evm.c50
-rw-r--r--sound/soc/omap/ams-delta.c1
-rw-r--r--sound/soc/omap/igep0020.c23
-rw-r--r--sound/soc/omap/mcpdm.c470
-rw-r--r--sound/soc/omap/mcpdm.h153
-rw-r--r--sound/soc/omap/n810.c42
-rw-r--r--sound/soc/omap/omap-mcbsp.c27
-rw-r--r--sound/soc/omap/omap-mcpdm.c481
-rw-r--r--sound/soc/omap/omap-mcpdm.h107
-rw-r--r--sound/soc/omap/omap-pcm.c8
-rw-r--r--sound/soc/omap/omap3evm.c23
-rw-r--r--sound/soc/omap/omap3pandora.c28
-rw-r--r--sound/soc/omap/osk5912.c50
-rw-r--r--sound/soc/omap/overo.c23
-rw-r--r--sound/soc/omap/rx51.c22
-rw-r--r--sound/soc/omap/sdp3430.c88
-rw-r--r--sound/soc/omap/sdp4430.c47
-rw-r--r--sound/soc/omap/zoom2.c96
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/pxa/corgi.c1
-rw-r--r--sound/soc/pxa/e740_wm9705.c2
-rw-r--r--sound/soc/pxa/e750_wm9705.c2
-rw-r--r--sound/soc/pxa/e800_wm9712.c1
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c1
-rw-r--r--sound/soc/pxa/palm27x.c4
-rw-r--r--sound/soc/pxa/poodle.c1
-rw-r--r--sound/soc/pxa/raumfeld.c4
-rw-r--r--sound/soc/pxa/saarb.c4
-rw-r--r--sound/soc/pxa/spitz.c3
-rw-r--r--sound/soc/pxa/tavorevb3.c4
-rw-r--r--sound/soc/pxa/tosa.c1
-rw-r--r--sound/soc/pxa/z2.c6
-rw-r--r--sound/soc/pxa/zylonite.c1
-rw-r--r--sound/soc/s6000/s6000-pcm.c1
-rw-r--r--sound/soc/samsung/Kconfig12
-rw-r--r--sound/soc/samsung/ac97.c4
-rw-r--r--sound/soc/samsung/goni_wm8994.c15
-rw-r--r--sound/soc/samsung/h1940_uda1380.c19
-rw-r--r--sound/soc/samsung/i2s.c2
-rw-r--r--sound/soc/samsung/jive_wm8750.c19
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c4
-rw-r--r--sound/soc/samsung/pcm.c2
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c33
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c1
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c6
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c6
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c2
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c11
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c11
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c8
-rw-r--r--sound/soc/samsung/smartq_wm8987.c27
-rw-r--r--sound/soc/samsung/smdk_wm8580.c51
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c4
-rw-r--r--sound/soc/samsung/smdk_wm8994.c2
-rw-r--r--sound/soc/samsung/spdif.c4
-rw-r--r--sound/soc/samsung/speyside.c10
-rw-r--r--sound/soc/samsung/speyside_wm8962.c41
-rw-r--r--sound/soc/sh/fsi.c12
-rw-r--r--sound/soc/sh/sh7760-ac97.c7
-rw-r--r--sound/soc/sh/ssi.c2
-rw-r--r--sound/soc/soc-cache.c7
-rw-r--r--sound/soc/soc-core.c215
-rw-r--r--sound/soc/soc-dapm.c416
-rw-r--r--sound/soc/soc-io.c357
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-pcm.c57
-rw-r--r--sound/soc/tegra/tegra_das.c4
-rw-r--r--sound/soc/tegra/tegra_i2s.c2
-rw-r--r--sound/soc/tegra/tegra_pcm.c2
-rw-r--r--sound/soc/tegra/tegra_spdif.c5
-rw-r--r--sound/soc/tegra/tegra_wm8903.c2
-rw-r--r--sound/soc/tegra/trimslice.c2
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c2
-rw-r--r--sound/soc/txx9/txx9aclc-generic.c2
211 files changed, 20860 insertions, 4413 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 8224db5f0434..1381db853ef0 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -7,6 +7,8 @@ menuconfig SND_SOC
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS 8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER
10 ---help--- 12 ---help---
11 13
12 If you want ASoC support, you should say Y here and also to the 14 If you want ASoC support, you should say Y here and also to the
@@ -51,6 +53,7 @@ source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 53source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 54source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/mid-x86/Kconfig" 55source "sound/soc/mid-x86/Kconfig"
56source "sound/soc/mxs/Kconfig"
54source "sound/soc/pxa/Kconfig" 57source "sound/soc/pxa/Kconfig"
55source "sound/soc/samsung/Kconfig" 58source "sound/soc/samsung/Kconfig"
56source "sound/soc/s6000/Kconfig" 59source "sound/soc/s6000/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 4f913876f332..9ea8ac827adc 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC) += fsl/
12obj-$(CONFIG_SND_SOC) += imx/ 12obj-$(CONFIG_SND_SOC) += imx/
13obj-$(CONFIG_SND_SOC) += jz4740/ 13obj-$(CONFIG_SND_SOC) += jz4740/
14obj-$(CONFIG_SND_SOC) += mid-x86/ 14obj-$(CONFIG_SND_SOC) += mid-x86/
15obj-$(CONFIG_SND_SOC) += mxs/
15obj-$(CONFIG_SND_SOC) += nuc900/ 16obj-$(CONFIG_SND_SOC) += nuc900/
16obj-$(CONFIG_SND_SOC) += omap/ 17obj-$(CONFIG_SND_SOC) += omap/
17obj-$(CONFIG_SND_SOC) += kirkwood/ 18obj-$(CONFIG_SND_SOC) += kirkwood/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 1aac2f4dbcf6..73ae99ad4578 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -338,7 +338,6 @@ static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
338 /* always connected pins */ 338 /* always connected pins */
339 snd_soc_dapm_enable_pin(dapm, "Int Mic"); 339 snd_soc_dapm_enable_pin(dapm, "Int Mic");
340 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 340 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
341 snd_soc_dapm_sync(dapm);
342 341
343 342
344 343
@@ -383,14 +382,17 @@ static int __init playpaq_asoc_init(void)
383 _gclk0 = clk_get(NULL, "gclk0"); 382 _gclk0 = clk_get(NULL, "gclk0");
384 if (IS_ERR(_gclk0)) { 383 if (IS_ERR(_gclk0)) {
385 _gclk0 = NULL; 384 _gclk0 = NULL;
385 ret = PTR_ERR(_gclk0);
386 goto err_gclk0; 386 goto err_gclk0;
387 } 387 }
388 _pll0 = clk_get(NULL, "pll0"); 388 _pll0 = clk_get(NULL, "pll0");
389 if (IS_ERR(_pll0)) { 389 if (IS_ERR(_pll0)) {
390 _pll0 = NULL; 390 _pll0 = NULL;
391 ret = PTR_ERR(_pll0);
391 goto err_pll0; 392 goto err_pll0;
392 } 393 }
393 if (clk_set_parent(_gclk0, _pll0)) { 394 ret = clk_set_parent(_gclk0, _pll0);
395 if (ret) {
394 pr_warning("snd-soc-playpaq: " 396 pr_warning("snd-soc-playpaq: "
395 "Failed to set PLL0 as parent for DAC clock\n"); 397 "Failed to set PLL0 as parent for DAC clock\n");
396 goto err_set_clk; 398 goto err_set_clk;
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index bad3aa14d5b3..0377c5451aed 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -173,8 +173,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
173 /* always connected */ 173 /* always connected */
174 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 174 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
175 175
176 snd_soc_dapm_sync(dapm);
177
178 return 0; 176 return 0;
179} 177}
180 178
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 5e4d499d8434..d427e9217ce4 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -117,8 +117,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
117 snd_soc_dapm_enable_pin(dapm, "Line In"); 117 snd_soc_dapm_enable_pin(dapm, "Line In");
118 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 118 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
119 119
120 snd_soc_dapm_sync(dapm);
121
122 return 0; 120 return 0;
123} 121}
124 122
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index 4b67140fdec3..6d592546e8fc 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -18,10 +18,38 @@ config SND_SOC_AU1XPSC_AC97
18 select SND_AC97_CODEC 18 select SND_AC97_CODEC
19 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
20 20
21##
22## Au1000/1500/1100 DMA + AC97C/I2SC
23##
24config SND_SOC_AU1XAUDIO
25 tristate "SoC Audio for Au1000/Au1500/Au1100"
26 depends on MIPS_ALCHEMY
27 help
28 This is a driver set for the AC97 unit and the
29 old DMA controller as found on the Au1000/Au1500/Au1100 chips.
30
31config SND_SOC_AU1XAC97C
32 tristate
33 select AC97_BUS
34 select SND_AC97_CODEC
35 select SND_SOC_AC97_BUS
36
37config SND_SOC_AU1XI2SC
38 tristate
39
21 40
22## 41##
23## Boards 42## Boards
24## 43##
44config SND_SOC_DB1000
45 tristate "DB1000 Audio support"
46 depends on SND_SOC_AU1XAUDIO
47 select SND_SOC_AU1XAC97C
48 select SND_SOC_AC97_CODEC
49 help
50 Select this option to enable AC97 audio on the early DB1x00 series
51 of boards (DB1000/DB1500/DB1100).
52
25config SND_SOC_DB1200 53config SND_SOC_DB1200
26 tristate "DB1200 AC97+I2S audio support" 54 tristate "DB1200 AC97+I2S audio support"
27 depends on SND_SOC_AU1XPSC 55 depends on SND_SOC_AU1XPSC
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 16873076e8c4..920710514ea0 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -3,11 +3,21 @@ snd-soc-au1xpsc-dbdma-objs := dbdma2.o
3snd-soc-au1xpsc-i2s-objs := psc-i2s.o 3snd-soc-au1xpsc-i2s-objs := psc-i2s.o
4snd-soc-au1xpsc-ac97-objs := psc-ac97.o 4snd-soc-au1xpsc-ac97-objs := psc-ac97.o
5 5
6# Au1000/1500/1100 Audio units
7snd-soc-au1x-dma-objs := dma.o
8snd-soc-au1x-ac97c-objs := ac97c.o
9snd-soc-au1x-i2sc-objs := i2sc.o
10
6obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o 11obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
7obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o 12obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o 13obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
14obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o
15obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o
16obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o
9 17
10# Boards 18# Boards
19snd-soc-db1000-objs := db1000.o
11snd-soc-db1200-objs := db1200.o 20snd-soc-db1200-objs := db1200.o
12 21
22obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o
13obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o 23obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
new file mode 100644
index 000000000000..726bd651a105
--- /dev/null
+++ b/sound/soc/au1x/ac97c.c
@@ -0,0 +1,366 @@
1/*
2 * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * based on the old ALSA driver originally written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/device.h>
14#include <linux/delay.h>
15#include <linux/mutex.h>
16#include <linux/platform_device.h>
17#include <linux/suspend.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22#include <asm/mach-au1x00/au1000.h>
23
24#include "psc.h"
25
26/* register offsets and bits */
27#define AC97_CONFIG 0x00
28#define AC97_STATUS 0x04
29#define AC97_DATA 0x08
30#define AC97_CMDRESP 0x0c
31#define AC97_ENABLE 0x10
32
33#define CFG_RC(x) (((x) & 0x3ff) << 13) /* valid rx slots mask */
34#define CFG_XS(x) (((x) & 0x3ff) << 3) /* valid tx slots mask */
35#define CFG_SG (1 << 2) /* sync gate */
36#define CFG_SN (1 << 1) /* sync control */
37#define CFG_RS (1 << 0) /* acrst# control */
38#define STAT_XU (1 << 11) /* tx underflow */
39#define STAT_XO (1 << 10) /* tx overflow */
40#define STAT_RU (1 << 9) /* rx underflow */
41#define STAT_RO (1 << 8) /* rx overflow */
42#define STAT_RD (1 << 7) /* codec ready */
43#define STAT_CP (1 << 6) /* command pending */
44#define STAT_TE (1 << 4) /* tx fifo empty */
45#define STAT_TF (1 << 3) /* tx fifo full */
46#define STAT_RE (1 << 1) /* rx fifo empty */
47#define STAT_RF (1 << 0) /* rx fifo full */
48#define CMD_SET_DATA(x) (((x) & 0xffff) << 16)
49#define CMD_GET_DATA(x) ((x) & 0xffff)
50#define CMD_READ (1 << 7)
51#define CMD_WRITE (0 << 7)
52#define CMD_IDX(x) ((x) & 0x7f)
53#define EN_D (1 << 1) /* DISable bit */
54#define EN_CE (1 << 0) /* clock enable bit */
55
56/* how often to retry failed codec register reads/writes */
57#define AC97_RW_RETRIES 5
58
59#define AC97_RATES \
60 SNDRV_PCM_RATE_CONTINUOUS
61
62#define AC97_FMTS \
63 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
64
65/* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
66 * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
67 */
68static struct au1xpsc_audio_data *ac97c_workdata;
69#define ac97_to_ctx(x) ac97c_workdata
70
71static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
72{
73 return __raw_readl(ctx->mmio + reg);
74}
75
76static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
77{
78 __raw_writel(v, ctx->mmio + reg);
79 wmb();
80}
81
82static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
83 unsigned short r)
84{
85 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
86 unsigned int tmo, retry;
87 unsigned long data;
88
89 data = ~0;
90 retry = AC97_RW_RETRIES;
91 do {
92 mutex_lock(&ctx->lock);
93
94 tmo = 5;
95 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
96 udelay(21); /* wait an ac97 frame time */
97 if (!tmo) {
98 pr_debug("ac97rd timeout #1\n");
99 goto next;
100 }
101
102 WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
103
104 /* stupid errata: data is only valid for 21us, so
105 * poll, Forrest, poll...
106 */
107 tmo = 0x10000;
108 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
109 asm volatile ("nop");
110 data = RD(ctx, AC97_CMDRESP);
111
112 if (!tmo)
113 pr_debug("ac97rd timeout #2\n");
114
115next:
116 mutex_unlock(&ctx->lock);
117 } while (--retry && !tmo);
118
119 pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
120
121 return retry ? data & 0xffff : 0xffff;
122}
123
124static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
125 unsigned short v)
126{
127 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
128 unsigned int tmo, retry;
129
130 retry = AC97_RW_RETRIES;
131 do {
132 mutex_lock(&ctx->lock);
133
134 for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
135 udelay(21);
136 if (!tmo) {
137 pr_debug("ac97wr timeout #1\n");
138 goto next;
139 }
140
141 WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
142
143 for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
144 udelay(21);
145 if (!tmo)
146 pr_debug("ac97wr timeout #2\n");
147next:
148 mutex_unlock(&ctx->lock);
149 } while (--retry && !tmo);
150
151 pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
152}
153
154static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
155{
156 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
157
158 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
159 msleep(20);
160 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
161 WR(ctx, AC97_CONFIG, ctx->cfg);
162}
163
164static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
167 int i;
168
169 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
170 msleep(500);
171 WR(ctx, AC97_CONFIG, ctx->cfg);
172
173 /* wait for codec ready */
174 i = 50;
175 while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
176 msleep(20);
177 if (!i)
178 printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
179}
180
181/* AC97 controller operations */
182struct snd_ac97_bus_ops soc_ac97_ops = {
183 .read = au1xac97c_ac97_read,
184 .write = au1xac97c_ac97_write,
185 .reset = au1xac97c_ac97_cold_reset,
186 .warm_reset = au1xac97c_ac97_warm_reset,
187};
188EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189
190static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
194 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
195 return 0;
196}
197
198static struct snd_soc_dai_ops alchemy_ac97c_ops = {
199 .startup = alchemy_ac97c_startup,
200};
201
202static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
203{
204 return ac97c_workdata ? 0 : -ENODEV;
205}
206
207static struct snd_soc_dai_driver au1xac97c_dai_driver = {
208 .name = "alchemy-ac97c",
209 .ac97_control = 1,
210 .probe = au1xac97c_dai_probe,
211 .playback = {
212 .rates = AC97_RATES,
213 .formats = AC97_FMTS,
214 .channels_min = 2,
215 .channels_max = 2,
216 },
217 .capture = {
218 .rates = AC97_RATES,
219 .formats = AC97_FMTS,
220 .channels_min = 2,
221 .channels_max = 2,
222 },
223 .ops = &alchemy_ac97c_ops,
224};
225
226static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
227{
228 int ret;
229 struct resource *iores, *dmares;
230 struct au1xpsc_audio_data *ctx;
231
232 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
233 if (!ctx)
234 return -ENOMEM;
235
236 mutex_init(&ctx->lock);
237
238 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!iores) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(iores->start, resource_size(iores),
246 pdev->name))
247 goto out0;
248
249 ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
250 if (!ctx->mmio)
251 goto out1;
252
253 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
254 if (!dmares)
255 goto out2;
256 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
257
258 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
259 if (!dmares)
260 goto out2;
261 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
262
263 /* switch it on */
264 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
265 WR(ctx, AC97_ENABLE, EN_CE);
266
267 ctx->cfg = CFG_RC(3) | CFG_XS(3);
268 WR(ctx, AC97_CONFIG, ctx->cfg);
269
270 platform_set_drvdata(pdev, ctx);
271
272 ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
273 if (ret)
274 goto out2;
275
276 ac97c_workdata = ctx;
277 return 0;
278
279out2:
280 iounmap(ctx->mmio);
281out1:
282 release_mem_region(iores->start, resource_size(iores));
283out0:
284 kfree(ctx);
285 return ret;
286}
287
288static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
289{
290 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
291 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292
293 snd_soc_unregister_dai(&pdev->dev);
294
295 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
296
297 iounmap(ctx->mmio);
298 release_mem_region(r->start, resource_size(r));
299 kfree(ctx);
300
301 ac97c_workdata = NULL; /* MDEV */
302
303 return 0;
304}
305
306#ifdef CONFIG_PM
307static int au1xac97c_drvsuspend(struct device *dev)
308{
309 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
310
311 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
312
313 return 0;
314}
315
316static int au1xac97c_drvresume(struct device *dev)
317{
318 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
319
320 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
321 WR(ctx, AC97_ENABLE, EN_CE);
322 WR(ctx, AC97_CONFIG, ctx->cfg);
323
324 return 0;
325}
326
327static const struct dev_pm_ops au1xpscac97_pmops = {
328 .suspend = au1xac97c_drvsuspend,
329 .resume = au1xac97c_drvresume,
330};
331
332#define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
333
334#else
335
336#define AU1XPSCAC97_PMOPS NULL
337
338#endif
339
340static struct platform_driver au1xac97c_driver = {
341 .driver = {
342 .name = "alchemy-ac97c",
343 .owner = THIS_MODULE,
344 .pm = AU1XPSCAC97_PMOPS,
345 },
346 .probe = au1xac97c_drvprobe,
347 .remove = __devexit_p(au1xac97c_drvremove),
348};
349
350static int __init au1xac97c_load(void)
351{
352 ac97c_workdata = NULL;
353 return platform_driver_register(&au1xac97c_driver);
354}
355
356static void __exit au1xac97c_unload(void)
357{
358 platform_driver_unregister(&au1xac97c_driver);
359}
360
361module_init(au1xac97c_load);
362module_exit(au1xac97c_unload);
363
364MODULE_LICENSE("GPL");
365MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
366MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
new file mode 100644
index 000000000000..127477a5e0c7
--- /dev/null
+++ b/sound/soc/au1x/db1000.c
@@ -0,0 +1,75 @@
1/*
2 * DB1000/DB1500/DB1100 ASoC audio fabric support code.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <asm/mach-au1x00/au1000.h>
17#include <asm/mach-db1x00/bcsr.h>
18
19#include "psc.h"
20
21static struct snd_soc_dai_link db1000_ac97_dai = {
22 .name = "AC97",
23 .stream_name = "AC97 HiFi",
24 .codec_dai_name = "ac97-hifi",
25 .cpu_dai_name = "alchemy-ac97c",
26 .platform_name = "alchemy-pcm-dma.0",
27 .codec_name = "ac97-codec",
28};
29
30static struct snd_soc_card db1000_ac97 = {
31 .name = "DB1000_AC97",
32 .dai_link = &db1000_ac97_dai,
33 .num_links = 1,
34};
35
36static int __devinit db1000_audio_probe(struct platform_device *pdev)
37{
38 struct snd_soc_card *card = &db1000_ac97;
39 card->dev = &pdev->dev;
40 return snd_soc_register_card(card);
41}
42
43static int __devexit db1000_audio_remove(struct platform_device *pdev)
44{
45 struct snd_soc_card *card = platform_get_drvdata(pdev);
46 snd_soc_unregister_card(card);
47 return 0;
48}
49
50static struct platform_driver db1000_audio_driver = {
51 .driver = {
52 .name = "db1000-audio",
53 .owner = THIS_MODULE,
54 .pm = &snd_soc_pm_ops,
55 },
56 .probe = db1000_audio_probe,
57 .remove = __devexit_p(db1000_audio_remove),
58};
59
60static int __init db1000_audio_load(void)
61{
62 return platform_driver_register(&db1000_audio_driver);
63}
64
65static void __exit db1000_audio_unload(void)
66{
67 platform_driver_unregister(&db1000_audio_driver);
68}
69
70module_init(db1000_audio_load);
71module_exit(db1000_audio_unload);
72
73MODULE_LICENSE("GPL");
74MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
75MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 1d3e258c9ea8..289312c14b99 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * DB1200 ASoC audio fabric support code. 2 * DB1200 ASoC audio fabric support code.
3 * 3 *
4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> 4 * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 * 5 *
6 */ 6 */
7 7
@@ -21,6 +21,17 @@
21#include "../codecs/wm8731.h" 21#include "../codecs/wm8731.h"
22#include "psc.h" 22#include "psc.h"
23 23
24static struct platform_device_id db1200_pids[] = {
25 {
26 .name = "db1200-ac97",
27 .driver_data = 0,
28 }, {
29 .name = "db1200-i2s",
30 .driver_data = 1,
31 },
32 {},
33};
34
24/*------------------------- AC97 PART ---------------------------*/ 35/*------------------------- AC97 PART ---------------------------*/
25 36
26static struct snd_soc_dai_link db1200_ac97_dai = { 37static struct snd_soc_dai_link db1200_ac97_dai = {
@@ -89,36 +100,47 @@ static struct snd_soc_card db1200_i2s_machine = {
89 100
90/*------------------------- COMMON PART ---------------------------*/ 101/*------------------------- COMMON PART ---------------------------*/
91 102
92static struct platform_device *db1200_asoc_dev; 103static struct snd_soc_card *db1200_cards[] __devinitdata = {
104 &db1200_ac97_machine,
105 &db1200_i2s_machine,
106};
93 107
94static int __init db1200_audio_load(void) 108static int __devinit db1200_audio_probe(struct platform_device *pdev)
95{ 109{
96 int ret; 110 const struct platform_device_id *pid = platform_get_device_id(pdev);
111 struct snd_soc_card *card;
97 112
98 ret = -ENOMEM; 113 card = db1200_cards[pid->driver_data];
99 db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */ 114 card->dev = &pdev->dev;
100 if (!db1200_asoc_dev) 115 return snd_soc_register_card(card);
101 goto out; 116}
102 117
103 /* DB1200 board setup set PSC1MUX to preferred audio device */ 118static int __devexit db1200_audio_remove(struct platform_device *pdev)
104 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) 119{
105 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine); 120 struct snd_soc_card *card = platform_get_drvdata(pdev);
106 else 121 snd_soc_unregister_card(card);
107 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine); 122 return 0;
123}
108 124
109 ret = platform_device_add(db1200_asoc_dev); 125static struct platform_driver db1200_audio_driver = {
126 .driver = {
127 .name = "db1200-ac97",
128 .owner = THIS_MODULE,
129 .pm = &snd_soc_pm_ops,
130 },
131 .id_table = db1200_pids,
132 .probe = db1200_audio_probe,
133 .remove = __devexit_p(db1200_audio_remove),
134};
110 135
111 if (ret) { 136static int __init db1200_audio_load(void)
112 platform_device_put(db1200_asoc_dev); 137{
113 db1200_asoc_dev = NULL; 138 return platform_driver_register(&db1200_audio_driver);
114 }
115out:
116 return ret;
117} 139}
118 140
119static void __exit db1200_audio_unload(void) 141static void __exit db1200_audio_unload(void)
120{ 142{
121 platform_device_unregister(db1200_asoc_dev); 143 platform_driver_unregister(&db1200_audio_driver);
122} 144}
123 145
124module_init(db1200_audio_load); 146module_init(db1200_audio_load);
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 20bb53a837b1..d7d04e26eee5 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -169,7 +169,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
169 169
170 au1x_pcm_dbdma_free(pcd); 170 au1x_pcm_dbdma_free(pcd);
171 171
172 if (stype == PCM_RX) 172 if (stype == SNDRV_PCM_STREAM_CAPTURE)
173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, 173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
174 DSCR_CMD0_ALWAYS, 174 DSCR_CMD0_ALWAYS,
175 au1x_pcm_dmarx_cb, (void *)pcd); 175 au1x_pcm_dmarx_cb, (void *)pcd);
@@ -198,7 +198,7 @@ static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream
198 struct snd_soc_pcm_runtime *rtd = ss->private_data; 198 struct snd_soc_pcm_runtime *rtd = ss->private_data;
199 struct au1xpsc_audio_dmadata *pcd = 199 struct au1xpsc_audio_dmadata *pcd =
200 snd_soc_platform_get_drvdata(rtd->platform); 200 snd_soc_platform_get_drvdata(rtd->platform);
201 return &pcd[SUBSTREAM_TYPE(ss)]; 201 return &pcd[ss->stream];
202} 202}
203 203
204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, 204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -212,7 +212,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
212 if (ret < 0) 212 if (ret < 0)
213 goto out; 213 goto out;
214 214
215 stype = SUBSTREAM_TYPE(substream); 215 stype = substream->stream;
216 pcd = to_dmadata(substream); 216 pcd = to_dmadata(substream);
217 217
218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " 218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
@@ -255,7 +255,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
255 255
256 au1xxx_dbdma_reset(pcd->ddma_chan); 256 au1xxx_dbdma_reset(pcd->ddma_chan);
257 257
258 if (SUBSTREAM_TYPE(substream) == PCM_RX) { 258 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
259 au1x_pcm_queue_rx(pcd); 259 au1x_pcm_queue_rx(pcd);
260 au1x_pcm_queue_rx(pcd); 260 au1x_pcm_queue_rx(pcd);
261 } else { 261 } else {
@@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
293 293
294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) 294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
295{ 295{
296 struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
297 struct snd_soc_pcm_runtime *rtd = substream->private_data;
298 int stype = substream->stream, *dmaids;
299
300 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
301 if (!dmaids)
302 return -ENODEV; /* whoa, has ordering changed? */
303
304 pcd->ddma_id = dmaids[stype];
305
296 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); 306 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
297 return 0; 307 return 0;
298} 308}
@@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = {
340static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) 350static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
341{ 351{
342 struct au1xpsc_audio_dmadata *dmadata; 352 struct au1xpsc_audio_dmadata *dmadata;
343 struct resource *r;
344 int ret; 353 int ret;
345 354
346 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); 355 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
347 if (!dmadata) 356 if (!dmadata)
348 return -ENOMEM; 357 return -ENOMEM;
349 358
350 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
351 if (!r) {
352 ret = -ENODEV;
353 goto out1;
354 }
355 dmadata[PCM_TX].ddma_id = r->start;
356
357 /* RX DMA */
358 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
359 if (!r) {
360 ret = -ENODEV;
361 goto out1;
362 }
363 dmadata[PCM_RX].ddma_id = r->start;
364
365 platform_set_drvdata(pdev, dmadata); 359 platform_set_drvdata(pdev, dmadata);
366 360
367 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); 361 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
368 if (!ret) 362 if (ret)
369 return ret; 363 kfree(dmadata);
370 364
371out1:
372 kfree(dmadata);
373 return ret; 365 return ret;
374} 366}
375 367
@@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void)
405module_init(au1xpsc_audio_dbdma_load); 397module_init(au1xpsc_audio_dbdma_load);
406module_exit(au1xpsc_audio_dbdma_unload); 398module_exit(au1xpsc_audio_dbdma_unload);
407 399
408
409struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
410{
411 struct resource *res, *r;
412 struct platform_device *pd;
413 int id[2];
414 int ret;
415
416 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
417 if (!r)
418 return NULL;
419 id[0] = r->start;
420
421 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
422 if (!r)
423 return NULL;
424 id[1] = r->start;
425
426 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
427 if (!res)
428 return NULL;
429
430 res[0].start = res[0].end = id[0];
431 res[1].start = res[1].end = id[1];
432 res[0].flags = res[1].flags = IORESOURCE_DMA;
433
434 pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
435 if (!pd)
436 goto out;
437
438 pd->resource = res;
439 pd->num_resources = 2;
440
441 ret = platform_device_add(pd);
442 if (!ret)
443 return pd;
444
445 platform_device_put(pd);
446out:
447 kfree(res);
448 return NULL;
449}
450EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
451
452void au1xpsc_pcm_destroy(struct platform_device *dmapd)
453{
454 if (dmapd)
455 platform_device_unregister(dmapd);
456}
457EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
458
459MODULE_LICENSE("GPL"); 400MODULE_LICENSE("GPL");
460MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 401MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
461MODULE_AUTHOR("Manuel Lauss"); 402MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
new file mode 100644
index 000000000000..177f7137a9c8
--- /dev/null
+++ b/sound/soc/au1x/dma.c
@@ -0,0 +1,377 @@
1/*
2 * Au1000/Au1500/Au1100 Audio DMA support.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * copied almost verbatim from the old ALSA driver, written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/dma-mapping.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <asm/mach-au1x00/au1000.h>
20#include <asm/mach-au1x00/au1000_dma.h>
21
22#include "psc.h"
23
24#define ALCHEMY_PCM_FMTS \
25 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
26 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
27 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
28 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
29 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
30 0)
31
32struct pcm_period {
33 u32 start;
34 u32 relative_end; /* relative to start of buffer */
35 struct pcm_period *next;
36};
37
38struct audio_stream {
39 struct snd_pcm_substream *substream;
40 int dma;
41 struct pcm_period *buffer;
42 unsigned int period_size;
43 unsigned int periods;
44};
45
46struct alchemy_pcm_ctx {
47 struct audio_stream stream[2]; /* playback & capture */
48};
49
50static void au1000_release_dma_link(struct audio_stream *stream)
51{
52 struct pcm_period *pointer;
53 struct pcm_period *pointer_next;
54
55 stream->period_size = 0;
56 stream->periods = 0;
57 pointer = stream->buffer;
58 if (!pointer)
59 return;
60 do {
61 pointer_next = pointer->next;
62 kfree(pointer);
63 pointer = pointer_next;
64 } while (pointer != stream->buffer);
65 stream->buffer = NULL;
66}
67
68static int au1000_setup_dma_link(struct audio_stream *stream,
69 unsigned int period_bytes,
70 unsigned int periods)
71{
72 struct snd_pcm_substream *substream = stream->substream;
73 struct snd_pcm_runtime *runtime = substream->runtime;
74 struct pcm_period *pointer;
75 unsigned long dma_start;
76 int i;
77
78 dma_start = virt_to_phys(runtime->dma_area);
79
80 if (stream->period_size == period_bytes &&
81 stream->periods == periods)
82 return 0; /* not changed */
83
84 au1000_release_dma_link(stream);
85
86 stream->period_size = period_bytes;
87 stream->periods = periods;
88
89 stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL);
90 if (!stream->buffer)
91 return -ENOMEM;
92 pointer = stream->buffer;
93 for (i = 0; i < periods; i++) {
94 pointer->start = (u32)(dma_start + (i * period_bytes));
95 pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
96 if (i < periods - 1) {
97 pointer->next = kmalloc(sizeof(struct pcm_period),
98 GFP_KERNEL);
99 if (!pointer->next) {
100 au1000_release_dma_link(stream);
101 return -ENOMEM;
102 }
103 pointer = pointer->next;
104 }
105 }
106 pointer->next = stream->buffer;
107 return 0;
108}
109
110static void au1000_dma_stop(struct audio_stream *stream)
111{
112 if (stream->buffer)
113 disable_dma(stream->dma);
114}
115
116static void au1000_dma_start(struct audio_stream *stream)
117{
118 if (!stream->buffer)
119 return;
120
121 init_dma(stream->dma);
122 if (get_dma_active_buffer(stream->dma) == 0) {
123 clear_dma_done0(stream->dma);
124 set_dma_addr0(stream->dma, stream->buffer->start);
125 set_dma_count0(stream->dma, stream->period_size >> 1);
126 set_dma_addr1(stream->dma, stream->buffer->next->start);
127 set_dma_count1(stream->dma, stream->period_size >> 1);
128 } else {
129 clear_dma_done1(stream->dma);
130 set_dma_addr1(stream->dma, stream->buffer->start);
131 set_dma_count1(stream->dma, stream->period_size >> 1);
132 set_dma_addr0(stream->dma, stream->buffer->next->start);
133 set_dma_count0(stream->dma, stream->period_size >> 1);
134 }
135 enable_dma_buffers(stream->dma);
136 start_dma(stream->dma);
137}
138
139static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
140{
141 struct audio_stream *stream = (struct audio_stream *)ptr;
142 struct snd_pcm_substream *substream = stream->substream;
143
144 switch (get_dma_buffer_done(stream->dma)) {
145 case DMA_D0:
146 stream->buffer = stream->buffer->next;
147 clear_dma_done0(stream->dma);
148 set_dma_addr0(stream->dma, stream->buffer->next->start);
149 set_dma_count0(stream->dma, stream->period_size >> 1);
150 enable_dma_buffer0(stream->dma);
151 break;
152 case DMA_D1:
153 stream->buffer = stream->buffer->next;
154 clear_dma_done1(stream->dma);
155 set_dma_addr1(stream->dma, stream->buffer->next->start);
156 set_dma_count1(stream->dma, stream->period_size >> 1);
157 enable_dma_buffer1(stream->dma);
158 break;
159 case (DMA_D0 | DMA_D1):
160 pr_debug("DMA %d missed interrupt.\n", stream->dma);
161 au1000_dma_stop(stream);
162 au1000_dma_start(stream);
163 break;
164 case (~DMA_D0 & ~DMA_D1):
165 pr_debug("DMA %d empty irq.\n", stream->dma);
166 }
167 snd_pcm_period_elapsed(substream);
168 return IRQ_HANDLED;
169}
170
171static const struct snd_pcm_hardware alchemy_pcm_hardware = {
172 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
173 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
174 .formats = ALCHEMY_PCM_FMTS,
175 .rates = SNDRV_PCM_RATE_8000_192000,
176 .rate_min = SNDRV_PCM_RATE_8000,
177 .rate_max = SNDRV_PCM_RATE_192000,
178 .channels_min = 2,
179 .channels_max = 2,
180 .period_bytes_min = 1024,
181 .period_bytes_max = 16 * 1024 - 1,
182 .periods_min = 4,
183 .periods_max = 255,
184 .buffer_bytes_max = 128 * 1024,
185 .fifo_size = 16,
186};
187
188static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
189{
190 struct snd_soc_pcm_runtime *rtd = ss->private_data;
191 return snd_soc_platform_get_drvdata(rtd->platform);
192}
193
194static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
195{
196 struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss);
197 return &(ctx->stream[ss->stream]);
198}
199
200static int alchemy_pcm_open(struct snd_pcm_substream *substream)
201{
202 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
203 struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 int *dmaids, s = substream->stream;
205 char *name;
206
207 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
208 if (!dmaids)
209 return -ENODEV; /* whoa, has ordering changed? */
210
211 /* DMA setup */
212 name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx";
213 ctx->stream[s].dma = request_au1000_dma(dmaids[s], name,
214 au1000_dma_interrupt, 0,
215 &ctx->stream[s]);
216 set_dma_mode(ctx->stream[s].dma,
217 get_dma_mode(ctx->stream[s].dma) & ~DMA_NC);
218
219 ctx->stream[s].substream = substream;
220 ctx->stream[s].buffer = NULL;
221 snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware);
222
223 return 0;
224}
225
226static int alchemy_pcm_close(struct snd_pcm_substream *substream)
227{
228 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
229 int stype = substream->stream;
230
231 ctx->stream[stype].substream = NULL;
232 free_au1000_dma(ctx->stream[stype].dma);
233
234 return 0;
235}
236
237static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream,
238 struct snd_pcm_hw_params *hw_params)
239{
240 struct audio_stream *stream = ss_to_as(substream);
241 int err;
242
243 err = snd_pcm_lib_malloc_pages(substream,
244 params_buffer_bytes(hw_params));
245 if (err < 0)
246 return err;
247 err = au1000_setup_dma_link(stream,
248 params_period_bytes(hw_params),
249 params_periods(hw_params));
250 if (err)
251 snd_pcm_lib_free_pages(substream);
252
253 return err;
254}
255
256static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream)
257{
258 struct audio_stream *stream = ss_to_as(substream);
259 au1000_release_dma_link(stream);
260 return snd_pcm_lib_free_pages(substream);
261}
262
263static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
264{
265 struct audio_stream *stream = ss_to_as(substream);
266 int err = 0;
267
268 switch (cmd) {
269 case SNDRV_PCM_TRIGGER_START:
270 au1000_dma_start(stream);
271 break;
272 case SNDRV_PCM_TRIGGER_STOP:
273 au1000_dma_stop(stream);
274 break;
275 default:
276 err = -EINVAL;
277 break;
278 }
279 return err;
280}
281
282static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
283{
284 struct audio_stream *stream = ss_to_as(ss);
285 long location;
286
287 location = get_dma_residue(stream->dma);
288 location = stream->buffer->relative_end - location;
289 if (location == -1)
290 location = 0;
291 return bytes_to_frames(ss->runtime, location);
292}
293
294static struct snd_pcm_ops alchemy_pcm_ops = {
295 .open = alchemy_pcm_open,
296 .close = alchemy_pcm_close,
297 .ioctl = snd_pcm_lib_ioctl,
298 .hw_params = alchemy_pcm_hw_params,
299 .hw_free = alchemy_pcm_hw_free,
300 .trigger = alchemy_pcm_trigger,
301 .pointer = alchemy_pcm_pointer,
302};
303
304static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
305{
306 snd_pcm_lib_preallocate_free_for_all(pcm);
307}
308
309static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
310{
311 struct snd_pcm *pcm = rtd->pcm;
312
313 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
314 snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1);
315
316 return 0;
317}
318
319struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
320 .ops = &alchemy_pcm_ops,
321 .pcm_new = alchemy_pcm_new,
322 .pcm_free = alchemy_pcm_free_dma_buffers,
323};
324
325static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
326{
327 struct alchemy_pcm_ctx *ctx;
328 int ret;
329
330 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
331 if (!ctx)
332 return -ENOMEM;
333
334 platform_set_drvdata(pdev, ctx);
335
336 ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
337 if (ret)
338 kfree(ctx);
339
340 return ret;
341}
342
343static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
344{
345 struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev);
346
347 snd_soc_unregister_platform(&pdev->dev);
348 kfree(ctx);
349
350 return 0;
351}
352
353static struct platform_driver alchemy_pcmdma_driver = {
354 .driver = {
355 .name = "alchemy-pcm-dma",
356 .owner = THIS_MODULE,
357 },
358 .probe = alchemy_pcm_drvprobe,
359 .remove = __devexit_p(alchemy_pcm_drvremove),
360};
361
362static int __init alchemy_pcmdma_load(void)
363{
364 return platform_driver_register(&alchemy_pcmdma_driver);
365}
366
367static void __exit alchemy_pcmdma_unload(void)
368{
369 platform_driver_unregister(&alchemy_pcmdma_driver);
370}
371
372module_init(alchemy_pcmdma_load);
373module_exit(alchemy_pcmdma_unload);
374
375MODULE_LICENSE("GPL");
376MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
377MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
new file mode 100644
index 000000000000..6bcf48f5884c
--- /dev/null
+++ b/sound/soc/au1x/i2sc.c
@@ -0,0 +1,349 @@
1/*
2 * Au1000/Au1500/Au1100 I2S controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * Note: clock supplied to the I2S controller must be 256x samplerate.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/suspend.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/initval.h>
16#include <sound/soc.h>
17#include <asm/mach-au1x00/au1000.h>
18
19#include "psc.h"
20
21#define I2S_RXTX 0x00
22#define I2S_CFG 0x04
23#define I2S_ENABLE 0x08
24
25#define CFG_XU (1 << 25) /* tx underflow */
26#define CFG_XO (1 << 24)
27#define CFG_RU (1 << 23)
28#define CFG_RO (1 << 22)
29#define CFG_TR (1 << 21)
30#define CFG_TE (1 << 20)
31#define CFG_TF (1 << 19)
32#define CFG_RR (1 << 18)
33#define CFG_RF (1 << 17)
34#define CFG_ICK (1 << 12) /* clock invert */
35#define CFG_PD (1 << 11) /* set to make I2SDIO INPUT */
36#define CFG_LB (1 << 10) /* loopback */
37#define CFG_IC (1 << 9) /* word select invert */
38#define CFG_FM_I2S (0 << 7) /* I2S format */
39#define CFG_FM_LJ (1 << 7) /* left-justified */
40#define CFG_FM_RJ (2 << 7) /* right-justified */
41#define CFG_FM_MASK (3 << 7)
42#define CFG_TN (1 << 6) /* tx fifo en */
43#define CFG_RN (1 << 5) /* rx fifo en */
44#define CFG_SZ_8 (0x08)
45#define CFG_SZ_16 (0x10)
46#define CFG_SZ_18 (0x12)
47#define CFG_SZ_20 (0x14)
48#define CFG_SZ_24 (0x18)
49#define CFG_SZ_MASK (0x1f)
50#define EN_D (1 << 1) /* DISable */
51#define EN_CE (1 << 0) /* clock enable */
52
53/* only limited by clock generator and board design */
54#define AU1XI2SC_RATES \
55 SNDRV_PCM_RATE_CONTINUOUS
56
57#define AU1XI2SC_FMTS \
58 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
59 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
60 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
61 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
62 SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE | \
63 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
64 SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE | \
65 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
66 SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE | \
67 0)
68
69static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
70{
71 return __raw_readl(ctx->mmio + reg);
72}
73
74static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
75{
76 __raw_writel(v, ctx->mmio + reg);
77 wmb();
78}
79
80static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
81{
82 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
83 unsigned long c;
84 int ret;
85
86 ret = -EINVAL;
87 c = ctx->cfg;
88
89 c &= ~CFG_FM_MASK;
90 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
91 case SND_SOC_DAIFMT_I2S:
92 c |= CFG_FM_I2S;
93 break;
94 case SND_SOC_DAIFMT_MSB:
95 c |= CFG_FM_RJ;
96 break;
97 case SND_SOC_DAIFMT_LSB:
98 c |= CFG_FM_LJ;
99 break;
100 default:
101 goto out;
102 }
103
104 c &= ~(CFG_IC | CFG_ICK); /* IB-IF */
105 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
106 case SND_SOC_DAIFMT_NB_NF:
107 c |= CFG_IC | CFG_ICK;
108 break;
109 case SND_SOC_DAIFMT_NB_IF:
110 c |= CFG_IC;
111 break;
112 case SND_SOC_DAIFMT_IB_NF:
113 c |= CFG_ICK;
114 break;
115 case SND_SOC_DAIFMT_IB_IF:
116 break;
117 default:
118 goto out;
119 }
120
121 /* I2S controller only supports master */
122 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
123 case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
124 break;
125 default:
126 goto out;
127 }
128
129 ret = 0;
130 ctx->cfg = c;
131out:
132 return ret;
133}
134
135static int au1xi2s_trigger(struct snd_pcm_substream *substream,
136 int cmd, struct snd_soc_dai *dai)
137{
138 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
139 int stype = SUBSTREAM_TYPE(substream);
140
141 switch (cmd) {
142 case SNDRV_PCM_TRIGGER_START:
143 case SNDRV_PCM_TRIGGER_RESUME:
144 /* power up */
145 WR(ctx, I2S_ENABLE, EN_D | EN_CE);
146 WR(ctx, I2S_ENABLE, EN_CE);
147 ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
148 WR(ctx, I2S_CFG, ctx->cfg);
149 break;
150 case SNDRV_PCM_TRIGGER_STOP:
151 case SNDRV_PCM_TRIGGER_SUSPEND:
152 ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
153 WR(ctx, I2S_CFG, ctx->cfg);
154 WR(ctx, I2S_ENABLE, EN_D); /* power off */
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 return 0;
161}
162
163static unsigned long msbits_to_reg(int msbits)
164{
165 switch (msbits) {
166 case 8:
167 return CFG_SZ_8;
168 case 16:
169 return CFG_SZ_16;
170 case 18:
171 return CFG_SZ_18;
172 case 20:
173 return CFG_SZ_20;
174 case 24:
175 return CFG_SZ_24;
176 }
177 return 0;
178}
179
180static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai)
183{
184 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
185 unsigned long v;
186
187 v = msbits_to_reg(params->msbits);
188 if (!v)
189 return -EINVAL;
190
191 ctx->cfg &= ~CFG_SZ_MASK;
192 ctx->cfg |= v;
193 return 0;
194}
195
196static int au1xi2s_startup(struct snd_pcm_substream *substream,
197 struct snd_soc_dai *dai)
198{
199 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
200 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
201 return 0;
202}
203
204static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
205 .startup = au1xi2s_startup,
206 .trigger = au1xi2s_trigger,
207 .hw_params = au1xi2s_hw_params,
208 .set_fmt = au1xi2s_set_fmt,
209};
210
211static struct snd_soc_dai_driver au1xi2s_dai_driver = {
212 .symmetric_rates = 1,
213 .playback = {
214 .rates = AU1XI2SC_RATES,
215 .formats = AU1XI2SC_FMTS,
216 .channels_min = 2,
217 .channels_max = 2,
218 },
219 .capture = {
220 .rates = AU1XI2SC_RATES,
221 .formats = AU1XI2SC_FMTS,
222 .channels_min = 2,
223 .channels_max = 2,
224 },
225 .ops = &au1xi2s_dai_ops,
226};
227
228static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
229{
230 int ret;
231 struct resource *iores, *dmares;
232 struct au1xpsc_audio_data *ctx;
233
234 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
235 if (!ctx)
236 return -ENOMEM;
237
238 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!iores) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(iores->start, resource_size(iores),
246 pdev->name))
247 goto out0;
248
249 ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
250 if (!ctx->mmio)
251 goto out1;
252
253 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
254 if (!dmares)
255 goto out2;
256 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
257
258 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
259 if (!dmares)
260 goto out2;
261 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
262
263 platform_set_drvdata(pdev, ctx);
264
265 ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
266 if (ret)
267 goto out2;
268
269 return 0;
270
271out2:
272 iounmap(ctx->mmio);
273out1:
274 release_mem_region(iores->start, resource_size(iores));
275out0:
276 kfree(ctx);
277 return ret;
278}
279
280static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
281{
282 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
283 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
284
285 snd_soc_unregister_dai(&pdev->dev);
286
287 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
288
289 iounmap(ctx->mmio);
290 release_mem_region(r->start, resource_size(r));
291 kfree(ctx);
292
293 return 0;
294}
295
296#ifdef CONFIG_PM
297static int au1xi2s_drvsuspend(struct device *dev)
298{
299 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
300
301 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
302
303 return 0;
304}
305
306static int au1xi2s_drvresume(struct device *dev)
307{
308 return 0;
309}
310
311static const struct dev_pm_ops au1xi2sc_pmops = {
312 .suspend = au1xi2s_drvsuspend,
313 .resume = au1xi2s_drvresume,
314};
315
316#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)
317
318#else
319
320#define AU1XI2SC_PMOPS NULL
321
322#endif
323
324static struct platform_driver au1xi2s_driver = {
325 .driver = {
326 .name = "alchemy-i2sc",
327 .owner = THIS_MODULE,
328 .pm = AU1XI2SC_PMOPS,
329 },
330 .probe = au1xi2s_drvprobe,
331 .remove = __devexit_p(au1xi2s_drvremove),
332};
333
334static int __init au1xi2s_load(void)
335{
336 return platform_driver_register(&au1xi2s_driver);
337}
338
339static void __exit au1xi2s_unload(void)
340{
341 platform_driver_unregister(&au1xi2s_driver);
342}
343
344module_init(au1xi2s_load);
345module_exit(au1xi2s_unload);
346
347MODULE_LICENSE("GPL");
348MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
349MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index d0db66f24a00..0c6acd547141 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -41,14 +41,14 @@
41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) 41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
42 42
43#define AC97PCR_START(stype) \ 43#define AC97PCR_START(stype) \
44 ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) 44 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
45#define AC97PCR_STOP(stype) \ 45#define AC97PCR_STOP(stype) \
46 ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) 46 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
47#define AC97PCR_CLRFIFO(stype) \ 47#define AC97PCR_CLRFIFO(stype) \
48 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) 48 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
49 49
50#define AC97STAT_BUSY(stype) \ 50#define AC97STAT_BUSY(stype) \
51 ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
52 52
53/* instance data. There can be only one, MacLeod!!!! */ 53/* instance data. There can be only one, MacLeod!!!! */
54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; 54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
@@ -215,7 +215,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
215{ 215{
216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
217 unsigned long r, ro, stat; 217 unsigned long r, ro, stat;
218 int chans, t, stype = SUBSTREAM_TYPE(substream); 218 int chans, t, stype = substream->stream;
219 219
220 chans = params_channels(params); 220 chans = params_channels(params);
221 221
@@ -235,7 +235,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
235 r |= PSC_AC97CFG_SET_LEN(params->msbits); 235 r |= PSC_AC97CFG_SET_LEN(params->msbits);
236 236
237 /* channels: enable slots for front L/R channel */ 237 /* channels: enable slots for front L/R channel */
238 if (stype == PCM_TX) { 238 if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
239 r &= ~PSC_AC97CFG_TXSLOT_MASK; 239 r &= ~PSC_AC97CFG_TXSLOT_MASK;
240 r |= PSC_AC97CFG_TXSLOT_ENA(3); 240 r |= PSC_AC97CFG_TXSLOT_ENA(3);
241 r |= PSC_AC97CFG_TXSLOT_ENA(4); 241 r |= PSC_AC97CFG_TXSLOT_ENA(4);
@@ -294,7 +294,7 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
294 int cmd, struct snd_soc_dai *dai) 294 int cmd, struct snd_soc_dai *dai)
295{ 295{
296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
297 int ret, stype = SUBSTREAM_TYPE(substream); 297 int ret, stype = substream->stream;
298 298
299 ret = 0; 299 ret = 0;
300 300
@@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
324 return ret; 324 return ret;
325} 325}
326 326
327static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
328 struct snd_soc_dai *dai)
329{
330 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
331 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
332 return 0;
333}
334
327static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) 335static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
328{ 336{
329 return au1xpsc_ac97_workdata ? 0 : -ENODEV; 337 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
330} 338}
331 339
332static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 340static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
341 .startup = au1xpsc_ac97_startup,
333 .trigger = au1xpsc_ac97_trigger, 342 .trigger = au1xpsc_ac97_trigger,
334 .hw_params = au1xpsc_ac97_hw_params, 343 .hw_params = au1xpsc_ac97_hw_params,
335}; 344};
@@ -355,7 +364,7 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
355static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) 364static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
356{ 365{
357 int ret; 366 int ret;
358 struct resource *r; 367 struct resource *iores, *dmares;
359 unsigned long sel; 368 unsigned long sel;
360 struct au1xpsc_audio_data *wd; 369 struct au1xpsc_audio_data *wd;
361 370
@@ -365,20 +374,31 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
365 374
366 mutex_init(&wd->lock); 375 mutex_init(&wd->lock);
367 376
368 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 377 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
369 if (!r) { 378 if (!iores) {
370 ret = -ENODEV; 379 ret = -ENODEV;
371 goto out0; 380 goto out0;
372 } 381 }
373 382
374 ret = -EBUSY; 383 ret = -EBUSY;
375 if (!request_mem_region(r->start, resource_size(r), pdev->name)) 384 if (!request_mem_region(iores->start, resource_size(iores),
385 pdev->name))
376 goto out0; 386 goto out0;
377 387
378 wd->mmio = ioremap(r->start, resource_size(r)); 388 wd->mmio = ioremap(iores->start, resource_size(iores));
379 if (!wd->mmio) 389 if (!wd->mmio)
380 goto out1; 390 goto out1;
381 391
392 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
393 if (!dmares)
394 goto out2;
395 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
396
397 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
398 if (!dmares)
399 goto out2;
400 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
401
382 /* configuration: max dma trigger threshold, enable ac97 */ 402 /* configuration: max dma trigger threshold, enable ac97 */
383 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | 403 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
384 PSC_AC97CFG_DE_ENABLE; 404 PSC_AC97CFG_DE_ENABLE;
@@ -401,17 +421,15 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
401 421
402 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 422 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
403 if (ret) 423 if (ret)
404 goto out1; 424 goto out2;
405 425
406 wd->dmapd = au1xpsc_pcm_add(pdev); 426 au1xpsc_ac97_workdata = wd;
407 if (wd->dmapd) { 427 return 0;
408 au1xpsc_ac97_workdata = wd;
409 return 0;
410 }
411 428
412 snd_soc_unregister_dai(&pdev->dev); 429out2:
430 iounmap(wd->mmio);
413out1: 431out1:
414 release_mem_region(r->start, resource_size(r)); 432 release_mem_region(iores->start, resource_size(iores));
415out0: 433out0:
416 kfree(wd); 434 kfree(wd);
417 return ret; 435 return ret;
@@ -422,9 +440,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
422 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 440 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
423 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 441 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
424 442
425 if (wd->dmapd)
426 au1xpsc_pcm_destroy(wd->dmapd);
427
428 snd_soc_unregister_dai(&pdev->dev); 443 snd_soc_unregister_dai(&pdev->dev);
429 444
430 /* disable PSC completely */ 445 /* disable PSC completely */
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index fca091276320..e03c5ce01b30 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -42,13 +42,13 @@
42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
43 43
44#define I2SSTAT_BUSY(stype) \ 44#define I2SSTAT_BUSY(stype) \
45 ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) 45 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
46#define I2SPCR_START(stype) \ 46#define I2SPCR_START(stype) \
47 ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) 47 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
48#define I2SPCR_STOP(stype) \ 48#define I2SPCR_STOP(stype) \
49 ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) 49 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
50#define I2SPCR_CLRFIFO(stype) \ 50#define I2SPCR_CLRFIFO(stype) \
51 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
52 52
53 53
54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -240,7 +240,7 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
240 struct snd_soc_dai *dai) 240 struct snd_soc_dai *dai)
241{ 241{
242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
243 int ret, stype = SUBSTREAM_TYPE(substream); 243 int ret, stype = substream->stream;
244 244
245 switch (cmd) { 245 switch (cmd) {
246 case SNDRV_PCM_TRIGGER_START: 246 case SNDRV_PCM_TRIGGER_START:
@@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
257 return ret; 257 return ret;
258} 258}
259 259
260static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
261 struct snd_soc_dai *dai)
262{
263 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
264 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
265 return 0;
266}
267
260static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 268static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
269 .startup = au1xpsc_i2s_startup,
261 .trigger = au1xpsc_i2s_trigger, 270 .trigger = au1xpsc_i2s_trigger,
262 .hw_params = au1xpsc_i2s_hw_params, 271 .hw_params = au1xpsc_i2s_hw_params,
263 .set_fmt = au1xpsc_i2s_set_fmt, 272 .set_fmt = au1xpsc_i2s_set_fmt,
@@ -281,7 +290,7 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
281 290
282static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) 291static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
283{ 292{
284 struct resource *r; 293 struct resource *iores, *dmares;
285 unsigned long sel; 294 unsigned long sel;
286 int ret; 295 int ret;
287 struct au1xpsc_audio_data *wd; 296 struct au1xpsc_audio_data *wd;
@@ -290,20 +299,31 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
290 if (!wd) 299 if (!wd)
291 return -ENOMEM; 300 return -ENOMEM;
292 301
293 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 302 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
294 if (!r) { 303 if (!iores) {
295 ret = -ENODEV; 304 ret = -ENODEV;
296 goto out0; 305 goto out0;
297 } 306 }
298 307
299 ret = -EBUSY; 308 ret = -EBUSY;
300 if (!request_mem_region(r->start, resource_size(r), pdev->name)) 309 if (!request_mem_region(iores->start, resource_size(iores),
310 pdev->name))
301 goto out0; 311 goto out0;
302 312
303 wd->mmio = ioremap(r->start, resource_size(r)); 313 wd->mmio = ioremap(iores->start, resource_size(iores));
304 if (!wd->mmio) 314 if (!wd->mmio)
305 goto out1; 315 goto out1;
306 316
317 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
318 if (!dmares)
319 goto out2;
320 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
321
322 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
323 if (!dmares)
324 goto out2;
325 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
326
307 /* preserve PSC clock source set up by platform (dev.platform_data 327 /* preserve PSC clock source set up by platform (dev.platform_data
308 * is already occupied by soc layer) 328 * is already occupied by soc layer)
309 */ 329 */
@@ -330,17 +350,13 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
330 platform_set_drvdata(pdev, wd); 350 platform_set_drvdata(pdev, wd);
331 351
332 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 352 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
333 if (ret) 353 if (!ret)
334 goto out1;
335
336 /* finally add the DMA device for this PSC */
337 wd->dmapd = au1xpsc_pcm_add(pdev);
338 if (wd->dmapd)
339 return 0; 354 return 0;
340 355
341 snd_soc_unregister_dai(&pdev->dev); 356out2:
357 iounmap(wd->mmio);
342out1: 358out1:
343 release_mem_region(r->start, resource_size(r)); 359 release_mem_region(iores->start, resource_size(iores));
344out0: 360out0:
345 kfree(wd); 361 kfree(wd);
346 return ret; 362 return ret;
@@ -351,9 +367,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
351 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 367 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
352 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 368 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 369
354 if (wd->dmapd)
355 au1xpsc_pcm_destroy(wd->dmapd);
356
357 snd_soc_unregister_dai(&pdev->dev); 370 snd_soc_unregister_dai(&pdev->dev);
358 371
359 au_writel(0, I2S_CFG(wd)); 372 au_writel(0, I2S_CFG(wd));
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index b30eadd422a7..b16b2e02e0c9 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Alchemy ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2011 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <manuel.lauss@gmail.com> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -13,10 +13,6 @@
13#ifndef _AU1X_PCM_H 13#ifndef _AU1X_PCM_H
14#define _AU1X_PCM_H 14#define _AU1X_PCM_H
15 15
16/* DBDMA helpers */
17extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
18extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
19
20struct au1xpsc_audio_data { 16struct au1xpsc_audio_data {
21 void __iomem *mmio; 17 void __iomem *mmio;
22 18
@@ -27,15 +23,9 @@ struct au1xpsc_audio_data {
27 23
28 unsigned long pm[2]; 24 unsigned long pm[2];
29 struct mutex lock; 25 struct mutex lock;
30 struct platform_device *dmapd; 26 int dmaids[2];
31}; 27};
32 28
33#define PCM_TX 0
34#define PCM_RX 1
35
36#define SUBSTREAM_TYPE(substream) \
37 ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX)
38
39/* easy access macros */ 29/* easy access macros */
40#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) 30#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
41#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) 31#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index fe9d548a6837..9f6bc55fc399 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701
27 board connected to one of the Blackfin evaluation boards like the 27 board connected to one of the Blackfin evaluation boards like the
28 BF5XX-STAMP or BF5XX-EZKIT. 28 BF5XX-STAMP or BF5XX-EZKIT.
29 29
30config SND_SOC_BFIN_EVAL_ADAU1373
31 tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && I2C
33 select SND_BF5XX_SOC_I2S
34 select SND_SOC_ADAU1373
35 help
36 Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
37 board connected to one of the Blackfin evaluation boards like the
38 BF5XX-STAMP or BF5XX-EZKIT.
39
40 Note: This driver assumes that first ADAU1373 DAI is connected to the
41 first SPORT port on the BF5XX board.
42
30config SND_SOC_BFIN_EVAL_ADAV80X 43config SND_SOC_BFIN_EVAL_ADAV80X
31 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" 44 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 45 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 6018bf52a234..1bf86ccaa8de 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -21,6 +21,7 @@ snd-ad1980-objs := bf5xx-ad1980.o
21snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
22snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad193x-objs := bf5xx-ad193x.o 23snd-ad193x-objs := bf5xx-ad193x.o
24snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
24snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o 25snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
25snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o 26snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
26 27
@@ -29,5 +30,6 @@ obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
29obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 30obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
30obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 31obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
31obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o 32obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
32obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o 34obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o 35obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 9e59f680bc19..56815c1d47b3 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -418,7 +418,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
418 418
419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
420 420
421int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) 421static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
422{ 422{
423 struct snd_card *card = rtd->card->snd_card; 423 struct snd_card *card = rtd->card->snd_card;
424 struct snd_soc_dai *dai = rtd->cpu_dai; 424 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 61ddf942fd4d..7565e1576ffa 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -257,7 +257,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
257 257
258static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 258static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
259 259
260int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) 260static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
261{ 261{
262 struct snd_card *card = rtd->card->snd_card; 262 struct snd_card *card = rtd->card->snd_card;
263 struct snd_soc_dai *dai = rtd->cpu_dai; 263 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
new file mode 100644
index 000000000000..8df2a3b0cb36
--- /dev/null
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -0,0 +1,202 @@
1/*
2 * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
3 * evaluation boards.
4 *
5 * Copyright 2011 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/pcm_params.h>
17
18#include "../codecs/adau1373.h"
19
20static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
21 SND_SOC_DAPM_LINE("Line In1", NULL),
22 SND_SOC_DAPM_LINE("Line In2", NULL),
23 SND_SOC_DAPM_LINE("Line In3", NULL),
24 SND_SOC_DAPM_LINE("Line In4", NULL),
25
26 SND_SOC_DAPM_LINE("Line Out1", NULL),
27 SND_SOC_DAPM_LINE("Line Out2", NULL),
28 SND_SOC_DAPM_LINE("Stereo Out", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_HP("Earpiece", NULL),
31 SND_SOC_DAPM_SPK("Speaker", NULL),
32};
33
34static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
35 { "AIN1L", NULL, "Line In1" },
36 { "AIN1R", NULL, "Line In1" },
37 { "AIN2L", NULL, "Line In2" },
38 { "AIN2R", NULL, "Line In2" },
39 { "AIN3L", NULL, "Line In3" },
40 { "AIN3R", NULL, "Line In3" },
41 { "AIN4L", NULL, "Line In4" },
42 { "AIN4R", NULL, "Line In4" },
43
44 /* MICBIAS can be connected via a jumper to the line-in jack, since w
45 don't know which one is going to be used, just power both. */
46 { "Line In1", NULL, "MICBIAS1" },
47 { "Line In2", NULL, "MICBIAS1" },
48 { "Line In3", NULL, "MICBIAS1" },
49 { "Line In4", NULL, "MICBIAS1" },
50 { "Line In1", NULL, "MICBIAS2" },
51 { "Line In2", NULL, "MICBIAS2" },
52 { "Line In3", NULL, "MICBIAS2" },
53 { "Line In4", NULL, "MICBIAS2" },
54
55 { "Line Out1", NULL, "LOUT1L" },
56 { "Line Out1", NULL, "LOUT1R" },
57 { "Line Out2", NULL, "LOUT2L" },
58 { "Line Out2", NULL, "LOUT2R" },
59 { "Headphone", NULL, "HPL" },
60 { "Headphone", NULL, "HPR" },
61 { "Earpiece", NULL, "EP" },
62 { "Speaker", NULL, "SPKL" },
63 { "Stereo Out", NULL, "SPKR" },
64};
65
66static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
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;
72 int ret;
73 int pll_rate;
74
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)) {
86 case 48000:
87 case 8000:
88 case 12000:
89 case 16000:
90 case 24000:
91 case 32000:
92 pll_rate = 48000 * 1024;
93 break;
94 case 44100:
95 case 7350:
96 case 11025:
97 case 14700:
98 case 22050:
99 case 29400:
100 pll_rate = 44100 * 1024;
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
107 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
108 if (ret)
109 return ret;
110
111 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
112 SND_SOC_CLOCK_IN);
113
114 return ret;
115}
116
117static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
118{
119 struct snd_soc_dai *codec_dai = rtd->codec_dai;
120 unsigned int pll_rate = 48000 * 1024;
121 int ret;
122
123 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
124 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
125 if (ret)
126 return ret;
127
128 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
129 SND_SOC_CLOCK_IN);
130
131 return ret;
132}
133static struct snd_soc_ops bfin_eval_adau1373_ops = {
134 .hw_params = bfin_eval_adau1373_hw_params,
135};
136
137static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
138 .name = "adau1373",
139 .stream_name = "adau1373",
140 .cpu_dai_name = "bfin-i2s.0",
141 .codec_dai_name = "adau1373-aif1",
142 .platform_name = "bfin-i2s-pcm-audio",
143 .codec_name = "adau1373.0-001a",
144 .ops = &bfin_eval_adau1373_ops,
145 .init = bfin_eval_adau1373_codec_init,
146};
147
148static struct snd_soc_card bfin_eval_adau1373 = {
149 .name = "bfin-eval-adau1373",
150 .dai_link = &bfin_eval_adau1373_dai,
151 .num_links = 1,
152
153 .dapm_widgets = bfin_eval_adau1373_dapm_widgets,
154 .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
155 .dapm_routes = bfin_eval_adau1373_dapm_routes,
156 .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
157};
158
159static int bfin_eval_adau1373_probe(struct platform_device *pdev)
160{
161 struct snd_soc_card *card = &bfin_eval_adau1373;
162
163 card->dev = &pdev->dev;
164
165 return snd_soc_register_card(&bfin_eval_adau1373);
166}
167
168static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
169{
170 struct snd_soc_card *card = platform_get_drvdata(pdev);
171
172 snd_soc_unregister_card(card);
173
174 return 0;
175}
176
177static struct platform_driver bfin_eval_adau1373_driver = {
178 .driver = {
179 .name = "bfin-eval-adau1373",
180 .owner = THIS_MODULE,
181 .pm = &snd_soc_pm_ops,
182 },
183 .probe = bfin_eval_adau1373_probe,
184 .remove = __devexit_p(bfin_eval_adau1373_remove),
185};
186
187static int __init bfin_eval_adau1373_init(void)
188{
189 return platform_driver_register(&bfin_eval_adau1373_driver);
190}
191module_init(bfin_eval_adau1373_init);
192
193static void __exit bfin_eval_adau1373_exit(void)
194{
195 platform_driver_unregister(&bfin_eval_adau1373_driver);
196}
197module_exit(bfin_eval_adau1373_exit);
198
199MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
200MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
201MODULE_LICENSE("GPL");
202MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 19241576b6b5..5ca122e51183 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -15,6 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/mfd/88pm860x.h> 16#include <linux/mfd/88pm860x.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/delay.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
@@ -772,11 +773,12 @@ static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = {
772 773
773 774
774 SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0, 775 SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0,
775 PM860X_DAC_EN_2, 0, 0), 776 SND_SOC_NOPM, 0, 0),
776 SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0, 777 SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0,
777 PM860X_DAC_EN_2, 0, 0), 778 SND_SOC_NOPM, 0, 0),
778 SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0, 779 SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0,
779 PM860X_I2S_IFACE_3, 5, 1), 780 PM860X_I2S_IFACE_3, 5, 1),
781 SND_SOC_DAPM_SUPPLY("I2S CLK", PM860X_DAC_EN_2, 0, 0, NULL, 0),
780 SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux), 782 SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux),
781 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux), 783 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
782 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), 784 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
@@ -868,6 +870,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
868 {"Left ADC", NULL, "Left ADC MOD"}, 870 {"Left ADC", NULL, "Left ADC MOD"},
869 {"Right ADC", NULL, "Right ADC MOD"}, 871 {"Right ADC", NULL, "Right ADC MOD"},
870 872
873 /* I2S Clock */
874 {"I2S DIN", NULL, "I2S CLK"},
875 {"I2S DIN1", NULL, "I2S CLK"},
876 {"I2S DOUT", NULL, "I2S CLK"},
877
871 /* PCM/AIF1 Inputs */ 878 /* PCM/AIF1 Inputs */
872 {"PCM SDO", NULL, "ADC Left Mux"}, 879 {"PCM SDO", NULL, "ADC Left Mux"},
873 {"PCM SDO", NULL, "ADCR EC Mux"}, 880 {"PCM SDO", NULL, "ADCR EC Mux"},
@@ -1173,6 +1180,9 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1173 case SND_SOC_BIAS_STANDBY: 1180 case SND_SOC_BIAS_STANDBY:
1174 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1181 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1175 /* Enable Audio PLL & Audio section */ 1182 /* Enable Audio PLL & Audio section */
1183 data = AUDIO_PLL | AUDIO_SECTION_ON;
1184 pm860x_reg_write(codec->control_data, REG_MISC2, data);
1185 udelay(300);
1176 data = AUDIO_PLL | AUDIO_SECTION_RESET 1186 data = AUDIO_PLL | AUDIO_SECTION_RESET
1177 | AUDIO_SECTION_ON; 1187 | AUDIO_SECTION_ON;
1178 pm860x_reg_write(codec->control_data, REG_MISC2, data); 1188 pm860x_reg_write(codec->control_data, REG_MISC2, data);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 665d9240c4ae..4584514d93d4 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311 19 select SND_SOC_AD73311
20 select SND_SOC_ADAU1373 if I2C
20 select SND_SOC_ADAV80X 21 select SND_SOC_ADAV80X
21 select SND_SOC_ADS117X 22 select SND_SOC_ADS117X
22 select SND_SOC_AK4104 if SPI_MASTER 23 select SND_SOC_AK4104 if SPI_MASTER
@@ -39,6 +40,7 @@ config SND_SOC_ALL_CODECS
39 select SND_SOC_MAX9850 if I2C 40 select SND_SOC_MAX9850 if I2C
40 select SND_SOC_MAX9877 if I2C 41 select SND_SOC_MAX9877 if I2C
41 select SND_SOC_PCM3008 42 select SND_SOC_PCM3008
43 select SND_SOC_RT5631 if I2C
42 select SND_SOC_SGTL5000 if I2C 44 select SND_SOC_SGTL5000 if I2C
43 select SND_SOC_SN95031 if INTEL_SCU_IPC 45 select SND_SOC_SN95031 if INTEL_SCU_IPC
44 select SND_SOC_SPDIF 46 select SND_SOC_SPDIF
@@ -47,7 +49,7 @@ config SND_SOC_ALL_CODECS
47 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 49 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
48 select SND_SOC_TLV320AIC23 if I2C 50 select SND_SOC_TLV320AIC23 if I2C
49 select SND_SOC_TLV320AIC26 if SPI_MASTER 51 select SND_SOC_TLV320AIC26 if SPI_MASTER
50 select SND_SOC_TVL320AIC32X4 if I2C 52 select SND_SOC_TLV320AIC32X4 if I2C
51 select SND_SOC_TLV320AIC3X if I2C 53 select SND_SOC_TLV320AIC3X if I2C
52 select SND_SOC_TPA6130A2 if I2C 54 select SND_SOC_TPA6130A2 if I2C
53 select SND_SOC_TLV320DAC33 if I2C 55 select SND_SOC_TLV320DAC33 if I2C
@@ -58,6 +60,7 @@ config SND_SOC_ALL_CODECS
58 select SND_SOC_WL1273 if MFD_WL1273_CORE 60 select SND_SOC_WL1273 if MFD_WL1273_CORE
59 select SND_SOC_WM1250_EV1 if I2C 61 select SND_SOC_WM1250_EV1 if I2C
60 select SND_SOC_WM2000 if I2C 62 select SND_SOC_WM2000 if I2C
63 select SND_SOC_WM5100 if I2C
61 select SND_SOC_WM8350 if MFD_WM8350 64 select SND_SOC_WM8350 if MFD_WM8350
62 select SND_SOC_WM8400 if MFD_WM8400 65 select SND_SOC_WM8400 if MFD_WM8400
63 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 66 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -139,6 +142,9 @@ config SND_SOC_ADAU1701
139 select SIGMA 142 select SIGMA
140 tristate 143 tristate
141 144
145config SND_SOC_ADAU1373
146 tristate
147
142config SND_SOC_ADAV80X 148config SND_SOC_ADAV80X
143 tristate 149 tristate
144 150
@@ -214,6 +220,9 @@ config SND_SOC_MAX9850
214config SND_SOC_PCM3008 220config SND_SOC_PCM3008
215 tristate 221 tristate
216 222
223config SND_SOC_RT5631
224 tristate
225
217#Freescale sgtl5000 codec 226#Freescale sgtl5000 codec
218config SND_SOC_SGTL5000 227config SND_SOC_SGTL5000
219 tristate 228 tristate
@@ -240,7 +249,7 @@ config SND_SOC_TLV320AIC26
240 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 249 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
241 depends on SPI 250 depends on SPI
242 251
243config SND_SOC_TVL320AIC32X4 252config SND_SOC_TLV320AIC32X4
244 tristate 253 tristate
245 254
246config SND_SOC_TLV320AIC3X 255config SND_SOC_TLV320AIC3X
@@ -269,6 +278,9 @@ config SND_SOC_WL1273
269config SND_SOC_WM1250_EV1 278config SND_SOC_WM1250_EV1
270 tristate 279 tristate
271 280
281config SND_SOC_WM5100
282 tristate
283
272config SND_SOC_WM8350 284config SND_SOC_WM8350
273 tristate 285 tristate
274 286
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5119a7e2c1a8..a2c7842e357b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -5,6 +5,7 @@ snd-soc-ad193x-objs := ad193x.o
5snd-soc-ad1980-objs := ad1980.o 5snd-soc-ad1980-objs := ad1980.o
6snd-soc-ad73311-objs := ad73311.o 6snd-soc-ad73311-objs := ad73311.o
7snd-soc-adau1701-objs := adau1701.o 7snd-soc-adau1701-objs := adau1701.o
8snd-soc-adau1373-objs := adau1373.o
8snd-soc-adav80x-objs := adav80x.o 9snd-soc-adav80x-objs := adav80x.o
9snd-soc-ads117x-objs := ads117x.o 10snd-soc-ads117x-objs := ads117x.o
10snd-soc-ak4104-objs := ak4104.o 11snd-soc-ak4104-objs := ak4104.o
@@ -25,6 +26,7 @@ snd-soc-max98088-objs := max98088.o
25snd-soc-max98095-objs := max98095.o 26snd-soc-max98095-objs := max98095.o
26snd-soc-max9850-objs := max9850.o 27snd-soc-max9850-objs := max9850.o
27snd-soc-pcm3008-objs := pcm3008.o 28snd-soc-pcm3008-objs := pcm3008.o
29snd-soc-rt5631-objs := rt5631.o
28snd-soc-sgtl5000-objs := sgtl5000.o 30snd-soc-sgtl5000-objs := sgtl5000.o
29snd-soc-alc5623-objs := alc5623.o 31snd-soc-alc5623-objs := alc5623.o
30snd-soc-sn95031-objs := sn95031.o 32snd-soc-sn95031-objs := sn95031.o
@@ -43,6 +45,7 @@ snd-soc-uda134x-objs := uda134x.o
43snd-soc-uda1380-objs := uda1380.o 45snd-soc-uda1380-objs := uda1380.o
44snd-soc-wl1273-objs := wl1273.o 46snd-soc-wl1273-objs := wl1273.o
45snd-soc-wm1250-ev1-objs := wm1250-ev1.o 47snd-soc-wm1250-ev1-objs := wm1250-ev1.o
48snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
46snd-soc-wm8350-objs := wm8350.o 49snd-soc-wm8350-objs := wm8350.o
47snd-soc-wm8400-objs := wm8400.o 50snd-soc-wm8400-objs := wm8400.o
48snd-soc-wm8510-objs := wm8510.o 51snd-soc-wm8510-objs := wm8510.o
@@ -100,6 +103,7 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
100obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 103obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
101obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 104obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
102obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 105obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
106obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
103obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 107obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
104obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 108obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
105obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 109obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
@@ -123,6 +127,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
123obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 127obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
124obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 128obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
125obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 129obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
130obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
126obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 131obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
127obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 132obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
128obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 133obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -132,7 +137,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
132obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 137obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
133obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 138obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
134obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 139obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
135obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o 140obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
136obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 141obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
137obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 142obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
138obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 143obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
@@ -140,6 +145,7 @@ obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
140obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 145obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
141obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 146obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
142obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o 147obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
148obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
143obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 149obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
144obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 150obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
145obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 151obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index eedb6f5e5823..120602130b5c 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,7 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type control_type; 26 struct regmap *regmap;
27 int sysclk; 27 int sysclk;
28}; 28};
29 29
@@ -103,12 +103,14 @@ static const struct snd_soc_dapm_route audio_paths[] = {
103static int ad193x_mute(struct snd_soc_dai *dai, int mute) 103static int ad193x_mute(struct snd_soc_dai *dai, int mute)
104{ 104{
105 struct snd_soc_codec *codec = dai->codec; 105 struct snd_soc_codec *codec = dai->codec;
106 int reg;
107 106
108 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 107 if (mute)
109 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg & 108 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
110 (~AD193X_DAC_MASTER_MUTE); 109 AD193X_DAC_MASTER_MUTE,
111 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 110 AD193X_DAC_MASTER_MUTE);
111 else
112 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
113 AD193X_DAC_MASTER_MUTE, 0);
112 114
113 return 0; 115 return 0;
114} 116}
@@ -262,7 +264,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params, 264 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai) 265 struct snd_soc_dai *dai)
264{ 266{
265 int word_len = 0, reg = 0, master_rate = 0; 267 int word_len = 0, master_rate = 0;
266 268
267 struct snd_soc_pcm_runtime *rtd = substream->private_data; 269 struct snd_soc_pcm_runtime *rtd = substream->private_data;
268 struct snd_soc_codec *codec = rtd->codec; 270 struct snd_soc_codec *codec = rtd->codec;
@@ -297,18 +299,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
297 break; 299 break;
298 } 300 }
299 301
300 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0); 302 snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0,
301 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate; 303 AD193X_PLL_INPUT_MASK, master_rate);
302 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
303 304
304 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 305 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
305 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) 306 AD193X_DAC_WORD_LEN_MASK,
306 | (word_len << AD193X_DAC_WORD_LEN_SHFT); 307 word_len << AD193X_DAC_WORD_LEN_SHFT);
307 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
308 308
309 reg = snd_soc_read(codec, AD193X_ADC_CTRL1); 309 snd_soc_update_bits(codec, AD193X_ADC_CTRL1,
310 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len; 310 AD193X_ADC_WORD_LEN_MASK, word_len);
311 snd_soc_write(codec, AD193X_ADC_CTRL1, reg);
312 311
313 return 0; 312 return 0;
314} 313}
@@ -349,10 +348,8 @@ static int ad193x_probe(struct snd_soc_codec *codec)
349 struct snd_soc_dapm_context *dapm = &codec->dapm; 348 struct snd_soc_dapm_context *dapm = &codec->dapm;
350 int ret; 349 int ret;
351 350
352 if (ad193x->control_type == SND_SOC_I2C) 351 codec->control_data = ad193x->regmap;
353 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); 352 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
354 else
355 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
356 if (ret < 0) { 353 if (ret < 0) {
357 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 354 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
358 return ret; 355 return ret;
@@ -388,6 +385,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
388}; 385};
389 386
390#if defined(CONFIG_SPI_MASTER) 387#if defined(CONFIG_SPI_MASTER)
388
389static const struct regmap_config ad193x_spi_regmap_config = {
390 .val_bits = 8,
391 .reg_bits = 16,
392 .read_flag_mask = 0x09,
393 .write_flag_mask = 0x08,
394};
395
391static int __devinit ad193x_spi_probe(struct spi_device *spi) 396static int __devinit ad193x_spi_probe(struct spi_device *spi)
392{ 397{
393 struct ad193x_priv *ad193x; 398 struct ad193x_priv *ad193x;
@@ -397,20 +402,36 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
397 if (ad193x == NULL) 402 if (ad193x == NULL)
398 return -ENOMEM; 403 return -ENOMEM;
399 404
405 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
406 if (IS_ERR(ad193x->regmap)) {
407 ret = PTR_ERR(ad193x->regmap);
408 goto err_free;
409 }
410
400 spi_set_drvdata(spi, ad193x); 411 spi_set_drvdata(spi, ad193x);
401 ad193x->control_type = SND_SOC_SPI;
402 412
403 ret = snd_soc_register_codec(&spi->dev, 413 ret = snd_soc_register_codec(&spi->dev,
404 &soc_codec_dev_ad193x, &ad193x_dai, 1); 414 &soc_codec_dev_ad193x, &ad193x_dai, 1);
405 if (ret < 0) 415 if (ret < 0)
406 kfree(ad193x); 416 goto err_regmap_exit;
417
418 return 0;
419
420err_regmap_exit:
421 regmap_exit(ad193x->regmap);
422err_free:
423 kfree(ad193x);
424
407 return ret; 425 return ret;
408} 426}
409 427
410static int __devexit ad193x_spi_remove(struct spi_device *spi) 428static int __devexit ad193x_spi_remove(struct spi_device *spi)
411{ 429{
430 struct ad193x_priv *ad193x = spi_get_drvdata(spi);
431
412 snd_soc_unregister_codec(&spi->dev); 432 snd_soc_unregister_codec(&spi->dev);
413 kfree(spi_get_drvdata(spi)); 433 regmap_exit(ad193x->regmap);
434 kfree(ad193x);
414 return 0; 435 return 0;
415} 436}
416 437
@@ -425,6 +446,12 @@ static struct spi_driver ad193x_spi_driver = {
425#endif 446#endif
426 447
427#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 448#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
449
450static const struct regmap_config ad193x_i2c_regmap_config = {
451 .val_bits = 8,
452 .reg_bits = 8,
453};
454
428static const struct i2c_device_id ad193x_id[] = { 455static const struct i2c_device_id ad193x_id[] = {
429 { "ad1936", 0 }, 456 { "ad1936", 0 },
430 { "ad1937", 0 }, 457 { "ad1937", 0 },
@@ -442,20 +469,35 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
442 if (ad193x == NULL) 469 if (ad193x == NULL)
443 return -ENOMEM; 470 return -ENOMEM;
444 471
472 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
473 if (IS_ERR(ad193x->regmap)) {
474 ret = PTR_ERR(ad193x->regmap);
475 goto err_free;
476 }
477
445 i2c_set_clientdata(client, ad193x); 478 i2c_set_clientdata(client, ad193x);
446 ad193x->control_type = SND_SOC_I2C;
447 479
448 ret = snd_soc_register_codec(&client->dev, 480 ret = snd_soc_register_codec(&client->dev,
449 &soc_codec_dev_ad193x, &ad193x_dai, 1); 481 &soc_codec_dev_ad193x, &ad193x_dai, 1);
450 if (ret < 0) 482 if (ret < 0)
451 kfree(ad193x); 483 goto err_regmap_exit;
484
485 return 0;
486
487err_regmap_exit:
488 regmap_exit(ad193x->regmap);
489err_free:
490 kfree(ad193x);
452 return ret; 491 return ret;
453} 492}
454 493
455static int __devexit ad193x_i2c_remove(struct i2c_client *client) 494static int __devexit ad193x_i2c_remove(struct i2c_client *client)
456{ 495{
496 struct ad193x_priv *ad193x = i2c_get_clientdata(client);
497
457 snd_soc_unregister_codec(&client->dev); 498 snd_soc_unregister_codec(&client->dev);
458 kfree(i2c_get_clientdata(client)); 499 regmap_exit(ad193x->regmap);
500 kfree(ad193x);
459 return 0; 501 return 0;
460} 502}
461 503
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index cccc2e8e5fbd..1507eaa425a3 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -9,20 +9,20 @@
9#ifndef __AD193X_H__ 9#ifndef __AD193X_H__
10#define __AD193X_H__ 10#define __AD193X_H__
11 11
12#define AD193X_PLL_CLK_CTRL0 0x800 12#define AD193X_PLL_CLK_CTRL0 0x00
13#define AD193X_PLL_POWERDOWN 0x01 13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK (~0x6) 14#define AD193X_PLL_INPUT_MASK 0x6
15#define AD193X_PLL_INPUT_256 (0 << 1) 15#define AD193X_PLL_INPUT_256 (0 << 1)
16#define AD193X_PLL_INPUT_384 (1 << 1) 16#define AD193X_PLL_INPUT_384 (1 << 1)
17#define AD193X_PLL_INPUT_512 (2 << 1) 17#define AD193X_PLL_INPUT_512 (2 << 1)
18#define AD193X_PLL_INPUT_768 (3 << 1) 18#define AD193X_PLL_INPUT_768 (3 << 1)
19#define AD193X_PLL_CLK_CTRL1 0x801 19#define AD193X_PLL_CLK_CTRL1 0x01
20#define AD193X_DAC_CTRL0 0x802 20#define AD193X_DAC_CTRL0 0x02
21#define AD193X_DAC_POWERDOWN 0x01 21#define AD193X_DAC_POWERDOWN 0x01
22#define AD193X_DAC_SERFMT_MASK 0xC0 22#define AD193X_DAC_SERFMT_MASK 0xC0
23#define AD193X_DAC_SERFMT_STEREO (0 << 6) 23#define AD193X_DAC_SERFMT_STEREO (0 << 6)
24#define AD193X_DAC_SERFMT_TDM (1 << 6) 24#define AD193X_DAC_SERFMT_TDM (1 << 6)
25#define AD193X_DAC_CTRL1 0x803 25#define AD193X_DAC_CTRL1 0x03
26#define AD193X_DAC_2_CHANNELS 0 26#define AD193X_DAC_2_CHANNELS 0
27#define AD193X_DAC_4_CHANNELS 1 27#define AD193X_DAC_4_CHANNELS 1
28#define AD193X_DAC_8_CHANNELS 2 28#define AD193X_DAC_8_CHANNELS 2
@@ -33,11 +33,11 @@
33#define AD193X_DAC_BCLK_MASTER (1 << 5) 33#define AD193X_DAC_BCLK_MASTER (1 << 5)
34#define AD193X_DAC_LEFT_HIGH (1 << 3) 34#define AD193X_DAC_LEFT_HIGH (1 << 3)
35#define AD193X_DAC_BCLK_INV (1 << 7) 35#define AD193X_DAC_BCLK_INV (1 << 7)
36#define AD193X_DAC_CTRL2 0x804 36#define AD193X_DAC_CTRL2 0x04
37#define AD193X_DAC_WORD_LEN_SHFT 3 37#define AD193X_DAC_WORD_LEN_SHFT 3
38#define AD193X_DAC_WORD_LEN_MASK 0x18 38#define AD193X_DAC_WORD_LEN_MASK 0x18
39#define AD193X_DAC_MASTER_MUTE 1 39#define AD193X_DAC_MASTER_MUTE 1
40#define AD193X_DAC_CHNL_MUTE 0x805 40#define AD193X_DAC_CHNL_MUTE 0x05
41#define AD193X_DACL1_MUTE 0 41#define AD193X_DACL1_MUTE 0
42#define AD193X_DACR1_MUTE 1 42#define AD193X_DACR1_MUTE 1
43#define AD193X_DACL2_MUTE 2 43#define AD193X_DACL2_MUTE 2
@@ -46,28 +46,28 @@
46#define AD193X_DACR3_MUTE 5 46#define AD193X_DACR3_MUTE 5
47#define AD193X_DACL4_MUTE 6 47#define AD193X_DACL4_MUTE 6
48#define AD193X_DACR4_MUTE 7 48#define AD193X_DACR4_MUTE 7
49#define AD193X_DAC_L1_VOL 0x806 49#define AD193X_DAC_L1_VOL 0x06
50#define AD193X_DAC_R1_VOL 0x807 50#define AD193X_DAC_R1_VOL 0x07
51#define AD193X_DAC_L2_VOL 0x808 51#define AD193X_DAC_L2_VOL 0x08
52#define AD193X_DAC_R2_VOL 0x809 52#define AD193X_DAC_R2_VOL 0x09
53#define AD193X_DAC_L3_VOL 0x80a 53#define AD193X_DAC_L3_VOL 0x0a
54#define AD193X_DAC_R3_VOL 0x80b 54#define AD193X_DAC_R3_VOL 0x0b
55#define AD193X_DAC_L4_VOL 0x80c 55#define AD193X_DAC_L4_VOL 0x0c
56#define AD193X_DAC_R4_VOL 0x80d 56#define AD193X_DAC_R4_VOL 0x0d
57#define AD193X_ADC_CTRL0 0x80e 57#define AD193X_ADC_CTRL0 0x0e
58#define AD193X_ADC_POWERDOWN 0x01 58#define AD193X_ADC_POWERDOWN 0x01
59#define AD193X_ADC_HIGHPASS_FILTER 1 59#define AD193X_ADC_HIGHPASS_FILTER 1
60#define AD193X_ADCL1_MUTE 2 60#define AD193X_ADCL1_MUTE 2
61#define AD193X_ADCR1_MUTE 3 61#define AD193X_ADCR1_MUTE 3
62#define AD193X_ADCL2_MUTE 4 62#define AD193X_ADCL2_MUTE 4
63#define AD193X_ADCR2_MUTE 5 63#define AD193X_ADCR2_MUTE 5
64#define AD193X_ADC_CTRL1 0x80f 64#define AD193X_ADC_CTRL1 0x0f
65#define AD193X_ADC_SERFMT_MASK 0x60 65#define AD193X_ADC_SERFMT_MASK 0x60
66#define AD193X_ADC_SERFMT_STEREO (0 << 5) 66#define AD193X_ADC_SERFMT_STEREO (0 << 5)
67#define AD193X_ADC_SERFMT_TDM (1 << 5) 67#define AD193X_ADC_SERFMT_TDM (1 << 5)
68#define AD193X_ADC_SERFMT_AUX (2 << 5) 68#define AD193X_ADC_SERFMT_AUX (2 << 5)
69#define AD193X_ADC_WORD_LEN_MASK 0x3 69#define AD193X_ADC_WORD_LEN_MASK 0x3
70#define AD193X_ADC_CTRL2 0x810 70#define AD193X_ADC_CTRL2 0x10
71#define AD193X_ADC_2_CHANNELS 0 71#define AD193X_ADC_2_CHANNELS 0
72#define AD193X_ADC_4_CHANNELS 1 72#define AD193X_ADC_4_CHANNELS 1
73#define AD193X_ADC_8_CHANNELS 2 73#define AD193X_ADC_8_CHANNELS 2
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 923b364a3e41..e3931cc5e66c 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -148,7 +148,6 @@ static struct snd_soc_dai_driver ad1980_dai = {
148 .rates = SNDRV_PCM_RATE_48000, 148 .rates = SNDRV_PCM_RATE_48000,
149 .formats = SND_SOC_STD_AC97_FMTS, }, 149 .formats = SND_SOC_STD_AC97_FMTS, },
150}; 150};
151EXPORT_SYMBOL_GPL(ad1980_dai);
152 151
153static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) 152static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
154{ 153{
@@ -200,18 +199,22 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
200 } 199 }
201 200
202 /* Read out vendor ID to make sure it is ad1980 */ 201 /* Read out vendor ID to make sure it is ad1980 */
203 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) 202 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) {
203 ret = -ENODEV;
204 goto reset_err; 204 goto reset_err;
205 }
205 206
206 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); 207 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
207 208
208 if (vendor_id2 != 0x5370) { 209 if (vendor_id2 != 0x5370) {
209 if (vendor_id2 != 0x5374) 210 if (vendor_id2 != 0x5374) {
211 ret = -ENODEV;
210 goto reset_err; 212 goto reset_err;
211 else 213 } else {
212 printk(KERN_WARNING "ad1980: " 214 printk(KERN_WARNING "ad1980: "
213 "Found AD1981 - only 2/2 IN/OUT Channels " 215 "Found AD1981 - only 2/2 IN/OUT Channels "
214 "supported\n"); 216 "supported\n");
217 }
215 } 218 }
216 219
217 /* unmute captures and playbacks volume */ 220 /* unmute captures and playbacks volume */
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
new file mode 100644
index 000000000000..1ccf8dd47576
--- /dev/null
+++ b/sound/soc/codecs/adau1373.c
@@ -0,0 +1,1414 @@
1/*
2 * Analog Devices ADAU1373 Audio Codec drive
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/delay.h>
13#include <linux/pm.h>
14#include <linux/i2c.h>
15#include <linux/slab.h>
16#include <linux/gcd.h>
17
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/tlv.h>
22#include <sound/soc.h>
23#include <sound/adau1373.h>
24
25#include "adau1373.h"
26
27struct adau1373_dai {
28 unsigned int clk_src;
29 unsigned int sysclk;
30 bool enable_src;
31 bool master;
32};
33
34struct adau1373 {
35 struct adau1373_dai dais[3];
36};
37
38#define ADAU1373_INPUT_MODE 0x00
39#define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2)
40#define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2)
41#define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2)
42#define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2)
43#define ADAU1373_LSPK_OUT 0x0d
44#define ADAU1373_RSPK_OUT 0x0e
45#define ADAU1373_LHP_OUT 0x0f
46#define ADAU1373_RHP_OUT 0x10
47#define ADAU1373_ADC_GAIN 0x11
48#define ADAU1373_LADC_MIXER 0x12
49#define ADAU1373_RADC_MIXER 0x13
50#define ADAU1373_LLINE1_MIX 0x14
51#define ADAU1373_RLINE1_MIX 0x15
52#define ADAU1373_LLINE2_MIX 0x16
53#define ADAU1373_RLINE2_MIX 0x17
54#define ADAU1373_LSPK_MIX 0x18
55#define ADAU1373_RSPK_MIX 0x19
56#define ADAU1373_LHP_MIX 0x1a
57#define ADAU1373_RHP_MIX 0x1b
58#define ADAU1373_EP_MIX 0x1c
59#define ADAU1373_HP_CTRL 0x1d
60#define ADAU1373_HP_CTRL2 0x1e
61#define ADAU1373_LS_CTRL 0x1f
62#define ADAU1373_EP_CTRL 0x21
63#define ADAU1373_MICBIAS_CTRL1 0x22
64#define ADAU1373_MICBIAS_CTRL2 0x23
65#define ADAU1373_OUTPUT_CTRL 0x24
66#define ADAU1373_PWDN_CTRL1 0x25
67#define ADAU1373_PWDN_CTRL2 0x26
68#define ADAU1373_PWDN_CTRL3 0x27
69#define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7)
70#define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7)
71#define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7)
72#define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7)
73#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7)
74#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7)
75#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7)
76#define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7)
77#define ADAU1373_HEADDECT 0x36
78#define ADAU1373_ADC_DAC_STATUS 0x37
79#define ADAU1373_ADC_CTRL 0x3c
80#define ADAU1373_DAI(x) (0x44 + (x))
81#define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2)
82#define ADAU1373_BCLKDIV(x) (0x47 + (x))
83#define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2)
84#define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2)
85#define ADAU1373_DEEMP_CTRL 0x50
86#define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x))
87#define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x))
88#define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x))
89#define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2)
90#define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2)
91#define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2)
92#define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2)
93#define ADAU1373_DAC1_PBL_VOL 0x6e
94#define ADAU1373_DAC1_PBR_VOL 0x6f
95#define ADAU1373_DAC2_PBL_VOL 0x70
96#define ADAU1373_DAC2_PBR_VOL 0x71
97#define ADAU1373_ADC_RECL_VOL 0x72
98#define ADAU1373_ADC_RECR_VOL 0x73
99#define ADAU1373_DMIC_RECL_VOL 0x74
100#define ADAU1373_DMIC_RECR_VOL 0x75
101#define ADAU1373_VOL_GAIN1 0x76
102#define ADAU1373_VOL_GAIN2 0x77
103#define ADAU1373_VOL_GAIN3 0x78
104#define ADAU1373_HPF_CTRL 0x7d
105#define ADAU1373_BASS1 0x7e
106#define ADAU1373_BASS2 0x7f
107#define ADAU1373_DRC(x) (0x80 + (x) * 0x10)
108#define ADAU1373_3D_CTRL1 0xc0
109#define ADAU1373_3D_CTRL2 0xc1
110#define ADAU1373_FDSP_SEL1 0xdc
111#define ADAU1373_FDSP_SEL2 0xdd
112#define ADAU1373_FDSP_SEL3 0xde
113#define ADAU1373_FDSP_SEL4 0xdf
114#define ADAU1373_DIGMICCTRL 0xe2
115#define ADAU1373_DIGEN 0xeb
116#define ADAU1373_SOFT_RESET 0xff
117
118
119#define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1)
120#define ADAU1373_PLL_CTRL6_PLL_EN BIT(0)
121
122#define ADAU1373_DAI_INVERT_BCLK BIT(7)
123#define ADAU1373_DAI_MASTER BIT(6)
124#define ADAU1373_DAI_INVERT_LRCLK BIT(4)
125#define ADAU1373_DAI_WLEN_16 0x0
126#define ADAU1373_DAI_WLEN_20 0x4
127#define ADAU1373_DAI_WLEN_24 0x8
128#define ADAU1373_DAI_WLEN_32 0xc
129#define ADAU1373_DAI_WLEN_MASK 0xc
130#define ADAU1373_DAI_FORMAT_RIGHT_J 0x0
131#define ADAU1373_DAI_FORMAT_LEFT_J 0x1
132#define ADAU1373_DAI_FORMAT_I2S 0x2
133#define ADAU1373_DAI_FORMAT_DSP 0x3
134
135#define ADAU1373_BCLKDIV_SOURCE BIT(5)
136#define ADAU1373_BCLKDIV_32 0x03
137#define ADAU1373_BCLKDIV_64 0x02
138#define ADAU1373_BCLKDIV_128 0x01
139#define ADAU1373_BCLKDIV_256 0x00
140
141#define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0)
142#define ADAU1373_ADC_CTRL_RESET BIT(1)
143#define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2)
144
145#define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3)
146#define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2)
147
148#define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0)
149
150#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
151#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
152
153static const uint8_t adau1373_default_regs[] = {
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */
161 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */
171 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
172 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */
173 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
174 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */
175 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
177 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */
183 0x00, 0x1f, 0x0f, 0x00, 0x00,
184};
185
186static const unsigned int adau1373_out_tlv[] = {
187 TLV_DB_RANGE_HEAD(4),
188 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
189 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
190 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
191 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
192};
193
194static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0);
195static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1);
196static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1);
197
198static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0);
199static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0);
200static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0);
201
202static const char *adau1373_fdsp_sel_text[] = {
203 "None",
204 "Channel 1",
205 "Channel 2",
206 "Channel 3",
207 "Channel 4",
208 "Channel 5",
209};
210
211static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
212 ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
213static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
214 ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
215static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
216 ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
217static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
218 ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
219static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
220 ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
221
222static const char *adau1373_hpf_cutoff_text[] = {
223 "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz",
224 "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz",
225 "800Hz",
226};
227
228static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
229 ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
230
231static const char *adau1373_bass_lpf_cutoff_text[] = {
232 "801Hz", "1001Hz",
233};
234
235static const char *adau1373_bass_clip_level_text[] = {
236 "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875",
237};
238
239static const unsigned int adau1373_bass_clip_level_values[] = {
240 1, 2, 3, 4, 5, 6, 7,
241};
242
243static const char *adau1373_bass_hpf_cutoff_text[] = {
244 "158Hz", "232Hz", "347Hz", "520Hz",
245};
246
247static const unsigned int adau1373_bass_tlv[] = {
248 TLV_DB_RANGE_HEAD(4),
249 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
250 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
251 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
252};
253
254static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
255 ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
256
257static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
258 ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
259 adau1373_bass_clip_level_values);
260
261static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
262 ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
263
264static const char *adau1373_3d_level_text[] = {
265 "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%",
266 "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%",
267 "80%", "86.67", "99.33%", "100%"
268};
269
270static const char *adau1373_3d_cutoff_text[] = {
271 "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs",
272 "0.16875 fs", "0.27083 fs"
273};
274
275static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
276 ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
277static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
278 ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
279
280static const unsigned int adau1373_3d_tlv[] = {
281 TLV_DB_RANGE_HEAD(2),
282 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
283 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120),
284};
285
286static const char *adau1373_lr_mux_text[] = {
287 "Mute",
288 "Right Channel (L+R)",
289 "Left Channel (L+R)",
290 "Stereo",
291};
292
293static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
294 ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
295static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
296 ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
297static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
298 ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
299
300static const struct snd_kcontrol_new adau1373_controls[] = {
301 SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0),
302 ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
303 SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1),
304 ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
305 SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2),
306 ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
307
308 SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL,
309 ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
310 SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL,
311 ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
312
313 SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0),
314 ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
315 SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1),
316 ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
317 SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2),
318 ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
319
320 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL,
321 ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
322 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL,
323 ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
324
325 SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0),
326 ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv),
327 SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT,
328 ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv),
329 SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT,
330 ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv),
331
332 SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0),
333 ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv),
334 SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1),
335 ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv),
336 SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2),
337 ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv),
338 SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3),
339 ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv),
340
341 SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0,
342 adau1373_ep_tlv),
343
344 SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5,
345 1, 0, adau1373_gain_boost_tlv),
346 SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3,
347 1, 0, adau1373_gain_boost_tlv),
348 SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1,
349 1, 0, adau1373_gain_boost_tlv),
350 SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5,
351 1, 0, adau1373_gain_boost_tlv),
352 SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3,
353 1, 0, adau1373_gain_boost_tlv),
354 SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1,
355 1, 0, adau1373_gain_boost_tlv),
356 SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7,
357 1, 0, adau1373_gain_boost_tlv),
358 SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5,
359 1, 0, adau1373_gain_boost_tlv),
360 SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3,
361 1, 0, adau1373_gain_boost_tlv),
362 SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1,
363 1, 0, adau1373_gain_boost_tlv),
364
365 SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4,
366 1, 0, adau1373_input_boost_tlv),
367 SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5,
368 1, 0, adau1373_input_boost_tlv),
369 SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6,
370 1, 0, adau1373_input_boost_tlv),
371 SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7,
372 1, 0, adau1373_input_boost_tlv),
373
374 SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3,
375 1, 0, adau1373_speaker_boost_tlv),
376
377 SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum),
378 SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum),
379
380 SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum),
381 SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0),
382 SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum),
383
384 SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum),
385 SOC_VALUE_ENUM("Bass Clip Level Threshold",
386 adau1373_bass_clip_level_enum),
387 SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum),
388 SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0),
389 SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0,
390 adau1373_bass_tlv),
391 SOC_ENUM("Bass Channel", adau1373_bass_channel_enum),
392
393 SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum),
394 SOC_ENUM("3D Level", adau1373_3d_level_enum),
395 SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0),
396 SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0,
397 adau1373_3d_tlv),
398 SOC_ENUM("3D Channel", adau1373_bass_channel_enum),
399
400 SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0),
401};
402
403static const struct snd_kcontrol_new adau1373_lineout2_controls[] = {
404 SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1),
405 ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv),
406 SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum),
407};
408
409static const struct snd_kcontrol_new adau1373_drc_controls[] = {
410 SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum),
411 SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum),
412 SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum),
413};
414
415static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 unsigned int pll_id = w->name[3] - '1';
420 unsigned int val;
421
422 if (SND_SOC_DAPM_EVENT_ON(event))
423 val = ADAU1373_PLL_CTRL6_PLL_EN;
424 else
425 val = 0;
426
427 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
428 ADAU1373_PLL_CTRL6_PLL_EN, val);
429
430 if (SND_SOC_DAPM_EVENT_ON(event))
431 mdelay(5);
432
433 return 0;
434}
435
436static const char *adau1373_decimator_text[] = {
437 "ADC",
438 "DMIC1",
439};
440
441static const struct soc_enum adau1373_decimator_enum =
442 SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text);
443
444static const struct snd_kcontrol_new adau1373_decimator_mux =
445 SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
446
447static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = {
448 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0),
449 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0),
450 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0),
451 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0),
452 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0),
453};
454
455static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = {
456 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0),
457 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0),
458 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0),
459 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0),
460 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0),
461};
462
463#define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \
464const struct snd_kcontrol_new _name[] = { \
465 SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \
466 SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \
467 SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \
468 SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \
469 SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \
470 SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \
471 SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \
472 SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \
473}
474
475static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls,
476 ADAU1373_LLINE1_MIX);
477static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls,
478 ADAU1373_RLINE1_MIX);
479static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls,
480 ADAU1373_LLINE2_MIX);
481static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls,
482 ADAU1373_RLINE2_MIX);
483static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls,
484 ADAU1373_LSPK_MIX);
485static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls,
486 ADAU1373_RSPK_MIX);
487static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls,
488 ADAU1373_EP_MIX);
489
490static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = {
491 SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0),
492 SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0),
493 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0),
494 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0),
495 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0),
496 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0),
497};
498
499static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = {
500 SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0),
501 SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0),
502 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0),
503 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0),
504 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0),
505 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0),
506};
507
508#define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \
509const struct snd_kcontrol_new _name[] = { \
510 SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \
511 SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \
512 SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \
513 SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \
514 SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \
515 SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \
516 SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \
517}
518
519static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls,
520 ADAU1373_DIN_MIX_CTRL(0));
521static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls,
522 ADAU1373_DIN_MIX_CTRL(1));
523static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls,
524 ADAU1373_DIN_MIX_CTRL(2));
525static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls,
526 ADAU1373_DIN_MIX_CTRL(3));
527static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls,
528 ADAU1373_DIN_MIX_CTRL(4));
529
530#define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \
531const struct snd_kcontrol_new _name[] = { \
532 SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \
533 SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \
534 SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \
535 SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \
536 SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \
537}
538
539static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls,
540 ADAU1373_DOUT_MIX_CTRL(0));
541static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls,
542 ADAU1373_DOUT_MIX_CTRL(1));
543static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls,
544 ADAU1373_DOUT_MIX_CTRL(2));
545static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls,
546 ADAU1373_DOUT_MIX_CTRL(3));
547static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls,
548 ADAU1373_DOUT_MIX_CTRL(4));
549
550static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
551 /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that
552 * doesn't seem to be the case. */
553 SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0),
554 SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0),
555
556 SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0),
557 SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0),
558
559 SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0,
560 &adau1373_decimator_mux),
561
562 SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0),
563 SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0),
564
565 SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0),
566 SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0),
567 SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0),
568 SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0),
569
570 SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0),
571 SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0),
572 SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0),
573 SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0),
574
575 SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
576 adau1373_left_adc_mixer_controls),
577 SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
578 adau1373_right_adc_mixer_controls),
579
580 SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0,
581 adau1373_left_line2_mixer_controls),
582 SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0,
583 adau1373_right_line2_mixer_controls),
584 SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0,
585 adau1373_left_line1_mixer_controls),
586 SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0,
587 adau1373_right_line1_mixer_controls),
588
589 SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0,
590 adau1373_ep_mixer_controls),
591 SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0,
592 adau1373_left_spk_mixer_controls),
593 SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0,
594 adau1373_right_spk_mixer_controls),
595 SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
596 adau1373_left_hp_mixer_controls),
597 SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
598 adau1373_right_hp_mixer_controls),
599 SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0,
600 NULL, 0),
601
602 SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0,
603 NULL, 0),
604 SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0,
605 NULL, 0),
606 SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0,
607 NULL, 0),
608 SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0,
609 NULL, 0),
610 SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0,
611 NULL, 0),
612 SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0,
613 NULL, 0),
614 SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0,
615 NULL, 0),
616 SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0,
617 NULL, 0),
618 SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0,
619 NULL, 0),
620
621 SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
622 SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
623 SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
624 SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
625 SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
626 SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
627
628 SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0,
629 adau1373_dsp_channel1_mixer_controls),
630 SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0,
631 adau1373_dsp_channel2_mixer_controls),
632 SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0,
633 adau1373_dsp_channel3_mixer_controls),
634 SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0,
635 adau1373_dsp_channel4_mixer_controls),
636 SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0,
637 adau1373_dsp_channel5_mixer_controls),
638
639 SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0,
640 adau1373_aif1_mixer_controls),
641 SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0,
642 adau1373_aif2_mixer_controls),
643 SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0,
644 adau1373_aif3_mixer_controls),
645 SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
646 adau1373_dac1_mixer_controls),
647 SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
648 adau1373_dac2_mixer_controls),
649
650 SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0),
651 SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0),
652 SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0),
653 SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0),
654 SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0),
655
656 SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
657 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
658 SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
659 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
660 SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0),
661 SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0),
662
663 SND_SOC_DAPM_INPUT("AIN1L"),
664 SND_SOC_DAPM_INPUT("AIN1R"),
665 SND_SOC_DAPM_INPUT("AIN2L"),
666 SND_SOC_DAPM_INPUT("AIN2R"),
667 SND_SOC_DAPM_INPUT("AIN3L"),
668 SND_SOC_DAPM_INPUT("AIN3R"),
669 SND_SOC_DAPM_INPUT("AIN4L"),
670 SND_SOC_DAPM_INPUT("AIN4R"),
671
672 SND_SOC_DAPM_INPUT("DMIC1DAT"),
673 SND_SOC_DAPM_INPUT("DMIC2DAT"),
674
675 SND_SOC_DAPM_OUTPUT("LOUT1L"),
676 SND_SOC_DAPM_OUTPUT("LOUT1R"),
677 SND_SOC_DAPM_OUTPUT("LOUT2L"),
678 SND_SOC_DAPM_OUTPUT("LOUT2R"),
679 SND_SOC_DAPM_OUTPUT("HPL"),
680 SND_SOC_DAPM_OUTPUT("HPR"),
681 SND_SOC_DAPM_OUTPUT("SPKL"),
682 SND_SOC_DAPM_OUTPUT("SPKR"),
683 SND_SOC_DAPM_OUTPUT("EP"),
684};
685
686static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
687 struct snd_soc_dapm_widget *sink)
688{
689 struct snd_soc_codec *codec = source->codec;
690 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
691 unsigned int dai;
692 const char *clk;
693
694 dai = sink->name[3] - '1';
695
696 if (!adau1373->dais[dai].master)
697 return 0;
698
699 if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1)
700 clk = "SYSCLK1";
701 else
702 clk = "SYSCLK2";
703
704 return strcmp(source->name, clk) == 0;
705}
706
707static int adau1373_check_src(struct snd_soc_dapm_widget *source,
708 struct snd_soc_dapm_widget *sink)
709{
710 struct snd_soc_codec *codec = source->codec;
711 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
712 unsigned int dai;
713
714 dai = sink->name[3] - '1';
715
716 return adau1373->dais[dai].enable_src;
717}
718
719#define DSP_CHANNEL_MIXER_ROUTES(_sink) \
720 { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \
721 { _sink, "DMIC2 Switch", "DMIC2" }, \
722 { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \
723 { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \
724 { _sink, "AIF1 Switch", "AIF1 IN" }, \
725 { _sink, "AIF2 Switch", "AIF2 IN" }, \
726 { _sink, "AIF3 Switch", "AIF3 IN" }
727
728#define DSP_OUTPUT_MIXER_ROUTES(_sink) \
729 { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \
730 { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \
731 { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \
732 { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \
733 { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" }
734
735#define LEFT_OUTPUT_MIXER_ROUTES(_sink) \
736 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
737 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
738 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
739 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
740 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
741 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
742 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
743 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
744
745#define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \
746 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
747 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
748 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
749 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
750 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
751 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
752 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
753 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
754
755static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
756 { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" },
757 { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" },
758 { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" },
759 { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" },
760 { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" },
761
762 { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" },
763 { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" },
764 { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" },
765 { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" },
766 { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" },
767
768 { "Left ADC", NULL, "Left ADC Mixer" },
769 { "Right ADC", NULL, "Right ADC Mixer" },
770
771 { "Decimator Mux", "ADC", "Left ADC" },
772 { "Decimator Mux", "ADC", "Right ADC" },
773 { "Decimator Mux", "DMIC1", "DMIC1" },
774
775 DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"),
776 DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"),
777 DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"),
778 DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"),
779 DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"),
780
781 DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"),
782 DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"),
783 DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"),
784 DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"),
785 DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"),
786
787 { "AIF1 OUT", NULL, "AIF1 Mixer" },
788 { "AIF2 OUT", NULL, "AIF2 Mixer" },
789 { "AIF3 OUT", NULL, "AIF3 Mixer" },
790 { "Left DAC1", NULL, "DAC1 Mixer" },
791 { "Right DAC1", NULL, "DAC1 Mixer" },
792 { "Left DAC2", NULL, "DAC2 Mixer" },
793 { "Right DAC2", NULL, "DAC2 Mixer" },
794
795 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"),
796 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"),
797 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"),
798 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"),
799 LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"),
800 RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"),
801
802 { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" },
803 { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" },
804 { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
805 { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
806 { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
807 { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
808 { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" },
809 { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" },
810 { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
811 { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
812 { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
813 { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
814
815 { "Left Headphone Mixer", NULL, "Headphone Enable" },
816 { "Right Headphone Mixer", NULL, "Headphone Enable" },
817
818 { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" },
819 { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" },
820 { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" },
821 { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" },
822 { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" },
823 { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" },
824 { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" },
825 { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" },
826
827 { "LOUT1L", NULL, "Left Lineout1 Mixer" },
828 { "LOUT1R", NULL, "Right Lineout1 Mixer" },
829 { "LOUT2L", NULL, "Left Lineout2 Mixer" },
830 { "LOUT2R", NULL, "Right Lineout2 Mixer" },
831 { "SPKL", NULL, "Left Speaker Mixer" },
832 { "SPKR", NULL, "Right Speaker Mixer" },
833 { "HPL", NULL, "Left Headphone Mixer" },
834 { "HPR", NULL, "Right Headphone Mixer" },
835 { "EP", NULL, "Earpiece Mixer" },
836
837 { "IN1PGA", NULL, "AIN1L" },
838 { "IN2PGA", NULL, "AIN2L" },
839 { "IN3PGA", NULL, "AIN3L" },
840 { "IN4PGA", NULL, "AIN4L" },
841 { "IN1PGA", NULL, "AIN1R" },
842 { "IN2PGA", NULL, "AIN2R" },
843 { "IN3PGA", NULL, "AIN3R" },
844 { "IN4PGA", NULL, "AIN4R" },
845
846 { "SYSCLK1", NULL, "PLL1" },
847 { "SYSCLK2", NULL, "PLL2" },
848
849 { "Left DAC1", NULL, "SYSCLK1" },
850 { "Right DAC1", NULL, "SYSCLK1" },
851 { "Left DAC2", NULL, "SYSCLK1" },
852 { "Right DAC2", NULL, "SYSCLK1" },
853 { "Left ADC", NULL, "SYSCLK1" },
854 { "Right ADC", NULL, "SYSCLK1" },
855
856 { "DSP", NULL, "SYSCLK1" },
857
858 { "AIF1 Mixer", NULL, "DSP" },
859 { "AIF2 Mixer", NULL, "DSP" },
860 { "AIF3 Mixer", NULL, "DSP" },
861 { "DAC1 Mixer", NULL, "DSP" },
862 { "DAC2 Mixer", NULL, "DSP" },
863 { "DAC1 Mixer", NULL, "Playback Engine A" },
864 { "DAC2 Mixer", NULL, "Playback Engine B" },
865 { "Left ADC Mixer", NULL, "Recording Engine A" },
866 { "Right ADC Mixer", NULL, "Recording Engine A" },
867
868 { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
869 { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
870 { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
871 { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
872 { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
873 { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
874
875 { "AIF1 IN", NULL, "AIF1 CLK" },
876 { "AIF1 OUT", NULL, "AIF1 CLK" },
877 { "AIF2 IN", NULL, "AIF2 CLK" },
878 { "AIF2 OUT", NULL, "AIF2 CLK" },
879 { "AIF3 IN", NULL, "AIF3 CLK" },
880 { "AIF3 OUT", NULL, "AIF3 CLK" },
881 { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src },
882 { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src },
883 { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src },
884 { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src },
885 { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src },
886 { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src },
887
888 { "DMIC1", NULL, "DMIC1DAT" },
889 { "DMIC1", NULL, "SYSCLK1" },
890 { "DMIC1", NULL, "Recording Engine A" },
891 { "DMIC2", NULL, "DMIC2DAT" },
892 { "DMIC2", NULL, "SYSCLK1" },
893 { "DMIC2", NULL, "Recording Engine B" },
894};
895
896static int adau1373_hw_params(struct snd_pcm_substream *substream,
897 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
898{
899 struct snd_soc_codec *codec = dai->codec;
900 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
901 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
902 unsigned int div;
903 unsigned int freq;
904 unsigned int ctrl;
905
906 freq = adau1373_dai->sysclk;
907
908 if (freq % params_rate(params) != 0)
909 return -EINVAL;
910
911 switch (freq / params_rate(params)) {
912 case 1024: /* sysclk / 256 */
913 div = 0;
914 break;
915 case 1536: /* 2/3 sysclk / 256 */
916 div = 1;
917 break;
918 case 2048: /* 1/2 sysclk / 256 */
919 div = 2;
920 break;
921 case 3072: /* 1/3 sysclk / 256 */
922 div = 3;
923 break;
924 case 4096: /* 1/4 sysclk / 256 */
925 div = 4;
926 break;
927 case 6144: /* 1/6 sysclk / 256 */
928 div = 5;
929 break;
930 case 5632: /* 2/11 sysclk / 256 */
931 div = 6;
932 break;
933 default:
934 return -EINVAL;
935 }
936
937 adau1373_dai->enable_src = (div != 0);
938
939 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
940 ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
941
942 switch (params_format(params)) {
943 case SNDRV_PCM_FORMAT_S16_LE:
944 ctrl = ADAU1373_DAI_WLEN_16;
945 break;
946 case SNDRV_PCM_FORMAT_S20_3LE:
947 ctrl = ADAU1373_DAI_WLEN_20;
948 break;
949 case SNDRV_PCM_FORMAT_S24_LE:
950 ctrl = ADAU1373_DAI_WLEN_24;
951 break;
952 case SNDRV_PCM_FORMAT_S32_LE:
953 ctrl = ADAU1373_DAI_WLEN_32;
954 break;
955 default:
956 return -EINVAL;
957 }
958
959 return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
960 ADAU1373_DAI_WLEN_MASK, ctrl);
961}
962
963static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
964{
965 struct snd_soc_codec *codec = dai->codec;
966 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
967 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
968 unsigned int ctrl;
969
970 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
971 case SND_SOC_DAIFMT_CBM_CFM:
972 ctrl = ADAU1373_DAI_MASTER;
973 adau1373_dai->master = true;
974 break;
975 case SND_SOC_DAIFMT_CBS_CFS:
976 ctrl = 0;
977 adau1373_dai->master = false;
978 break;
979 default:
980 return -EINVAL;
981 }
982
983 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
984 case SND_SOC_DAIFMT_I2S:
985 ctrl |= ADAU1373_DAI_FORMAT_I2S;
986 break;
987 case SND_SOC_DAIFMT_LEFT_J:
988 ctrl |= ADAU1373_DAI_FORMAT_LEFT_J;
989 break;
990 case SND_SOC_DAIFMT_RIGHT_J:
991 ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J;
992 break;
993 case SND_SOC_DAIFMT_DSP_B:
994 ctrl |= ADAU1373_DAI_FORMAT_DSP;
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1001 case SND_SOC_DAIFMT_NB_NF:
1002 break;
1003 case SND_SOC_DAIFMT_IB_NF:
1004 ctrl |= ADAU1373_DAI_INVERT_BCLK;
1005 break;
1006 case SND_SOC_DAIFMT_NB_IF:
1007 ctrl |= ADAU1373_DAI_INVERT_LRCLK;
1008 break;
1009 case SND_SOC_DAIFMT_IB_IF:
1010 ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK;
1011 break;
1012 default:
1013 return -EINVAL;
1014 }
1015
1016 snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
1017 ~ADAU1373_DAI_WLEN_MASK, ctrl);
1018
1019 return 0;
1020}
1021
1022static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
1023 int clk_id, unsigned int freq, int dir)
1024{
1025 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
1026 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
1027
1028 switch (clk_id) {
1029 case ADAU1373_CLK_SRC_PLL1:
1030 case ADAU1373_CLK_SRC_PLL2:
1031 break;
1032 default:
1033 return -EINVAL;
1034 }
1035
1036 adau1373_dai->sysclk = freq;
1037 adau1373_dai->clk_src = clk_id;
1038
1039 snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id),
1040 ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
1041
1042 return 0;
1043}
1044
1045static const struct snd_soc_dai_ops adau1373_dai_ops = {
1046 .hw_params = adau1373_hw_params,
1047 .set_sysclk = adau1373_set_dai_sysclk,
1048 .set_fmt = adau1373_set_dai_fmt,
1049};
1050
1051#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1052 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1053
1054static struct snd_soc_dai_driver adau1373_dai_driver[] = {
1055 {
1056 .id = 0,
1057 .name = "adau1373-aif1",
1058 .playback = {
1059 .stream_name = "AIF1 Playback",
1060 .channels_min = 2,
1061 .channels_max = 2,
1062 .rates = SNDRV_PCM_RATE_8000_48000,
1063 .formats = ADAU1373_FORMATS,
1064 },
1065 .capture = {
1066 .stream_name = "AIF1 Capture",
1067 .channels_min = 2,
1068 .channels_max = 2,
1069 .rates = SNDRV_PCM_RATE_8000_48000,
1070 .formats = ADAU1373_FORMATS,
1071 },
1072 .ops = &adau1373_dai_ops,
1073 .symmetric_rates = 1,
1074 },
1075 {
1076 .id = 1,
1077 .name = "adau1373-aif2",
1078 .playback = {
1079 .stream_name = "AIF2 Playback",
1080 .channels_min = 2,
1081 .channels_max = 2,
1082 .rates = SNDRV_PCM_RATE_8000_48000,
1083 .formats = ADAU1373_FORMATS,
1084 },
1085 .capture = {
1086 .stream_name = "AIF2 Capture",
1087 .channels_min = 2,
1088 .channels_max = 2,
1089 .rates = SNDRV_PCM_RATE_8000_48000,
1090 .formats = ADAU1373_FORMATS,
1091 },
1092 .ops = &adau1373_dai_ops,
1093 .symmetric_rates = 1,
1094 },
1095 {
1096 .id = 2,
1097 .name = "adau1373-aif3",
1098 .playback = {
1099 .stream_name = "AIF3 Playback",
1100 .channels_min = 2,
1101 .channels_max = 2,
1102 .rates = SNDRV_PCM_RATE_8000_48000,
1103 .formats = ADAU1373_FORMATS,
1104 },
1105 .capture = {
1106 .stream_name = "AIF3 Capture",
1107 .channels_min = 2,
1108 .channels_max = 2,
1109 .rates = SNDRV_PCM_RATE_8000_48000,
1110 .formats = ADAU1373_FORMATS,
1111 },
1112 .ops = &adau1373_dai_ops,
1113 .symmetric_rates = 1,
1114 },
1115};
1116
1117static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1118 int source, unsigned int freq_in, unsigned int freq_out)
1119{
1120 unsigned int dpll_div = 0;
1121 unsigned int x, r, n, m, i, j, mode;
1122
1123 switch (pll_id) {
1124 case ADAU1373_PLL1:
1125 case ADAU1373_PLL2:
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130
1131 switch (source) {
1132 case ADAU1373_PLL_SRC_BCLK1:
1133 case ADAU1373_PLL_SRC_BCLK2:
1134 case ADAU1373_PLL_SRC_BCLK3:
1135 case ADAU1373_PLL_SRC_LRCLK1:
1136 case ADAU1373_PLL_SRC_LRCLK2:
1137 case ADAU1373_PLL_SRC_LRCLK3:
1138 case ADAU1373_PLL_SRC_MCLK1:
1139 case ADAU1373_PLL_SRC_MCLK2:
1140 case ADAU1373_PLL_SRC_GPIO1:
1141 case ADAU1373_PLL_SRC_GPIO2:
1142 case ADAU1373_PLL_SRC_GPIO3:
1143 case ADAU1373_PLL_SRC_GPIO4:
1144 break;
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 if (freq_in < 7813 || freq_in > 27000000)
1150 return -EINVAL;
1151
1152 if (freq_out < 45158000 || freq_out > 49152000)
1153 return -EINVAL;
1154
1155 /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the
1156 * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */
1157 while (freq_in < 8000000) {
1158 freq_in *= 2;
1159 dpll_div++;
1160 }
1161
1162 if (freq_out % freq_in != 0) {
1163 /* fout = fin * (r + (n/m)) / x */
1164 x = DIV_ROUND_UP(freq_in, 13500000);
1165 freq_in /= x;
1166 r = freq_out / freq_in;
1167 i = freq_out % freq_in;
1168 j = gcd(i, freq_in);
1169 n = i / j;
1170 m = freq_in / j;
1171 x--;
1172 mode = 1;
1173 } else {
1174 /* fout = fin / r */
1175 r = freq_out / freq_in;
1176 n = 0;
1177 m = 0;
1178 x = 0;
1179 mode = 0;
1180 }
1181
1182 if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
1183 return -EINVAL;
1184
1185 if (dpll_div) {
1186 dpll_div = 11 - dpll_div;
1187 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1188 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
1189 } else {
1190 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1191 ADAU1373_PLL_CTRL6_DPLL_BYPASS,
1192 ADAU1373_PLL_CTRL6_DPLL_BYPASS);
1193 }
1194
1195 snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id),
1196 (source << 4) | dpll_div);
1197 snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
1198 snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
1199 snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
1200 snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
1201 snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id),
1202 (r << 3) | (x << 1) | mode);
1203
1204 /* Set sysclk to pll_rate / 4 */
1205 snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
1206
1207 return 0;
1208}
1209
1210static void adau1373_load_drc_settings(struct snd_soc_codec *codec,
1211 unsigned int nr, uint8_t *drc)
1212{
1213 unsigned int i;
1214
1215 for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
1216 snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]);
1217}
1218
1219static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
1220{
1221 switch (micbias) {
1222 case ADAU1373_MICBIAS_2_9V:
1223 case ADAU1373_MICBIAS_2_2V:
1224 case ADAU1373_MICBIAS_2_6V:
1225 case ADAU1373_MICBIAS_1_8V:
1226 return true;
1227 default:
1228 break;
1229 }
1230 return false;
1231}
1232
1233static int adau1373_probe(struct snd_soc_codec *codec)
1234{
1235 struct adau1373_platform_data *pdata = codec->dev->platform_data;
1236 bool lineout_differential = false;
1237 unsigned int val;
1238 int ret;
1239 int i;
1240
1241 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
1242 if (ret) {
1243 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
1244 return ret;
1245 }
1246
1247 codec->dapm.idle_bias_off = true;
1248
1249 if (pdata) {
1250 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
1251 return -EINVAL;
1252
1253 if (!adau1373_valid_micbias(pdata->micbias1) ||
1254 !adau1373_valid_micbias(pdata->micbias2))
1255 return -EINVAL;
1256
1257 for (i = 0; i < pdata->num_drc; ++i) {
1258 adau1373_load_drc_settings(codec, i,
1259 pdata->drc_setting[i]);
1260 }
1261
1262 snd_soc_add_controls(codec, adau1373_drc_controls,
1263 pdata->num_drc);
1264
1265 val = 0;
1266 for (i = 0; i < 4; ++i) {
1267 if (pdata->input_differential[i])
1268 val |= BIT(i);
1269 }
1270 snd_soc_write(codec, ADAU1373_INPUT_MODE, val);
1271
1272 val = 0;
1273 if (pdata->lineout_differential)
1274 val |= ADAU1373_OUTPUT_CTRL_LDIFF;
1275 if (pdata->lineout_ground_sense)
1276 val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
1277 snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val);
1278
1279 lineout_differential = pdata->lineout_differential;
1280
1281 snd_soc_write(codec, ADAU1373_EP_CTRL,
1282 (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
1283 (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
1284 }
1285
1286 if (!lineout_differential) {
1287 snd_soc_add_controls(codec, adau1373_lineout2_controls,
1288 ARRAY_SIZE(adau1373_lineout2_controls));
1289 }
1290
1291 snd_soc_write(codec, ADAU1373_ADC_CTRL,
1292 ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
1293
1294 return 0;
1295}
1296
1297static int adau1373_set_bias_level(struct snd_soc_codec *codec,
1298 enum snd_soc_bias_level level)
1299{
1300 switch (level) {
1301 case SND_SOC_BIAS_ON:
1302 break;
1303 case SND_SOC_BIAS_PREPARE:
1304 break;
1305 case SND_SOC_BIAS_STANDBY:
1306 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1307 ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
1308 break;
1309 case SND_SOC_BIAS_OFF:
1310 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1311 ADAU1373_PWDN_CTRL3_PWR_EN, 0);
1312 break;
1313 }
1314 codec->dapm.bias_level = level;
1315 return 0;
1316}
1317
1318static int adau1373_remove(struct snd_soc_codec *codec)
1319{
1320 adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1321 return 0;
1322}
1323
1324static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{
1326 return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327}
1328
1329static int adau1373_resume(struct snd_soc_codec *codec)
1330{
1331 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1332 snd_soc_cache_sync(codec);
1333
1334 return 0;
1335}
1336
1337static struct snd_soc_codec_driver adau1373_codec_driver = {
1338 .probe = adau1373_probe,
1339 .remove = adau1373_remove,
1340 .suspend = adau1373_suspend,
1341 .resume = adau1373_resume,
1342 .set_bias_level = adau1373_set_bias_level,
1343 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1344 .reg_cache_default = adau1373_default_regs,
1345 .reg_word_size = sizeof(uint8_t),
1346
1347 .set_pll = adau1373_set_pll,
1348
1349 .controls = adau1373_controls,
1350 .num_controls = ARRAY_SIZE(adau1373_controls),
1351 .dapm_widgets = adau1373_dapm_widgets,
1352 .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
1353 .dapm_routes = adau1373_dapm_routes,
1354 .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
1355};
1356
1357static int __devinit adau1373_i2c_probe(struct i2c_client *client,
1358 const struct i2c_device_id *id)
1359{
1360 struct adau1373 *adau1373;
1361 int ret;
1362
1363 adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL);
1364 if (!adau1373)
1365 return -ENOMEM;
1366
1367 dev_set_drvdata(&client->dev, adau1373);
1368
1369 ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
1370 adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
1371 if (ret < 0)
1372 kfree(adau1373);
1373
1374 return ret;
1375}
1376
1377static int __devexit adau1373_i2c_remove(struct i2c_client *client)
1378{
1379 snd_soc_unregister_codec(&client->dev);
1380 kfree(dev_get_drvdata(&client->dev));
1381 return 0;
1382}
1383
1384static const struct i2c_device_id adau1373_i2c_id[] = {
1385 { "adau1373", 0 },
1386 { }
1387};
1388MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
1389
1390static struct i2c_driver adau1373_i2c_driver = {
1391 .driver = {
1392 .name = "adau1373",
1393 .owner = THIS_MODULE,
1394 },
1395 .probe = adau1373_i2c_probe,
1396 .remove = __devexit_p(adau1373_i2c_remove),
1397 .id_table = adau1373_i2c_id,
1398};
1399
1400static int __init adau1373_init(void)
1401{
1402 return i2c_add_driver(&adau1373_i2c_driver);
1403}
1404module_init(adau1373_init);
1405
1406static void __exit adau1373_exit(void)
1407{
1408 i2c_del_driver(&adau1373_i2c_driver);
1409}
1410module_exit(adau1373_exit);
1411
1412MODULE_DESCRIPTION("ASoC ADAU1373 driver");
1413MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1414MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h
new file mode 100644
index 000000000000..c6ab5530760c
--- /dev/null
+++ b/sound/soc/codecs/adau1373.h
@@ -0,0 +1,29 @@
1#ifndef __ADAU1373_H__
2#define __ADAU1373_H__
3
4enum adau1373_pll_src {
5 ADAU1373_PLL_SRC_MCLK1 = 0,
6 ADAU1373_PLL_SRC_BCLK1 = 1,
7 ADAU1373_PLL_SRC_BCLK2 = 2,
8 ADAU1373_PLL_SRC_BCLK3 = 3,
9 ADAU1373_PLL_SRC_LRCLK1 = 4,
10 ADAU1373_PLL_SRC_LRCLK2 = 5,
11 ADAU1373_PLL_SRC_LRCLK3 = 6,
12 ADAU1373_PLL_SRC_GPIO1 = 7,
13 ADAU1373_PLL_SRC_GPIO2 = 8,
14 ADAU1373_PLL_SRC_GPIO3 = 9,
15 ADAU1373_PLL_SRC_GPIO4 = 10,
16 ADAU1373_PLL_SRC_MCLK2 = 11,
17};
18
19enum adau1373_pll {
20 ADAU1373_PLL1 = 0,
21 ADAU1373_PLL2 = 1,
22};
23
24enum adau1373_clk_src {
25 ADAU1373_CLK_SRC_PLL1 = 0,
26 ADAU1373_CLK_SRC_PLL2 = 1,
27};
28
29#endif
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 2758d5fc60d6..8b7e1c50d6e9 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -401,7 +401,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
401} 401}
402 402
403static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, 403static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
404 unsigned int freq, int dir) 404 int source, unsigned int freq, int dir)
405{ 405{
406 unsigned int val; 406 unsigned int val;
407 407
@@ -458,6 +458,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
458 int ret; 458 int ret;
459 459
460 codec->dapm.idle_bias_off = 1; 460 codec->dapm.idle_bias_off = 1;
461 codec->control_data = to_i2c_client(codec->dev);
461 462
462 ret = adau1701_load_firmware(codec); 463 ret = adau1701_load_firmware(codec);
463 if (ret) 464 if (ret)
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 300c04b70e71..f9f08948e5e8 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -523,7 +523,8 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
523} 523}
524 524
525static int adav80x_set_sysclk(struct snd_soc_codec *codec, 525static int adav80x_set_sysclk(struct snd_soc_codec *codec,
526 int clk_id, unsigned int freq, int dir) 526 int clk_id, int source,
527 unsigned int freq, int dir)
527{ 528{
528 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 529 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
529 530
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
deleted file mode 100644
index 3ce028614002..000000000000
--- a/sound/soc/codecs/ads117x.h
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
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 */
12extern struct snd_soc_dai_driver ads117x_dai;
13extern struct snd_soc_codec_driver soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index cbf0b6d400b8..d3b29dce6ed7 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -247,7 +247,7 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe, 247 .probe = ak4104_probe,
248 .remove = ak4104_remove, 248 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS, 249 .reg_cache_size = AK4104_NUM_REGS,
250 .reg_word_size = sizeof(u16), 250 .reg_word_size = sizeof(u8),
251}; 251};
252 252
253static int ak4104_spi_probe(struct spi_device *spi) 253static int ak4104_spi_probe(struct spi_device *spi)
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index e1a214ee757f..95d782d86e7d 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -34,74 +34,16 @@
34struct ak4535_priv { 34struct ak4535_priv {
35 unsigned int sysclk; 35 unsigned int sysclk;
36 enum snd_soc_control_type control_type; 36 enum snd_soc_control_type control_type;
37 void *control_data;
38}; 37};
39 38
40/* 39/*
41 * ak4535 register cache 40 * ak4535 register cache
42 */ 41 */
43static const u16 ak4535_reg[AK4535_CACHEREGNUM] = { 42static const u8 ak4535_reg[AK4535_CACHEREGNUM] = {
44 0x0000, 0x0080, 0x0000, 0x0003, 43 0x00, 0x80, 0x00, 0x03,
45 0x0002, 0x0000, 0x0011, 0x0001, 44 0x02, 0x00, 0x11, 0x01,
46 0x0000, 0x0040, 0x0036, 0x0010, 45 0x00, 0x40, 0x36, 0x10,
47 0x0000, 0x0000, 0x0057, 0x0000, 46 0x00, 0x00, 0x57, 0x00,
48};
49
50/*
51 * read ak4535 register cache
52 */
53static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
54 unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= AK4535_CACHEREGNUM)
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write ak4535 register cache
64 */
65static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec,
66 u16 reg, unsigned int value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= AK4535_CACHEREGNUM)
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the AK4535 register space
76 */
77static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80 u8 data[2];
81
82 /* data is
83 * D15..D8 AK4535 register offset
84 * D7...D0 register data
85 */
86 data[0] = reg & 0xff;
87 data[1] = value & 0xff;
88
89 ak4535_write_reg_cache(codec, reg, value);
90 if (codec->hw_write(codec->control_data, data, 2) == 2)
91 return 0;
92 else
93 return -EIO;
94}
95
96static int ak4535_sync(struct snd_soc_codec *codec)
97{
98 u16 *cache = codec->reg_cache;
99 int i, r = 0;
100
101 for (i = 0; i < AK4535_CACHEREGNUM; i++)
102 r |= ak4535_write(codec, i, cache[i]);
103
104 return r;
105}; 47};
106 48
107static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 49static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
@@ -304,7 +246,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
304 struct snd_soc_pcm_runtime *rtd = substream->private_data; 246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
305 struct snd_soc_codec *codec = rtd->codec; 247 struct snd_soc_codec *codec = rtd->codec;
306 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 248 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
307 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 249 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
308 int rate = params_rate(params), fs = 256; 250 int rate = params_rate(params), fs = 256;
309 251
310 if (rate) 252 if (rate)
@@ -323,7 +265,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
323 } 265 }
324 266
325 /* set rate */ 267 /* set rate */
326 ak4535_write(codec, AK4535_MODE2, mode2); 268 snd_soc_write(codec, AK4535_MODE2, mode2);
327 return 0; 269 return 0;
328} 270}
329 271
@@ -348,44 +290,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
348 /* use 32 fs for BCLK to save power */ 290 /* use 32 fs for BCLK to save power */
349 mode1 |= 0x4; 291 mode1 |= 0x4;
350 292
351 ak4535_write(codec, AK4535_MODE1, mode1); 293 snd_soc_write(codec, AK4535_MODE1, mode1);
352 return 0; 294 return 0;
353} 295}
354 296
355static int ak4535_mute(struct snd_soc_dai *dai, int mute) 297static int ak4535_mute(struct snd_soc_dai *dai, int mute)
356{ 298{
357 struct snd_soc_codec *codec = dai->codec; 299 struct snd_soc_codec *codec = dai->codec;
358 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 300 u16 mute_reg = snd_soc_read(codec, AK4535_DAC);
359 if (!mute) 301 if (!mute)
360 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); 302 snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20);
361 else 303 else
362 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); 304 snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20);
363 return 0; 305 return 0;
364} 306}
365 307
366static int ak4535_set_bias_level(struct snd_soc_codec *codec, 308static int ak4535_set_bias_level(struct snd_soc_codec *codec,
367 enum snd_soc_bias_level level) 309 enum snd_soc_bias_level level)
368{ 310{
369 u16 i, mute_reg;
370
371 switch (level) { 311 switch (level) {
372 case SND_SOC_BIAS_ON: 312 case SND_SOC_BIAS_ON:
373 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 313 snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0);
374 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
375 break; 314 break;
376 case SND_SOC_BIAS_PREPARE: 315 case SND_SOC_BIAS_PREPARE:
377 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 316 snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20);
378 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
379 break; 317 break;
380 case SND_SOC_BIAS_STANDBY: 318 case SND_SOC_BIAS_STANDBY:
381 i = ak4535_read_reg_cache(codec, AK4535_PM1); 319 snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80);
382 ak4535_write(codec, AK4535_PM1, i | 0x80); 320 snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0);
383 i = ak4535_read_reg_cache(codec, AK4535_PM2);
384 ak4535_write(codec, AK4535_PM2, i & (~0x80));
385 break; 321 break;
386 case SND_SOC_BIAS_OFF: 322 case SND_SOC_BIAS_OFF:
387 i = ak4535_read_reg_cache(codec, AK4535_PM1); 323 snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
388 ak4535_write(codec, AK4535_PM1, i & (~0x80));
389 break; 324 break;
390 } 325 }
391 codec->dapm.bias_level = level; 326 codec->dapm.bias_level = level;
@@ -428,7 +363,7 @@ static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
428 363
429static int ak4535_resume(struct snd_soc_codec *codec) 364static int ak4535_resume(struct snd_soc_codec *codec)
430{ 365{
431 ak4535_sync(codec); 366 snd_soc_cache_sync(codec);
432 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 367 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
433 return 0; 368 return 0;
434} 369}
@@ -436,11 +371,15 @@ static int ak4535_resume(struct snd_soc_codec *codec)
436static int ak4535_probe(struct snd_soc_codec *codec) 371static int ak4535_probe(struct snd_soc_codec *codec)
437{ 372{
438 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 373 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
374 int ret;
439 375
440 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 376 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
441 377
442 codec->control_data = ak4535->control_data; 378 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
443 379 if (ret < 0) {
380 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
381 return ret;
382 }
444 /* power on device */ 383 /* power on device */
445 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 384 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 385
@@ -461,8 +400,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
461 .remove = ak4535_remove, 400 .remove = ak4535_remove,
462 .suspend = ak4535_suspend, 401 .suspend = ak4535_suspend,
463 .resume = ak4535_resume, 402 .resume = ak4535_resume,
464 .read = ak4535_read_reg_cache,
465 .write = ak4535_write,
466 .set_bias_level = ak4535_set_bias_level, 403 .set_bias_level = ak4535_set_bias_level,
467 .reg_cache_size = ARRAY_SIZE(ak4535_reg), 404 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
468 .reg_word_size = sizeof(u8), 405 .reg_word_size = sizeof(u8),
@@ -485,7 +422,6 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
485 return -ENOMEM; 422 return -ENOMEM;
486 423
487 i2c_set_clientdata(i2c, ak4535); 424 i2c_set_clientdata(i2c, ak4535);
488 ak4535->control_data = i2c;
489 ak4535->control_type = SND_SOC_I2C; 425 ak4535->control_type = SND_SOC_I2C;
490 426
491 ret = snd_soc_register_codec(&i2c->dev, 427 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 7a64e58cddc4..77838586f358 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -31,7 +31,6 @@
31 31
32/* codec private data */ 32/* codec private data */
33struct ak4641_priv { 33struct ak4641_priv {
34 struct snd_soc_codec *codec;
35 unsigned int sysclk; 34 unsigned int sysclk;
36 int deemph; 35 int deemph;
37 int playback_fs; 36 int playback_fs;
@@ -226,7 +225,7 @@ static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
226 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0), 225 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
227 226
228 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0), 227 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
229 SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0), 228 SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
230 229
231 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0), 230 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
232 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0), 231 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 65f46047b1cb..d8fc04486abb 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -156,81 +156,22 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
156struct ak4642_priv { 156struct ak4642_priv {
157 unsigned int sysclk; 157 unsigned int sysclk;
158 enum snd_soc_control_type control_type; 158 enum snd_soc_control_type control_type;
159 void *control_data;
160}; 159};
161 160
162/* 161/*
163 * ak4642 register cache 162 * ak4642 register cache
164 */ 163 */
165static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { 164static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
166 0x0000, 0x0000, 0x0001, 0x0000, 165 0x00, 0x00, 0x01, 0x00,
167 0x0002, 0x0000, 0x0000, 0x0000, 166 0x02, 0x00, 0x00, 0x00,
168 0x00e1, 0x00e1, 0x0018, 0x0000, 167 0xe1, 0xe1, 0x18, 0x00,
169 0x00e1, 0x0018, 0x0011, 0x0008, 168 0xe1, 0x18, 0x11, 0x08,
170 0x0000, 0x0000, 0x0000, 0x0000, 169 0x00, 0x00, 0x00, 0x00,
171 0x0000, 0x0000, 0x0000, 0x0000, 170 0x00, 0x00, 0x00, 0x00,
172 0x0000, 0x0000, 0x0000, 0x0000, 171 0x00, 0x00, 0x00, 0x00,
173 0x0000, 0x0000, 0x0000, 0x0000, 172 0x00, 0x00, 0x00, 0x00,
174 0x0000, 0x0000, 0x0000, 0x0000, 173 0x00, 0x00, 0x00, 0x00,
175 0x0000, 174 0x00,
176};
177
178/*
179 * read ak4642 register cache
180 */
181static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
182 unsigned int reg)
183{
184 u16 *cache = codec->reg_cache;
185 if (reg >= AK4642_CACHEREGNUM)
186 return -1;
187 return cache[reg];
188}
189
190/*
191 * write ak4642 register cache
192 */
193static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
194 u16 reg, unsigned int value)
195{
196 u16 *cache = codec->reg_cache;
197 if (reg >= AK4642_CACHEREGNUM)
198 return;
199
200 cache[reg] = value;
201}
202
203/*
204 * write to the AK4642 register space
205 */
206static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
207 unsigned int value)
208{
209 u8 data[2];
210
211 /* data is
212 * D15..D8 AK4642 register offset
213 * D7...D0 register data
214 */
215 data[0] = reg & 0xff;
216 data[1] = value & 0xff;
217
218 if (codec->hw_write(codec->control_data, data, 2) == 2) {
219 ak4642_write_reg_cache(codec, reg, value);
220 return 0;
221 } else
222 return -EIO;
223}
224
225static int ak4642_sync(struct snd_soc_codec *codec)
226{
227 u16 *cache = codec->reg_cache;
228 int i, r = 0;
229
230 for (i = 0; i < AK4642_CACHEREGNUM; i++)
231 r |= ak4642_write(codec, i, cache[i]);
232
233 return r;
234}; 175};
235 176
236static int ak4642_dai_startup(struct snd_pcm_substream *substream, 177static int ak4642_dai_startup(struct snd_pcm_substream *substream,
@@ -252,8 +193,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
252 */ 193 */
253 snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); 194 snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
254 snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); 195 snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
255 ak4642_write(codec, L_IVC, 0x91); /* volume */ 196 snd_soc_write(codec, L_IVC, 0x91); /* volume */
256 ak4642_write(codec, R_IVC, 0x91); /* volume */ 197 snd_soc_write(codec, R_IVC, 0x91); /* volume */
257 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, 198 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
258 PMVCM | PMMIN | PMDAC); 199 PMVCM | PMMIN | PMDAC);
259 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); 200 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
@@ -272,9 +213,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
272 * This operation came from example code of 213 * This operation came from example code of
273 * "ASAHI KASEI AK4642" (japanese) manual p94. 214 * "ASAHI KASEI AK4642" (japanese) manual p94.
274 */ 215 */
275 ak4642_write(codec, SG_SL1, PMMP | MGAIN0); 216 snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
276 ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); 217 snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
277 ak4642_write(codec, ALC_CTL1, ALC | LMTH0); 218 snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
278 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, 219 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
279 PMVCM | PMADL); 220 PMVCM | PMADL);
280 snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); 221 snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
@@ -462,7 +403,7 @@ static struct snd_soc_dai_driver ak4642_dai = {
462 403
463static int ak4642_resume(struct snd_soc_codec *codec) 404static int ak4642_resume(struct snd_soc_codec *codec)
464{ 405{
465 ak4642_sync(codec); 406 snd_soc_cache_sync(codec);
466 return 0; 407 return 0;
467} 408}
468 409
@@ -470,11 +411,15 @@ static int ak4642_resume(struct snd_soc_codec *codec)
470static int ak4642_probe(struct snd_soc_codec *codec) 411static int ak4642_probe(struct snd_soc_codec *codec)
471{ 412{
472 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); 413 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
414 int ret;
473 415
474 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 416 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
475 417
476 codec->hw_write = (hw_write_t)i2c_master_send; 418 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
477 codec->control_data = ak4642->control_data; 419 if (ret < 0) {
420 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
421 return ret;
422 }
478 423
479 snd_soc_add_controls(codec, ak4642_snd_controls, 424 snd_soc_add_controls(codec, ak4642_snd_controls,
480 ARRAY_SIZE(ak4642_snd_controls)); 425 ARRAY_SIZE(ak4642_snd_controls));
@@ -485,8 +430,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
485static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 430static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
486 .probe = ak4642_probe, 431 .probe = ak4642_probe,
487 .resume = ak4642_resume, 432 .resume = ak4642_resume,
488 .read = ak4642_read_reg_cache,
489 .write = ak4642_write,
490 .reg_cache_size = ARRAY_SIZE(ak4642_reg), 433 .reg_cache_size = ARRAY_SIZE(ak4642_reg),
491 .reg_word_size = sizeof(u8), 434 .reg_word_size = sizeof(u8),
492 .reg_cache_default = ak4642_reg, 435 .reg_cache_default = ak4642_reg,
@@ -504,7 +447,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
504 return -ENOMEM; 447 return -ENOMEM;
505 448
506 i2c_set_clientdata(i2c, ak4642); 449 i2c_set_clientdata(i2c, ak4642);
507 ak4642->control_data = i2c;
508 ak4642->control_type = SND_SOC_I2C; 450 ak4642->control_type = SND_SOC_I2C;
509 451
510 ret = snd_soc_register_codec(&i2c->dev, 452 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 88b29f8c748b..de9ff66d3721 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -26,7 +26,6 @@
26/* codec private data */ 26/* codec private data */
27struct ak4671_priv { 27struct ak4671_priv {
28 enum snd_soc_control_type control_type; 28 enum snd_soc_control_type control_type;
29 void *control_data;
30}; 29};
31 30
32/* ak4671 register cache & default register settings */ 31/* ak4671 register cache & default register settings */
@@ -169,18 +168,15 @@ static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event) 168 struct snd_kcontrol *kcontrol, int event)
170{ 169{
171 struct snd_soc_codec *codec = w->codec; 170 struct snd_soc_codec *codec = w->codec;
172 u8 reg;
173 171
174 switch (event) { 172 switch (event) {
175 case SND_SOC_DAPM_POST_PMU: 173 case SND_SOC_DAPM_POST_PMU:
176 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); 174 snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
177 reg |= AK4671_MUTEN; 175 AK4671_MUTEN, AK4671_MUTEN);
178 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
179 break; 176 break;
180 case SND_SOC_DAPM_PRE_PMD: 177 case SND_SOC_DAPM_PRE_PMD:
181 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); 178 snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
182 reg &= ~AK4671_MUTEN; 179 AK4671_MUTEN, 0);
183 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
184 break; 180 break;
185 } 181 }
186 182
@@ -576,15 +572,12 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
576static int ak4671_set_bias_level(struct snd_soc_codec *codec, 572static int ak4671_set_bias_level(struct snd_soc_codec *codec,
577 enum snd_soc_bias_level level) 573 enum snd_soc_bias_level level)
578{ 574{
579 u8 reg;
580
581 switch (level) { 575 switch (level) {
582 case SND_SOC_BIAS_ON: 576 case SND_SOC_BIAS_ON:
583 case SND_SOC_BIAS_PREPARE: 577 case SND_SOC_BIAS_PREPARE:
584 case SND_SOC_BIAS_STANDBY: 578 case SND_SOC_BIAS_STANDBY:
585 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT); 579 snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT,
586 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 580 AK4671_PMVCM, AK4671_PMVCM);
587 reg | AK4671_PMVCM);
588 break; 581 break;
589 case SND_SOC_BIAS_OFF: 582 case SND_SOC_BIAS_OFF:
590 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); 583 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
@@ -629,8 +622,6 @@ static int ak4671_probe(struct snd_soc_codec *codec)
629 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); 622 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
630 int ret; 623 int ret;
631 624
632 codec->hw_write = (hw_write_t)i2c_master_send;
633
634 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); 625 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
635 if (ret < 0) { 626 if (ret < 0) {
636 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 627 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -675,7 +666,6 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client,
675 return -ENOMEM; 666 return -ENOMEM;
676 667
677 i2c_set_clientdata(client, ak4671); 668 i2c_set_clientdata(client, ak4671);
678 ak4671->control_data = client;
679 ak4671->control_type = SND_SOC_I2C; 669 ak4671->control_type = SND_SOC_I2C;
680 670
681 ret = snd_soc_register_codec(&client->dev, 671 ret = snd_soc_register_codec(&client->dev,
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index eecffb548947..984b14bcb605 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -40,8 +40,6 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
40/* codec private data */ 40/* codec private data */
41struct alc5623_priv { 41struct alc5623_priv {
42 enum snd_soc_control_type control_type; 42 enum snd_soc_control_type control_type;
43 void *control_data;
44 struct mutex mutex;
45 u8 id; 43 u8 id;
46 unsigned int sysclk; 44 unsigned int sysclk;
47 u16 reg_cache[ALC5623_VENDOR_ID2+2]; 45 u16 reg_cache[ALC5623_VENDOR_ID2+2];
@@ -55,8 +53,10 @@ static void alc5623_fill_cache(struct snd_soc_codec *codec)
55 u16 *cache = codec->reg_cache; 53 u16 *cache = codec->reg_cache;
56 54
57 /* not really efficient ... */ 55 /* not really efficient ... */
56 codec->cache_bypass = 1;
58 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) 57 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
59 cache[i] = codec->hw_read(codec, i); 58 cache[i] = snd_soc_read(codec, i);
59 codec->cache_bypass = 0;
60} 60}
61 61
62static inline int alc5623_reset(struct snd_soc_codec *codec) 62static inline int alc5623_reset(struct snd_soc_codec *codec)
@@ -1050,9 +1050,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1050 } 1050 }
1051 1051
1052 i2c_set_clientdata(client, alc5623); 1052 i2c_set_clientdata(client, alc5623);
1053 alc5623->control_data = client;
1054 alc5623->control_type = SND_SOC_I2C; 1053 alc5623->control_type = SND_SOC_I2C;
1055 mutex_init(&alc5623->mutex);
1056 1054
1057 ret = snd_soc_register_codec(&client->dev, 1055 ret = snd_soc_register_codec(&client->dev,
1058 &soc_codec_device_alc5623, &alc5623_dai, 1); 1056 &soc_codec_device_alc5623, &alc5623_dai, 1);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 6cc8678f49f3..f1f237ecec2a 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -128,7 +128,6 @@ static const char *supply_names[] = {
128/* Private data for the CS4270 */ 128/* Private data for the CS4270 */
129struct cs4270_private { 129struct cs4270_private {
130 enum snd_soc_control_type control_type; 130 enum snd_soc_control_type control_type;
131 void *control_data;
132 unsigned int mclk; /* Input frequency of the MCLK pin */ 131 unsigned int mclk; /* Input frequency of the MCLK pin */
133 unsigned int mode; /* The mode (I2S or left-justified) */ 132 unsigned int mode; /* The mode (I2S or left-justified) */
134 unsigned int slave_mode; 133 unsigned int slave_mode;
@@ -262,7 +261,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
262{ 261{
263 struct snd_soc_codec *codec = codec_dai->codec; 262 struct snd_soc_codec *codec = codec_dai->codec;
264 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 263 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
265 int ret = 0;
266 264
267 /* set DAI format */ 265 /* set DAI format */
268 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 266 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -272,7 +270,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
272 break; 270 break;
273 default: 271 default:
274 dev_err(codec->dev, "invalid dai format\n"); 272 dev_err(codec->dev, "invalid dai format\n");
275 ret = -EINVAL; 273 return -EINVAL;
276 } 274 }
277 275
278 /* set master/slave audio interface */ 276 /* set master/slave audio interface */
@@ -285,10 +283,11 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
285 break; 283 break;
286 default: 284 default:
287 /* all other modes are unsupported by the hardware */ 285 /* all other modes are unsupported by the hardware */
288 ret = -EINVAL; 286 dev_err(codec->dev, "Unknown master/slave configuration\n");
287 return -EINVAL;
289 } 288 }
290 289
291 return ret; 290 return 0;
292} 291}
293 292
294/** 293/**
@@ -490,8 +489,6 @@ static int cs4270_probe(struct snd_soc_codec *codec)
490 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 489 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
491 int i, ret; 490 int i, ret;
492 491
493 codec->control_data = cs4270->control_data;
494
495 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will 492 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
496 * then do the I2C transactions itself. 493 * then do the I2C transactions itself.
497 */ 494 */
@@ -604,7 +601,7 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
604static int cs4270_soc_resume(struct snd_soc_codec *codec) 601static int cs4270_soc_resume(struct snd_soc_codec *codec)
605{ 602{
606 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
607 struct i2c_client *i2c_client = codec->control_data; 604 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
608 int reg; 605 int reg;
609 606
610 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), 607 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
@@ -690,7 +687,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
690 } 687 }
691 688
692 i2c_set_clientdata(i2c_client, cs4270); 689 i2c_set_clientdata(i2c_client, cs4270);
693 cs4270->control_data = i2c_client;
694 cs4270->control_type = SND_SOC_I2C; 690 cs4270->control_type = SND_SOC_I2C;
695 691
696 ret = snd_soc_register_codec(&i2c_client->dev, 692 ret = snd_soc_register_codec(&i2c_client->dev,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 083aab96ca80..23d1bd5dadda 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -156,7 +156,6 @@ static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
156struct cs4271_private { 156struct cs4271_private {
157 /* SND_SOC_I2C or SND_SOC_SPI */ 157 /* SND_SOC_I2C or SND_SOC_SPI */
158 enum snd_soc_control_type bus_type; 158 enum snd_soc_control_type bus_type;
159 void *control_data;
160 unsigned int mclk; 159 unsigned int mclk;
161 bool master; 160 bool master;
162 bool deemph; 161 bool deemph;
@@ -466,8 +465,6 @@ static int cs4271_probe(struct snd_soc_codec *codec)
466 int ret; 465 int ret;
467 int gpio_nreset = -EINVAL; 466 int gpio_nreset = -EINVAL;
468 467
469 codec->control_data = cs4271->control_data;
470
471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) 468 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
472 gpio_nreset = cs4271plat->gpio_nreset; 469 gpio_nreset = cs4271plat->gpio_nreset;
473 470
@@ -555,7 +552,6 @@ static int __devinit cs4271_spi_probe(struct spi_device *spi)
555 return -ENOMEM; 552 return -ENOMEM;
556 553
557 spi_set_drvdata(spi, cs4271); 554 spi_set_drvdata(spi, cs4271);
558 cs4271->control_data = spi;
559 cs4271->bus_type = SND_SOC_SPI; 555 cs4271->bus_type = SND_SOC_SPI;
560 556
561 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, 557 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
@@ -595,7 +591,6 @@ static int __devinit cs4271_i2c_probe(struct i2c_client *client,
595 return -ENOMEM; 591 return -ENOMEM;
596 592
597 i2c_set_clientdata(client, cs4271); 593 i2c_set_clientdata(client, cs4271);
598 cs4271->control_data = client;
599 cs4271->bus_type = SND_SOC_I2C; 594 cs4271->bus_type = SND_SOC_I2C;
600 595
601 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, 596 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 8fb7070108dd..8c3c8205d19e 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -42,7 +42,6 @@ enum master_slave_mode {
42 42
43struct cs42l51_private { 43struct cs42l51_private {
44 enum snd_soc_control_type control_type; 44 enum snd_soc_control_type control_type;
45 void *control_data;
46 unsigned int mclk; 45 unsigned int mclk;
47 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 46 unsigned int audio_mode; /* The mode (I2S or left-justified) */
48 enum master_slave_mode func; 47 enum master_slave_mode func;
@@ -57,7 +56,7 @@ struct cs42l51_private {
57static int cs42l51_fill_cache(struct snd_soc_codec *codec) 56static int cs42l51_fill_cache(struct snd_soc_codec *codec)
58{ 57{
59 u8 *cache = codec->reg_cache + 1; 58 u8 *cache = codec->reg_cache + 1;
60 struct i2c_client *i2c_client = codec->control_data; 59 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
61 s32 length; 60 s32 length;
62 61
63 length = i2c_smbus_read_i2c_block_data(i2c_client, 62 length = i2c_smbus_read_i2c_block_data(i2c_client,
@@ -289,7 +288,6 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
289{ 288{
290 struct snd_soc_codec *codec = codec_dai->codec; 289 struct snd_soc_codec *codec = codec_dai->codec;
291 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 290 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
292 int ret = 0;
293 291
294 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 292 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
295 case SND_SOC_DAIFMT_I2S: 293 case SND_SOC_DAIFMT_I2S:
@@ -299,7 +297,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
299 break; 297 break;
300 default: 298 default:
301 dev_err(codec->dev, "invalid DAI format\n"); 299 dev_err(codec->dev, "invalid DAI format\n");
302 ret = -EINVAL; 300 return -EINVAL;
303 } 301 }
304 302
305 switch (format & SND_SOC_DAIFMT_MASTER_MASK) { 303 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -310,11 +308,11 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
310 cs42l51->func = MODE_SLAVE_AUTO; 308 cs42l51->func = MODE_SLAVE_AUTO;
311 break; 309 break;
312 default: 310 default:
313 ret = -EINVAL; 311 dev_err(codec->dev, "Unknown master/slave configuration\n");
314 break; 312 return -EINVAL;
315 } 313 }
316 314
317 return ret; 315 return 0;
318} 316}
319 317
320struct cs42l51_ratios { 318struct cs42l51_ratios {
@@ -520,8 +518,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
520 struct snd_soc_dapm_context *dapm = &codec->dapm; 518 struct snd_soc_dapm_context *dapm = &codec->dapm;
521 int ret, reg; 519 int ret, reg;
522 520
523 codec->control_data = cs42l51->control_data;
524
525 ret = cs42l51_fill_cache(codec); 521 ret = cs42l51_fill_cache(codec);
526 if (ret < 0) { 522 if (ret < 0) {
527 dev_err(codec->dev, "failed to fill register cache\n"); 523 dev_err(codec->dev, "failed to fill register cache\n");
@@ -593,7 +589,6 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
593 } 589 }
594 590
595 i2c_set_clientdata(i2c_client, cs42l51); 591 i2c_set_clientdata(i2c_client, cs42l51);
596 cs42l51->control_data = i2c_client;
597 cs42l51->control_type = SND_SOC_I2C; 592 cs42l51->control_type = SND_SOC_I2C;
598 593
599 ret = snd_soc_register_codec(&i2c_client->dev, 594 ret = snd_soc_register_codec(&i2c_client->dev,
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 92fd9d7a9221..0ebcbd534490 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -26,23 +26,41 @@
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
28/* DA7210 register space */ 28/* DA7210 register space */
29#define DA7210_CONTROL 0x01
29#define DA7210_STATUS 0x02 30#define DA7210_STATUS 0x02
30#define DA7210_STARTUP1 0x03 31#define DA7210_STARTUP1 0x03
32#define DA7210_STARTUP2 0x04
33#define DA7210_STARTUP3 0x05
31#define DA7210_MIC_L 0x07 34#define DA7210_MIC_L 0x07
32#define DA7210_MIC_R 0x08 35#define DA7210_MIC_R 0x08
36#define DA7210_AUX1_L 0x09
37#define DA7210_AUX1_R 0x0A
38#define DA7210_AUX2 0x0B
39#define DA7210_IN_GAIN 0x0C
33#define DA7210_INMIX_L 0x0D 40#define DA7210_INMIX_L 0x0D
34#define DA7210_INMIX_R 0x0E 41#define DA7210_INMIX_R 0x0E
35#define DA7210_ADC_HPF 0x0F 42#define DA7210_ADC_HPF 0x0F
36#define DA7210_ADC 0x10 43#define DA7210_ADC 0x10
44#define DA7210_ADC_EQ1_2 0X11
45#define DA7210_ADC_EQ3_4 0x12
46#define DA7210_ADC_EQ5 0x13
37#define DA7210_DAC_HPF 0x14 47#define DA7210_DAC_HPF 0x14
38#define DA7210_DAC_L 0x15 48#define DA7210_DAC_L 0x15
39#define DA7210_DAC_R 0x16 49#define DA7210_DAC_R 0x16
40#define DA7210_DAC_SEL 0x17 50#define DA7210_DAC_SEL 0x17
51#define DA7210_SOFTMUTE 0x18
52#define DA7210_DAC_EQ1_2 0x19
53#define DA7210_DAC_EQ3_4 0x1A
54#define DA7210_DAC_EQ5 0x1B
41#define DA7210_OUTMIX_L 0x1C 55#define DA7210_OUTMIX_L 0x1C
42#define DA7210_OUTMIX_R 0x1D 56#define DA7210_OUTMIX_R 0x1D
57#define DA7210_OUT1_L 0x1E
58#define DA7210_OUT1_R 0x1F
59#define DA7210_OUT2 0x20
43#define DA7210_HP_L_VOL 0x21 60#define DA7210_HP_L_VOL 0x21
44#define DA7210_HP_R_VOL 0x22 61#define DA7210_HP_R_VOL 0x22
45#define DA7210_HP_CFG 0x23 62#define DA7210_HP_CFG 0x23
63#define DA7210_ZERO_CROSS 0x24
46#define DA7210_DAI_SRC_SEL 0x25 64#define DA7210_DAI_SRC_SEL 0x25
47#define DA7210_DAI_CFG1 0x26 65#define DA7210_DAI_CFG1 0x26
48#define DA7210_DAI_CFG3 0x28 66#define DA7210_DAI_CFG3 0x28
@@ -50,6 +68,12 @@
50#define DA7210_PLL_DIV2 0x2A 68#define DA7210_PLL_DIV2 0x2A
51#define DA7210_PLL_DIV3 0x2B 69#define DA7210_PLL_DIV3 0x2B
52#define DA7210_PLL 0x2C 70#define DA7210_PLL 0x2C
71#define DA7210_ALC_MAX 0x83
72#define DA7210_ALC_MIN 0x84
73#define DA7210_ALC_NOIS 0x85
74#define DA7210_ALC_ATT 0x86
75#define DA7210_ALC_REL 0x87
76#define DA7210_ALC_DEL 0x88
53#define DA7210_A_HID_UNLOCK 0x8A 77#define DA7210_A_HID_UNLOCK 0x8A
54#define DA7210_A_TEST_UNLOCK 0x8B 78#define DA7210_A_TEST_UNLOCK 0x8B
55#define DA7210_A_PLL1 0x90 79#define DA7210_A_PLL1 0x90
@@ -72,6 +96,7 @@
72#define DA7210_IN_R_EN (1 << 7) 96#define DA7210_IN_R_EN (1 << 7)
73 97
74/* ADC bit fields */ 98/* ADC bit fields */
99#define DA7210_ADC_ALC_EN (1 << 0)
75#define DA7210_ADC_L_EN (1 << 3) 100#define DA7210_ADC_L_EN (1 << 3)
76#define DA7210_ADC_R_EN (1 << 7) 101#define DA7210_ADC_R_EN (1 << 7)
77 102
@@ -105,12 +130,17 @@
105 130
106/* DAI_CFG1 bit fields */ 131/* DAI_CFG1 bit fields */
107#define DA7210_DAI_WORD_S16_LE (0 << 0) 132#define DA7210_DAI_WORD_S16_LE (0 << 0)
133#define DA7210_DAI_WORD_S20_3LE (1 << 0)
108#define DA7210_DAI_WORD_S24_LE (2 << 0) 134#define DA7210_DAI_WORD_S24_LE (2 << 0)
135#define DA7210_DAI_WORD_S32_LE (3 << 0)
109#define DA7210_DAI_FLEN_64BIT (1 << 2) 136#define DA7210_DAI_FLEN_64BIT (1 << 2)
137#define DA7210_DAI_MODE_SLAVE (0 << 7)
110#define DA7210_DAI_MODE_MASTER (1 << 7) 138#define DA7210_DAI_MODE_MASTER (1 << 7)
111 139
112/* DAI_CFG3 bit fields */ 140/* DAI_CFG3 bit fields */
113#define DA7210_DAI_FORMAT_I2SMODE (0 << 0) 141#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
142#define DA7210_DAI_FORMAT_LEFT_J (1 << 0)
143#define DA7210_DAI_FORMAT_RIGHT_J (2 << 0)
114#define DA7210_DAI_OE (1 << 3) 144#define DA7210_DAI_OE (1 << 3)
115#define DA7210_DAI_EN (1 << 7) 145#define DA7210_DAI_EN (1 << 7)
116 146
@@ -133,6 +163,43 @@
133#define DA7210_PLL_FS_96000 (0xF << 0) 163#define DA7210_PLL_FS_96000 (0xF << 0)
134#define DA7210_PLL_EN (0x1 << 7) 164#define DA7210_PLL_EN (0x1 << 7)
135 165
166/* SOFTMUTE bit fields */
167#define DA7210_RAMP_EN (1 << 6)
168
169/* CONTROL bit fields */
170#define DA7210_NOISE_SUP_EN (1 << 3)
171
172/* IN_GAIN bit fields */
173#define DA7210_INPGA_L_VOL (0x0F << 0)
174#define DA7210_INPGA_R_VOL (0xF0 << 0)
175
176/* ZERO_CROSS bit fields */
177#define DA7210_AUX1_L_ZC (1 << 0)
178#define DA7210_AUX1_R_ZC (1 << 1)
179#define DA7210_HP_L_ZC (1 << 6)
180#define DA7210_HP_R_ZC (1 << 7)
181
182/* AUX1_L bit fields */
183#define DA7210_AUX1_L_VOL (0x3F << 0)
184
185/* AUX1_R bit fields */
186#define DA7210_AUX1_R_VOL (0x3F << 0)
187
188/* Minimum INPGA and AUX1 volume to enable noise suppression */
189#define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */
190#define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */
191
192/* OUT1_L bit fields */
193#define DA7210_OUT1_L_EN (1 << 7)
194
195/* OUT1_R bit fields */
196#define DA7210_OUT1_R_EN (1 << 7)
197
198/* OUT2 bit fields */
199#define DA7210_OUT2_OUTMIX_R (1 << 5)
200#define DA7210_OUT2_OUTMIX_L (1 << 6)
201#define DA7210_OUT2_EN (1 << 7)
202
136#define DA7210_VERSION "0.0.1" 203#define DA7210_VERSION "0.0.1"
137 204
138/* 205/*
@@ -144,24 +211,351 @@
144 * mute : 0x10 211 * mute : 0x10
145 * reserved : 0x00 - 0x0F 212 * reserved : 0x00 - 0x0F
146 * 213 *
147 * ** FIXME **
148 *
149 * Reserved area are considered as "mute". 214 * Reserved area are considered as "mute".
150 * -> min = -79.5 dB
151 */ 215 */
152static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1); 216static const unsigned int hp_out_tlv[] = {
217 TLV_DB_RANGE_HEAD(2),
218 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
219 /* -54 dB to +15 dB */
220 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0),
221};
222
223static const unsigned int lineout_vol_tlv[] = {
224 TLV_DB_RANGE_HEAD(2),
225 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
226 /* -54dB to 15dB */
227 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
228};
229
230static const unsigned int mono_vol_tlv[] = {
231 TLV_DB_RANGE_HEAD(2),
232 0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1),
233 /* -18dB to 6dB */
234 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0)
235};
236
237static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
238static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
239static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
240
241/* ADC and DAC high pass filter f0 value */
242static const char const *da7210_hpf_cutoff_txt[] = {
243 "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
244};
245
246static const struct soc_enum da7210_dac_hpf_cutoff =
247 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt);
248
249static const struct soc_enum da7210_adc_hpf_cutoff =
250 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
251
252/* ADC and DAC voice (8kHz) high pass cutoff value */
253static const char const *da7210_vf_cutoff_txt[] = {
254 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
255};
256
257static const struct soc_enum da7210_dac_vf_cutoff =
258 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt);
259
260static const struct soc_enum da7210_adc_vf_cutoff =
261 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt);
262
263static const char *da7210_hp_mode_txt[] = {
264 "Class H", "Class G"
265};
266
267static const struct soc_enum da7210_hp_mode_sel =
268 SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt);
269
270/* ALC can be enabled only if noise suppression is disabled */
271static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
273{
274 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
275
276 if (ucontrol->value.integer.value[0]) {
277 /* Check if noise suppression is enabled */
278 if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
279 dev_dbg(codec->dev,
280 "Disable noise suppression to enable ALC\n");
281 return -EINVAL;
282 }
283 }
284 /* If all conditions are met or we are actually disabling ALC */
285 return snd_soc_put_volsw(kcontrol, ucontrol);
286}
287
288/* Noise suppression can be enabled only if following conditions are met
289 * ALC disabled
290 * ZC enabled for HP and AUX1 PGA
291 * INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB
292 * AUX1_L_VOL and AUX1_R_VOL >= 6 dB
293 */
294static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_value *ucontrol)
296{
297 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
298 u8 val;
299
300 if (ucontrol->value.integer.value[0]) {
301 /* Check if ALC is enabled */
302 if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN)
303 goto err;
304
305 /* Check ZC for HP and AUX1 PGA */
306 if ((snd_soc_read(codec, DA7210_ZERO_CROSS) &
307 (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
308 DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC |
309 DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC))
310 goto err;
311
312 /* Check INPGA_L_VOL and INPGA_R_VOL */
313 val = snd_soc_read(codec, DA7210_IN_GAIN);
314 if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
315 (((val & DA7210_INPGA_R_VOL) >> 4) <
316 DA7210_INPGA_MIN_VOL_NS))
317 goto err;
318
319 /* Check AUX1_L_VOL and AUX1_R_VOL */
320 if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
321 DA7210_AUX1_MIN_VOL_NS) ||
322 ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
323 DA7210_AUX1_MIN_VOL_NS))
324 goto err;
325 }
326 /* If all conditions are met or we are actually disabling Noise sup */
327 return snd_soc_put_volsw(kcontrol, ucontrol);
328
329err:
330 return -EINVAL;
331}
153 332
154static const struct snd_kcontrol_new da7210_snd_controls[] = { 333static const struct snd_kcontrol_new da7210_snd_controls[] = {
155 334
156 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", 335 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
157 DA7210_HP_L_VOL, DA7210_HP_R_VOL, 336 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
158 0, 0x3F, 0, hp_out_tlv), 337 0, 0x3F, 0, hp_out_tlv),
338 SOC_DOUBLE_R_TLV("Digital Playback Volume",
339 DA7210_DAC_L, DA7210_DAC_R,
340 0, 0x77, 1, dac_gain_tlv),
341 SOC_DOUBLE_R_TLV("Lineout Playback Volume",
342 DA7210_OUT1_L, DA7210_OUT1_R,
343 0, 0x3f, 0, lineout_vol_tlv),
344 SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0,
345 mono_vol_tlv),
346
347 /* DAC Equalizer controls */
348 SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0),
349 SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1,
350 eq_gain_tlv),
351 SOC_SINGLE_TLV("DAC EQ2 Volume", DA7210_DAC_EQ1_2, 4, 0xf, 1,
352 eq_gain_tlv),
353 SOC_SINGLE_TLV("DAC EQ3 Volume", DA7210_DAC_EQ3_4, 0, 0xf, 1,
354 eq_gain_tlv),
355 SOC_SINGLE_TLV("DAC EQ4 Volume", DA7210_DAC_EQ3_4, 4, 0xf, 1,
356 eq_gain_tlv),
357 SOC_SINGLE_TLV("DAC EQ5 Volume", DA7210_DAC_EQ5, 0, 0xf, 1,
358 eq_gain_tlv),
359
360 /* ADC Equalizer controls */
361 SOC_SINGLE("ADC EQ Switch", DA7210_ADC_EQ5, 7, 1, 0),
362 SOC_SINGLE_TLV("ADC EQ Master Volume", DA7210_ADC_EQ5, 4, 0x3,
363 1, adc_eq_master_gain_tlv),
364 SOC_SINGLE_TLV("ADC EQ1 Volume", DA7210_ADC_EQ1_2, 0, 0xf, 1,
365 eq_gain_tlv),
366 SOC_SINGLE_TLV("ADC EQ2 Volume", DA7210_ADC_EQ1_2, 4, 0xf, 1,
367 eq_gain_tlv),
368 SOC_SINGLE_TLV("ADC EQ3 Volume", DA7210_ADC_EQ3_4, 0, 0xf, 1,
369 eq_gain_tlv),
370 SOC_SINGLE_TLV("ADC EQ4 Volume", DA7210_ADC_EQ3_4, 4, 0xf, 1,
371 eq_gain_tlv),
372 SOC_SINGLE_TLV("ADC EQ5 Volume", DA7210_ADC_EQ5, 0, 0xf, 1,
373 eq_gain_tlv),
374
375 SOC_SINGLE("DAC HPF Switch", DA7210_DAC_HPF, 3, 1, 0),
376 SOC_ENUM("DAC HPF Cutoff", da7210_dac_hpf_cutoff),
377 SOC_SINGLE("DAC Voice Mode Switch", DA7210_DAC_HPF, 7, 1, 0),
378 SOC_ENUM("DAC Voice Cutoff", da7210_dac_vf_cutoff),
379
380 SOC_SINGLE("ADC HPF Switch", DA7210_ADC_HPF, 3, 1, 0),
381 SOC_ENUM("ADC HPF Cutoff", da7210_adc_hpf_cutoff),
382 SOC_SINGLE("ADC Voice Mode Switch", DA7210_ADC_HPF, 7, 1, 0),
383 SOC_ENUM("ADC Voice Cutoff", da7210_adc_vf_cutoff),
384
385 /* Mute controls */
386 SOC_DOUBLE_R("Mic Capture Switch", DA7210_MIC_L, DA7210_MIC_R, 3, 1, 0),
387 SOC_SINGLE("Aux2 Capture Switch", DA7210_AUX2, 2, 1, 0),
388 SOC_DOUBLE("ADC Capture Switch", DA7210_ADC, 2, 6, 1, 0),
389 SOC_SINGLE("Digital Soft Mute Switch", DA7210_SOFTMUTE, 7, 1, 0),
390 SOC_SINGLE("Digital Soft Mute Rate", DA7210_SOFTMUTE, 0, 0x7, 0),
391
392 /* Zero cross controls */
393 SOC_DOUBLE("Aux1 ZC Switch", DA7210_ZERO_CROSS, 0, 1, 1, 0),
394 SOC_DOUBLE("In PGA ZC Switch", DA7210_ZERO_CROSS, 2, 3, 1, 0),
395 SOC_DOUBLE("Lineout ZC Switch", DA7210_ZERO_CROSS, 4, 5, 1, 0),
396 SOC_DOUBLE("Headphone ZC Switch", DA7210_ZERO_CROSS, 6, 7, 1, 0),
397
398 SOC_ENUM("Headphone Class", da7210_hp_mode_sel),
399
400 /* ALC controls */
401 SOC_SINGLE_EXT("ALC Enable Switch", DA7210_ADC, 0, 1, 0,
402 snd_soc_get_volsw, da7210_put_alc_sw),
403 SOC_SINGLE("ALC Capture Max Volume", DA7210_ALC_MAX, 0, 0x3F, 0),
404 SOC_SINGLE("ALC Capture Min Volume", DA7210_ALC_MIN, 0, 0x3F, 0),
405 SOC_SINGLE("ALC Capture Noise Volume", DA7210_ALC_NOIS, 0, 0x3F, 0),
406 SOC_SINGLE("ALC Capture Attack Rate", DA7210_ALC_ATT, 0, 0xFF, 0),
407 SOC_SINGLE("ALC Capture Release Rate", DA7210_ALC_REL, 0, 0xFF, 0),
408 SOC_SINGLE("ALC Capture Release Delay", DA7210_ALC_DEL, 0, 0xFF, 0),
409
410 SOC_SINGLE_EXT("Noise Suppression Enable Switch", DA7210_CONTROL, 3, 1,
411 0, snd_soc_get_volsw, da7210_put_noise_sup_sw),
412};
413
414/*
415 * DAPM Controls
416 *
417 * Current DAPM implementation covers almost all codec components e.g. IOs,
418 * mixers, PGAs,ADC and DAC.
419 */
420/* In Mixer Left */
421static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = {
422 SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0),
423 SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0),
424};
425
426/* In Mixer Right */
427static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = {
428 SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0),
429 SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0),
430};
431
432/* Out Mixer Left */
433static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = {
434 SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0),
435};
436
437/* Out Mixer Right */
438static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = {
439 SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0),
440};
441
442/* Mono Mixer */
443static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = {
444 SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0),
445 SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0),
446};
447
448/* DAPM widgets */
449static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = {
450 /* Input Side */
451 /* Input Lines */
452 SND_SOC_DAPM_INPUT("MICL"),
453 SND_SOC_DAPM_INPUT("MICR"),
454
455 /* Input PGAs */
456 SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0),
457 SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0),
458
459 SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0),
460 SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0),
461
462 /* Input Mixers */
463 SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
464 &da7210_dapm_inmixl_controls[0],
465 ARRAY_SIZE(da7210_dapm_inmixl_controls)),
466
467 SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,
468 &da7210_dapm_inmixr_controls[0],
469 ARRAY_SIZE(da7210_dapm_inmixr_controls)),
470
471 /* ADCs */
472 SND_SOC_DAPM_ADC("ADC Left", "Capture", DA7210_STARTUP3, 5, 1),
473 SND_SOC_DAPM_ADC("ADC Right", "Capture", DA7210_STARTUP3, 6, 1),
474
475 /* Output Side */
476 /* DACs */
477 SND_SOC_DAPM_DAC("DAC Left", "Playback", DA7210_STARTUP2, 5, 1),
478 SND_SOC_DAPM_DAC("DAC Right", "Playback", DA7210_STARTUP2, 6, 1),
479
480 /* Output Mixers */
481 SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,
482 &da7210_dapm_outmixl_controls[0],
483 ARRAY_SIZE(da7210_dapm_outmixl_controls)),
484
485 SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,
486 &da7210_dapm_outmixr_controls[0],
487 ARRAY_SIZE(da7210_dapm_outmixr_controls)),
488
489 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
490 &da7210_dapm_monomix_controls[0],
491 ARRAY_SIZE(da7210_dapm_monomix_controls)),
492
493 /* Output PGAs */
494 SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0),
495 SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0),
496
497 SND_SOC_DAPM_PGA("Out1 Left", DA7210_STARTUP2, 0, 1, NULL, 0),
498 SND_SOC_DAPM_PGA("Out1 Right", DA7210_STARTUP2, 1, 1, NULL, 0),
499 SND_SOC_DAPM_PGA("Out2 Mono", DA7210_STARTUP2, 2, 1, NULL, 0),
500 SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0),
501 SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0),
502
503 /* Output Lines */
504 SND_SOC_DAPM_OUTPUT("OUT1L"),
505 SND_SOC_DAPM_OUTPUT("OUT1R"),
506 SND_SOC_DAPM_OUTPUT("HPL"),
507 SND_SOC_DAPM_OUTPUT("HPR"),
508 SND_SOC_DAPM_OUTPUT("OUT2"),
509};
510
511/* DAPM audio route definition */
512static const struct snd_soc_dapm_route da7210_audio_map[] = {
513 /* Dest Connecting Widget source */
514 /* Input path */
515 {"Mic Left", NULL, "MICL"},
516 {"Mic Right", NULL, "MICR"},
517
518 {"In Mixer Left", "Mic Left Switch", "Mic Left"},
519 {"In Mixer Left", "Mic Right Switch", "Mic Right"},
520
521 {"In Mixer Right", "Mic Right Switch", "Mic Right"},
522 {"In Mixer Right", "Mic Left Switch", "Mic Left"},
523
524 {"INPGA Left", NULL, "In Mixer Left"},
525 {"ADC Left", NULL, "INPGA Left"},
526
527 {"INPGA Right", NULL, "In Mixer Right"},
528 {"ADC Right", NULL, "INPGA Right"},
529
530 /* Output path */
531 {"Out Mixer Left", "DAC Left Switch", "DAC Left"},
532 {"Out Mixer Right", "DAC Right Switch", "DAC Right"},
533
534 {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"},
535 {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"},
536
537 {"OUTPGA Left Enable", NULL, "Out Mixer Left"},
538 {"OUTPGA Right Enable", NULL, "Out Mixer Right"},
539
540 {"Out1 Left", NULL, "OUTPGA Left Enable"},
541 {"OUT1L", NULL, "Out1 Left"},
542
543 {"Out1 Right", NULL, "OUTPGA Right Enable"},
544 {"OUT1R", NULL, "Out1 Right"},
545
546 {"Headphone Left", NULL, "OUTPGA Left Enable"},
547 {"HPL", NULL, "Headphone Left"},
548
549 {"Headphone Right", NULL, "OUTPGA Right Enable"},
550 {"HPR", NULL, "Headphone Right"},
551
552 {"Out2 Mono", NULL, "Mono Mixer"},
553 {"OUT2", NULL, "Out2 Mono"},
159}; 554};
160 555
161/* Codec private data */ 556/* Codec private data */
162struct da7210_priv { 557struct da7210_priv {
163 enum snd_soc_control_type control_type; 558 enum snd_soc_control_type control_type;
164 void *control_data;
165}; 559};
166 560
167/* 561/*
@@ -188,72 +582,15 @@ static const u8 da7210_reg[] = {
188 0x00, /* R88 */ 582 0x00, /* R88 */
189}; 583};
190 584
191/* 585static int da7210_volatile_register(struct snd_soc_codec *codec,
192 * Read da7210 register cache 586 unsigned int reg)
193 */
194static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
195{
196 u8 *cache = codec->reg_cache;
197 BUG_ON(reg >= ARRAY_SIZE(da7210_reg));
198 return cache[reg];
199}
200
201/*
202 * Write to the da7210 register space
203 */
204static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
205{ 587{
206 u8 *cache = codec->reg_cache; 588 switch (reg) {
207 u8 data[2]; 589 case DA7210_STATUS:
208 590 return 1;
209 BUG_ON(codec->driver->volatile_register); 591 default:
210 592 return 0;
211 data[0] = reg & 0xff;
212 data[1] = value & 0xff;
213
214 if (reg >= codec->driver->reg_cache_size)
215 return -EIO;
216
217 if (2 != codec->hw_write(codec->control_data, data, 2))
218 return -EIO;
219
220 cache[reg] = value;
221 return 0;
222}
223
224/*
225 * Read from the da7210 register space.
226 */
227static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
228{
229 if (DA7210_STATUS == reg)
230 return i2c_smbus_read_byte_data(codec->control_data, reg);
231
232 return da7210_read_reg_cache(codec, reg);
233}
234
235static int da7210_startup(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai)
237{
238 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
239 struct snd_soc_codec *codec = dai->codec;
240
241 if (is_play) {
242 /* Enable Out */
243 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
244 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
245
246 } else {
247 /* Volume 7 */
248 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
249 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
250
251 /* Enable Mic */
252 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
253 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
254 } 593 }
255
256 return 0;
257} 594}
258 595
259/* 596/*
@@ -266,93 +603,75 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 603 struct snd_soc_pcm_runtime *rtd = substream->private_data;
267 struct snd_soc_codec *codec = rtd->codec; 604 struct snd_soc_codec *codec = rtd->codec;
268 u32 dai_cfg1; 605 u32 dai_cfg1;
269 u32 hpf_reg, hpf_mask, hpf_value;
270 u32 fs, bypass; 606 u32 fs, bypass;
271 607
272 /* set DAI source to Left and Right ADC */ 608 /* set DAI source to Left and Right ADC */
273 da7210_write(codec, DA7210_DAI_SRC_SEL, 609 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
274 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC); 610 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
275 611
276 /* Enable DAI */ 612 /* Enable DAI */
277 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN); 613 snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
278 614
279 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1); 615 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
280 616
281 switch (params_format(params)) { 617 switch (params_format(params)) {
282 case SNDRV_PCM_FORMAT_S16_LE: 618 case SNDRV_PCM_FORMAT_S16_LE:
283 dai_cfg1 |= DA7210_DAI_WORD_S16_LE; 619 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
284 break; 620 break;
621 case SNDRV_PCM_FORMAT_S20_3LE:
622 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
623 break;
285 case SNDRV_PCM_FORMAT_S24_LE: 624 case SNDRV_PCM_FORMAT_S24_LE:
286 dai_cfg1 |= DA7210_DAI_WORD_S24_LE; 625 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
287 break; 626 break;
627 case SNDRV_PCM_FORMAT_S32_LE:
628 dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
629 break;
288 default: 630 default:
289 return -EINVAL; 631 return -EINVAL;
290 } 632 }
291 633
292 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 634 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
293
294 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
295 DA7210_DAC_HPF : DA7210_ADC_HPF;
296 635
297 switch (params_rate(params)) { 636 switch (params_rate(params)) {
298 case 8000: 637 case 8000:
299 fs = DA7210_PLL_FS_8000; 638 fs = DA7210_PLL_FS_8000;
300 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
301 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
302 bypass = DA7210_PLL_BYP; 639 bypass = DA7210_PLL_BYP;
303 break; 640 break;
304 case 11025: 641 case 11025:
305 fs = DA7210_PLL_FS_11025; 642 fs = DA7210_PLL_FS_11025;
306 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
307 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
308 bypass = 0; 643 bypass = 0;
309 break; 644 break;
310 case 12000: 645 case 12000:
311 fs = DA7210_PLL_FS_12000; 646 fs = DA7210_PLL_FS_12000;
312 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
313 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
314 bypass = DA7210_PLL_BYP; 647 bypass = DA7210_PLL_BYP;
315 break; 648 break;
316 case 16000: 649 case 16000:
317 fs = DA7210_PLL_FS_16000; 650 fs = DA7210_PLL_FS_16000;
318 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
319 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
320 bypass = DA7210_PLL_BYP; 651 bypass = DA7210_PLL_BYP;
321 break; 652 break;
322 case 22050: 653 case 22050:
323 fs = DA7210_PLL_FS_22050; 654 fs = DA7210_PLL_FS_22050;
324 hpf_mask = DA7210_VOICE_EN;
325 hpf_value = 0;
326 bypass = 0; 655 bypass = 0;
327 break; 656 break;
328 case 32000: 657 case 32000:
329 fs = DA7210_PLL_FS_32000; 658 fs = DA7210_PLL_FS_32000;
330 hpf_mask = DA7210_VOICE_EN;
331 hpf_value = 0;
332 bypass = DA7210_PLL_BYP; 659 bypass = DA7210_PLL_BYP;
333 break; 660 break;
334 case 44100: 661 case 44100:
335 fs = DA7210_PLL_FS_44100; 662 fs = DA7210_PLL_FS_44100;
336 hpf_mask = DA7210_VOICE_EN;
337 hpf_value = 0;
338 bypass = 0; 663 bypass = 0;
339 break; 664 break;
340 case 48000: 665 case 48000:
341 fs = DA7210_PLL_FS_48000; 666 fs = DA7210_PLL_FS_48000;
342 hpf_mask = DA7210_VOICE_EN;
343 hpf_value = 0;
344 bypass = DA7210_PLL_BYP; 667 bypass = DA7210_PLL_BYP;
345 break; 668 break;
346 case 88200: 669 case 88200:
347 fs = DA7210_PLL_FS_88200; 670 fs = DA7210_PLL_FS_88200;
348 hpf_mask = DA7210_VOICE_EN;
349 hpf_value = 0;
350 bypass = 0; 671 bypass = 0;
351 break; 672 break;
352 case 96000: 673 case 96000:
353 fs = DA7210_PLL_FS_96000; 674 fs = DA7210_PLL_FS_96000;
354 hpf_mask = DA7210_VOICE_EN;
355 hpf_value = 0;
356 bypass = DA7210_PLL_BYP; 675 bypass = DA7210_PLL_BYP;
357 break; 676 break;
358 default: 677 default:
@@ -362,7 +681,6 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
362 /* Disable active mode */ 681 /* Disable active mode */
363 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); 682 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
364 683
365 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
366 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); 684 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
367 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass); 685 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
368 686
@@ -382,13 +700,16 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
382 u32 dai_cfg1; 700 u32 dai_cfg1;
383 u32 dai_cfg3; 701 u32 dai_cfg3;
384 702
385 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1); 703 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
386 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3); 704 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
387 705
388 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 706 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
389 case SND_SOC_DAIFMT_CBM_CFM: 707 case SND_SOC_DAIFMT_CBM_CFM:
390 dai_cfg1 |= DA7210_DAI_MODE_MASTER; 708 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
391 break; 709 break;
710 case SND_SOC_DAIFMT_CBS_CFS:
711 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
712 break;
392 default: 713 default:
393 return -EINVAL; 714 return -EINVAL;
394 } 715 }
@@ -401,6 +722,12 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
401 case SND_SOC_DAIFMT_I2S: 722 case SND_SOC_DAIFMT_I2S:
402 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE; 723 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
403 break; 724 break;
725 case SND_SOC_DAIFMT_LEFT_J:
726 dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J;
727 break;
728 case SND_SOC_DAIFMT_RIGHT_J:
729 dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J;
730 break;
404 default: 731 default:
405 return -EINVAL; 732 return -EINVAL;
406 } 733 }
@@ -411,19 +738,32 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
411 */ 738 */
412 dai_cfg1 |= DA7210_DAI_FLEN_64BIT; 739 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
413 740
414 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 741 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
415 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3); 742 snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
743
744 return 0;
745}
746
747static int da7210_mute(struct snd_soc_dai *dai, int mute)
748{
749 struct snd_soc_codec *codec = dai->codec;
750 u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB;
416 751
752 if (mute)
753 snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4);
754 else
755 snd_soc_write(codec, DA7210_DAC_HPF, mute_reg);
417 return 0; 756 return 0;
418} 757}
419 758
420#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 759#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
760 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
421 761
422/* DAI operations */ 762/* DAI operations */
423static struct snd_soc_dai_ops da7210_dai_ops = { 763static struct snd_soc_dai_ops da7210_dai_ops = {
424 .startup = da7210_startup,
425 .hw_params = da7210_hw_params, 764 .hw_params = da7210_hw_params,
426 .set_fmt = da7210_set_dai_fmt, 765 .set_fmt = da7210_set_dai_fmt,
766 .digital_mute = da7210_mute,
427}; 767};
428 768
429static struct snd_soc_dai_driver da7210_dai = { 769static struct snd_soc_dai_driver da7210_dai = {
@@ -451,11 +791,15 @@ static struct snd_soc_dai_driver da7210_dai = {
451static int da7210_probe(struct snd_soc_codec *codec) 791static int da7210_probe(struct snd_soc_codec *codec)
452{ 792{
453 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); 793 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
794 int ret;
454 795
455 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 796 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
456 797
457 codec->control_data = da7210->control_data; 798 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type);
458 codec->hw_write = (hw_write_t)i2c_master_send; 799 if (ret < 0) {
800 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
801 return ret;
802 }
459 803
460 /* FIXME 804 /* FIXME
461 * 805 *
@@ -472,8 +816,8 @@ static int da7210_probe(struct snd_soc_codec *codec)
472 /* 816 /*
473 * make sure that DA7210 use bypass mode before start up 817 * make sure that DA7210 use bypass mode before start up
474 */ 818 */
475 da7210_write(codec, DA7210_STARTUP1, 0); 819 snd_soc_write(codec, DA7210_STARTUP1, 0);
476 da7210_write(codec, DA7210_PLL_DIV3, 820 snd_soc_write(codec, DA7210_PLL_DIV3,
477 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 821 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
478 822
479 /* 823 /*
@@ -481,36 +825,70 @@ static int da7210_probe(struct snd_soc_codec *codec)
481 */ 825 */
482 826
483 /* Enable Left & Right MIC PGA and Mic Bias */ 827 /* Enable Left & Right MIC PGA and Mic Bias */
484 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN); 828 snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
485 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN); 829 snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
486 830
487 /* Enable Left and Right input PGA */ 831 /* Enable Left and Right input PGA */
488 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN); 832 snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
489 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN); 833 snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
490 834
491 /* Enable Left and Right ADC */ 835 /* Enable Left and Right ADC */
492 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN); 836 snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
493 837
494 /* 838 /*
495 * DAC settings 839 * DAC settings
496 */ 840 */
497 841
498 /* Enable Left and Right DAC */ 842 /* Enable Left and Right DAC */
499 da7210_write(codec, DA7210_DAC_SEL, 843 snd_soc_write(codec, DA7210_DAC_SEL,
500 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN | 844 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
501 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN); 845 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
502 846
503 /* Enable Left and Right out PGA */ 847 /* Enable Left and Right out PGA */
504 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN); 848 snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
505 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN); 849 snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
506 850
507 /* Enable Left and Right HeadPhone PGA */ 851 /* Enable Left and Right HeadPhone PGA */
508 da7210_write(codec, DA7210_HP_CFG, 852 snd_soc_write(codec, DA7210_HP_CFG,
509 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN | 853 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
510 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN); 854 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
511 855
856 /* Enable ramp mode for DAC gain update */
857 snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN);
858
859 /*
860 * For DA7210 codec, there are two ways to enable/disable analog IOs
861 * and ADC/DAC,
862 * (1) Using "Enable Bit" of register associated with that IO
863 * (or ADC/DAC)
864 * e.g. Mic Left can be enabled using bit 7 of MIC_L(0x7) reg
865 *
866 * (2) Using "Standby Bit" of STARTUP2 or STARTUP3 register
867 * e.g. Mic left can be put to STANDBY using bit 0 of STARTUP3(0x5)
868 *
869 * Out of these two methods, the one using STANDBY bits is preferred
870 * way to enable/disable individual blocks. This is because STANDBY
871 * registers are part of system controller which allows system power
872 * up/down in a controlled, pop-free manner. Also, as per application
873 * note of DA7210, STANDBY register bits are only effective if a
874 * particular IO (or ADC/DAC) is already enabled using enable/disable
875 * register bits. Keeping these things in mind, current DAPM
876 * implementation manipulates only STANDBY bits.
877 *
878 * Overall implementation can be outlined as below,
879 *
880 * - "Enable bit" of an IO or ADC/DAC is used to enable it in probe()
881 * - "STANDBY bit" is controlled by DAPM
882 */
883
884 /* Enable Line out amplifiers */
885 snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN);
886 snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN);
887 snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
888 DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
889
512 /* Diable PLL and bypass it */ 890 /* Diable PLL and bypass it */
513 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 891 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
514 892
515 /* 893 /*
516 * If 48kHz sound came, it use bypass mode, 894 * If 48kHz sound came, it use bypass mode,
@@ -521,25 +899,22 @@ static int da7210_probe(struct snd_soc_codec *codec)
521 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit. 899 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
522 * see da7210_hw_params 900 * see da7210_hw_params
523 */ 901 */
524 da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */ 902 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
525 da7210_write(codec, DA7210_PLL_DIV2, 0x99); 903 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
526 da7210_write(codec, DA7210_PLL_DIV3, 0x0A | 904 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
527 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 905 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
528 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); 906 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
529 907
530 /* As suggested by Dialog */ 908 /* As suggested by Dialog */
531 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ 909 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
532 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); 910 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
533 da7210_write(codec, DA7210_A_PLL1, 0x01); 911 snd_soc_write(codec, DA7210_A_PLL1, 0x01);
534 da7210_write(codec, DA7210_A_CP_MODE, 0x7C); 912 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C);
535 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ 913 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
536 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00); 914 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
537 915
538 /* Activate all enabled subsystem */ 916 /* Activate all enabled subsystem */
539 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 917 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
540
541 snd_soc_add_controls(codec, da7210_snd_controls,
542 ARRAY_SIZE(da7210_snd_controls));
543 918
544 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 919 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
545 920
@@ -548,11 +923,18 @@ static int da7210_probe(struct snd_soc_codec *codec)
548 923
549static struct snd_soc_codec_driver soc_codec_dev_da7210 = { 924static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
550 .probe = da7210_probe, 925 .probe = da7210_probe,
551 .read = da7210_read,
552 .write = da7210_write,
553 .reg_cache_size = ARRAY_SIZE(da7210_reg), 926 .reg_cache_size = ARRAY_SIZE(da7210_reg),
554 .reg_word_size = sizeof(u8), 927 .reg_word_size = sizeof(u8),
555 .reg_cache_default = da7210_reg, 928 .reg_cache_default = da7210_reg,
929 .volatile_register = da7210_volatile_register,
930
931 .controls = da7210_snd_controls,
932 .num_controls = ARRAY_SIZE(da7210_snd_controls),
933
934 .dapm_widgets = da7210_dapm_widgets,
935 .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets),
936 .dapm_routes = da7210_audio_map,
937 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
556}; 938};
557 939
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 940#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -567,7 +949,6 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
567 return -ENOMEM; 949 return -ENOMEM;
568 950
569 i2c_set_clientdata(i2c, da7210); 951 i2c_set_clientdata(i2c, da7210);
570 da7210->control_data = i2c;
571 da7210->control_type = SND_SOC_I2C; 952 da7210->control_type = SND_SOC_I2C;
572 953
573 ret = snd_soc_register_codec(&i2c->dev, 954 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 2c2a681da0d7..c387dafc6ab6 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2007 Wolfson Microelectronics PLC. 4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 6 * graeme.gregory@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> 7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index ac65a2d36408..ebbf63c79c34 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -40,7 +40,6 @@ struct max98088_cdata {
40 40
41struct max98088_priv { 41struct max98088_priv {
42 enum max98088_type devtype; 42 enum max98088_type devtype;
43 void *control_data;
44 struct max98088_pdata *pdata; 43 struct max98088_pdata *pdata;
45 unsigned int sysclk; 44 unsigned int sysclk;
46 struct max98088_cdata dai[2]; 45 struct max98088_cdata dai[2];
@@ -1697,13 +1696,19 @@ static struct snd_soc_dai_driver max98088_dai[] = {
1697} 1696}
1698}; 1697};
1699 1698
1700static int max98088_get_channel(const char *name) 1699static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
1700
1701static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
1701{ 1702{
1702 if (strcmp(name, "EQ1 Mode") == 0) 1703 int i;
1703 return 0; 1704
1704 if (strcmp(name, "EQ2 Mode") == 0) 1705 for (i = 0; i < ARRAY_SIZE(eq_mode_name); i++)
1705 return 1; 1706 if (strcmp(name, eq_mode_name[i]) == 0)
1706 return -EINVAL; 1707 return i;
1708
1709 /* Shouldn't happen */
1710 dev_err(codec->dev, "Bad EQ channel name '%s'\n", name);
1711 return -EINVAL;
1707} 1712}
1708 1713
1709static void max98088_setup_eq1(struct snd_soc_codec *codec) 1714static void max98088_setup_eq1(struct snd_soc_codec *codec)
@@ -1807,10 +1812,13 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
1807 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1812 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1808 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); 1813 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1809 struct max98088_pdata *pdata = max98088->pdata; 1814 struct max98088_pdata *pdata = max98088->pdata;
1810 int channel = max98088_get_channel(kcontrol->id.name); 1815 int channel = max98088_get_channel(codec, kcontrol->id.name);
1811 struct max98088_cdata *cdata; 1816 struct max98088_cdata *cdata;
1812 int sel = ucontrol->value.integer.value[0]; 1817 int sel = ucontrol->value.integer.value[0];
1813 1818
1819 if (channel < 0)
1820 return channel;
1821
1814 cdata = &max98088->dai[channel]; 1822 cdata = &max98088->dai[channel];
1815 1823
1816 if (sel >= pdata->eq_cfgcnt) 1824 if (sel >= pdata->eq_cfgcnt)
@@ -1835,9 +1843,12 @@ static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
1835{ 1843{
1836 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1844 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1837 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); 1845 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1838 int channel = max98088_get_channel(kcontrol->id.name); 1846 int channel = max98088_get_channel(codec, kcontrol->id.name);
1839 struct max98088_cdata *cdata; 1847 struct max98088_cdata *cdata;
1840 1848
1849 if (channel < 0)
1850 return channel;
1851
1841 cdata = &max98088->dai[channel]; 1852 cdata = &max98088->dai[channel];
1842 ucontrol->value.enumerated.item[0] = cdata->eq_sel; 1853 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1843 return 0; 1854 return 0;
@@ -1852,17 +1863,17 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1852 int i, j; 1863 int i, j;
1853 const char **t; 1864 const char **t;
1854 int ret; 1865 int ret;
1855
1856 struct snd_kcontrol_new controls[] = { 1866 struct snd_kcontrol_new controls[] = {
1857 SOC_ENUM_EXT("EQ1 Mode", 1867 SOC_ENUM_EXT((char *)eq_mode_name[0],
1858 max98088->eq_enum, 1868 max98088->eq_enum,
1859 max98088_get_eq_enum, 1869 max98088_get_eq_enum,
1860 max98088_put_eq_enum), 1870 max98088_put_eq_enum),
1861 SOC_ENUM_EXT("EQ2 Mode", 1871 SOC_ENUM_EXT((char *)eq_mode_name[1],
1862 max98088->eq_enum, 1872 max98088->eq_enum,
1863 max98088_get_eq_enum, 1873 max98088_get_eq_enum,
1864 max98088_put_eq_enum), 1874 max98088_put_eq_enum),
1865 }; 1875 };
1876 BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(eq_mode_name));
1866 1877
1867 cfg = pdata->eq_cfg; 1878 cfg = pdata->eq_cfg;
1868 cfgcnt = pdata->eq_cfgcnt; 1879 cfgcnt = pdata->eq_cfgcnt;
@@ -2066,7 +2077,6 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
2066 max98088->devtype = id->driver_data; 2077 max98088->devtype = id->driver_data;
2067 2078
2068 i2c_set_clientdata(i2c, max98088); 2079 i2c_set_clientdata(i2c, max98088);
2069 max98088->control_data = i2c;
2070 max98088->pdata = i2c->dev.platform_data; 2080 max98088->pdata = i2c->dev.platform_data;
2071 2081
2072 ret = snd_soc_register_codec(&i2c->dev, 2082 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 668434d44303..26d7b089fb9c 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -40,7 +40,6 @@ struct max98095_cdata {
40 40
41struct max98095_priv { 41struct max98095_priv {
42 enum max98095_type devtype; 42 enum max98095_type devtype;
43 void *control_data;
44 struct max98095_pdata *pdata; 43 struct max98095_pdata *pdata;
45 unsigned int sysclk; 44 unsigned int sysclk;
46 struct max98095_cdata dai[3]; 45 struct max98095_cdata dai[3];
@@ -618,14 +617,13 @@ static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
618static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg, 617static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
619 unsigned int value) 618 unsigned int value)
620{ 619{
621 u8 data[2]; 620 int ret;
622 621
623 data[0] = reg; 622 codec->cache_bypass = 1;
624 data[1] = value; 623 ret = snd_soc_write(codec, reg, value);
625 if (codec->hw_write(codec->control_data, data, 2) == 2) 624 codec->cache_bypass = 0;
626 return 0; 625
627 else 626 return ret ? -EIO : 0;
628 return -EIO;
629} 627}
630 628
631/* 629/*
@@ -1992,12 +1990,19 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1992 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1990 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1993} 1991}
1994 1992
1995static int max98095_get_bq_channel(const char *name) 1993static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
1994
1995static int max98095_get_bq_channel(struct snd_soc_codec *codec,
1996 const char *name)
1996{ 1997{
1997 if (strcmp(name, "Biquad1 Mode") == 0) 1998 int i;
1998 return 0; 1999
1999 if (strcmp(name, "Biquad2 Mode") == 0) 2000 for (i = 0; i < ARRAY_SIZE(bq_mode_name); i++)
2000 return 1; 2001 if (strcmp(name, bq_mode_name[i]) == 0)
2002 return i;
2003
2004 /* Shouldn't happen */
2005 dev_err(codec->dev, "Bad biquad channel name '%s'\n", name);
2001 return -EINVAL; 2006 return -EINVAL;
2002} 2007}
2003 2008
@@ -2007,14 +2012,15 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
2007 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2012 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2008 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2013 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2009 struct max98095_pdata *pdata = max98095->pdata; 2014 struct max98095_pdata *pdata = max98095->pdata;
2010 int channel = max98095_get_bq_channel(kcontrol->id.name); 2015 int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
2011 struct max98095_cdata *cdata; 2016 struct max98095_cdata *cdata;
2012 int sel = ucontrol->value.integer.value[0]; 2017 int sel = ucontrol->value.integer.value[0];
2013 struct max98095_biquad_cfg *coef_set; 2018 struct max98095_biquad_cfg *coef_set;
2014 int fs, best, best_val, i; 2019 int fs, best, best_val, i;
2015 int regmask, regsave; 2020 int regmask, regsave;
2016 2021
2017 BUG_ON(channel > 1); 2022 if (channel < 0)
2023 return channel;
2018 2024
2019 if (!pdata || !max98095->bq_textcnt) 2025 if (!pdata || !max98095->bq_textcnt)
2020 return 0; 2026 return 0;
@@ -2066,9 +2072,12 @@ static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
2066{ 2072{
2067 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2073 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2068 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2074 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2069 int channel = max98095_get_bq_channel(kcontrol->id.name); 2075 int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
2070 struct max98095_cdata *cdata; 2076 struct max98095_cdata *cdata;
2071 2077
2078 if (channel < 0)
2079 return channel;
2080
2072 cdata = &max98095->dai[channel]; 2081 cdata = &max98095->dai[channel];
2073 ucontrol->value.enumerated.item[0] = cdata->bq_sel; 2082 ucontrol->value.enumerated.item[0] = cdata->bq_sel;
2074 2083
@@ -2086,15 +2095,16 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2086 int ret; 2095 int ret;
2087 2096
2088 struct snd_kcontrol_new controls[] = { 2097 struct snd_kcontrol_new controls[] = {
2089 SOC_ENUM_EXT("Biquad1 Mode", 2098 SOC_ENUM_EXT((char *)bq_mode_name[0],
2090 max98095->bq_enum, 2099 max98095->bq_enum,
2091 max98095_get_bq_enum, 2100 max98095_get_bq_enum,
2092 max98095_put_bq_enum), 2101 max98095_put_bq_enum),
2093 SOC_ENUM_EXT("Biquad2 Mode", 2102 SOC_ENUM_EXT((char *)bq_mode_name[1],
2094 max98095->bq_enum, 2103 max98095->bq_enum,
2095 max98095_get_bq_enum, 2104 max98095_get_bq_enum,
2096 max98095_put_bq_enum), 2105 max98095_put_bq_enum),
2097 }; 2106 };
2107 BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(bq_mode_name));
2098 2108
2099 cfg = pdata->bq_cfg; 2109 cfg = pdata->bq_cfg;
2100 cfgcnt = pdata->bq_cfgcnt; 2110 cfgcnt = pdata->bq_cfgcnt;
@@ -2337,7 +2347,6 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
2337 2347
2338 max98095->devtype = id->driver_data; 2348 max98095->devtype = id->driver_data;
2339 i2c_set_clientdata(i2c, max98095); 2349 i2c_set_clientdata(i2c, max98095);
2340 max98095->control_data = i2c;
2341 max98095->pdata = i2c->dev.platform_data; 2350 max98095->pdata = i2c->dev.platform_data;
2342 2351
2343 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095, 2352 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
new file mode 100644
index 000000000000..27a078cbb6eb
--- /dev/null
+++ b/sound/soc/codecs/rt5631.c
@@ -0,0 +1,1773 @@
1/*
2 * rt5631.c -- RT5631 ALSA Soc Audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 *
6 * Author: flove <flove@realtek.com>
7 *
8 * Based on WM8753.c
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 */
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "rt5631.h"
32
33struct rt5631_priv {
34 int codec_version;
35 int master;
36 int sysclk;
37 int rx_rate;
38 int bclk_rate;
39 int dmic_used_flag;
40};
41
42static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = {
43 [RT5631_SPK_OUT_VOL] = 0x8888,
44 [RT5631_HP_OUT_VOL] = 0x8080,
45 [RT5631_MONO_AXO_1_2_VOL] = 0xa080,
46 [RT5631_AUX_IN_VOL] = 0x0808,
47 [RT5631_ADC_REC_MIXER] = 0xf0f0,
48 [RT5631_VDAC_DIG_VOL] = 0x0010,
49 [RT5631_OUTMIXER_L_CTRL] = 0xffc0,
50 [RT5631_OUTMIXER_R_CTRL] = 0xffc0,
51 [RT5631_AXO1MIXER_CTRL] = 0x88c0,
52 [RT5631_AXO2MIXER_CTRL] = 0x88c0,
53 [RT5631_DIG_MIC_CTRL] = 0x3000,
54 [RT5631_MONO_INPUT_VOL] = 0x8808,
55 [RT5631_SPK_MIXER_CTRL] = 0xf8f8,
56 [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00,
57 [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440,
58 [RT5631_SDP_CTRL] = 0x8000,
59 [RT5631_MONO_SDP_CTRL] = 0x8000,
60 [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010,
61 [RT5631_GEN_PUR_CTRL_REG] = 0x0e00,
62 [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a,
63 [RT5631_MISC_CTRL] = 0x2040,
64 [RT5631_DEPOP_FUN_CTRL_2] = 0x8000,
65 [RT5631_SOFT_VOL_CTRL] = 0x07e0,
66 [RT5631_ALC_CTRL_1] = 0x0206,
67 [RT5631_ALC_CTRL_3] = 0x2000,
68 [RT5631_PSEUDO_SPATL_CTRL] = 0x0553,
69};
70
71/**
72 * rt5631_write_index - write index register of 2nd layer
73 */
74static void rt5631_write_index(struct snd_soc_codec *codec,
75 unsigned int reg, unsigned int value)
76{
77 snd_soc_write(codec, RT5631_INDEX_ADD, reg);
78 snd_soc_write(codec, RT5631_INDEX_DATA, value);
79}
80
81/**
82 * rt5631_read_index - read index register of 2nd layer
83 */
84static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
85 unsigned int reg)
86{
87 unsigned int value;
88
89 snd_soc_write(codec, RT5631_INDEX_ADD, reg);
90 value = snd_soc_read(codec, RT5631_INDEX_DATA);
91
92 return value;
93}
94
95static int rt5631_reset(struct snd_soc_codec *codec)
96{
97 return snd_soc_write(codec, RT5631_RESET, 0);
98}
99
100static int rt5631_volatile_register(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 switch (reg) {
104 case RT5631_RESET:
105 case RT5631_INT_ST_IRQ_CTRL_2:
106 case RT5631_INDEX_ADD:
107 case RT5631_INDEX_DATA:
108 case RT5631_EQ_CTRL:
109 return 1;
110 default:
111 return 0;
112 }
113}
114
115static int rt5631_readable_register(struct snd_soc_codec *codec,
116 unsigned int reg)
117{
118 switch (reg) {
119 case RT5631_RESET:
120 case RT5631_SPK_OUT_VOL:
121 case RT5631_HP_OUT_VOL:
122 case RT5631_MONO_AXO_1_2_VOL:
123 case RT5631_AUX_IN_VOL:
124 case RT5631_STEREO_DAC_VOL_1:
125 case RT5631_MIC_CTRL_1:
126 case RT5631_STEREO_DAC_VOL_2:
127 case RT5631_ADC_CTRL_1:
128 case RT5631_ADC_REC_MIXER:
129 case RT5631_ADC_CTRL_2:
130 case RT5631_VDAC_DIG_VOL:
131 case RT5631_OUTMIXER_L_CTRL:
132 case RT5631_OUTMIXER_R_CTRL:
133 case RT5631_AXO1MIXER_CTRL:
134 case RT5631_AXO2MIXER_CTRL:
135 case RT5631_MIC_CTRL_2:
136 case RT5631_DIG_MIC_CTRL:
137 case RT5631_MONO_INPUT_VOL:
138 case RT5631_SPK_MIXER_CTRL:
139 case RT5631_SPK_MONO_OUT_CTRL:
140 case RT5631_SPK_MONO_HP_OUT_CTRL:
141 case RT5631_SDP_CTRL:
142 case RT5631_MONO_SDP_CTRL:
143 case RT5631_STEREO_AD_DA_CLK_CTRL:
144 case RT5631_PWR_MANAG_ADD1:
145 case RT5631_PWR_MANAG_ADD2:
146 case RT5631_PWR_MANAG_ADD3:
147 case RT5631_PWR_MANAG_ADD4:
148 case RT5631_GEN_PUR_CTRL_REG:
149 case RT5631_GLOBAL_CLK_CTRL:
150 case RT5631_PLL_CTRL:
151 case RT5631_INT_ST_IRQ_CTRL_1:
152 case RT5631_INT_ST_IRQ_CTRL_2:
153 case RT5631_GPIO_CTRL:
154 case RT5631_MISC_CTRL:
155 case RT5631_DEPOP_FUN_CTRL_1:
156 case RT5631_DEPOP_FUN_CTRL_2:
157 case RT5631_JACK_DET_CTRL:
158 case RT5631_SOFT_VOL_CTRL:
159 case RT5631_ALC_CTRL_1:
160 case RT5631_ALC_CTRL_2:
161 case RT5631_ALC_CTRL_3:
162 case RT5631_PSEUDO_SPATL_CTRL:
163 case RT5631_INDEX_ADD:
164 case RT5631_INDEX_DATA:
165 case RT5631_EQ_CTRL:
166 case RT5631_VENDOR_ID:
167 case RT5631_VENDOR_ID1:
168 case RT5631_VENDOR_ID2:
169 return 1;
170 default:
171 return 0;
172 }
173}
174
175static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
176static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
177static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
178/* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
179static unsigned int mic_bst_tlv[] = {
180 TLV_DB_RANGE_HEAD(6),
181 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
182 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
183 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
184 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
185 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
186 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
187 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
188};
189
190static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_value *ucontrol)
192{
193 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
194 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
195
196 ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
197
198 return 0;
199}
200
201static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
202 struct snd_ctl_elem_value *ucontrol)
203{
204 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
205 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
206
207 rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
208 return 0;
209}
210
211/* MIC Input Type */
212static const char *rt5631_input_mode[] = {
213 "Single ended", "Differential"};
214
215static const SOC_ENUM_SINGLE_DECL(
216 rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1,
217 RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
218
219static const SOC_ENUM_SINGLE_DECL(
220 rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1,
221 RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
222
223/* MONO Input Type */
224static const SOC_ENUM_SINGLE_DECL(
225 rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL,
226 RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
227
228/* SPK Ratio Gain Control */
229static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x",
230 "1.56x", "1.68x", "1.99x", "2.34x"};
231
232static const SOC_ENUM_SINGLE_DECL(
233 rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
234 RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
235
236static const struct snd_kcontrol_new rt5631_snd_controls[] = {
237 /* MIC */
238 SOC_ENUM("MIC1 Mode Control", rt5631_mic1_mode_enum),
239 SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2,
240 RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv),
241 SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum),
242 SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2,
243 RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv),
244 /* MONO IN */
245 SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum),
246 SOC_DOUBLE_TLV("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL,
247 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
248 RT5631_VOL_MASK, 1, in_vol_tlv),
249 /* AXI */
250 SOC_DOUBLE_TLV("AXI Capture Volume", RT5631_AUX_IN_VOL,
251 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
252 RT5631_VOL_MASK, 1, in_vol_tlv),
253 /* DAC */
254 SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2,
255 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
256 RT5631_DAC_VOL_MASK, 1, dac_vol_tlv),
257 SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1,
258 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
259 /* AXO */
260 SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
261 RT5631_L_MUTE_SHIFT, 1, 1),
262 SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
263 RT5631_R_VOL_SHIFT, 1, 1),
264 /* OUTVOL */
265 SOC_DOUBLE("OUTVOL Channel Switch", RT5631_SPK_OUT_VOL,
266 RT5631_L_EN_SHIFT, RT5631_R_EN_SHIFT, 1, 0),
267
268 /* SPK */
269 SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL,
270 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
271 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5631_SPK_OUT_VOL,
272 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, 39, 1, out_vol_tlv),
273 /* MONO OUT */
274 SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL,
275 RT5631_MUTE_MONO_SHIFT, 1, 1),
276 /* HP */
277 SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL,
278 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
279 SOC_DOUBLE_TLV("HP Playback Volume", RT5631_HP_OUT_VOL,
280 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
281 RT5631_VOL_MASK, 1, out_vol_tlv),
282 /* DMIC */
283 SOC_SINGLE_EXT("DMIC Switch", 0, 0, 1, 0,
284 rt5631_dmic_get, rt5631_dmic_put),
285 SOC_DOUBLE("DMIC Capture Switch", RT5631_DIG_MIC_CTRL,
286 RT5631_DMIC_L_CH_MUTE_SHIFT,
287 RT5631_DMIC_R_CH_MUTE_SHIFT, 1, 1),
288
289 /* SPK Ratio Gain Control */
290 SOC_ENUM("SPK Ratio Control", rt5631_spk_ratio_enum),
291};
292
293static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
294 struct snd_soc_dapm_widget *sink)
295{
296 unsigned int reg;
297
298 reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL);
299 return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
300}
301
302static int check_dmic_used(struct snd_soc_dapm_widget *source,
303 struct snd_soc_dapm_widget *sink)
304{
305 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec);
306 return rt5631->dmic_used_flag;
307}
308
309static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
310 struct snd_soc_dapm_widget *sink)
311{
312 unsigned int reg;
313
314 reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL);
315 return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
316}
317
318static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
319 struct snd_soc_dapm_widget *sink)
320{
321 unsigned int reg;
322
323 reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL);
324 return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
325}
326
327static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
328 struct snd_soc_dapm_widget *sink)
329{
330 unsigned int reg;
331
332 reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
333 return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
334}
335
336static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
337 struct snd_soc_dapm_widget *sink)
338{
339 unsigned int reg;
340
341 reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
342 return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
343}
344
345static int check_adcl_select(struct snd_soc_dapm_widget *source,
346 struct snd_soc_dapm_widget *sink)
347{
348 unsigned int reg;
349
350 reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
351 return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
352}
353
354static int check_adcr_select(struct snd_soc_dapm_widget *source,
355 struct snd_soc_dapm_widget *sink)
356{
357 unsigned int reg;
358
359 reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
360 return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
361}
362
363/**
364 * onebit_depop_power_stage - auto depop in power stage.
365 * @enable: power on/off
366 *
367 * When power on/off headphone, the depop sequence is done by hardware.
368 */
369static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
370{
371 unsigned int soft_vol, hp_zc;
372
373 /* enable one-bit depop function */
374 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
375 RT5631_EN_ONE_BIT_DEPOP, 0);
376
377 /* keep soft volume and zero crossing setting */
378 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
379 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
380 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
381 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
382 if (enable) {
383 /* config one-bit depop parameter */
384 rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
385 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
386 rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
387 /* power on capless block */
388 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
389 RT5631_EN_CAP_FREE_DEPOP);
390 } else {
391 /* power off capless block */
392 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
393 msleep(100);
394 }
395
396 /* recover soft volume and zero crossing setting */
397 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
398 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
399}
400
401/**
402 * onebit_depop_mute_stage - auto depop in mute stage.
403 * @enable: mute/unmute
404 *
405 * When mute/unmute headphone, the depop sequence is done by hardware.
406 */
407static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
408{
409 unsigned int soft_vol, hp_zc;
410
411 /* enable one-bit depop function */
412 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
413 RT5631_EN_ONE_BIT_DEPOP, 0);
414
415 /* keep soft volume and zero crossing setting */
416 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
417 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
418 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
419 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
420 if (enable) {
421 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
422 /* config one-bit depop parameter */
423 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
424 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
425 RT5631_L_MUTE | RT5631_R_MUTE, 0);
426 msleep(300);
427 } else {
428 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
429 RT5631_L_MUTE | RT5631_R_MUTE,
430 RT5631_L_MUTE | RT5631_R_MUTE);
431 msleep(100);
432 }
433
434 /* recover soft volume and zero crossing setting */
435 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
436 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
437}
438
439/**
440 * onebit_depop_power_stage - step by step depop sequence in power stage.
441 * @enable: power on/off
442 *
443 * When power on/off headphone, the depop sequence is done in step by step.
444 */
445static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
446{
447 unsigned int soft_vol, hp_zc;
448
449 /* depop control by register */
450 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
451 RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
452
453 /* keep soft volume and zero crossing setting */
454 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
455 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
456 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
457 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
458 if (enable) {
459 /* config depop sequence parameter */
460 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
461
462 /* power on headphone and charge pump */
463 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
464 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
465 RT5631_PWR_HP_R_AMP,
466 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
467 RT5631_PWR_HP_R_AMP);
468
469 /* power on soft generator and depop mode2 */
470 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
471 RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
472 msleep(100);
473
474 /* stop depop mode */
475 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
476 RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
477 } else {
478 /* config depop sequence parameter */
479 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
480 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
481 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
482 RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
483 msleep(75);
484 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
485 RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
486 RT5631_PD_HPAMP_R_ST_UP);
487
488 /* start depop mode */
489 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
490 RT5631_PWR_HP_DEPOP_DIS, 0);
491
492 /* config depop sequence parameter */
493 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
494 RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
495 RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
496 msleep(80);
497 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
498 RT5631_POW_ON_SOFT_GEN);
499
500 /* power down headphone and charge pump */
501 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
502 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
503 RT5631_PWR_HP_R_AMP, 0);
504 }
505
506 /* recover soft volume and zero crossing setting */
507 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
508 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
509}
510
511/**
512 * depop_seq_mute_stage - step by step depop sequence in mute stage.
513 * @enable: mute/unmute
514 *
515 * When mute/unmute headphone, the depop sequence is done in step by step.
516 */
517static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
518{
519 unsigned int soft_vol, hp_zc;
520
521 /* depop control by register */
522 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
523 RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
524
525 /* keep soft volume and zero crossing setting */
526 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
527 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
528 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
529 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
530 if (enable) {
531 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
532
533 /* config depop sequence parameter */
534 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
535 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
536 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
537 RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
538 RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
539
540 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
541 RT5631_L_MUTE | RT5631_R_MUTE, 0);
542 msleep(160);
543 } else {
544 /* config depop sequence parameter */
545 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
546 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
547 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
548 RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
549 RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
550
551 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
552 RT5631_L_MUTE | RT5631_R_MUTE,
553 RT5631_L_MUTE | RT5631_R_MUTE);
554 msleep(150);
555 }
556
557 /* recover soft volume and zero crossing setting */
558 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
559 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
560}
561
562static int hp_event(struct snd_soc_dapm_widget *w,
563 struct snd_kcontrol *kcontrol, int event)
564{
565 struct snd_soc_codec *codec = w->codec;
566 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
567
568 switch (event) {
569 case SND_SOC_DAPM_PRE_PMD:
570 if (rt5631->codec_version) {
571 onebit_depop_mute_stage(codec, 0);
572 onebit_depop_power_stage(codec, 0);
573 } else {
574 depop_seq_mute_stage(codec, 0);
575 depop_seq_power_stage(codec, 0);
576 }
577 break;
578
579 case SND_SOC_DAPM_POST_PMU:
580 if (rt5631->codec_version) {
581 onebit_depop_power_stage(codec, 1);
582 onebit_depop_mute_stage(codec, 1);
583 } else {
584 depop_seq_power_stage(codec, 1);
585 depop_seq_mute_stage(codec, 1);
586 }
587 break;
588
589 default:
590 break;
591 }
592
593 return 0;
594}
595
596static int set_dmic_params(struct snd_soc_dapm_widget *w,
597 struct snd_kcontrol *kcontrol, int event)
598{
599 struct snd_soc_codec *codec = w->codec;
600 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
601
602 switch (rt5631->rx_rate) {
603 case 44100:
604 case 48000:
605 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
606 RT5631_DMIC_CLK_CTRL_MASK,
607 RT5631_DMIC_CLK_CTRL_TO_32FS);
608 break;
609
610 case 32000:
611 case 22050:
612 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
613 RT5631_DMIC_CLK_CTRL_MASK,
614 RT5631_DMIC_CLK_CTRL_TO_64FS);
615 break;
616
617 case 16000:
618 case 11025:
619 case 8000:
620 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
621 RT5631_DMIC_CLK_CTRL_MASK,
622 RT5631_DMIC_CLK_CTRL_TO_128FS);
623 break;
624
625 default:
626 return -EINVAL;
627 }
628
629 return 0;
630}
631
632static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
633 SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER,
634 RT5631_M_OUTMIXL_RECMIXL_BIT, 1, 1),
635 SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER,
636 RT5631_M_MIC1_RECMIXL_BIT, 1, 1),
637 SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER,
638 RT5631_M_AXIL_RECMIXL_BIT, 1, 1),
639 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
640 RT5631_M_MONO_IN_RECMIXL_BIT, 1, 1),
641};
642
643static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
644 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
645 RT5631_M_MONO_IN_RECMIXR_BIT, 1, 1),
646 SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER,
647 RT5631_M_AXIR_RECMIXR_BIT, 1, 1),
648 SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER,
649 RT5631_M_MIC2_RECMIXR_BIT, 1, 1),
650 SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER,
651 RT5631_M_OUTMIXR_RECMIXR_BIT, 1, 1),
652};
653
654static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
655 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
656 RT5631_M_RECMIXL_SPKMIXL_BIT, 1, 1),
657 SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL,
658 RT5631_M_MIC1P_SPKMIXL_BIT, 1, 1),
659 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL,
660 RT5631_M_DACL_SPKMIXL_BIT, 1, 1),
661 SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
662 RT5631_M_OUTMIXL_SPKMIXL_BIT, 1, 1),
663};
664
665static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
666 SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
667 RT5631_M_OUTMIXR_SPKMIXR_BIT, 1, 1),
668 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL,
669 RT5631_M_DACR_SPKMIXR_BIT, 1, 1),
670 SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL,
671 RT5631_M_MIC2P_SPKMIXR_BIT, 1, 1),
672 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
673 RT5631_M_RECMIXR_SPKMIXR_BIT, 1, 1),
674};
675
676static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
677 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL,
678 RT5631_M_RECMIXL_OUTMIXL_BIT, 1, 1),
679 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL,
680 RT5631_M_RECMIXR_OUTMIXL_BIT, 1, 1),
681 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL,
682 RT5631_M_DACL_OUTMIXL_BIT, 1, 1),
683 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL,
684 RT5631_M_MIC1_OUTMIXL_BIT, 1, 1),
685 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL,
686 RT5631_M_MIC2_OUTMIXL_BIT, 1, 1),
687 SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL,
688 RT5631_M_MONO_INP_OUTMIXL_BIT, 1, 1),
689 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
690 RT5631_M_AXIL_OUTMIXL_BIT, 1, 1),
691 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
692 RT5631_M_AXIR_OUTMIXL_BIT, 1, 1),
693 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL,
694 RT5631_M_VDAC_OUTMIXL_BIT, 1, 1),
695};
696
697static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
698 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL,
699 RT5631_M_VDAC_OUTMIXR_BIT, 1, 1),
700 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
701 RT5631_M_AXIR_OUTMIXR_BIT, 1, 1),
702 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
703 RT5631_M_AXIL_OUTMIXR_BIT, 1, 1),
704 SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL,
705 RT5631_M_MONO_INN_OUTMIXR_BIT, 1, 1),
706 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL,
707 RT5631_M_MIC2_OUTMIXR_BIT, 1, 1),
708 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL,
709 RT5631_M_MIC1_OUTMIXR_BIT, 1, 1),
710 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL,
711 RT5631_M_DACR_OUTMIXR_BIT, 1, 1),
712 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL,
713 RT5631_M_RECMIXR_OUTMIXR_BIT, 1, 1),
714 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL,
715 RT5631_M_RECMIXL_OUTMIXR_BIT, 1, 1),
716};
717
718static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
719 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL,
720 RT5631_M_MIC1_AXO1MIX_BIT , 1, 1),
721 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL,
722 RT5631_M_MIC2_AXO1MIX_BIT, 1, 1),
723 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL,
724 RT5631_M_OUTMIXL_AXO1MIX_BIT , 1 , 1),
725 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL,
726 RT5631_M_OUTMIXR_AXO1MIX_BIT, 1, 1),
727};
728
729static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
730 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL,
731 RT5631_M_MIC1_AXO2MIX_BIT, 1, 1),
732 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL,
733 RT5631_M_MIC2_AXO2MIX_BIT, 1, 1),
734 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL,
735 RT5631_M_OUTMIXL_AXO2MIX_BIT, 1, 1),
736 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL,
737 RT5631_M_OUTMIXR_AXO2MIX_BIT, 1 , 1),
738};
739
740static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
741 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
742 RT5631_M_SPKVOLL_SPOLMIX_BIT, 1, 1),
743 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
744 RT5631_M_SPKVOLR_SPOLMIX_BIT, 1, 1),
745};
746
747static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
748 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
749 RT5631_M_SPKVOLL_SPORMIX_BIT, 1, 1),
750 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
751 RT5631_M_SPKVOLR_SPORMIX_BIT, 1, 1),
752};
753
754static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
755 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
756 RT5631_M_OUTVOLL_MONOMIX_BIT, 1, 1),
757 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
758 RT5631_M_OUTVOLR_MONOMIX_BIT, 1, 1),
759};
760
761/* Left SPK Volume Input */
762static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"};
763
764static const SOC_ENUM_SINGLE_DECL(
765 rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL,
766 RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
767
768static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
769 SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum);
770
771/* Left HP Volume Input */
772static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"};
773
774static const SOC_ENUM_SINGLE_DECL(
775 rt5631_hpvoll_enum, RT5631_HP_OUT_VOL,
776 RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
777
778static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
779 SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum);
780
781/* Left Out Volume Input */
782static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"};
783
784static const SOC_ENUM_SINGLE_DECL(
785 rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL,
786 RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
787
788static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
789 SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum);
790
791/* Right Out Volume Input */
792static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"};
793
794static const SOC_ENUM_SINGLE_DECL(
795 rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL,
796 RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
797
798static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
799 SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum);
800
801/* Right HP Volume Input */
802static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"};
803
804static const SOC_ENUM_SINGLE_DECL(
805 rt5631_hpvolr_enum, RT5631_HP_OUT_VOL,
806 RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
807
808static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
809 SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum);
810
811/* Right SPK Volume Input */
812static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"};
813
814static const SOC_ENUM_SINGLE_DECL(
815 rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL,
816 RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
817
818static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
819 SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum);
820
821/* SPO Left Channel Input */
822static const char *rt5631_spol_src_sel[] = {
823 "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
824
825static const SOC_ENUM_SINGLE_DECL(
826 rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
827 RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
828
829static const struct snd_kcontrol_new rt5631_spol_mux_control =
830 SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum);
831
832/* SPO Right Channel Input */
833static const char *rt5631_spor_src_sel[] = {
834 "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
835
836static const SOC_ENUM_SINGLE_DECL(
837 rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
838 RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
839
840static const struct snd_kcontrol_new rt5631_spor_mux_control =
841 SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum);
842
843/* MONO Input */
844static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
845
846static const SOC_ENUM_SINGLE_DECL(
847 rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
848 RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
849
850static const struct snd_kcontrol_new rt5631_mono_mux_control =
851 SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum);
852
853/* Left HPO Input */
854static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"};
855
856static const SOC_ENUM_SINGLE_DECL(
857 rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
858 RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
859
860static const struct snd_kcontrol_new rt5631_hpl_mux_control =
861 SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum);
862
863/* Right HPO Input */
864static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"};
865
866static const SOC_ENUM_SINGLE_DECL(
867 rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
868 RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
869
870static const struct snd_kcontrol_new rt5631_hpr_mux_control =
871 SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum);
872
873static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = {
874 /* Vmid */
875 SND_SOC_DAPM_VMID("Vmid"),
876 /* PLL1 */
877 SND_SOC_DAPM_SUPPLY("PLL1", RT5631_PWR_MANAG_ADD2,
878 RT5631_PWR_PLL1_BIT, 0, NULL, 0),
879
880 /* Input Side */
881 /* Input Lines */
882 SND_SOC_DAPM_INPUT("MIC1"),
883 SND_SOC_DAPM_INPUT("MIC2"),
884 SND_SOC_DAPM_INPUT("AXIL"),
885 SND_SOC_DAPM_INPUT("AXIR"),
886 SND_SOC_DAPM_INPUT("MONOIN_RXN"),
887 SND_SOC_DAPM_INPUT("MONOIN_RXP"),
888 SND_SOC_DAPM_INPUT("DMIC"),
889
890 /* MICBIAS */
891 SND_SOC_DAPM_MICBIAS("MIC Bias1", RT5631_PWR_MANAG_ADD2,
892 RT5631_PWR_MICBIAS1_VOL_BIT, 0),
893 SND_SOC_DAPM_MICBIAS("MIC Bias2", RT5631_PWR_MANAG_ADD2,
894 RT5631_PWR_MICBIAS2_VOL_BIT, 0),
895
896 /* Boost */
897 SND_SOC_DAPM_PGA("MIC1 Boost", RT5631_PWR_MANAG_ADD2,
898 RT5631_PWR_MIC1_BOOT_GAIN_BIT, 0, NULL, 0),
899 SND_SOC_DAPM_PGA("MIC2 Boost", RT5631_PWR_MANAG_ADD2,
900 RT5631_PWR_MIC2_BOOT_GAIN_BIT, 0, NULL, 0),
901 SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4,
902 RT5631_PWR_MONO_IN_P_VOL_BIT, 0, NULL, 0),
903 SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4,
904 RT5631_PWR_MONO_IN_N_VOL_BIT, 0, NULL, 0),
905 SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4,
906 RT5631_PWR_AXIL_IN_VOL_BIT, 0, NULL, 0),
907 SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4,
908 RT5631_PWR_AXIR_IN_VOL_BIT, 0, NULL, 0),
909
910 /* MONO In */
911 SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
912
913 /* REC Mixer */
914 SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2,
915 RT5631_PWR_RECMIXER_L_BIT, 0,
916 &rt5631_recmixl_mixer_controls[0],
917 ARRAY_SIZE(rt5631_recmixl_mixer_controls)),
918 SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2,
919 RT5631_PWR_RECMIXER_R_BIT, 0,
920 &rt5631_recmixr_mixer_controls[0],
921 ARRAY_SIZE(rt5631_recmixr_mixer_controls)),
922 /* Because of record duplication for L/R channel,
923 * L/R ADCs need power up at the same time */
924 SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
925
926 /* DMIC */
927 SND_SOC_DAPM_SUPPLY("DMIC Supply", RT5631_DIG_MIC_CTRL,
928 RT5631_DMIC_ENA_SHIFT, 0,
929 set_dmic_params, SND_SOC_DAPM_PRE_PMU),
930 /* ADC Data Srouce */
931 SND_SOC_DAPM_SUPPLY("Left ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
932 RT5631_ADC_DATA_SEL_MIC1_SHIFT, 0, NULL, 0),
933 SND_SOC_DAPM_SUPPLY("Right ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
934 RT5631_ADC_DATA_SEL_MIC2_SHIFT, 0, NULL, 0),
935
936 /* ADCs */
937 SND_SOC_DAPM_ADC("Left ADC", "HIFI Capture",
938 RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_L_CLK_BIT, 0),
939 SND_SOC_DAPM_ADC("Right ADC", "HIFI Capture",
940 RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_R_CLK_BIT, 0),
941
942 /* DAC and ADC supply power */
943 SND_SOC_DAPM_SUPPLY("I2S", RT5631_PWR_MANAG_ADD1,
944 RT5631_PWR_MAIN_I2S_BIT, 0, NULL, 0),
945 SND_SOC_DAPM_SUPPLY("DAC REF", RT5631_PWR_MANAG_ADD1,
946 RT5631_PWR_DAC_REF_BIT, 0, NULL, 0),
947
948 /* Output Side */
949 /* DACs */
950 SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback",
951 RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_L_CLK_BIT, 0),
952 SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback",
953 RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_R_CLK_BIT, 0),
954 SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback",
955 SND_SOC_NOPM, 0, 0),
956 SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
957 /* DAC supply power */
958 SND_SOC_DAPM_SUPPLY("Left DAC To Mixer", RT5631_PWR_MANAG_ADD1,
959 RT5631_PWR_DAC_L_TO_MIXER_BIT, 0, NULL, 0),
960 SND_SOC_DAPM_SUPPLY("Right DAC To Mixer", RT5631_PWR_MANAG_ADD1,
961 RT5631_PWR_DAC_R_TO_MIXER_BIT, 0, NULL, 0),
962
963 /* Left SPK Mixer */
964 SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2,
965 RT5631_PWR_SPKMIXER_L_BIT, 0,
966 &rt5631_spkmixl_mixer_controls[0],
967 ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
968 /* Left Out Mixer */
969 SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2,
970 RT5631_PWR_OUTMIXER_L_BIT, 0,
971 &rt5631_outmixl_mixer_controls[0],
972 ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
973 /* Right Out Mixer */
974 SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2,
975 RT5631_PWR_OUTMIXER_R_BIT, 0,
976 &rt5631_outmixr_mixer_controls[0],
977 ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
978 /* Right SPK Mixer */
979 SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2,
980 RT5631_PWR_SPKMIXER_R_BIT, 0,
981 &rt5631_spkmixr_mixer_controls[0],
982 ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
983
984 /* Volume Mux */
985 SND_SOC_DAPM_MUX("Left SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
986 RT5631_PWR_SPK_L_VOL_BIT, 0,
987 &rt5631_spkvoll_mux_control),
988 SND_SOC_DAPM_MUX("Left HPVOL Mux", RT5631_PWR_MANAG_ADD4,
989 RT5631_PWR_HP_L_OUT_VOL_BIT, 0,
990 &rt5631_hpvoll_mux_control),
991 SND_SOC_DAPM_MUX("Left OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
992 RT5631_PWR_LOUT_VOL_BIT, 0,
993 &rt5631_outvoll_mux_control),
994 SND_SOC_DAPM_MUX("Right OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
995 RT5631_PWR_ROUT_VOL_BIT, 0,
996 &rt5631_outvolr_mux_control),
997 SND_SOC_DAPM_MUX("Right HPVOL Mux", RT5631_PWR_MANAG_ADD4,
998 RT5631_PWR_HP_R_OUT_VOL_BIT, 0,
999 &rt5631_hpvolr_mux_control),
1000 SND_SOC_DAPM_MUX("Right SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
1001 RT5631_PWR_SPK_R_VOL_BIT, 0,
1002 &rt5631_spkvolr_mux_control),
1003
1004 /* DAC To HP */
1005 SND_SOC_DAPM_PGA_S("Left DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
1006 SND_SOC_DAPM_PGA_S("Right DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
1007
1008 /* HP Depop */
1009 SND_SOC_DAPM_PGA_S("HP Depop", 1, SND_SOC_NOPM, 0, 0,
1010 hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1011
1012 /* AXO1 Mixer */
1013 SND_SOC_DAPM_MIXER("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3,
1014 RT5631_PWR_AXO1MIXER_BIT, 0,
1015 &rt5631_AXO1MIX_mixer_controls[0],
1016 ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls)),
1017 /* SPOL Mixer */
1018 SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
1019 &rt5631_spolmix_mixer_controls[0],
1020 ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
1021 /* MONO Mixer */
1022 SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3,
1023 RT5631_PWR_MONOMIXER_BIT, 0,
1024 &rt5631_monomix_mixer_controls[0],
1025 ARRAY_SIZE(rt5631_monomix_mixer_controls)),
1026 /* SPOR Mixer */
1027 SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
1028 &rt5631_spormix_mixer_controls[0],
1029 ARRAY_SIZE(rt5631_spormix_mixer_controls)),
1030 /* AXO2 Mixer */
1031 SND_SOC_DAPM_MIXER("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3,
1032 RT5631_PWR_AXO2MIXER_BIT, 0,
1033 &rt5631_AXO2MIX_mixer_controls[0],
1034 ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls)),
1035
1036 /* Mux */
1037 SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0,
1038 &rt5631_spol_mux_control),
1039 SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0,
1040 &rt5631_spor_mux_control),
1041 SND_SOC_DAPM_MUX("MONO Mux", SND_SOC_NOPM, 0, 0,
1042 &rt5631_mono_mux_control),
1043 SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0,
1044 &rt5631_hpl_mux_control),
1045 SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0,
1046 &rt5631_hpr_mux_control),
1047
1048 /* AMP supply */
1049 SND_SOC_DAPM_SUPPLY("MONO Depop", RT5631_PWR_MANAG_ADD3,
1050 RT5631_PWR_MONO_DEPOP_DIS_BIT, 0, NULL, 0),
1051 SND_SOC_DAPM_SUPPLY("Class D", RT5631_PWR_MANAG_ADD1,
1052 RT5631_PWR_CLASS_D_BIT, 0, NULL, 0),
1053
1054 /* Output Lines */
1055 SND_SOC_DAPM_OUTPUT("AUXO1"),
1056 SND_SOC_DAPM_OUTPUT("AUXO2"),
1057 SND_SOC_DAPM_OUTPUT("SPOL"),
1058 SND_SOC_DAPM_OUTPUT("SPOR"),
1059 SND_SOC_DAPM_OUTPUT("HPOL"),
1060 SND_SOC_DAPM_OUTPUT("HPOR"),
1061 SND_SOC_DAPM_OUTPUT("MONO"),
1062};
1063
1064static const struct snd_soc_dapm_route rt5631_dapm_routes[] = {
1065 {"MIC1 Boost", NULL, "MIC1"},
1066 {"MIC2 Boost", NULL, "MIC2"},
1067 {"MONOIN_RXP Boost", NULL, "MONOIN_RXP"},
1068 {"MONOIN_RXN Boost", NULL, "MONOIN_RXN"},
1069 {"AXIL Boost", NULL, "AXIL"},
1070 {"AXIR Boost", NULL, "AXIR"},
1071
1072 {"MONO_IN", NULL, "MONOIN_RXP Boost"},
1073 {"MONO_IN", NULL, "MONOIN_RXN Boost"},
1074
1075 {"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"},
1076 {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "MIC1 Boost"},
1077 {"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"},
1078 {"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
1079
1080 {"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"},
1081 {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "MIC2 Boost"},
1082 {"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"},
1083 {"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
1084
1085 {"ADC Mixer", NULL, "RECMIXL Mixer"},
1086 {"ADC Mixer", NULL, "RECMIXR Mixer"},
1087
1088 {"Left ADC", NULL, "ADC Mixer"},
1089 {"Left ADC", NULL, "Left ADC Select", check_adcl_select},
1090 {"Left ADC", NULL, "PLL1", check_sysclk1_source},
1091 {"Left ADC", NULL, "I2S"},
1092 {"Left ADC", NULL, "DAC REF"},
1093
1094 {"Right ADC", NULL, "ADC Mixer"},
1095 {"Right ADC", NULL, "Right ADC Select", check_adcr_select},
1096 {"Right ADC", NULL, "PLL1", check_sysclk1_source},
1097 {"Right ADC", NULL, "I2S"},
1098 {"Right ADC", NULL, "DAC REF"},
1099
1100 {"DMIC", NULL, "DMIC Supply", check_dmic_used},
1101 {"Left ADC", NULL, "DMIC"},
1102 {"Right ADC", NULL, "DMIC"},
1103
1104 {"Left DAC", NULL, "PLL1", check_sysclk1_source},
1105 {"Left DAC", NULL, "I2S"},
1106 {"Left DAC", NULL, "DAC REF"},
1107 {"Right DAC", NULL, "PLL1", check_sysclk1_source},
1108 {"Right DAC", NULL, "I2S"},
1109 {"Right DAC", NULL, "DAC REF"},
1110
1111 {"Voice DAC Boost", NULL, "Voice DAC"},
1112
1113 {"SPKMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_spkmixl},
1114 {"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1115 {"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"},
1116 {"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"},
1117 {"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"},
1118
1119 {"SPKMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_spkmixr},
1120 {"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"},
1121 {"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"},
1122 {"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"},
1123 {"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1124
1125 {"OUTMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_outmixl},
1126 {"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1127 {"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1128 {"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"},
1129 {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1130 {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1131 {"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"},
1132 {"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
1133 {"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
1134 {"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
1135
1136 {"OUTMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_outmixr},
1137 {"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1138 {"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1139 {"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"},
1140 {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1141 {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1142 {"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"},
1143 {"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
1144 {"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
1145 {"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
1146
1147 {"Left SPKVOL Mux", "SPKMIXL", "SPKMIXL Mixer"},
1148 {"Left SPKVOL Mux", "Vmid", "Vmid"},
1149 {"Left HPVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
1150 {"Left HPVOL Mux", "Vmid", "Vmid"},
1151 {"Left OUTVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
1152 {"Left OUTVOL Mux", "Vmid", "Vmid"},
1153 {"Right OUTVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
1154 {"Right OUTVOL Mux", "Vmid", "Vmid"},
1155 {"Right HPVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
1156 {"Right HPVOL Mux", "Vmid", "Vmid"},
1157 {"Right SPKVOL Mux", "SPKMIXR", "SPKMIXR Mixer"},
1158 {"Right SPKVOL Mux", "Vmid", "Vmid"},
1159
1160 {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1161 {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1162 {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1163 {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1164
1165 {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1166 {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1167 {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1168 {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1169
1170 {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
1171 {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
1172
1173 {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
1174 {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
1175
1176 {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1177 {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1178
1179 {"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"},
1180 {"SPOL Mux", "MONOIN_RX", "MONO_IN"},
1181 {"SPOL Mux", "VDAC", "Voice DAC Boost"},
1182 {"SPOL Mux", "DACL", "Left DAC"},
1183
1184 {"SPOR Mux", "SPORMIX", "SPORMIX Mixer"},
1185 {"SPOR Mux", "MONOIN_RX", "MONO_IN"},
1186 {"SPOR Mux", "VDAC", "Voice DAC Boost"},
1187 {"SPOR Mux", "DACR", "Right DAC"},
1188
1189 {"MONO Mux", "MONOMIX", "MONOMIX Mixer"},
1190 {"MONO Mux", "MONOIN_RX", "MONO_IN"},
1191 {"MONO Mux", "VDAC", "Voice DAC Boost"},
1192
1193 {"Right DAC_HP", NULL, "Right DAC"},
1194 {"Left DAC_HP", NULL, "Left DAC"},
1195
1196 {"HPL Mux", "Left HPVOL", "Left HPVOL Mux"},
1197 {"HPL Mux", "Left DAC", "Left DAC_HP"},
1198 {"HPR Mux", "Right HPVOL", "Right HPVOL Mux"},
1199 {"HPR Mux", "Right DAC", "Right DAC_HP"},
1200
1201 {"HP Depop", NULL, "HPL Mux"},
1202 {"HP Depop", NULL, "HPR Mux"},
1203
1204 {"AUXO1", NULL, "AXO1MIX Mixer"},
1205 {"AUXO2", NULL, "AXO2MIX Mixer"},
1206
1207 {"SPOL", NULL, "Class D"},
1208 {"SPOL", NULL, "SPOL Mux"},
1209 {"SPOR", NULL, "Class D"},
1210 {"SPOR", NULL, "SPOR Mux"},
1211
1212 {"HPOL", NULL, "HP Depop"},
1213 {"HPOR", NULL, "HP Depop"},
1214
1215 {"MONO", NULL, "MONO Depop"},
1216 {"MONO", NULL, "MONO Mux"},
1217};
1218
1219struct coeff_clk_div {
1220 u32 mclk;
1221 u32 bclk;
1222 u32 rate;
1223 u16 reg_val;
1224};
1225
1226/* PLL divisors */
1227struct pll_div {
1228 u32 pll_in;
1229 u32 pll_out;
1230 u16 reg_val;
1231};
1232
1233static const struct pll_div codec_master_pll_div[] = {
1234 {2048000, 8192000, 0x0ea0},
1235 {3686400, 8192000, 0x4e27},
1236 {12000000, 8192000, 0x456b},
1237 {13000000, 8192000, 0x495f},
1238 {13100000, 8192000, 0x0320},
1239 {2048000, 11289600, 0xf637},
1240 {3686400, 11289600, 0x2f22},
1241 {12000000, 11289600, 0x3e2f},
1242 {13000000, 11289600, 0x4d5b},
1243 {13100000, 11289600, 0x363b},
1244 {2048000, 16384000, 0x1ea0},
1245 {3686400, 16384000, 0x9e27},
1246 {12000000, 16384000, 0x452b},
1247 {13000000, 16384000, 0x542f},
1248 {13100000, 16384000, 0x03a0},
1249 {2048000, 16934400, 0xe625},
1250 {3686400, 16934400, 0x9126},
1251 {12000000, 16934400, 0x4d2c},
1252 {13000000, 16934400, 0x742f},
1253 {13100000, 16934400, 0x3c27},
1254 {2048000, 22579200, 0x2aa0},
1255 {3686400, 22579200, 0x2f20},
1256 {12000000, 22579200, 0x7e2f},
1257 {13000000, 22579200, 0x742f},
1258 {13100000, 22579200, 0x3c27},
1259 {2048000, 24576000, 0x2ea0},
1260 {3686400, 24576000, 0xee27},
1261 {12000000, 24576000, 0x2915},
1262 {13000000, 24576000, 0x772e},
1263 {13100000, 24576000, 0x0d20},
1264 {26000000, 24576000, 0x2027},
1265 {26000000, 22579200, 0x392f},
1266 {24576000, 22579200, 0x0921},
1267 {24576000, 24576000, 0x02a0},
1268};
1269
1270static const struct pll_div codec_slave_pll_div[] = {
1271 {256000, 2048000, 0x46f0},
1272 {256000, 4096000, 0x3ea0},
1273 {352800, 5644800, 0x3ea0},
1274 {512000, 8192000, 0x3ea0},
1275 {1024000, 8192000, 0x46f0},
1276 {705600, 11289600, 0x3ea0},
1277 {1024000, 16384000, 0x3ea0},
1278 {1411200, 22579200, 0x3ea0},
1279 {1536000, 24576000, 0x3ea0},
1280 {2048000, 16384000, 0x1ea0},
1281 {2822400, 22579200, 0x1ea0},
1282 {2822400, 45158400, 0x5ec0},
1283 {5644800, 45158400, 0x46f0},
1284 {3072000, 24576000, 0x1ea0},
1285 {3072000, 49152000, 0x5ec0},
1286 {6144000, 49152000, 0x46f0},
1287 {705600, 11289600, 0x3ea0},
1288 {705600, 8467200, 0x3ab0},
1289 {24576000, 24576000, 0x02a0},
1290 {1411200, 11289600, 0x1690},
1291 {2822400, 11289600, 0x0a90},
1292 {1536000, 12288000, 0x1690},
1293 {3072000, 12288000, 0x0a90},
1294};
1295
1296static struct coeff_clk_div coeff_div[] = {
1297 /* sysclk is 256fs */
1298 {2048000, 8000 * 32, 8000, 0x1000},
1299 {2048000, 8000 * 64, 8000, 0x0000},
1300 {2822400, 11025 * 32, 11025, 0x1000},
1301 {2822400, 11025 * 64, 11025, 0x0000},
1302 {4096000, 16000 * 32, 16000, 0x1000},
1303 {4096000, 16000 * 64, 16000, 0x0000},
1304 {5644800, 22050 * 32, 22050, 0x1000},
1305 {5644800, 22050 * 64, 22050, 0x0000},
1306 {8192000, 32000 * 32, 32000, 0x1000},
1307 {8192000, 32000 * 64, 32000, 0x0000},
1308 {11289600, 44100 * 32, 44100, 0x1000},
1309 {11289600, 44100 * 64, 44100, 0x0000},
1310 {12288000, 48000 * 32, 48000, 0x1000},
1311 {12288000, 48000 * 64, 48000, 0x0000},
1312 {22579200, 88200 * 32, 88200, 0x1000},
1313 {22579200, 88200 * 64, 88200, 0x0000},
1314 {24576000, 96000 * 32, 96000, 0x1000},
1315 {24576000, 96000 * 64, 96000, 0x0000},
1316 /* sysclk is 512fs */
1317 {4096000, 8000 * 32, 8000, 0x3000},
1318 {4096000, 8000 * 64, 8000, 0x2000},
1319 {5644800, 11025 * 32, 11025, 0x3000},
1320 {5644800, 11025 * 64, 11025, 0x2000},
1321 {8192000, 16000 * 32, 16000, 0x3000},
1322 {8192000, 16000 * 64, 16000, 0x2000},
1323 {11289600, 22050 * 32, 22050, 0x3000},
1324 {11289600, 22050 * 64, 22050, 0x2000},
1325 {16384000, 32000 * 32, 32000, 0x3000},
1326 {16384000, 32000 * 64, 32000, 0x2000},
1327 {22579200, 44100 * 32, 44100, 0x3000},
1328 {22579200, 44100 * 64, 44100, 0x2000},
1329 {24576000, 48000 * 32, 48000, 0x3000},
1330 {24576000, 48000 * 64, 48000, 0x2000},
1331 {45158400, 88200 * 32, 88200, 0x3000},
1332 {45158400, 88200 * 64, 88200, 0x2000},
1333 {49152000, 96000 * 32, 96000, 0x3000},
1334 {49152000, 96000 * 64, 96000, 0x2000},
1335 /* sysclk is 24.576Mhz or 22.5792Mhz */
1336 {24576000, 8000 * 32, 8000, 0x7080},
1337 {24576000, 8000 * 64, 8000, 0x6080},
1338 {24576000, 16000 * 32, 16000, 0x5080},
1339 {24576000, 16000 * 64, 16000, 0x4080},
1340 {24576000, 24000 * 32, 24000, 0x5000},
1341 {24576000, 24000 * 64, 24000, 0x4000},
1342 {24576000, 32000 * 32, 32000, 0x3080},
1343 {24576000, 32000 * 64, 32000, 0x2080},
1344 {22579200, 11025 * 32, 11025, 0x7000},
1345 {22579200, 11025 * 64, 11025, 0x6000},
1346 {22579200, 22050 * 32, 22050, 0x5000},
1347 {22579200, 22050 * 64, 22050, 0x4000},
1348};
1349
1350static int get_coeff(int mclk, int rate, int timesofbclk)
1351{
1352 int i;
1353
1354 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
1355 if (coeff_div[i].mclk == mclk && coeff_div[i].rate == rate &&
1356 (coeff_div[i].bclk / coeff_div[i].rate) == timesofbclk)
1357 return i;
1358 }
1359 return -EINVAL;
1360}
1361
1362static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
1363 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1364{
1365 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1366 struct snd_soc_codec *codec = rtd->codec;
1367 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1368 int timesofbclk = 32, coeff;
1369 unsigned int iface = 0;
1370
1371 dev_dbg(codec->dev, "enter %s\n", __func__);
1372
1373 rt5631->bclk_rate = snd_soc_params_to_bclk(params);
1374 if (rt5631->bclk_rate < 0) {
1375 dev_err(codec->dev, "Fail to get BCLK rate\n");
1376 return rt5631->bclk_rate;
1377 }
1378 rt5631->rx_rate = params_rate(params);
1379
1380 if (rt5631->master)
1381 coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
1382 rt5631->bclk_rate / rt5631->rx_rate);
1383 else
1384 coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
1385 timesofbclk);
1386 if (coeff < 0) {
1387 dev_err(codec->dev, "Fail to get coeff\n");
1388 return -EINVAL;
1389 }
1390
1391 switch (params_format(params)) {
1392 case SNDRV_PCM_FORMAT_S16_LE:
1393 break;
1394 case SNDRV_PCM_FORMAT_S20_3LE:
1395 iface |= RT5631_SDP_I2S_DL_20;
1396 break;
1397 case SNDRV_PCM_FORMAT_S24_LE:
1398 iface |= RT5631_SDP_I2S_DL_24;
1399 break;
1400 case SNDRV_PCM_FORMAT_S8:
1401 iface |= RT5631_SDP_I2S_DL_8;
1402 break;
1403 default:
1404 return -EINVAL;
1405 }
1406
1407 snd_soc_update_bits(codec, RT5631_SDP_CTRL,
1408 RT5631_SDP_I2S_DL_MASK, iface);
1409 snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
1410 coeff_div[coeff].reg_val);
1411
1412 return 0;
1413}
1414
1415static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
1416 unsigned int fmt)
1417{
1418 struct snd_soc_codec *codec = codec_dai->codec;
1419 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1420 unsigned int iface = 0;
1421
1422 dev_dbg(codec->dev, "enter %s\n", __func__);
1423
1424 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1425 case SND_SOC_DAIFMT_CBM_CFM:
1426 rt5631->master = 1;
1427 break;
1428 case SND_SOC_DAIFMT_CBS_CFS:
1429 iface |= RT5631_SDP_MODE_SEL_SLAVE;
1430 rt5631->master = 0;
1431 break;
1432 default:
1433 return -EINVAL;
1434 }
1435
1436 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1437 case SND_SOC_DAIFMT_I2S:
1438 break;
1439 case SND_SOC_DAIFMT_LEFT_J:
1440 iface |= RT5631_SDP_I2S_DF_LEFT;
1441 break;
1442 case SND_SOC_DAIFMT_DSP_A:
1443 iface |= RT5631_SDP_I2S_DF_PCM_A;
1444 break;
1445 case SND_SOC_DAIFMT_DSP_B:
1446 iface |= RT5631_SDP_I2S_DF_PCM_B;
1447 break;
1448 default:
1449 return -EINVAL;
1450 }
1451
1452 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1453 case SND_SOC_DAIFMT_NB_NF:
1454 break;
1455 case SND_SOC_DAIFMT_IB_NF:
1456 iface |= RT5631_SDP_I2S_BCLK_POL_CTRL;
1457 break;
1458 default:
1459 return -EINVAL;
1460 }
1461
1462 snd_soc_write(codec, RT5631_SDP_CTRL, iface);
1463
1464 return 0;
1465}
1466
1467static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1468 int clk_id, unsigned int freq, int dir)
1469{
1470 struct snd_soc_codec *codec = codec_dai->codec;
1471 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1472
1473 dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
1474
1475 if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
1476 rt5631->sysclk = freq;
1477 return 0;
1478 }
1479
1480 return -EINVAL;
1481}
1482
1483static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1484 int source, unsigned int freq_in, unsigned int freq_out)
1485{
1486 struct snd_soc_codec *codec = codec_dai->codec;
1487 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1488 int i, ret = -EINVAL;
1489
1490 dev_dbg(codec->dev, "enter %s\n", __func__);
1491
1492 if (!freq_in || !freq_out) {
1493 dev_dbg(codec->dev, "PLL disabled\n");
1494
1495 snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
1496 RT5631_SYSCLK_SOUR_SEL_MASK,
1497 RT5631_SYSCLK_SOUR_SEL_MCLK);
1498
1499 return 0;
1500 }
1501
1502 if (rt5631->master) {
1503 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
1504 if (freq_in == codec_master_pll_div[i].pll_in &&
1505 freq_out == codec_master_pll_div[i].pll_out) {
1506 dev_info(codec->dev,
1507 "change PLL in master mode\n");
1508 snd_soc_write(codec, RT5631_PLL_CTRL,
1509 codec_master_pll_div[i].reg_val);
1510 schedule_timeout_uninterruptible(
1511 msecs_to_jiffies(20));
1512 snd_soc_update_bits(codec,
1513 RT5631_GLOBAL_CLK_CTRL,
1514 RT5631_SYSCLK_SOUR_SEL_MASK |
1515 RT5631_PLLCLK_SOUR_SEL_MASK,
1516 RT5631_SYSCLK_SOUR_SEL_PLL |
1517 RT5631_PLLCLK_SOUR_SEL_MCLK);
1518 ret = 0;
1519 break;
1520 }
1521 } else {
1522 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
1523 if (freq_in == codec_slave_pll_div[i].pll_in &&
1524 freq_out == codec_slave_pll_div[i].pll_out) {
1525 dev_info(codec->dev,
1526 "change PLL in slave mode\n");
1527 snd_soc_write(codec, RT5631_PLL_CTRL,
1528 codec_slave_pll_div[i].reg_val);
1529 schedule_timeout_uninterruptible(
1530 msecs_to_jiffies(20));
1531 snd_soc_update_bits(codec,
1532 RT5631_GLOBAL_CLK_CTRL,
1533 RT5631_SYSCLK_SOUR_SEL_MASK |
1534 RT5631_PLLCLK_SOUR_SEL_MASK,
1535 RT5631_SYSCLK_SOUR_SEL_PLL |
1536 RT5631_PLLCLK_SOUR_SEL_BCLK);
1537 ret = 0;
1538 break;
1539 }
1540 }
1541
1542 return ret;
1543}
1544
1545static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1546 enum snd_soc_bias_level level)
1547{
1548 switch (level) {
1549 case SND_SOC_BIAS_ON:
1550 case SND_SOC_BIAS_PREPARE:
1551 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
1552 RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
1553 RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
1554 break;
1555
1556 case SND_SOC_BIAS_STANDBY:
1557 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1558 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1559 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
1560 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
1561 msleep(80);
1562 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1563 RT5631_PWR_FAST_VREF_CTRL,
1564 RT5631_PWR_FAST_VREF_CTRL);
1565 codec->cache_only = false;
1566 snd_soc_cache_sync(codec);
1567 }
1568 break;
1569
1570 case SND_SOC_BIAS_OFF:
1571 snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
1572 snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
1573 snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
1574 snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
1575 break;
1576
1577 default:
1578 break;
1579 }
1580 codec->dapm.bias_level = level;
1581
1582 return 0;
1583}
1584
1585static int rt5631_probe(struct snd_soc_codec *codec)
1586{
1587 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1588 unsigned int val;
1589 int ret;
1590
1591 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1592 if (ret != 0) {
1593 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1594 return ret;
1595 }
1596
1597 val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
1598 if (val & 0x0002)
1599 rt5631->codec_version = 1;
1600 else
1601 rt5631->codec_version = 0;
1602
1603 rt5631_reset(codec);
1604 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1605 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
1606 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
1607 msleep(80);
1608 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1609 RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
1610 /* enable HP zero cross */
1611 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
1612 /* power off ClassD auto Recovery */
1613 if (rt5631->codec_version)
1614 snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
1615 0x2000, 0x2000);
1616 else
1617 snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
1618 0x2000, 0);
1619 /* DMIC */
1620 if (rt5631->dmic_used_flag) {
1621 snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
1622 RT5631_GPIO_PIN_FUN_SEL_MASK |
1623 RT5631_GPIO_DMIC_FUN_SEL_MASK,
1624 RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
1625 RT5631_GPIO_DMIC_FUN_SEL_DIMC);
1626 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
1627 RT5631_DMIC_L_CH_LATCH_MASK |
1628 RT5631_DMIC_R_CH_LATCH_MASK,
1629 RT5631_DMIC_L_CH_LATCH_FALLING |
1630 RT5631_DMIC_R_CH_LATCH_RISING);
1631 }
1632
1633 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
1634
1635 return 0;
1636}
1637
1638static int rt5631_remove(struct snd_soc_codec *codec)
1639{
1640 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
1641 return 0;
1642}
1643
1644#ifdef CONFIG_PM
1645static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state)
1646{
1647 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
1648 return 0;
1649}
1650
1651static int rt5631_resume(struct snd_soc_codec *codec)
1652{
1653 rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1654 return 0;
1655}
1656#else
1657#define rt5631_suspend NULL
1658#define rt5631_resume NULL
1659#endif
1660
1661#define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000
1662#define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
1663 SNDRV_PCM_FMTBIT_S20_3LE | \
1664 SNDRV_PCM_FMTBIT_S24_LE | \
1665 SNDRV_PCM_FMTBIT_S8)
1666
1667static struct snd_soc_dai_ops rt5631_ops = {
1668 .hw_params = rt5631_hifi_pcm_params,
1669 .set_fmt = rt5631_hifi_codec_set_dai_fmt,
1670 .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
1671 .set_pll = rt5631_codec_set_dai_pll,
1672};
1673
1674static struct snd_soc_dai_driver rt5631_dai[] = {
1675 {
1676 .name = "rt5631-hifi",
1677 .id = 1,
1678 .playback = {
1679 .stream_name = "HIFI Playback",
1680 .channels_min = 1,
1681 .channels_max = 2,
1682 .rates = RT5631_STEREO_RATES,
1683 .formats = RT5631_FORMAT,
1684 },
1685 .capture = {
1686 .stream_name = "HIFI Capture",
1687 .channels_min = 1,
1688 .channels_max = 2,
1689 .rates = RT5631_STEREO_RATES,
1690 .formats = RT5631_FORMAT,
1691 },
1692 .ops = &rt5631_ops,
1693 },
1694};
1695
1696static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
1697 .probe = rt5631_probe,
1698 .remove = rt5631_remove,
1699 .suspend = rt5631_suspend,
1700 .resume = rt5631_resume,
1701 .set_bias_level = rt5631_set_bias_level,
1702 .reg_cache_size = RT5631_VENDOR_ID2 + 1,
1703 .reg_word_size = sizeof(u16),
1704 .reg_cache_default = rt5631_reg,
1705 .volatile_register = rt5631_volatile_register,
1706 .readable_register = rt5631_readable_register,
1707 .reg_cache_step = 1,
1708 .controls = rt5631_snd_controls,
1709 .num_controls = ARRAY_SIZE(rt5631_snd_controls),
1710 .dapm_widgets = rt5631_dapm_widgets,
1711 .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
1712 .dapm_routes = rt5631_dapm_routes,
1713 .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
1714};
1715
1716static const struct i2c_device_id rt5631_i2c_id[] = {
1717 { "rt5631", 0 },
1718 { }
1719};
1720MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1721
1722static int rt5631_i2c_probe(struct i2c_client *i2c,
1723 const struct i2c_device_id *id)
1724{
1725 struct rt5631_priv *rt5631;
1726 int ret;
1727
1728 rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL);
1729 if (NULL == rt5631)
1730 return -ENOMEM;
1731
1732 i2c_set_clientdata(i2c, rt5631);
1733
1734 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
1735 rt5631_dai, ARRAY_SIZE(rt5631_dai));
1736 if (ret < 0)
1737 kfree(rt5631);
1738
1739 return ret;
1740}
1741
1742static __devexit int rt5631_i2c_remove(struct i2c_client *client)
1743{
1744 snd_soc_unregister_codec(&client->dev);
1745 kfree(i2c_get_clientdata(client));
1746 return 0;
1747}
1748
1749static struct i2c_driver rt5631_i2c_driver = {
1750 .driver = {
1751 .name = "rt5631",
1752 .owner = THIS_MODULE,
1753 },
1754 .probe = rt5631_i2c_probe,
1755 .remove = __devexit_p(rt5631_i2c_remove),
1756 .id_table = rt5631_i2c_id,
1757};
1758
1759static int __init rt5631_modinit(void)
1760{
1761 return i2c_add_driver(&rt5631_i2c_driver);
1762}
1763module_init(rt5631_modinit);
1764
1765static void __exit rt5631_modexit(void)
1766{
1767 i2c_del_driver(&rt5631_i2c_driver);
1768}
1769module_exit(rt5631_modexit);
1770
1771MODULE_DESCRIPTION("ASoC RT5631 driver");
1772MODULE_AUTHOR("flove <flove@realtek.com>");
1773MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt5631.h b/sound/soc/codecs/rt5631.h
new file mode 100644
index 000000000000..13401581b0df
--- /dev/null
+++ b/sound/soc/codecs/rt5631.h
@@ -0,0 +1,701 @@
1#ifndef __RTCODEC5631_H__
2#define __RTCODEC5631_H__
3
4
5#define RT5631_RESET 0x00
6#define RT5631_SPK_OUT_VOL 0x02
7#define RT5631_HP_OUT_VOL 0x04
8#define RT5631_MONO_AXO_1_2_VOL 0x06
9#define RT5631_AUX_IN_VOL 0x0A
10#define RT5631_STEREO_DAC_VOL_1 0x0C
11#define RT5631_MIC_CTRL_1 0x0E
12#define RT5631_STEREO_DAC_VOL_2 0x10
13#define RT5631_ADC_CTRL_1 0x12
14#define RT5631_ADC_REC_MIXER 0x14
15#define RT5631_ADC_CTRL_2 0x16
16#define RT5631_VDAC_DIG_VOL 0x18
17#define RT5631_OUTMIXER_L_CTRL 0x1A
18#define RT5631_OUTMIXER_R_CTRL 0x1C
19#define RT5631_AXO1MIXER_CTRL 0x1E
20#define RT5631_AXO2MIXER_CTRL 0x20
21#define RT5631_MIC_CTRL_2 0x22
22#define RT5631_DIG_MIC_CTRL 0x24
23#define RT5631_MONO_INPUT_VOL 0x26
24#define RT5631_SPK_MIXER_CTRL 0x28
25#define RT5631_SPK_MONO_OUT_CTRL 0x2A
26#define RT5631_SPK_MONO_HP_OUT_CTRL 0x2C
27#define RT5631_SDP_CTRL 0x34
28#define RT5631_MONO_SDP_CTRL 0x36
29#define RT5631_STEREO_AD_DA_CLK_CTRL 0x38
30#define RT5631_PWR_MANAG_ADD1 0x3A
31#define RT5631_PWR_MANAG_ADD2 0x3B
32#define RT5631_PWR_MANAG_ADD3 0x3C
33#define RT5631_PWR_MANAG_ADD4 0x3E
34#define RT5631_GEN_PUR_CTRL_REG 0x40
35#define RT5631_GLOBAL_CLK_CTRL 0x42
36#define RT5631_PLL_CTRL 0x44
37#define RT5631_INT_ST_IRQ_CTRL_1 0x48
38#define RT5631_INT_ST_IRQ_CTRL_2 0x4A
39#define RT5631_GPIO_CTRL 0x4C
40#define RT5631_MISC_CTRL 0x52
41#define RT5631_DEPOP_FUN_CTRL_1 0x54
42#define RT5631_DEPOP_FUN_CTRL_2 0x56
43#define RT5631_JACK_DET_CTRL 0x5A
44#define RT5631_SOFT_VOL_CTRL 0x5C
45#define RT5631_ALC_CTRL_1 0x64
46#define RT5631_ALC_CTRL_2 0x65
47#define RT5631_ALC_CTRL_3 0x66
48#define RT5631_PSEUDO_SPATL_CTRL 0x68
49#define RT5631_INDEX_ADD 0x6A
50#define RT5631_INDEX_DATA 0x6C
51#define RT5631_EQ_CTRL 0x6E
52#define RT5631_VENDOR_ID 0x7A
53#define RT5631_VENDOR_ID1 0x7C
54#define RT5631_VENDOR_ID2 0x7E
55
56/* Index of Codec Private Register definition */
57#define RT5631_EQ_BW_LOP 0x00
58#define RT5631_EQ_GAIN_LOP 0x01
59#define RT5631_EQ_FC_BP1 0x02
60#define RT5631_EQ_BW_BP1 0x03
61#define RT5631_EQ_GAIN_BP1 0x04
62#define RT5631_EQ_FC_BP2 0x05
63#define RT5631_EQ_BW_BP2 0x06
64#define RT5631_EQ_GAIN_BP2 0x07
65#define RT5631_EQ_FC_BP3 0x08
66#define RT5631_EQ_BW_BP3 0x09
67#define RT5631_EQ_GAIN_BP3 0x0a
68#define RT5631_EQ_BW_HIP 0x0b
69#define RT5631_EQ_GAIN_HIP 0x0c
70#define RT5631_EQ_HPF_A1 0x0d
71#define RT5631_EQ_HPF_A2 0x0e
72#define RT5631_EQ_HPF_GAIN 0x0f
73#define RT5631_EQ_PRE_VOL_CTRL 0x11
74#define RT5631_EQ_POST_VOL_CTRL 0x12
75#define RT5631_TEST_MODE_CTRL 0x39
76#define RT5631_CP_INTL_REG2 0x45
77#define RT5631_ADDA_MIXER_INTL_REG3 0x52
78#define RT5631_SPK_INTL_CTRL 0x56
79
80
81/* global definition */
82#define RT5631_L_MUTE (0x1 << 15)
83#define RT5631_L_MUTE_SHIFT 15
84#define RT5631_L_EN (0x1 << 14)
85#define RT5631_L_EN_SHIFT 14
86#define RT5631_R_MUTE (0x1 << 7)
87#define RT5631_R_MUTE_SHIFT 7
88#define RT5631_R_EN (0x1 << 6)
89#define RT5631_R_EN_SHIFT 6
90#define RT5631_VOL_MASK 0x1f
91#define RT5631_L_VOL_SHIFT 8
92#define RT5631_R_VOL_SHIFT 0
93
94/* Speaker Output Control(0x02) */
95#define RT5631_SPK_L_VOL_SEL_MASK (0x1 << 14)
96#define RT5631_SPK_L_VOL_SEL_VMID (0x0 << 14)
97#define RT5631_SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14)
98#define RT5631_SPK_R_VOL_SEL_MASK (0x1 << 6)
99#define RT5631_SPK_R_VOL_SEL_VMID (0x0 << 6)
100#define RT5631_SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6)
101
102/* Headphone Output Control(0x04) */
103#define RT5631_HP_L_VOL_SEL_MASK (0x1 << 14)
104#define RT5631_HP_L_VOL_SEL_VMID (0x0 << 14)
105#define RT5631_HP_L_VOL_SEL_OUTMIX_L (0x1 << 14)
106#define RT5631_HP_R_VOL_SEL_MASK (0x1 << 6)
107#define RT5631_HP_R_VOL_SEL_VMID (0x0 << 6)
108#define RT5631_HP_R_VOL_SEL_OUTMIX_R (0x1 << 6)
109
110/* Output Control for AUXOUT/MONO(0x06) */
111#define RT5631_AUXOUT_1_VOL_SEL_MASK (0x1 << 14)
112#define RT5631_AUXOUT_1_VOL_SEL_VMID (0x0 << 14)
113#define RT5631_AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14)
114#define RT5631_MUTE_MONO (0x1 << 13)
115#define RT5631_MUTE_MONO_SHIFT 13
116#define RT5631_AUXOUT_2_VOL_SEL_MASK (0x1 << 6)
117#define RT5631_AUXOUT_2_VOL_SEL_VMID (0x0 << 6)
118#define RT5631_AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6)
119
120/* Microphone Input Control 1(0x0E) */
121#define RT5631_MIC1_DIFF_INPUT_CTRL (0x1 << 15)
122#define RT5631_MIC1_DIFF_INPUT_SHIFT 15
123#define RT5631_MIC2_DIFF_INPUT_CTRL (0x1 << 7)
124#define RT5631_MIC2_DIFF_INPUT_SHIFT 7
125
126/* Stereo DAC Digital Volume2(0x10) */
127#define RT5631_DAC_VOL_MASK 0xff
128
129/* ADC Recording Mixer Control(0x14) */
130#define RT5631_M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15)
131#define RT5631_M_OUTMIXL_RECMIXL_BIT 15
132#define RT5631_M_MIC1_TO_RECMIXER_L (0x1 << 14)
133#define RT5631_M_MIC1_RECMIXL_BIT 14
134#define RT5631_M_AXIL_TO_RECMIXER_L (0x1 << 13)
135#define RT5631_M_AXIL_RECMIXL_BIT 13
136#define RT5631_M_MONO_IN_TO_RECMIXER_L (0x1 << 12)
137#define RT5631_M_MONO_IN_RECMIXL_BIT 12
138#define RT5631_M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7)
139#define RT5631_M_OUTMIXR_RECMIXR_BIT 7
140#define RT5631_M_MIC2_TO_RECMIXER_R (0x1 << 6)
141#define RT5631_M_MIC2_RECMIXR_BIT 6
142#define RT5631_M_AXIR_TO_RECMIXER_R (0x1 << 5)
143#define RT5631_M_AXIR_RECMIXR_BIT 5
144#define RT5631_M_MONO_IN_TO_RECMIXER_R (0x1 << 4)
145#define RT5631_M_MONO_IN_RECMIXR_BIT 4
146
147/* Left Output Mixer Control(0x1A) */
148#define RT5631_M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15)
149#define RT5631_M_RECMIXL_OUTMIXL_BIT 15
150#define RT5631_M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14)
151#define RT5631_M_RECMIXR_OUTMIXL_BIT 14
152#define RT5631_M_DAC_L_TO_OUTMIXER_L (0x1 << 13)
153#define RT5631_M_DACL_OUTMIXL_BIT 13
154#define RT5631_M_MIC1_TO_OUTMIXER_L (0x1 << 12)
155#define RT5631_M_MIC1_OUTMIXL_BIT 12
156#define RT5631_M_MIC2_TO_OUTMIXER_L (0x1 << 11)
157#define RT5631_M_MIC2_OUTMIXL_BIT 11
158#define RT5631_M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10)
159#define RT5631_M_MONO_INP_OUTMIXL_BIT 10
160#define RT5631_M_AXIL_TO_OUTMIXER_L (0x1 << 9)
161#define RT5631_M_AXIL_OUTMIXL_BIT 9
162#define RT5631_M_AXIR_TO_OUTMIXER_L (0x1 << 8)
163#define RT5631_M_AXIR_OUTMIXL_BIT 8
164#define RT5631_M_VDAC_TO_OUTMIXER_L (0x1 << 7)
165#define RT5631_M_VDAC_OUTMIXL_BIT 7
166
167/* Right Output Mixer Control(0x1C) */
168#define RT5631_M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15)
169#define RT5631_M_RECMIXL_OUTMIXR_BIT 15
170#define RT5631_M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14)
171#define RT5631_M_RECMIXR_OUTMIXR_BIT 14
172#define RT5631_M_DAC_R_TO_OUTMIXER_R (0x1 << 13)
173#define RT5631_M_DACR_OUTMIXR_BIT 13
174#define RT5631_M_MIC1_TO_OUTMIXER_R (0x1 << 12)
175#define RT5631_M_MIC1_OUTMIXR_BIT 12
176#define RT5631_M_MIC2_TO_OUTMIXER_R (0x1 << 11)
177#define RT5631_M_MIC2_OUTMIXR_BIT 11
178#define RT5631_M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10)
179#define RT5631_M_MONO_INN_OUTMIXR_BIT 10
180#define RT5631_M_AXIL_TO_OUTMIXER_R (0x1 << 9)
181#define RT5631_M_AXIL_OUTMIXR_BIT 9
182#define RT5631_M_AXIR_TO_OUTMIXER_R (0x1 << 8)
183#define RT5631_M_AXIR_OUTMIXR_BIT 8
184#define RT5631_M_VDAC_TO_OUTMIXER_R (0x1 << 7)
185#define RT5631_M_VDAC_OUTMIXR_BIT 7
186
187/* Lout Mixer Control(0x1E) */
188#define RT5631_M_MIC1_TO_AXO1MIXER (0x1 << 15)
189#define RT5631_M_MIC1_AXO1MIX_BIT 15
190#define RT5631_M_MIC2_TO_AXO1MIXER (0x1 << 11)
191#define RT5631_M_MIC2_AXO1MIX_BIT 11
192#define RT5631_M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7)
193#define RT5631_M_OUTMIXL_AXO1MIX_BIT 7
194#define RT5631_M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6)
195#define RT5631_M_OUTMIXR_AXO1MIX_BIT 6
196
197/* Rout Mixer Control(0x20) */
198#define RT5631_M_MIC1_TO_AXO2MIXER (0x1 << 15)
199#define RT5631_M_MIC1_AXO2MIX_BIT 15
200#define RT5631_M_MIC2_TO_AXO2MIXER (0x1 << 11)
201#define RT5631_M_MIC2_AXO2MIX_BIT 11
202#define RT5631_M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7)
203#define RT5631_M_OUTMIXL_AXO2MIX_BIT 7
204#define RT5631_M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6)
205#define RT5631_M_OUTMIXR_AXO2MIX_BIT 6
206
207/* Micphone Input Control 2(0x22) */
208#define RT5631_MIC_BIAS_90_PRECNET_AVDD 1
209#define RT5631_MIC_BIAS_75_PRECNET_AVDD 2
210
211#define RT5631_MIC1_BOOST_CTRL_MASK (0xf << 12)
212#define RT5631_MIC1_BOOST_CTRL_BYPASS (0x0 << 12)
213#define RT5631_MIC1_BOOST_CTRL_20DB (0x1 << 12)
214#define RT5631_MIC1_BOOST_CTRL_24DB (0x2 << 12)
215#define RT5631_MIC1_BOOST_CTRL_30DB (0x3 << 12)
216#define RT5631_MIC1_BOOST_CTRL_35DB (0x4 << 12)
217#define RT5631_MIC1_BOOST_CTRL_40DB (0x5 << 12)
218#define RT5631_MIC1_BOOST_CTRL_34DB (0x6 << 12)
219#define RT5631_MIC1_BOOST_CTRL_50DB (0x7 << 12)
220#define RT5631_MIC1_BOOST_CTRL_52DB (0x8 << 12)
221#define RT5631_MIC1_BOOST_SHIFT 12
222
223#define RT5631_MIC2_BOOST_CTRL_MASK (0xf << 8)
224#define RT5631_MIC2_BOOST_CTRL_BYPASS (0x0 << 8)
225#define RT5631_MIC2_BOOST_CTRL_20DB (0x1 << 8)
226#define RT5631_MIC2_BOOST_CTRL_24DB (0x2 << 8)
227#define RT5631_MIC2_BOOST_CTRL_30DB (0x3 << 8)
228#define RT5631_MIC2_BOOST_CTRL_35DB (0x4 << 8)
229#define RT5631_MIC2_BOOST_CTRL_40DB (0x5 << 8)
230#define RT5631_MIC2_BOOST_CTRL_34DB (0x6 << 8)
231#define RT5631_MIC2_BOOST_CTRL_50DB (0x7 << 8)
232#define RT5631_MIC2_BOOST_CTRL_52DB (0x8 << 8)
233#define RT5631_MIC2_BOOST_SHIFT 8
234
235#define RT5631_MICBIAS1_VOLT_CTRL_MASK (0x1 << 7)
236#define RT5631_MICBIAS1_VOLT_CTRL_90P (0x0 << 7)
237#define RT5631_MICBIAS1_VOLT_CTRL_75P (0x1 << 7)
238
239#define RT5631_MICBIAS1_S_C_DET_MASK (0x1 << 6)
240#define RT5631_MICBIAS1_S_C_DET_DIS (0x0 << 6)
241#define RT5631_MICBIAS1_S_C_DET_ENA (0x1 << 6)
242
243#define RT5631_MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4)
244#define RT5631_MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4)
245#define RT5631_MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4)
246#define RT5631_MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4)
247
248#define RT5631_MICBIAS2_VOLT_CTRL_MASK (0x1 << 3)
249#define RT5631_MICBIAS2_VOLT_CTRL_90P (0x0 << 3)
250#define RT5631_MICBIAS2_VOLT_CTRL_75P (0x1 << 3)
251
252#define RT5631_MICBIAS2_S_C_DET_MASK (0x1 << 2)
253#define RT5631_MICBIAS2_S_C_DET_DIS (0x0 << 2)
254#define RT5631_MICBIAS2_S_C_DET_ENA (0x1 << 2)
255
256#define RT5631_MICBIAS2_SHORT_CURR_DET_MASK (0x3)
257#define RT5631_MICBIAS2_SHORT_CURR_DET_600UA (0x0)
258#define RT5631_MICBIAS2_SHORT_CURR_DET_1500UA (0x1)
259#define RT5631_MICBIAS2_SHORT_CURR_DET_2000UA (0x2)
260
261
262/* Digital Microphone Control(0x24) */
263#define RT5631_DMIC_ENA_MASK (0x1 << 15)
264#define RT5631_DMIC_ENA_SHIFT 15
265/* DMIC_ENA: DMIC to ADC Digital filter */
266#define RT5631_DMIC_ENA (0x1 << 15)
267/* DMIC_DIS: ADC mixer to ADC Digital filter */
268#define RT5631_DMIC_DIS (0x0 << 15)
269#define RT5631_DMIC_L_CH_MUTE (0x1 << 13)
270#define RT5631_DMIC_L_CH_MUTE_SHIFT 13
271#define RT5631_DMIC_R_CH_MUTE (0x1 << 12)
272#define RT5631_DMIC_R_CH_MUTE_SHIFT 12
273#define RT5631_DMIC_L_CH_LATCH_MASK (0x1 << 9)
274#define RT5631_DMIC_L_CH_LATCH_RISING (0x1 << 9)
275#define RT5631_DMIC_L_CH_LATCH_FALLING (0x0 << 9)
276#define RT5631_DMIC_R_CH_LATCH_MASK (0x1 << 8)
277#define RT5631_DMIC_R_CH_LATCH_RISING (0x1 << 8)
278#define RT5631_DMIC_R_CH_LATCH_FALLING (0x0 << 8)
279#define RT5631_DMIC_CLK_CTRL_MASK (0x3 << 4)
280#define RT5631_DMIC_CLK_CTRL_TO_128FS (0x0 << 4)
281#define RT5631_DMIC_CLK_CTRL_TO_64FS (0x1 << 4)
282#define RT5631_DMIC_CLK_CTRL_TO_32FS (0x2 << 4)
283
284/* Microphone Input Volume(0x26) */
285#define RT5631_MONO_DIFF_INPUT_SHIFT 15
286
287/* Speaker Mixer Control(0x28) */
288#define RT5631_M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15)
289#define RT5631_M_RECMIXL_SPKMIXL_BIT 15
290#define RT5631_M_MIC1_P_TO_SPKMIXER_L (0x1 << 14)
291#define RT5631_M_MIC1P_SPKMIXL_BIT 14
292#define RT5631_M_DAC_L_TO_SPKMIXER_L (0x1 << 13)
293#define RT5631_M_DACL_SPKMIXL_BIT 13
294#define RT5631_M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12)
295#define RT5631_M_OUTMIXL_SPKMIXL_BIT 12
296
297#define RT5631_M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7)
298#define RT5631_M_RECMIXR_SPKMIXR_BIT 7
299#define RT5631_M_MIC2_P_TO_SPKMIXER_R (0x1 << 6)
300#define RT5631_M_MIC2P_SPKMIXR_BIT 6
301#define RT5631_M_DAC_R_TO_SPKMIXER_R (0x1 << 5)
302#define RT5631_M_DACR_SPKMIXR_BIT 5
303#define RT5631_M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4)
304#define RT5631_M_OUTMIXR_SPKMIXR_BIT 4
305
306/* Speaker/Mono Output Control(0x2A) */
307#define RT5631_M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15)
308#define RT5631_M_SPKVOLL_SPOLMIX_BIT 15
309#define RT5631_M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14)
310#define RT5631_M_SPKVOLR_SPOLMIX_BIT 14
311#define RT5631_M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13)
312#define RT5631_M_SPKVOLL_SPORMIX_BIT 13
313#define RT5631_M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12)
314#define RT5631_M_SPKVOLR_SPORMIX_BIT 12
315#define RT5631_M_OUTVOL_L_TO_MONOMIXER (0x1 << 11)
316#define RT5631_M_OUTVOLL_MONOMIX_BIT 11
317#define RT5631_M_OUTVOL_R_TO_MONOMIXER (0x1 << 10)
318#define RT5631_M_OUTVOLR_MONOMIX_BIT 10
319
320/* Speaker/Mono/HP Output Control(0x2C) */
321#define RT5631_SPK_L_MUX_SEL_MASK (0x3 << 14)
322#define RT5631_SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14)
323#define RT5631_SPK_L_MUX_SEL_MONO_IN (0x1 << 14)
324#define RT5631_SPK_L_MUX_SEL_DAC_L (0x3 << 14)
325#define RT5631_SPK_L_MUX_SEL_SHIFT 14
326
327#define RT5631_SPK_R_MUX_SEL_MASK (0x3 << 10)
328#define RT5631_SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10)
329#define RT5631_SPK_R_MUX_SEL_MONO_IN (0x1 << 10)
330#define RT5631_SPK_R_MUX_SEL_DAC_R (0x3 << 10)
331#define RT5631_SPK_R_MUX_SEL_SHIFT 10
332
333#define RT5631_MONO_MUX_SEL_MASK (0x3 << 6)
334#define RT5631_MONO_MUX_SEL_MONOMIXER (0x0 << 6)
335#define RT5631_MONO_MUX_SEL_MONO_IN (0x1 << 6)
336#define RT5631_MONO_MUX_SEL_SHIFT 6
337
338#define RT5631_HP_L_MUX_SEL_MASK (0x1 << 3)
339#define RT5631_HP_L_MUX_SEL_HPVOL_L (0x0 << 3)
340#define RT5631_HP_L_MUX_SEL_DAC_L (0x1 << 3)
341#define RT5631_HP_L_MUX_SEL_SHIFT 3
342
343#define RT5631_HP_R_MUX_SEL_MASK (0x1 << 2)
344#define RT5631_HP_R_MUX_SEL_HPVOL_R (0x0 << 2)
345#define RT5631_HP_R_MUX_SEL_DAC_R (0x1 << 2)
346#define RT5631_HP_R_MUX_SEL_SHIFT 2
347
348/* Stereo I2S Serial Data Port Control(0x34) */
349#define RT5631_SDP_MODE_SEL_MASK (0x1 << 15)
350#define RT5631_SDP_MODE_SEL_MASTER (0x0 << 15)
351#define RT5631_SDP_MODE_SEL_SLAVE (0x1 << 15)
352
353#define RT5631_SDP_ADC_CPS_SEL_MASK (0x3 << 10)
354#define RT5631_SDP_ADC_CPS_SEL_OFF (0x0 << 10)
355#define RT5631_SDP_ADC_CPS_SEL_U_LAW (0x1 << 10)
356#define RT5631_SDP_ADC_CPS_SEL_A_LAW (0x2 << 10)
357
358#define RT5631_SDP_DAC_CPS_SEL_MASK (0x3 << 8)
359#define RT5631_SDP_DAC_CPS_SEL_OFF (0x0 << 8)
360#define RT5631_SDP_DAC_CPS_SEL_U_LAW (0x1 << 8)
361#define RT5631_SDP_DAC_CPS_SEL_A_LAW (0x2 << 8)
362/* 0:Normal 1:Invert */
363#define RT5631_SDP_I2S_BCLK_POL_CTRL (0x1 << 7)
364/* 0:Normal 1:Invert */
365#define RT5631_SDP_DAC_R_INV (0x1 << 6)
366/* 0:ADC data appear at left phase of LRCK
367 * 1:ADC data appear at right phase of LRCK
368 */
369#define RT5631_SDP_ADC_DATA_L_R_SWAP (0x1 << 5)
370/* 0:DAC data appear at left phase of LRCK
371 * 1:DAC data appear at right phase of LRCK
372 */
373#define RT5631_SDP_DAC_DATA_L_R_SWAP (0x1 << 4)
374
375/* Data Length Slection */
376#define RT5631_SDP_I2S_DL_MASK (0x3 << 2)
377#define RT5631_SDP_I2S_DL_16 (0x0 << 2)
378#define RT5631_SDP_I2S_DL_20 (0x1 << 2)
379#define RT5631_SDP_I2S_DL_24 (0x2 << 2)
380#define RT5631_SDP_I2S_DL_8 (0x3 << 2)
381
382/* PCM Data Format Selection */
383#define RT5631_SDP_I2S_DF_MASK (0x3)
384#define RT5631_SDP_I2S_DF_I2S (0x0)
385#define RT5631_SDP_I2S_DF_LEFT (0x1)
386#define RT5631_SDP_I2S_DF_PCM_A (0x2)
387#define RT5631_SDP_I2S_DF_PCM_B (0x3)
388
389/* Stereo AD/DA Clock Control(0x38h) */
390#define RT5631_I2S_PRE_DIV_MASK (0x7 << 13)
391#define RT5631_I2S_PRE_DIV_1 (0x0 << 13)
392#define RT5631_I2S_PRE_DIV_2 (0x1 << 13)
393#define RT5631_I2S_PRE_DIV_4 (0x2 << 13)
394#define RT5631_I2S_PRE_DIV_8 (0x3 << 13)
395#define RT5631_I2S_PRE_DIV_16 (0x4 << 13)
396#define RT5631_I2S_PRE_DIV_32 (0x5 << 13)
397/* CLOCK RELATIVE OF BCLK AND LCRK */
398#define RT5631_I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12)
399#define RT5631_I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */
400#define RT5631_I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */
401
402#define RT5631_DAC_OSR_SEL_MASK (0x3 << 10)
403#define RT5631_DAC_OSR_SEL_128FS (0x3 << 10)
404#define RT5631_DAC_OSR_SEL_64FS (0x3 << 10)
405#define RT5631_DAC_OSR_SEL_32FS (0x3 << 10)
406#define RT5631_DAC_OSR_SEL_16FS (0x3 << 10)
407
408#define RT5631_ADC_OSR_SEL_MASK (0x3 << 8)
409#define RT5631_ADC_OSR_SEL_128FS (0x3 << 8)
410#define RT5631_ADC_OSR_SEL_64FS (0x3 << 8)
411#define RT5631_ADC_OSR_SEL_32FS (0x3 << 8)
412#define RT5631_ADC_OSR_SEL_16FS (0x3 << 8)
413
414#define RT5631_ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */
415#define RT5631_ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */
416
417/* Power managment addition 1 (0x3A) */
418#define RT5631_PWR_MAIN_I2S_EN (0x1 << 15)
419#define RT5631_PWR_MAIN_I2S_BIT 15
420#define RT5631_PWR_CLASS_D (0x1 << 12)
421#define RT5631_PWR_CLASS_D_BIT 12
422#define RT5631_PWR_ADC_L_CLK (0x1 << 11)
423#define RT5631_PWR_ADC_L_CLK_BIT 11
424#define RT5631_PWR_ADC_R_CLK (0x1 << 10)
425#define RT5631_PWR_ADC_R_CLK_BIT 10
426#define RT5631_PWR_DAC_L_CLK (0x1 << 9)
427#define RT5631_PWR_DAC_L_CLK_BIT 9
428#define RT5631_PWR_DAC_R_CLK (0x1 << 8)
429#define RT5631_PWR_DAC_R_CLK_BIT 8
430#define RT5631_PWR_DAC_REF (0x1 << 7)
431#define RT5631_PWR_DAC_REF_BIT 7
432#define RT5631_PWR_DAC_L_TO_MIXER (0x1 << 6)
433#define RT5631_PWR_DAC_L_TO_MIXER_BIT 6
434#define RT5631_PWR_DAC_R_TO_MIXER (0x1 << 5)
435#define RT5631_PWR_DAC_R_TO_MIXER_BIT 5
436
437/* Power managment addition 2 (0x3B) */
438#define RT5631_PWR_OUTMIXER_L (0x1 << 15)
439#define RT5631_PWR_OUTMIXER_L_BIT 15
440#define RT5631_PWR_OUTMIXER_R (0x1 << 14)
441#define RT5631_PWR_OUTMIXER_R_BIT 14
442#define RT5631_PWR_SPKMIXER_L (0x1 << 13)
443#define RT5631_PWR_SPKMIXER_L_BIT 13
444#define RT5631_PWR_SPKMIXER_R (0x1 << 12)
445#define RT5631_PWR_SPKMIXER_R_BIT 12
446#define RT5631_PWR_RECMIXER_L (0x1 << 11)
447#define RT5631_PWR_RECMIXER_L_BIT 11
448#define RT5631_PWR_RECMIXER_R (0x1 << 10)
449#define RT5631_PWR_RECMIXER_R_BIT 10
450#define RT5631_PWR_MIC1_BOOT_GAIN (0x1 << 5)
451#define RT5631_PWR_MIC1_BOOT_GAIN_BIT 5
452#define RT5631_PWR_MIC2_BOOT_GAIN (0x1 << 4)
453#define RT5631_PWR_MIC2_BOOT_GAIN_BIT 4
454#define RT5631_PWR_MICBIAS1_VOL (0x1 << 3)
455#define RT5631_PWR_MICBIAS1_VOL_BIT 3
456#define RT5631_PWR_MICBIAS2_VOL (0x1 << 2)
457#define RT5631_PWR_MICBIAS2_VOL_BIT 2
458#define RT5631_PWR_PLL1 (0x1 << 1)
459#define RT5631_PWR_PLL1_BIT 1
460#define RT5631_PWR_PLL2 (0x1 << 0)
461#define RT5631_PWR_PLL2_BIT 0
462
463/* Power managment addition 3(0x3C) */
464#define RT5631_PWR_VREF (0x1 << 15)
465#define RT5631_PWR_VREF_BIT 15
466#define RT5631_PWR_FAST_VREF_CTRL (0x1 << 14)
467#define RT5631_PWR_FAST_VREF_CTRL_BIT 14
468#define RT5631_PWR_MAIN_BIAS (0x1 << 13)
469#define RT5631_PWR_MAIN_BIAS_BIT 13
470#define RT5631_PWR_AXO1MIXER (0x1 << 11)
471#define RT5631_PWR_AXO1MIXER_BIT 11
472#define RT5631_PWR_AXO2MIXER (0x1 << 10)
473#define RT5631_PWR_AXO2MIXER_BIT 10
474#define RT5631_PWR_MONOMIXER (0x1 << 9)
475#define RT5631_PWR_MONOMIXER_BIT 9
476#define RT5631_PWR_MONO_DEPOP_DIS (0x1 << 8)
477#define RT5631_PWR_MONO_DEPOP_DIS_BIT 8
478#define RT5631_PWR_MONO_AMP_EN (0x1 << 7)
479#define RT5631_PWR_MONO_AMP_EN_BIT 7
480#define RT5631_PWR_CHARGE_PUMP (0x1 << 4)
481#define RT5631_PWR_CHARGE_PUMP_BIT 4
482#define RT5631_PWR_HP_L_AMP (0x1 << 3)
483#define RT5631_PWR_HP_L_AMP_BIT 3
484#define RT5631_PWR_HP_R_AMP (0x1 << 2)
485#define RT5631_PWR_HP_R_AMP_BIT 2
486#define RT5631_PWR_HP_DEPOP_DIS (0x1 << 1)
487#define RT5631_PWR_HP_DEPOP_DIS_BIT 1
488#define RT5631_PWR_HP_AMP_DRIVING (0x1 << 0)
489#define RT5631_PWR_HP_AMP_DRIVING_BIT 0
490
491/* Power managment addition 4(0x3E) */
492#define RT5631_PWR_SPK_L_VOL (0x1 << 15)
493#define RT5631_PWR_SPK_L_VOL_BIT 15
494#define RT5631_PWR_SPK_R_VOL (0x1 << 14)
495#define RT5631_PWR_SPK_R_VOL_BIT 14
496#define RT5631_PWR_LOUT_VOL (0x1 << 13)
497#define RT5631_PWR_LOUT_VOL_BIT 13
498#define RT5631_PWR_ROUT_VOL (0x1 << 12)
499#define RT5631_PWR_ROUT_VOL_BIT 12
500#define RT5631_PWR_HP_L_OUT_VOL (0x1 << 11)
501#define RT5631_PWR_HP_L_OUT_VOL_BIT 11
502#define RT5631_PWR_HP_R_OUT_VOL (0x1 << 10)
503#define RT5631_PWR_HP_R_OUT_VOL_BIT 10
504#define RT5631_PWR_AXIL_IN_VOL (0x1 << 9)
505#define RT5631_PWR_AXIL_IN_VOL_BIT 9
506#define RT5631_PWR_AXIR_IN_VOL (0x1 << 8)
507#define RT5631_PWR_AXIR_IN_VOL_BIT 8
508#define RT5631_PWR_MONO_IN_P_VOL (0x1 << 7)
509#define RT5631_PWR_MONO_IN_P_VOL_BIT 7
510#define RT5631_PWR_MONO_IN_N_VOL (0x1 << 6)
511#define RT5631_PWR_MONO_IN_N_VOL_BIT 6
512
513/* General Purpose Control Register(0x40) */
514#define RT5631_SPK_AMP_AUTO_RATIO_EN (0x1 << 15)
515
516#define RT5631_SPK_AMP_RATIO_CTRL_MASK (0x7 << 12)
517#define RT5631_SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */
518#define RT5631_SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */
519#define RT5631_SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */
520#define RT5631_SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */
521#define RT5631_SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */
522#define RT5631_SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */
523#define RT5631_SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */
524#define RT5631_SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */
525#define RT5631_SPK_AMP_RATIO_CTRL_SHIFT 12
526
527#define RT5631_STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11)
528#define RT5631_STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10)
529/* Select ADC Wind Filter Clock type */
530#define RT5631_ADC_WIND_FILT_MASK (0x3 << 4)
531#define RT5631_ADC_WIND_FILT_8_16_32K (0x0 << 4) /*8/16/32k*/
532#define RT5631_ADC_WIND_FILT_11_22_44K (0x1 << 4) /*11/22/44k*/
533#define RT5631_ADC_WIND_FILT_12_24_48K (0x2 << 4) /*12/24/48k*/
534#define RT5631_ADC_WIND_FILT_EN (0x1 << 3)
535/* SelectADC Wind Filter Corner Frequency */
536#define RT5631_ADC_WIND_CNR_FREQ_MASK (0x7 << 0)
537#define RT5631_ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */
538#define RT5631_ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */
539#define RT5631_ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */
540#define RT5631_ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */
541#define RT5631_ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */
542#define RT5631_ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */
543#define RT5631_ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */
544#define RT5631_ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */
545
546/* Global Clock Control Register(0x42) */
547#define RT5631_SYSCLK_SOUR_SEL_MASK (0x3 << 14)
548#define RT5631_SYSCLK_SOUR_SEL_MCLK (0x0 << 14)
549#define RT5631_SYSCLK_SOUR_SEL_PLL (0x1 << 14)
550#define RT5631_SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14)
551
552#define RT5631_PLLCLK_SOUR_SEL_MASK (0x3 << 12)
553#define RT5631_PLLCLK_SOUR_SEL_MCLK (0x0 << 12)
554#define RT5631_PLLCLK_SOUR_SEL_BCLK (0x1 << 12)
555#define RT5631_PLLCLK_SOUR_SEL_VBCLK (0x2 << 12)
556
557#define RT5631_PLLCLK_PRE_DIV1 (0x0 << 11)
558#define RT5631_PLLCLK_PRE_DIV2 (0x1 << 11)
559
560/* PLL Control(0x44) */
561#define RT5631_PLL_CTRL_M_VAL(m) ((m)&0xf)
562#define RT5631_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
563#define RT5631_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
564
565/* Internal Status and IRQ Control2(0x4A) */
566#define RT5631_ADC_DATA_SEL_MASK (0x3 << 14)
567#define RT5631_ADC_DATA_SEL_Disable (0x0 << 14)
568#define RT5631_ADC_DATA_SEL_MIC1 (0x1 << 14)
569#define RT5631_ADC_DATA_SEL_MIC1_SHIFT 14
570#define RT5631_ADC_DATA_SEL_MIC2 (0x2 << 14)
571#define RT5631_ADC_DATA_SEL_MIC2_SHIFT 15
572#define RT5631_ADC_DATA_SEL_STO (0x3 << 14)
573#define RT5631_ADC_DATA_SEL_SHIFT 14
574
575/* GPIO Pin Configuration(0x4C) */
576#define RT5631_GPIO_PIN_FUN_SEL_MASK (0x1 << 15)
577#define RT5631_GPIO_PIN_FUN_SEL_IRQ (0x1 << 15)
578#define RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15)
579
580#define RT5631_GPIO_DMIC_FUN_SEL_MASK (0x1 << 3)
581#define RT5631_GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3)
582#define RT5631_GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3)
583
584#define RT5631_GPIO_PIN_CON_MASK (0x1 << 2)
585#define RT5631_GPIO_PIN_SET_INPUT (0x0 << 2)
586#define RT5631_GPIO_PIN_SET_OUTPUT (0x1 << 2)
587
588/* De-POP function Control 1(0x54) */
589#define RT5631_POW_ON_SOFT_GEN (0x1 << 15)
590#define RT5631_EN_MUTE_UNMUTE_DEPOP (0x1 << 14)
591#define RT5631_EN_DEPOP2_FOR_HP (0x1 << 7)
592/* Power Down HPAMP_L Starts Up Signal */
593#define RT5631_PD_HPAMP_L_ST_UP (0x1 << 5)
594/* Power Down HPAMP_R Starts Up Signal */
595#define RT5631_PD_HPAMP_R_ST_UP (0x1 << 4)
596/* Enable left HP mute/unmute depop */
597#define RT5631_EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1)
598/* Enable right HP mute/unmute depop */
599#define RT5631_EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0)
600
601/* De-POP Fnction Control(0x56) */
602#define RT5631_EN_ONE_BIT_DEPOP (0x1 << 15)
603#define RT5631_EN_CAP_FREE_DEPOP (0x1 << 14)
604
605/* Jack Detect Control Register(0x5A) */
606#define RT5631_JD_USE_MASK (0x3 << 14)
607#define RT5631_JD_USE_JD2 (0x3 << 14)
608#define RT5631_JD_USE_JD1 (0x2 << 14)
609#define RT5631_JD_USE_GPIO (0x1 << 14)
610#define RT5631_JD_OFF (0x0 << 14)
611/* JD trigger enable for HP */
612#define RT5631_JD_HP_EN (0x1 << 11)
613#define RT5631_JD_HP_TRI_MASK (0x1 << 10)
614#define RT5631_JD_HP_TRI_HI (0x1 << 10)
615#define RT5631_JD_HP_TRI_LO (0x1 << 10)
616/* JD trigger enable for speaker LP/LN */
617#define RT5631_JD_SPK_L_EN (0x1 << 9)
618#define RT5631_JD_SPK_L_TRI_MASK (0x1 << 8)
619#define RT5631_JD_SPK_L_TRI_HI (0x1 << 8)
620#define RT5631_JD_SPK_L_TRI_LO (0x0 << 8)
621/* JD trigger enable for speaker RP/RN */
622#define RT5631_JD_SPK_R_EN (0x1 << 7)
623#define RT5631_JD_SPK_R_TRI_MASK (0x1 << 6)
624#define RT5631_JD_SPK_R_TRI_HI (0x1 << 6)
625#define RT5631_JD_SPK_R_TRI_LO (0x0 << 6)
626/* JD trigger enable for monoout */
627#define RT5631_JD_MONO_EN (0x1 << 5)
628#define RT5631_JD_MONO_TRI_MASK (0x1 << 4)
629#define RT5631_JD_MONO_TRI_HI (0x1 << 4)
630#define RT5631_JD_MONO_TRI_LO (0x0 << 4)
631/* JD trigger enable for Lout */
632#define RT5631_JD_AUX_1_EN (0x1 << 3)
633#define RT5631_JD_AUX_1_MASK (0x1 << 2)
634#define RT5631_JD_AUX_1_TRI_HI (0x1 << 2)
635#define RT5631_JD_AUX_1_TRI_LO (0x0 << 2)
636/* JD trigger enable for Rout */
637#define RT5631_JD_AUX_2_EN (0x1 << 1)
638#define RT5631_JD_AUX_2_MASK (0x1 << 0)
639#define RT5631_JD_AUX_2_TRI_HI (0x1 << 0)
640#define RT5631_JD_AUX_2_TRI_LO (0x0 << 0)
641
642/* ALC CONTROL 1(0x64) */
643#define RT5631_ALC_ATTACK_RATE_MASK (0x1F << 8)
644#define RT5631_ALC_RECOVERY_RATE_MASK (0x1F << 0)
645
646/* ALC CONTROL 2(0x65) */
647/* select Compensation gain for Noise gate function */
648#define RT5631_ALC_COM_NOISE_GATE_MASK (0xF << 0)
649
650/* ALC CONTROL 3(0x66) */
651#define RT5631_ALC_FUN_MASK (0x3 << 14)
652#define RT5631_ALC_FUN_DIS (0x0 << 14)
653#define RT5631_ALC_ENA_DAC_PATH (0x1 << 14)
654#define RT5631_ALC_ENA_ADC_PATH (0x3 << 14)
655#define RT5631_ALC_PARA_UPDATE (0x1 << 13)
656#define RT5631_ALC_LIMIT_LEVEL_MASK (0x1F << 8)
657#define RT5631_ALC_NOISE_GATE_FUN_MASK (0x1 << 7)
658#define RT5631_ALC_NOISE_GATE_FUN_DIS (0x0 << 7)
659#define RT5631_ALC_NOISE_GATE_FUN_ENA (0x1 << 7)
660/* ALC noise gate hold data function */
661#define RT5631_ALC_NOISE_GATE_H_D_MASK (0x1 << 6)
662#define RT5631_ALC_NOISE_GATE_H_D_DIS (0x0 << 6)
663#define RT5631_ALC_NOISE_GATE_H_D_ENA (0x1 << 6)
664
665/* Psedueo Stereo & Spatial Effect Block Control(0x68) */
666#define RT5631_SPATIAL_CTRL_EN (0x1 << 15)
667#define RT5631_ALL_PASS_FILTER_EN (0x1 << 14)
668#define RT5631_PSEUDO_STEREO_EN (0x1 << 13)
669#define RT5631_STEREO_EXPENSION_EN (0x1 << 12)
670/* 3D gain parameter */
671#define RT5631_GAIN_3D_PARA_MASK (0x3 << 6)
672#define RT5631_GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */
673#define RT5631_GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */
674#define RT5631_GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */
675/* 3D ratio parameter */
676#define RT5631_RATIO_3D_MASK (0x3 << 4)
677#define RT5631_RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */
678#define RT5631_RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */
679#define RT5631_RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */
680/* select samplerate for all pass filter */
681#define RT5631_APF_FUN_SLE_MASK (0x3 << 0)
682#define RT5631_APF_FUN_SEL_48K (0x3 << 0)
683#define RT5631_APF_FUN_SEL_44_1K (0x2 << 0)
684#define RT5631_APF_FUN_SEL_32K (0x1 << 0)
685#define RT5631_APF_FUN_DIS (0x0 << 0)
686
687/* EQ CONTROL 1(0x6E) */
688#define RT5631_HW_EQ_PATH_SEL_MASK (0x1 << 15)
689#define RT5631_HW_EQ_PATH_SEL_DAC (0x0 << 15)
690#define RT5631_HW_EQ_PATH_SEL_ADC (0x1 << 15)
691#define RT5631_HW_EQ_UPDATE_CTRL (0x1 << 14)
692
693#define RT5631_EN_HW_EQ_HPF2 (0x1 << 5)
694#define RT5631_EN_HW_EQ_HPF1 (0x1 << 4)
695#define RT5631_EN_HW_EQ_BP3 (0x1 << 3)
696#define RT5631_EN_HW_EQ_BP2 (0x1 << 2)
697#define RT5631_EN_HW_EQ_BP1 (0x1 << 1)
698#define RT5631_EN_HW_EQ_LPF (0x1 << 0)
699
700
701#endif /* __RTCODEC5631_H__ */
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7e4066e131e6..d15695d1c273 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/driver.h> 20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/tlv.h> 25#include <sound/tlv.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -130,16 +131,13 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
130 case SND_SOC_DAPM_POST_PMU: 131 case SND_SOC_DAPM_POST_PMU:
131 /* change mic bias resistor to 4Kohm */ 132 /* change mic bias resistor to 4Kohm */
132 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, 133 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
133 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k); 134 SGTL5000_BIAS_R_MASK,
135 SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT);
134 break; 136 break;
135 137
136 case SND_SOC_DAPM_PRE_PMD: 138 case SND_SOC_DAPM_PRE_PMD:
137 /*
138 * SGTL5000_BIAS_R_8k as mask to clean the two bits
139 * of mic bias and output impedance
140 */
141 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, 139 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
142 SGTL5000_BIAS_R_8k, 0); 140 SGTL5000_BIAS_R_MASK, 0);
143 break; 141 break;
144 } 142 }
145 return 0; 143 return 0;
@@ -725,7 +723,9 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
725 return -EINVAL; 723 return -EINVAL;
726 } 724 }
727 725
728 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl); 726 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL,
727 SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK,
728 i2s_ctl);
729 729
730 return 0; 730 return 0;
731} 731}
@@ -756,7 +756,7 @@ static int ldo_regulator_enable(struct regulator_dev *dev)
756 756
757 /* set voltage to register */ 757 /* set voltage to register */
758 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 758 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
759 (0x1 << 4) - 1, reg); 759 SGTL5000_LINREG_VDDD_MASK, reg);
760 760
761 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, 761 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
762 SGTL5000_LINEREG_D_POWERUP, 762 SGTL5000_LINEREG_D_POWERUP,
@@ -782,7 +782,7 @@ static int ldo_regulator_disable(struct regulator_dev *dev)
782 782
783 /* clear voltage info */ 783 /* clear voltage info */
784 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 784 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
785 (0x1 << 4) - 1, 0); 785 SGTL5000_LINREG_VDDD_MASK, 0);
786 786
787 ldo->enabled = 0; 787 ldo->enabled = 0;
788 788
@@ -808,6 +808,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
808 int voltage) 808 int voltage)
809{ 809{
810 struct ldo_regulator *ldo; 810 struct ldo_regulator *ldo;
811 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
811 812
812 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL); 813 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
813 814
@@ -842,6 +843,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
842 843
843 return ret; 844 return ret;
844 } 845 }
846 sgtl5000->ldo = ldo;
845 847
846 return 0; 848 return 0;
847} 849}
@@ -1115,7 +1117,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1115 1117
1116 /* set voltage to register */ 1118 /* set voltage to register */
1117 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 1119 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1118 (0x1 << 4) - 1, 0x8); 1120 SGTL5000_LINREG_VDDD_MASK, 0x8);
1119 1121
1120 /* 1122 /*
1121 * if vddd linear reg has been enabled, 1123 * if vddd linear reg has been enabled,
@@ -1146,8 +1148,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1146 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP; 1148 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1147 1149
1148 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL, 1150 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1149 vag << SGTL5000_ANA_GND_SHIFT, 1151 SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
1150 vag << SGTL5000_ANA_GND_SHIFT);
1151 1152
1152 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ 1153 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1153 vag = vddio / 2; 1154 vag = vddio / 2;
@@ -1161,9 +1162,8 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1161 SGTL5000_LINE_OUT_GND_STP; 1162 SGTL5000_LINE_OUT_GND_STP;
1162 1163
1163 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, 1164 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1164 vag << SGTL5000_LINE_OUT_GND_SHIFT | 1165 SGTL5000_LINE_OUT_CURRENT_MASK |
1165 SGTL5000_LINE_OUT_CURRENT_360u << 1166 SGTL5000_LINE_OUT_GND_MASK,
1166 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1167 vag << SGTL5000_LINE_OUT_GND_SHIFT | 1167 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1168 SGTL5000_LINE_OUT_CURRENT_360u << 1168 SGTL5000_LINE_OUT_CURRENT_360u <<
1169 SGTL5000_LINE_OUT_CURRENT_SHIFT); 1169 SGTL5000_LINE_OUT_CURRENT_SHIFT);
@@ -1436,10 +1436,17 @@ static const struct i2c_device_id sgtl5000_id[] = {
1436 1436
1437MODULE_DEVICE_TABLE(i2c, sgtl5000_id); 1437MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1438 1438
1439static const struct of_device_id sgtl5000_dt_ids[] = {
1440 { .compatible = "fsl,sgtl5000", },
1441 { /* sentinel */ }
1442};
1443MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);
1444
1439static struct i2c_driver sgtl5000_i2c_driver = { 1445static struct i2c_driver sgtl5000_i2c_driver = {
1440 .driver = { 1446 .driver = {
1441 .name = "sgtl5000", 1447 .name = "sgtl5000",
1442 .owner = THIS_MODULE, 1448 .owner = THIS_MODULE,
1449 .of_match_table = sgtl5000_dt_ids,
1443 }, 1450 },
1444 .probe = sgtl5000_i2c_probe, 1451 .probe = sgtl5000_i2c_probe,
1445 .remove = __devexit_p(sgtl5000_i2c_remove), 1452 .remove = __devexit_p(sgtl5000_i2c_remove),
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index eec3ab368f39..8a9f43534b79 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -280,7 +280,7 @@
280/* 280/*
281 * SGTL5000_CHIP_MIC_CTRL 281 * SGTL5000_CHIP_MIC_CTRL
282 */ 282 */
283#define SGTL5000_BIAS_R_MASK 0x0200 283#define SGTL5000_BIAS_R_MASK 0x0300
284#define SGTL5000_BIAS_R_SHIFT 8 284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2 285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0 286#define SGTL5000_BIAS_R_off 0x0
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 84ffdebb8a8b..f681e41fc12e 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -79,7 +79,7 @@ static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
79 */ 79 */
80static int find_free_channel(struct snd_soc_codec *sn95031_codec) 80static int find_free_channel(struct snd_soc_codec *sn95031_codec)
81{ 81{
82 int ret = 0, i, value; 82 int i, value;
83 83
84 /* check whether ADC is enabled */ 84 /* check whether ADC is enabled */
85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); 85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
@@ -91,12 +91,10 @@ static int find_free_channel(struct snd_soc_codec *sn95031_codec)
91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { 91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
92 value = snd_soc_read(sn95031_codec, 92 value = snd_soc_read(sn95031_codec,
93 SN95031_ADC_CHNL_START_ADDR + i); 93 SN95031_ADC_CHNL_START_ADDR + i);
94 if (value & SN95031_STOPBIT_MASK) { 94 if (value & SN95031_STOPBIT_MASK)
95 ret = i;
96 break; 95 break;
97 }
98 } 96 }
99 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret; 97 return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i;
100} 98}
101 99
102/* Initialize the ADC for reading micbias values. Can sleep. */ 100/* Initialize the ADC for reading micbias values. Can sleep. */
@@ -104,7 +102,7 @@ static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
104{ 102{
105 int base_addr, chnl_addr; 103 int base_addr, chnl_addr;
106 int value; 104 int value;
107 static int channel_index; 105 int channel_index;
108 106
109 /* Index of the first channel in which the stop bit is set */ 107 /* Index of the first channel in which the stop bit is set */
110 channel_index = find_free_channel(sn95031_codec); 108 channel_index = find_free_channel(sn95031_codec);
@@ -163,7 +161,6 @@ static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
163 pr_debug("mic bias = %dmV\n", mic_bias); 161 pr_debug("mic bias = %dmV\n", mic_bias);
164 return mic_bias; 162 return mic_bias;
165} 163}
166EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
167/*end - adc helper functions */ 164/*end - adc helper functions */
168 165
169static inline unsigned int sn95031_read(struct snd_soc_codec *codec, 166static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
@@ -660,7 +657,7 @@ static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
660 return 0; 657 return 0;
661} 658}
662 659
663int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, 660static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
664 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 661 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
665{ 662{
666 unsigned int format, rate; 663 unsigned int format, rate;
@@ -718,7 +715,7 @@ static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
718 .hw_params = sn95031_pcm_hw_params, 715 .hw_params = sn95031_pcm_hw_params,
719}; 716};
720 717
721struct snd_soc_dai_driver sn95031_dais[] = { 718static struct snd_soc_dai_driver sn95031_dais[] = {
722{ 719{
723 .name = "SN95031 Headset", 720 .name = "SN95031 Headset",
724 .playback = { 721 .playback = {
@@ -829,7 +826,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{ 826{
830 pr_debug("codec_probe called\n"); 827 pr_debug("codec_probe called\n");
831 828
832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
833 codec->dapm.idle_bias_off = 1; 829 codec->dapm.idle_bias_off = 1;
834 830
835 /* PCM interface config 831 /* PCM interface config
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 9801cd7cfcb5..3cb3271c5fe2 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -59,6 +59,7 @@ struct ssm2602_priv {
59 struct snd_pcm_substream *slave_substream; 59 struct snd_pcm_substream *slave_substream;
60 60
61 enum ssm2602_type type; 61 enum ssm2602_type type;
62 unsigned int clk_out_pwr;
62}; 63};
63 64
64/* 65/*
@@ -294,7 +295,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 295 struct snd_soc_pcm_runtime *rtd = substream->private_data;
295 struct snd_soc_codec *codec = rtd->codec; 296 struct snd_soc_codec *codec = rtd->codec;
296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 297 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
297 struct i2c_client *i2c = codec->control_data;
298 struct snd_pcm_runtime *master_runtime; 298 struct snd_pcm_runtime *master_runtime;
299 299
300 /* The DAI has shared clocks so if we already have a playback or 300 /* The DAI has shared clocks so if we already have a playback or
@@ -303,7 +303,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
303 */ 303 */
304 if (ssm2602->master_substream) { 304 if (ssm2602->master_substream) {
305 master_runtime = ssm2602->master_substream->runtime; 305 master_runtime = ssm2602->master_substream->runtime;
306 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n", 306 dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n",
307 master_runtime->sample_bits, 307 master_runtime->sample_bits,
308 master_runtime->rate); 308 master_runtime->rate);
309 309
@@ -343,12 +343,14 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
343static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 343static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
344{ 344{
345 struct snd_soc_codec *codec = dai->codec; 345 struct snd_soc_codec *codec = dai->codec;
346 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 346
347 if (mute) 347 if (mute)
348 snd_soc_write(codec, SSM2602_APDIGI, 348 snd_soc_update_bits(codec, SSM2602_APDIGI,
349 mute_reg | APDIGI_ENABLE_DAC_MUTE); 349 APDIGI_ENABLE_DAC_MUTE,
350 APDIGI_ENABLE_DAC_MUTE);
350 else 351 else
351 snd_soc_write(codec, SSM2602_APDIGI, mute_reg); 352 snd_soc_update_bits(codec, SSM2602_APDIGI,
353 APDIGI_ENABLE_DAC_MUTE, 0);
352 return 0; 354 return 0;
353} 355}
354 356
@@ -357,16 +359,46 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
357{ 359{
358 struct snd_soc_codec *codec = codec_dai->codec; 360 struct snd_soc_codec *codec = codec_dai->codec;
359 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 361 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
360 switch (freq) { 362
361 case 11289600: 363 if (dir == SND_SOC_CLOCK_IN) {
362 case 12000000: 364 if (clk_id != SSM2602_SYSCLK)
363 case 12288000: 365 return -EINVAL;
364 case 16934400: 366
365 case 18432000: 367 switch (freq) {
366 ssm2602->sysclk = freq; 368 case 11289600:
367 return 0; 369 case 12000000:
370 case 12288000:
371 case 16934400:
372 case 18432000:
373 ssm2602->sysclk = freq;
374 break;
375 default:
376 return -EINVAL;
377 }
378 } else {
379 unsigned int mask;
380
381 switch (clk_id) {
382 case SSM2602_CLK_CLKOUT:
383 mask = PWR_CLK_OUT_PDN;
384 break;
385 case SSM2602_CLK_XTO:
386 mask = PWR_OSC_PDN;
387 break;
388 default:
389 return -EINVAL;
390 }
391
392 if (freq == 0)
393 ssm2602->clk_out_pwr |= mask;
394 else
395 ssm2602->clk_out_pwr &= ~mask;
396
397 snd_soc_update_bits(codec, SSM2602_PWR,
398 PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr);
368 } 399 }
369 return -EINVAL; 400
401 return 0;
370} 402}
371 403
372static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, 404static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
@@ -431,23 +463,27 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
431static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 463static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
432 enum snd_soc_bias_level level) 464 enum snd_soc_bias_level level)
433{ 465{
434 u16 reg = snd_soc_read(codec, SSM2602_PWR); 466 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
435 reg &= ~(PWR_POWER_OFF | PWR_OSC_PDN);
436 467
437 switch (level) { 468 switch (level) {
438 case SND_SOC_BIAS_ON: 469 case SND_SOC_BIAS_ON:
439 /* vref/mid, osc on, dac unmute */ 470 /* vref/mid on, osc and clkout on if enabled */
440 snd_soc_write(codec, SSM2602_PWR, reg); 471 snd_soc_update_bits(codec, SSM2602_PWR,
472 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
473 ssm2602->clk_out_pwr);
441 break; 474 break;
442 case SND_SOC_BIAS_PREPARE: 475 case SND_SOC_BIAS_PREPARE:
443 break; 476 break;
444 case SND_SOC_BIAS_STANDBY: 477 case SND_SOC_BIAS_STANDBY:
445 /* everything off except vref/vmid, */ 478 /* everything off except vref/vmid, */
446 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 479 snd_soc_update_bits(codec, SSM2602_PWR,
480 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
481 PWR_CLK_OUT_PDN | PWR_OSC_PDN);
447 break; 482 break;
448 case SND_SOC_BIAS_OFF: 483 case SND_SOC_BIAS_OFF:
449 /* everything off, dac mute, inactive */ 484 /* everything off */
450 snd_soc_write(codec, SSM2602_PWR, 0xffff); 485 snd_soc_update_bits(codec, SSM2602_PWR,
486 PWR_POWER_OFF, PWR_POWER_OFF);
451 break; 487 break;
452 488
453 } 489 }
@@ -506,12 +542,12 @@ static int ssm2602_resume(struct snd_soc_codec *codec)
506static int ssm2602_probe(struct snd_soc_codec *codec) 542static int ssm2602_probe(struct snd_soc_codec *codec)
507{ 543{
508 struct snd_soc_dapm_context *dapm = &codec->dapm; 544 struct snd_soc_dapm_context *dapm = &codec->dapm;
509 int ret, reg; 545 int ret;
510 546
511 reg = snd_soc_read(codec, SSM2602_LOUT1V); 547 snd_soc_update_bits(codec, SSM2602_LOUT1V,
512 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); 548 LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH);
513 reg = snd_soc_read(codec, SSM2602_ROUT1V); 549 snd_soc_update_bits(codec, SSM2602_ROUT1V,
514 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); 550 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
515 551
516 ret = snd_soc_add_controls(codec, ssm2602_snd_controls, 552 ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
517 ARRAY_SIZE(ssm2602_snd_controls)); 553 ARRAY_SIZE(ssm2602_snd_controls));
@@ -544,7 +580,7 @@ static int ssm2604_probe(struct snd_soc_codec *codec)
544static int ssm260x_probe(struct snd_soc_codec *codec) 580static int ssm260x_probe(struct snd_soc_codec *codec)
545{ 581{
546 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 582 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
547 int ret, reg; 583 int ret;
548 584
549 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 585 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
550 586
@@ -561,10 +597,10 @@ static int ssm260x_probe(struct snd_soc_codec *codec)
561 } 597 }
562 598
563 /* set the update bits */ 599 /* set the update bits */
564 reg = snd_soc_read(codec, SSM2602_LINVOL); 600 snd_soc_update_bits(codec, SSM2602_LINVOL,
565 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 601 LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH);
566 reg = snd_soc_read(codec, SSM2602_RINVOL); 602 snd_soc_update_bits(codec, SSM2602_RINVOL,
567 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 603 RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH);
568 /*select Line in as default input*/ 604 /*select Line in as default input*/
569 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 605 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
570 APANA_ENABLE_MIC_BOOST); 606 APANA_ENABLE_MIC_BOOST);
@@ -578,7 +614,12 @@ static int ssm260x_probe(struct snd_soc_codec *codec)
578 break; 614 break;
579 } 615 }
580 616
581 return ret; 617 if (ret)
618 return ret;
619
620 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
621
622 return 0;
582} 623}
583 624
584/* remove everything here */ 625/* remove everything here */
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index b98c69168036..fbd07d7b73ca 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -116,6 +116,10 @@
116 116
117#define SSM2602_CACHEREGNUM 10 117#define SSM2602_CACHEREGNUM 10
118 118
119#define SSM2602_SYSCLK 0 119enum ssm2602_clk {
120 SSM2602_SYSCLK,
121 SSM2602_CLK_CLKOUT,
122 SSM2602_CLK_XTO
123};
120 124
121#endif 125#endif
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index fbd7eb9e61ce..bb82408ab8e1 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -524,13 +524,17 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
524 rate = params_rate(params); 524 rate = params_rate(params);
525 pr_debug("rate: %u\n", rate); 525 pr_debug("rate: %u\n", rate);
526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) 526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
527 if (interpolation_ratios[i].fs == rate) 527 if (interpolation_ratios[i].fs == rate) {
528 ir = interpolation_ratios[i].ir; 528 ir = interpolation_ratios[i].ir;
529 break;
530 }
529 if (ir < 0) 531 if (ir < 0)
530 return -EINVAL; 532 return -EINVAL;
531 for (i = 0; mclk_ratios[ir][i].ratio; i++) 533 for (i = 0; mclk_ratios[ir][i].ratio; i++)
532 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) 534 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
533 mcs = mclk_ratios[ir][i].mcs; 535 mcs = mclk_ratios[ir][i].mcs;
536 break;
537 }
534 if (mcs < 0) 538 if (mcs < 0)
535 return -EINVAL; 539 return -EINVAL;
536 540
@@ -752,25 +756,19 @@ static int sta32x_probe(struct snd_soc_codec *codec)
752 return ret; 756 return ret;
753 } 757 }
754 758
755 /* read reg reset values into cache */ 759 /* Chip documentation explicitly requires that the reset values
756 for (i = 0; i < STA32X_REGISTER_COUNT; i++) 760 * of reserved register bits are left untouched.
757 snd_soc_cache_write(codec, i, sta32x_regs[i]); 761 * Write the register default value to cache for reserved registers,
758 762 * so the write to the these registers are suppressed by the cache
759 /* preserve reset values of reserved register bits */ 763 * restore code when it skips writes of default registers.
760 snd_soc_cache_write(codec, STA32X_CONFC, 764 */
761 codec->hw_read(codec, STA32X_CONFC)); 765 snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
762 snd_soc_cache_write(codec, STA32X_CONFE, 766 snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
763 codec->hw_read(codec, STA32X_CONFE)); 767 snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
764 snd_soc_cache_write(codec, STA32X_CONFF, 768 snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
765 codec->hw_read(codec, STA32X_CONFF)); 769 snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
766 snd_soc_cache_write(codec, STA32X_MMUTE, 770 snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
767 codec->hw_read(codec, STA32X_MMUTE)); 771 snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
768 snd_soc_cache_write(codec, STA32X_AUTO1,
769 codec->hw_read(codec, STA32X_AUTO1));
770 snd_soc_cache_write(codec, STA32X_AUTO3,
771 codec->hw_read(codec, STA32X_AUTO3));
772 snd_soc_cache_write(codec, STA32X_C3CFG,
773 codec->hw_read(codec, STA32X_C3CFG));
774 772
775 /* FIXME enable thermal warning adjustment and recovery */ 773 /* FIXME enable thermal warning adjustment and recovery */
776 snd_soc_update_bits(codec, STA32X_CONFA, 774 snd_soc_update_bits(codec, STA32X_CONFA,
@@ -808,6 +806,7 @@ static int sta32x_remove(struct snd_soc_codec *codec)
808{ 806{
809 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); 807 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
810 808
809 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
811 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 810 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
812 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 811 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
813 812
@@ -832,6 +831,7 @@ static const struct snd_soc_codec_driver sta32x_codec = {
832 .resume = sta32x_resume, 831 .resume = sta32x_resume,
833 .reg_cache_size = STA32X_REGISTER_COUNT, 832 .reg_cache_size = STA32X_REGISTER_COUNT,
834 .reg_word_size = sizeof(u8), 833 .reg_word_size = sizeof(u8),
834 .reg_cache_default = sta32x_regs,
835 .volatile_register = sta32x_reg_is_volatile, 835 .volatile_register = sta32x_reg_is_volatile,
836 .set_bias_level = sta32x_set_bias_level, 836 .set_bias_level = sta32x_set_bias_level,
837 .controls = sta32x_snd_controls, 837 .controls = sta32x_snd_controls,
@@ -867,18 +867,8 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
867static __devexit int sta32x_i2c_remove(struct i2c_client *client) 867static __devexit int sta32x_i2c_remove(struct i2c_client *client)
868{ 868{
869 struct sta32x_priv *sta32x = i2c_get_clientdata(client); 869 struct sta32x_priv *sta32x = i2c_get_clientdata(client);
870 struct snd_soc_codec *codec = sta32x->codec;
871
872 if (codec)
873 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
874
875 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
876
877 if (codec) {
878 snd_soc_unregister_codec(&client->dev);
879 snd_soc_codec_set_drvdata(codec, NULL);
880 }
881 870
871 snd_soc_unregister_codec(&client->dev);
882 kfree(sta32x); 872 kfree(sta32x);
883 return 0; 873 return 0;
884} 874}
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 33bb52f3f683..ab27dbcd1262 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -47,63 +47,6 @@ static const u16 tlv320aic23_reg[] = {
47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ 47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
48}; 48};
49 49
50/*
51 * read tlv320aic23 register cache
52 */
53static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
54 *codec, unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write tlv320aic23 register cache
64 */
65static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
66 u8 reg, u16 value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the tlv320aic23 register space
76 */
77static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80
81 u8 data[2];
82
83 /* TLV320AIC23 has 7 bit address and 9 bits of data
84 * so we need to switch one data bit into reg and rest
85 * of data into val
86 */
87
88 if (reg > 9 && reg != 15) {
89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1;
91 }
92
93 data[0] = (reg << 1) | (value >> 8 & 0x01);
94 data[1] = value & 0xff;
95
96 tlv320aic23_write_reg_cache(codec, reg, value);
97
98 if (codec->hw_write(codec->control_data, data, 2) == 2)
99 return 0;
100
101 printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
102 value, reg);
103
104 return -EIO;
105}
106
107static const char *rec_src_text[] = { "Line", "Mic" }; 50static const char *rec_src_text[] = { "Line", "Mic" };
108static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 51static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
109 52
@@ -139,8 +82,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
139 */ 82 */
140 val = (val >= 4) ? 4 : (3 - val); 83 val = (val >= 4) ? 4 : (3 - val);
141 84
142 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0); 85 reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
143 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); 86 snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
144 87
145 return 0; 88 return 0;
146} 89}
@@ -151,7 +94,7 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 94 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 u16 val; 95 u16 val;
153 96
154 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0); 97 val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
155 val = val >> 6; 98 val = val >> 6;
156 val = (val >= 4) ? 4 : (3 - val); 99 val = (val >= 4) ? 4 : (3 - val);
157 ucontrol->value.integer.value[0] = val; 100 ucontrol->value.integer.value[0] = val;
@@ -159,15 +102,6 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
159 102
160} 103}
161 104
162#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
165 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
166 .tlv.p = (tlv_array), \
167 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
168 .put = snd_soc_tlv320aic23_put_volsw, \
169 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
170
171static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { 105static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
172 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, 106 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
173 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), 107 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
@@ -178,8 +112,9 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), 112 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
179 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), 113 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
180 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), 114 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
181 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG, 115 SOC_SINGLE_EXT_TLV("Sidetone Volume", TLV320AIC23_ANLG, 6, 4, 0,
182 6, 4, 0, sidetone_vol_tlv), 116 snd_soc_tlv320aic23_get_volsw,
117 snd_soc_tlv320aic23_put_volsw, sidetone_vol_tlv),
183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), 118 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
184}; 119};
185 120
@@ -240,7 +175,6 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
240/* AIC23 driver data */ 175/* AIC23 driver data */
241struct aic23 { 176struct aic23 {
242 enum snd_soc_control_type control_type; 177 enum snd_soc_control_type control_type;
243 void *control_data;
244 int mclk; 178 int mclk;
245 int requested_adc; 179 int requested_adc;
246 int requested_dac; 180 int requested_dac;
@@ -352,7 +286,7 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
352static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, 286static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
353 u32 *sample_rate_adc, u32 *sample_rate_dac) 287 u32 *sample_rate_adc, u32 *sample_rate_dac)
354{ 288{
355 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE); 289 int src = snd_soc_read(codec, TLV320AIC23_SRATE);
356 int sr = (src >> 2) & 0x0f; 290 int sr = (src >> 2) & 0x0f;
357 int val = (mclk / bosr_usb_divisor_table[src & 3]); 291 int val = (mclk / bosr_usb_divisor_table[src & 3]);
358 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; 292 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -376,7 +310,7 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
376 __func__, sample_rate_adc, sample_rate_dac); 310 __func__, sample_rate_adc, sample_rate_dac);
377 return -EINVAL; 311 return -EINVAL;
378 } 312 }
379 tlv320aic23_write(codec, TLV320AIC23_SRATE, data); 313 snd_soc_write(codec, TLV320AIC23_SRATE, data);
380#ifdef DEBUG 314#ifdef DEBUG
381 { 315 {
382 u32 adc, dac; 316 u32 adc, dac;
@@ -415,9 +349,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
415 if (ret < 0) 349 if (ret < 0)
416 return ret; 350 return ret;
417 351
418 iface_reg = 352 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
419 tlv320aic23_read_reg_cache(codec, 353
420 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
421 switch (params_format(params)) { 354 switch (params_format(params)) {
422 case SNDRV_PCM_FORMAT_S16_LE: 355 case SNDRV_PCM_FORMAT_S16_LE:
423 break; 356 break;
@@ -431,7 +364,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
431 iface_reg |= (0x03 << 2); 364 iface_reg |= (0x03 << 2);
432 break; 365 break;
433 } 366 }
434 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 367 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
435 368
436 return 0; 369 return 0;
437} 370}
@@ -443,7 +376,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
443 struct snd_soc_codec *codec = rtd->codec; 376 struct snd_soc_codec *codec = rtd->codec;
444 377
445 /* set active */ 378 /* set active */
446 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 379 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
447 380
448 return 0; 381 return 0;
449} 382}
@@ -458,7 +391,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
458 /* deactivate */ 391 /* deactivate */
459 if (!codec->active) { 392 if (!codec->active) {
460 udelay(50); 393 udelay(50);
461 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 394 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
462 } 395 }
463 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
464 aic23->requested_dac = 0; 397 aic23->requested_dac = 0;
@@ -471,14 +404,14 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
471 struct snd_soc_codec *codec = dai->codec; 404 struct snd_soc_codec *codec = dai->codec;
472 u16 reg; 405 u16 reg;
473 406
474 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT); 407 reg = snd_soc_read(codec, TLV320AIC23_DIGT);
475 if (mute) 408 if (mute)
476 reg |= TLV320AIC23_DACM_MUTE; 409 reg |= TLV320AIC23_DACM_MUTE;
477 410
478 else 411 else
479 reg &= ~TLV320AIC23_DACM_MUTE; 412 reg &= ~TLV320AIC23_DACM_MUTE;
480 413
481 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg); 414 snd_soc_write(codec, TLV320AIC23_DIGT, reg);
482 415
483 return 0; 416 return 0;
484} 417}
@@ -489,8 +422,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
489 struct snd_soc_codec *codec = codec_dai->codec; 422 struct snd_soc_codec *codec = codec_dai->codec;
490 u16 iface_reg; 423 u16 iface_reg;
491 424
492 iface_reg = 425 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
493 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
494 426
495 /* set master/slave audio interface */ 427 /* set master/slave audio interface */
496 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 428 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -524,7 +456,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
524 456
525 } 457 }
526 458
527 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 459 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
528 460
529 return 0; 461 return 0;
530} 462}
@@ -540,26 +472,26 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
540static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 472static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
541 enum snd_soc_bias_level level) 473 enum snd_soc_bias_level level)
542{ 474{
543 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f; 475 u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f;
544 476
545 switch (level) { 477 switch (level) {
546 case SND_SOC_BIAS_ON: 478 case SND_SOC_BIAS_ON:
547 /* vref/mid, osc on, dac unmute */ 479 /* vref/mid, osc on, dac unmute */
548 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \ 480 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
549 TLV320AIC23_DAC_OFF); 481 TLV320AIC23_DAC_OFF);
550 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 482 snd_soc_write(codec, TLV320AIC23_PWR, reg);
551 break; 483 break;
552 case SND_SOC_BIAS_PREPARE: 484 case SND_SOC_BIAS_PREPARE:
553 break; 485 break;
554 case SND_SOC_BIAS_STANDBY: 486 case SND_SOC_BIAS_STANDBY:
555 /* everything off except vref/vmid, */ 487 /* everything off except vref/vmid, */
556 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \ 488 snd_soc_write(codec, TLV320AIC23_PWR,
557 TLV320AIC23_CLK_OFF); 489 reg | TLV320AIC23_CLK_OFF);
558 break; 490 break;
559 case SND_SOC_BIAS_OFF: 491 case SND_SOC_BIAS_OFF:
560 /* everything off, dac mute, inactive */ 492 /* everything off, dac mute, inactive */
561 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 493 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
562 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 494 snd_soc_write(codec, TLV320AIC23_PWR, 0xffff);
563 break; 495 break;
564 } 496 }
565 codec->dapm.bias_level = level; 497 codec->dapm.bias_level = level;
@@ -606,13 +538,7 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec,
606 538
607static int tlv320aic23_resume(struct snd_soc_codec *codec) 539static int tlv320aic23_resume(struct snd_soc_codec *codec)
608{ 540{
609 u16 reg; 541 snd_soc_cache_sync(codec);
610
611 /* Sync reg_cache with the hardware */
612 for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
613 u16 val = tlv320aic23_read_reg_cache(codec, reg);
614 tlv320aic23_write(codec, reg, val);
615 }
616 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 542 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
617 543
618 return 0; 544 return 0;
@@ -621,46 +547,52 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
621static int tlv320aic23_probe(struct snd_soc_codec *codec) 547static int tlv320aic23_probe(struct snd_soc_codec *codec)
622{ 548{
623 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 549 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
624 int reg; 550 int ret;
625 551
626 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 552 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
627 codec->control_data = aic23->control_data; 553
628 codec->hw_write = (hw_write_t)i2c_master_send; 554 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
629 codec->hw_read = NULL; 555 if (ret < 0) {
556 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
557 return ret;
558 }
630 559
631 /* Reset codec */ 560 /* Reset codec */
632 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 561 snd_soc_write(codec, TLV320AIC23_RESET, 0);
562
563 /* Write the register default value to cache for reserved registers,
564 * so the write to the these registers are suppressed by the cache
565 * restore code when it skips writes of default registers.
566 */
567 snd_soc_cache_write(codec, 0x0A, 0);
568 snd_soc_cache_write(codec, 0x0B, 0);
569 snd_soc_cache_write(codec, 0x0C, 0);
570 snd_soc_cache_write(codec, 0x0D, 0);
571 snd_soc_cache_write(codec, 0x0E, 0);
633 572
634 /* power on device */ 573 /* power on device */
635 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 574 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
636 575
637 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); 576 snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
638 577
639 /* Unmute input */ 578 /* Unmute input */
640 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL); 579 snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
641 tlv320aic23_write(codec, TLV320AIC23_LINVOL, 580 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
642 (reg & (~TLV320AIC23_LIM_MUTED)) |
643 (TLV320AIC23_LRS_ENABLED));
644 581
645 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL); 582 snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
646 tlv320aic23_write(codec, TLV320AIC23_RINVOL, 583 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
647 (reg & (~TLV320AIC23_LIM_MUTED)) |
648 TLV320AIC23_LRS_ENABLED);
649 584
650 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG); 585 snd_soc_update_bits(codec, TLV320AIC23_ANLG,
651 tlv320aic23_write(codec, TLV320AIC23_ANLG, 586 TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
652 (reg) & (~TLV320AIC23_BYPASS_ON) & 587 0);
653 (~TLV320AIC23_MICM_MUTED));
654 588
655 /* Default output volume */ 589 /* Default output volume */
656 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL, 590 snd_soc_write(codec, TLV320AIC23_LCHNVOL,
657 TLV320AIC23_DEFAULT_OUT_VOL & 591 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
658 TLV320AIC23_OUT_VOL_MASK); 592 snd_soc_write(codec, TLV320AIC23_RCHNVOL,
659 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL, 593 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
660 TLV320AIC23_DEFAULT_OUT_VOL &
661 TLV320AIC23_OUT_VOL_MASK);
662 594
663 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); 595 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
664 596
665 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 597 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
666 ARRAY_SIZE(tlv320aic23_snd_controls)); 598 ARRAY_SIZE(tlv320aic23_snd_controls));
@@ -682,8 +614,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
682 .remove = tlv320aic23_remove, 614 .remove = tlv320aic23_remove,
683 .suspend = tlv320aic23_suspend, 615 .suspend = tlv320aic23_suspend,
684 .resume = tlv320aic23_resume, 616 .resume = tlv320aic23_resume,
685 .read = tlv320aic23_read_reg_cache,
686 .write = tlv320aic23_write,
687 .set_bias_level = tlv320aic23_set_bias_level, 617 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets, 618 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 619 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
@@ -710,7 +640,6 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
710 return -ENOMEM; 640 return -ENOMEM;
711 641
712 i2c_set_clientdata(i2c, aic23); 642 i2c_set_clientdata(i2c, aic23);
713 aic23->control_data = i2c;
714 aic23->control_type = SND_SOC_I2C; 643 aic23->control_type = SND_SOC_I2C;
715 644
716 ret = snd_soc_register_codec(&i2c->dev, 645 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index e93b9d1ae1dd..b21c610051c0 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -528,40 +528,33 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level) 528 enum snd_soc_bias_level level)
529{ 529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); 530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532 531
533 switch (level) { 532 switch (level) {
534 case SND_SOC_BIAS_ON: 533 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) { 534 if (aic32x4->master) {
536 /* Switch on PLL */ 535 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR); 536 snd_soc_update_bits(codec, AIC32X4_PLLPR,
538 snd_soc_write(codec, AIC32X4_PLLPR, 537 AIC32X4_PLLEN, AIC32X4_PLLEN);
539 (value | AIC32X4_PLLEN));
540 538
541 /* Switch on NDAC Divider */ 539 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC); 540 snd_soc_update_bits(codec, AIC32X4_NDAC,
543 snd_soc_write(codec, AIC32X4_NDAC, 541 AIC32X4_NDACEN, AIC32X4_NDACEN);
544 value | AIC32X4_NDACEN);
545 542
546 /* Switch on MDAC Divider */ 543 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC); 544 snd_soc_update_bits(codec, AIC32X4_MDAC,
548 snd_soc_write(codec, AIC32X4_MDAC, 545 AIC32X4_MDACEN, AIC32X4_MDACEN);
549 value | AIC32X4_MDACEN);
550 546
551 /* Switch on NADC Divider */ 547 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC); 548 snd_soc_update_bits(codec, AIC32X4_NADC,
553 snd_soc_write(codec, AIC32X4_NADC, 549 AIC32X4_NADCEN, AIC32X4_NADCEN);
554 value | AIC32X4_MDACEN);
555 550
556 /* Switch on MADC Divider */ 551 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC); 552 snd_soc_update_bits(codec, AIC32X4_MADC,
558 snd_soc_write(codec, AIC32X4_MADC, 553 AIC32X4_MADCEN, AIC32X4_MADCEN);
559 value | AIC32X4_MDACEN);
560 554
561 /* Switch on BCLK_N Divider */ 555 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN); 556 snd_soc_update_bits(codec, AIC32X4_BCLKN,
563 snd_soc_write(codec, AIC32X4_BCLKN, 557 AIC32X4_BCLKEN, AIC32X4_BCLKEN);
564 value | AIC32X4_BCLKEN);
565 } 558 }
566 break; 559 break;
567 case SND_SOC_BIAS_PREPARE: 560 case SND_SOC_BIAS_PREPARE:
@@ -569,34 +562,28 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
569 case SND_SOC_BIAS_STANDBY: 562 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) { 563 if (aic32x4->master) {
571 /* Switch off PLL */ 564 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR); 565 snd_soc_update_bits(codec, AIC32X4_PLLPR,
573 snd_soc_write(codec, AIC32X4_PLLPR, 566 AIC32X4_PLLEN, 0);
574 (value & ~AIC32X4_PLLEN));
575 567
576 /* Switch off NDAC Divider */ 568 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC); 569 snd_soc_update_bits(codec, AIC32X4_NDAC,
578 snd_soc_write(codec, AIC32X4_NDAC, 570 AIC32X4_NDACEN, 0);
579 value & ~AIC32X4_NDACEN);
580 571
581 /* Switch off MDAC Divider */ 572 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC); 573 snd_soc_update_bits(codec, AIC32X4_MDAC,
583 snd_soc_write(codec, AIC32X4_MDAC, 574 AIC32X4_MDACEN, 0);
584 value & ~AIC32X4_MDACEN);
585 575
586 /* Switch off NADC Divider */ 576 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC); 577 snd_soc_update_bits(codec, AIC32X4_NADC,
588 snd_soc_write(codec, AIC32X4_NADC, 578 AIC32X4_NADCEN, 0);
589 value & ~AIC32X4_NDACEN);
590 579
591 /* Switch off MADC Divider */ 580 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC); 581 snd_soc_update_bits(codec, AIC32X4_MADC,
593 snd_soc_write(codec, AIC32X4_MADC, 582 AIC32X4_MADCEN, 0);
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596 583
597 /* Switch off BCLK_N Divider */ 584 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN, 585 snd_soc_update_bits(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN); 586 AIC32X4_BCLKEN, 0);
600 } 587 }
601 break; 588 break;
602 case SND_SOC_BIAS_OFF: 589 case SND_SOC_BIAS_OFF:
@@ -685,10 +672,10 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
685 } 672 }
686 673
687 /* Mic PGA routing */ 674 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) { 675 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K); 676 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 } 677 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) { 678 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K); 679 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 } 680 }
694 681
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 0963c4c7a83f..7a49390bc30d 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -76,7 +76,6 @@ struct aic3x_priv {
76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; 76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
77 enum snd_soc_control_type control_type; 77 enum snd_soc_control_type control_type;
78 struct aic3x_setup_data *setup; 78 struct aic3x_setup_data *setup;
79 void *control_data;
80 unsigned int sysclk; 79 unsigned int sysclk;
81 struct list_head list; 80 struct list_head list;
82 int master; 81 int master;
@@ -138,7 +137,10 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
138 if (reg >= AIC3X_CACHEREGNUM) 137 if (reg >= AIC3X_CACHEREGNUM)
139 return -1; 138 return -1;
140 139
141 *value = codec->hw_read(codec, reg); 140 codec->cache_bypass = 1;
141 *value = snd_soc_read(codec, reg);
142 codec->cache_bypass = 0;
143
142 cache[reg] = *value; 144 cache[reg] = *value;
143 145
144 return 0; 146 return 0;
@@ -198,6 +200,10 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
198 else 200 else
199 /* old connection must be powered down */ 201 /* old connection must be powered down */
200 path->connect = invert ? 1 : 0; 202 path->connect = invert ? 1 : 0;
203
204 dapm_mark_dirty(path->source, "tlv320aic3x source");
205 dapm_mark_dirty(path->sink, "tlv320aic3x sink");
206
201 break; 207 break;
202 } 208 }
203 209
@@ -1383,7 +1389,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1383 int ret, i; 1389 int ret, i;
1384 1390
1385 INIT_LIST_HEAD(&aic3x->list); 1391 INIT_LIST_HEAD(&aic3x->list);
1386 codec->control_data = aic3x->control_data;
1387 aic3x->codec = codec; 1392 aic3x->codec = codec;
1388 codec->dapm.idle_bias_off = 1; 1393 codec->dapm.idle_bias_off = 1;
1389 1394
@@ -1495,9 +1500,9 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1495 */ 1500 */
1496 1501
1497static const struct i2c_device_id aic3x_i2c_id[] = { 1502static const struct i2c_device_id aic3x_i2c_id[] = {
1498 [AIC3X_MODEL_3X] = { "tlv320aic3x", 0 }, 1503 { "tlv320aic3x", AIC3X_MODEL_3X },
1499 [AIC3X_MODEL_33] = { "tlv320aic33", 0 }, 1504 { "tlv320aic33", AIC3X_MODEL_33 },
1500 [AIC3X_MODEL_3007] = { "tlv320aic3007", 0 }, 1505 { "tlv320aic3007", AIC3X_MODEL_3007 },
1501 { } 1506 { }
1502}; 1507};
1503MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1508MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1512,7 +1517,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1512 struct aic3x_pdata *pdata = i2c->dev.platform_data; 1517 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1513 struct aic3x_priv *aic3x; 1518 struct aic3x_priv *aic3x;
1514 int ret; 1519 int ret;
1515 const struct i2c_device_id *tbl;
1516 1520
1517 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1521 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1518 if (aic3x == NULL) { 1522 if (aic3x == NULL) {
@@ -1520,7 +1524,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1520 return -ENOMEM; 1524 return -ENOMEM;
1521 } 1525 }
1522 1526
1523 aic3x->control_data = i2c;
1524 aic3x->control_type = SND_SOC_I2C; 1527 aic3x->control_type = SND_SOC_I2C;
1525 1528
1526 i2c_set_clientdata(i2c, aic3x); 1529 i2c_set_clientdata(i2c, aic3x);
@@ -1531,11 +1534,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1531 aic3x->gpio_reset = -1; 1534 aic3x->gpio_reset = -1;
1532 } 1535 }
1533 1536
1534 for (tbl = aic3x_i2c_id; tbl->name[0]; tbl++) { 1537 aic3x->model = id->driver_data;
1535 if (!strcmp(tbl->name, id->name))
1536 break;
1537 }
1538 aic3x->model = tbl - aic3x_i2c_id;
1539 1538
1540 ret = snd_soc_register_codec(&i2c->dev, 1539 ret = snd_soc_register_codec(&i2c->dev,
1541 &soc_codec_dev_aic3x, &aic3x_dai, 1); 1540 &soc_codec_dev_aic3x, &aic3x_dai, 1);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index faa5e9fb1471..dc8a2b2bdc1c 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -55,13 +55,13 @@
55#define BURST_BASEFREQ_HZ 49152000 55#define BURST_BASEFREQ_HZ 49152000
56 56
57#define SAMPLES_TO_US(rate, samples) \ 57#define SAMPLES_TO_US(rate, samples) \
58 (1000000000 / ((rate * 1000) / samples)) 58 (1000000000 / (((rate) * 1000) / (samples)))
59 59
60#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
61 (rate / (1000000 / (us < 1000000 ? us : 1000000))) 61 ((rate) / (1000000 / ((us) < 1000000 ? (us) : 1000000)))
62 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ 63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) 64 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
65 65
66static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
67static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
@@ -627,18 +627,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
627 {"RIGHT_LO", NULL, "Codec Power"}, 627 {"RIGHT_LO", NULL, "Codec Power"},
628}; 628};
629 629
630static int dac33_add_widgets(struct snd_soc_codec *codec)
631{
632 struct snd_soc_dapm_context *dapm = &codec->dapm;
633
634 snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
635 ARRAY_SIZE(dac33_dapm_widgets));
636 /* set up audio path interconnects */
637 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
638
639 return 0;
640}
641
642static int dac33_set_bias_level(struct snd_soc_codec *codec, 630static int dac33_set_bias_level(struct snd_soc_codec *codec,
643 enum snd_soc_bias_level level) 631 enum snd_soc_bias_level level)
644{ 632{
@@ -1431,7 +1419,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1431 /* Check if the IRQ number is valid and request it */ 1419 /* Check if the IRQ number is valid and request it */
1432 if (dac33->irq >= 0) { 1420 if (dac33->irq >= 0) {
1433 ret = request_irq(dac33->irq, dac33_interrupt_handler, 1421 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1434 IRQF_TRIGGER_RISING | IRQF_DISABLED, 1422 IRQF_TRIGGER_RISING,
1435 codec->name, codec); 1423 codec->name, codec);
1436 if (ret < 0) { 1424 if (ret < 0) {
1437 dev_err(codec->dev, "Could not request IRQ%d (%d)\n", 1425 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
@@ -1451,15 +1439,11 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1451 } 1439 }
1452 } 1440 }
1453 1441
1454 snd_soc_add_controls(codec, dac33_snd_controls,
1455 ARRAY_SIZE(dac33_snd_controls));
1456 /* Only add the FIFO controls, if we have valid IRQ number */ 1442 /* Only add the FIFO controls, if we have valid IRQ number */
1457 if (dac33->irq >= 0) 1443 if (dac33->irq >= 0)
1458 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1444 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1459 ARRAY_SIZE(dac33_mode_snd_controls)); 1445 ARRAY_SIZE(dac33_mode_snd_controls));
1460 1446
1461 dac33_add_widgets(codec);
1462
1463err_power: 1447err_power:
1464 return ret; 1448 return ret;
1465} 1449}
@@ -1502,6 +1486,13 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1502 .remove = dac33_soc_remove, 1486 .remove = dac33_soc_remove,
1503 .suspend = dac33_soc_suspend, 1487 .suspend = dac33_soc_suspend,
1504 .resume = dac33_soc_resume, 1488 .resume = dac33_soc_resume,
1489
1490 .controls = dac33_snd_controls,
1491 .num_controls = ARRAY_SIZE(dac33_snd_controls),
1492 .dapm_widgets = dac33_dapm_widgets,
1493 .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets),
1494 .dapm_routes = audio_map,
1495 .num_dapm_routes = ARRAY_SIZE(audio_map),
1505}; 1496};
1506 1497
1507#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1498#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 239e0c461068..7eeca79d7387 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -33,6 +33,11 @@
33 33
34#include "tpa6130a2.h" 34#include "tpa6130a2.h"
35 35
36enum tpa_model {
37 TPA6130A2,
38 TPA6140A2,
39};
40
36static struct i2c_client *tpa6130a2_client; 41static struct i2c_client *tpa6130a2_client;
37 42
38/* This struct is used to save the context */ 43/* This struct is used to save the context */
@@ -383,7 +388,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
383 388
384 pdata = client->dev.platform_data; 389 pdata = client->dev.platform_data;
385 data->power_gpio = pdata->power_gpio; 390 data->power_gpio = pdata->power_gpio;
386 data->id = pdata->id; 391 data->id = id->driver_data;
387 392
388 mutex_init(&data->mutex); 393 mutex_init(&data->mutex);
389 394
@@ -405,7 +410,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
405 switch (data->id) { 410 switch (data->id) {
406 default: 411 default:
407 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", 412 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
408 pdata->id); 413 data->id);
409 case TPA6130A2: 414 case TPA6130A2:
410 regulator = "Vdd"; 415 regulator = "Vdd";
411 break; 416 break;
@@ -446,7 +451,6 @@ err_regulator:
446 gpio_free(data->power_gpio); 451 gpio_free(data->power_gpio);
447err_gpio: 452err_gpio:
448 kfree(data); 453 kfree(data);
449 i2c_set_clientdata(tpa6130a2_client, NULL);
450 tpa6130a2_client = NULL; 454 tpa6130a2_client = NULL;
451 455
452 return ret; 456 return ret;
@@ -470,7 +474,8 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client)
470} 474}
471 475
472static const struct i2c_device_id tpa6130a2_id[] = { 476static const struct i2c_device_id tpa6130a2_id[] = {
473 { "tpa6130a2", 0 }, 477 { "tpa6130a2", TPA6130A2 },
478 { "tpa6140a2", TPA6140A2 },
474 { } 479 { }
475}; 480};
476MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); 481MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 71674bec9604..f798247ac1b2 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -863,34 +863,6 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
863 * Inverting not going to help with these. 863 * Inverting not going to help with these.
864 * Custom volsw and volsw_2r get/put functions to handle these gain bits. 864 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
865 */ 865 */
866#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
867 xinvert, tlv_array) \
868{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
869 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
870 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
871 .tlv.p = (tlv_array), \
872 .info = snd_soc_info_volsw, \
873 .get = snd_soc_get_volsw_twl4030, \
874 .put = snd_soc_put_volsw_twl4030, \
875 .private_value = (unsigned long)&(struct soc_mixer_control) \
876 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
877 .max = xmax, .invert = xinvert} }
878#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
879 xinvert, tlv_array) \
880{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
881 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
882 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
883 .tlv.p = (tlv_array), \
884 .info = snd_soc_info_volsw_2r, \
885 .get = snd_soc_get_volsw_r2_twl4030,\
886 .put = snd_soc_put_volsw_r2_twl4030, \
887 .private_value = (unsigned long)&(struct soc_mixer_control) \
888 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
889 .rshift = xshift, .max = xmax, .invert = xinvert} }
890#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
891 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
892 xinvert, tlv_array)
893
894static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, 866static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
895 struct snd_ctl_elem_value *ucontrol) 867 struct snd_ctl_elem_value *ucontrol)
896{ 868{
@@ -1197,19 +1169,23 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1197 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0), 1169 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
1198 1170
1199 /* Separate output gain controls */ 1171 /* Separate output gain controls */
1200 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", 1172 SOC_DOUBLE_R_EXT_TLV("PreDriv Playback Volume",
1201 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, 1173 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
1202 4, 3, 0, output_tvl), 1174 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
1175 snd_soc_put_volsw_r2_twl4030, output_tvl),
1203 1176
1204 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume", 1177 SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
1205 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl), 1178 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, snd_soc_get_volsw_twl4030,
1179 snd_soc_put_volsw_twl4030, output_tvl),
1206 1180
1207 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume", 1181 SOC_DOUBLE_R_EXT_TLV("Carkit Playback Volume",
1208 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, 1182 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
1209 4, 3, 0, output_tvl), 1183 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
1184 snd_soc_put_volsw_r2_twl4030, output_tvl),
1210 1185
1211 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume", 1186 SOC_SINGLE_EXT_TLV("Earpiece Playback Volume",
1212 TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl), 1187 TWL4030_REG_EAR_CTL, 4, 3, 0, snd_soc_get_volsw_twl4030,
1188 snd_soc_put_volsw_twl4030, output_ear_tvl),
1213 1189
1214 /* Common capture gain controls */ 1190 /* Common capture gain controls */
1215 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume", 1191 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
@@ -1633,17 +1609,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1633 1609
1634}; 1610};
1635 1611
1636static int twl4030_add_widgets(struct snd_soc_codec *codec)
1637{
1638 struct snd_soc_dapm_context *dapm = &codec->dapm;
1639
1640 snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
1641 ARRAY_SIZE(twl4030_dapm_widgets));
1642 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1643
1644 return 0;
1645}
1646
1647static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1612static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1648 enum snd_soc_bias_level level) 1613 enum snd_soc_bias_level level)
1649{ 1614{
@@ -2265,9 +2230,6 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2265 2230
2266 twl4030_init_chip(codec); 2231 twl4030_init_chip(codec);
2267 2232
2268 snd_soc_add_controls(codec, twl4030_snd_controls,
2269 ARRAY_SIZE(twl4030_snd_controls));
2270 twl4030_add_widgets(codec);
2271 return 0; 2233 return 0;
2272} 2234}
2273 2235
@@ -2293,6 +2255,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2293 .reg_cache_size = sizeof(twl4030_reg), 2255 .reg_cache_size = sizeof(twl4030_reg),
2294 .reg_word_size = sizeof(u8), 2256 .reg_word_size = sizeof(u8),
2295 .reg_cache_default = twl4030_reg, 2257 .reg_cache_default = twl4030_reg,
2258
2259 .controls = twl4030_snd_controls,
2260 .num_controls = ARRAY_SIZE(twl4030_snd_controls),
2261 .dapm_widgets = twl4030_dapm_widgets,
2262 .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets),
2263 .dapm_routes = intercon,
2264 .num_dapm_routes = ARRAY_SIZE(intercon),
2296}; 2265};
2297 2266
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2267static int __devinit twl4030_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 443032b3b329..73e11f022ded 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -57,6 +57,13 @@
57#define TWL6040_HF_VOL_MASK 0x1F 57#define TWL6040_HF_VOL_MASK 0x1F
58#define TWL6040_HF_VOL_SHIFT 0 58#define TWL6040_HF_VOL_SHIFT 0
59 59
60/* Shadow register used by the driver */
61#define TWL6040_REG_SW_SHADOW 0x2F
62#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
63
64/* TWL6040_REG_SW_SHADOW (0x2F) fields */
65#define TWL6040_EAR_PATH_ENABLE 0x01
66
60struct twl6040_output { 67struct twl6040_output {
61 u16 active; 68 u16 active;
62 u16 left_vol; 69 u16 left_vol;
@@ -65,12 +72,13 @@ struct twl6040_output {
65 u16 right_step; 72 u16 right_step;
66 unsigned int step_delay; 73 unsigned int step_delay;
67 u16 ramp; 74 u16 ramp;
68 u16 mute; 75 struct delayed_work work;
69 struct completion ramp_done; 76 struct completion ramp_done;
70}; 77};
71 78
72struct twl6040_jack_data { 79struct twl6040_jack_data {
73 struct snd_soc_jack *jack; 80 struct snd_soc_jack *jack;
81 struct delayed_work work;
74 int report; 82 int report;
75}; 83};
76 84
@@ -79,7 +87,6 @@ struct twl6040_data {
79 int plug_irq; 87 int plug_irq;
80 int codec_powered; 88 int codec_powered;
81 int pll; 89 int pll;
82 int non_lp;
83 int pll_power_mode; 90 int pll_power_mode;
84 int hs_power_mode; 91 int hs_power_mode;
85 int hs_power_mode_locked; 92 int hs_power_mode_locked;
@@ -92,104 +99,68 @@ struct twl6040_data {
92 struct twl6040_jack_data hs_jack; 99 struct twl6040_jack_data hs_jack;
93 struct snd_soc_codec *codec; 100 struct snd_soc_codec *codec;
94 struct workqueue_struct *workqueue; 101 struct workqueue_struct *workqueue;
95 struct delayed_work delayed_work;
96 struct mutex mutex; 102 struct mutex mutex;
97 struct twl6040_output headset; 103 struct twl6040_output headset;
98 struct twl6040_output handsfree; 104 struct twl6040_output handsfree;
99 struct workqueue_struct *hf_workqueue;
100 struct workqueue_struct *hs_workqueue;
101 struct delayed_work hs_delayed_work;
102 struct delayed_work hf_delayed_work;
103}; 105};
104 106
105/* 107/*
106 * twl6040 register cache & default register settings 108 * twl6040 register cache & default register settings
107 */ 109 */
108static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { 110static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
109 0x00, /* not used 0x00 */ 111 0x00, /* not used 0x00 */
110 0x4B, /* TWL6040_ASICID (ro) 0x01 */ 112 0x4B, /* REG_ASICID 0x01 (ro) */
111 0x00, /* TWL6040_ASICREV (ro) 0x02 */ 113 0x00, /* REG_ASICREV 0x02 (ro) */
112 0x00, /* TWL6040_INTID 0x03 */ 114 0x00, /* REG_INTID 0x03 */
113 0x00, /* TWL6040_INTMR 0x04 */ 115 0x00, /* REG_INTMR 0x04 */
114 0x00, /* TWL6040_NCPCTRL 0x05 */ 116 0x00, /* REG_NCPCTRL 0x05 */
115 0x00, /* TWL6040_LDOCTL 0x06 */ 117 0x00, /* REG_LDOCTL 0x06 */
116 0x60, /* TWL6040_HPPLLCTL 0x07 */ 118 0x60, /* REG_HPPLLCTL 0x07 */
117 0x00, /* TWL6040_LPPLLCTL 0x08 */ 119 0x00, /* REG_LPPLLCTL 0x08 */
118 0x4A, /* TWL6040_LPPLLDIV 0x09 */ 120 0x4A, /* REG_LPPLLDIV 0x09 */
119 0x00, /* TWL6040_AMICBCTL 0x0A */ 121 0x00, /* REG_AMICBCTL 0x0A */
120 0x00, /* TWL6040_DMICBCTL 0x0B */ 122 0x00, /* REG_DMICBCTL 0x0B */
121 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ 123 0x00, /* REG_MICLCTL 0x0C */
122 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ 124 0x00, /* REG_MICRCTL 0x0D */
123 0x00, /* TWL6040_MICGAIN 0x0E */ 125 0x00, /* REG_MICGAIN 0x0E */
124 0x1B, /* TWL6040_LINEGAIN 0x0F */ 126 0x1B, /* REG_LINEGAIN 0x0F */
125 0x00, /* TWL6040_HSLCTL 0x10 */ 127 0x00, /* REG_HSLCTL 0x10 */
126 0x00, /* TWL6040_HSRCTL 0x11 */ 128 0x00, /* REG_HSRCTL 0x11 */
127 0x00, /* TWL6040_HSGAIN 0x12 */ 129 0x00, /* REG_HSGAIN 0x12 */
128 0x00, /* TWL6040_EARCTL 0x13 */ 130 0x00, /* REG_EARCTL 0x13 */
129 0x00, /* TWL6040_HFLCTL 0x14 */ 131 0x00, /* REG_HFLCTL 0x14 */
130 0x00, /* TWL6040_HFLGAIN 0x15 */ 132 0x00, /* REG_HFLGAIN 0x15 */
131 0x00, /* TWL6040_HFRCTL 0x16 */ 133 0x00, /* REG_HFRCTL 0x16 */
132 0x00, /* TWL6040_HFRGAIN 0x17 */ 134 0x00, /* REG_HFRGAIN 0x17 */
133 0x00, /* TWL6040_VIBCTLL 0x18 */ 135 0x00, /* REG_VIBCTLL 0x18 */
134 0x00, /* TWL6040_VIBDATL 0x19 */ 136 0x00, /* REG_VIBDATL 0x19 */
135 0x00, /* TWL6040_VIBCTLR 0x1A */ 137 0x00, /* REG_VIBCTLR 0x1A */
136 0x00, /* TWL6040_VIBDATR 0x1B */ 138 0x00, /* REG_VIBDATR 0x1B */
137 0x00, /* TWL6040_HKCTL1 0x1C */ 139 0x00, /* REG_HKCTL1 0x1C */
138 0x00, /* TWL6040_HKCTL2 0x1D */ 140 0x00, /* REG_HKCTL2 0x1D */
139 0x00, /* TWL6040_GPOCTL 0x1E */ 141 0x00, /* REG_GPOCTL 0x1E */
140 0x00, /* TWL6040_ALB 0x1F */ 142 0x00, /* REG_ALB 0x1F */
141 0x00, /* TWL6040_DLB 0x20 */ 143 0x00, /* REG_DLB 0x20 */
142 0x00, /* not used 0x21 */ 144 0x00, /* not used 0x21 */
143 0x00, /* not used 0x22 */ 145 0x00, /* not used 0x22 */
144 0x00, /* not used 0x23 */ 146 0x00, /* not used 0x23 */
145 0x00, /* not used 0x24 */ 147 0x00, /* not used 0x24 */
146 0x00, /* not used 0x25 */ 148 0x00, /* not used 0x25 */
147 0x00, /* not used 0x26 */ 149 0x00, /* not used 0x26 */
148 0x00, /* not used 0x27 */ 150 0x00, /* not used 0x27 */
149 0x00, /* TWL6040_TRIM1 0x28 */ 151 0x00, /* REG_TRIM1 0x28 */
150 0x00, /* TWL6040_TRIM2 0x29 */ 152 0x00, /* REG_TRIM2 0x29 */
151 0x00, /* TWL6040_TRIM3 0x2A */ 153 0x00, /* REG_TRIM3 0x2A */
152 0x00, /* TWL6040_HSOTRIM 0x2B */ 154 0x00, /* REG_HSOTRIM 0x2B */
153 0x00, /* TWL6040_HFOTRIM 0x2C */ 155 0x00, /* REG_HFOTRIM 0x2C */
154 0x09, /* TWL6040_ACCCTL 0x2D */ 156 0x09, /* REG_ACCCTL 0x2D */
155 0x00, /* TWL6040_STATUS (ro) 0x2E */ 157 0x00, /* REG_STATUS 0x2E (ro) */
156}; 158
157 159 0x00, /* REG_SW_SHADOW 0x2F - Shadow, non HW register */
158/*
159 * twl6040 vio/gnd registers:
160 * registers under vio/gnd supply can be accessed
161 * before the power-up sequence, after NRESPWRON goes high
162 */
163static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
164 TWL6040_REG_ASICID,
165 TWL6040_REG_ASICREV,
166 TWL6040_REG_INTID,
167 TWL6040_REG_INTMR,
168 TWL6040_REG_NCPCTL,
169 TWL6040_REG_LDOCTL,
170 TWL6040_REG_AMICBCTL,
171 TWL6040_REG_DMICBCTL,
172 TWL6040_REG_HKCTL1,
173 TWL6040_REG_HKCTL2,
174 TWL6040_REG_GPOCTL,
175 TWL6040_REG_TRIM1,
176 TWL6040_REG_TRIM2,
177 TWL6040_REG_TRIM3,
178 TWL6040_REG_HSOTRIM,
179 TWL6040_REG_HFOTRIM,
180 TWL6040_REG_ACCCTL,
181 TWL6040_REG_STATUS,
182}; 160};
183 161
184/* 162/* List of registers to be restored after power up */
185 * twl6040 vdd/vss registers: 163static const int twl6040_restore_list[] = {
186 * registers under vdd/vss supplies can only be accessed
187 * after the power-up sequence
188 */
189static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
190 TWL6040_REG_HPPLLCTL,
191 TWL6040_REG_LPPLLCTL,
192 TWL6040_REG_LPPLLDIV,
193 TWL6040_REG_MICLCTL, 164 TWL6040_REG_MICLCTL,
194 TWL6040_REG_MICRCTL, 165 TWL6040_REG_MICRCTL,
195 TWL6040_REG_MICGAIN, 166 TWL6040_REG_MICGAIN,
@@ -202,12 +173,6 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
202 TWL6040_REG_HFLGAIN, 173 TWL6040_REG_HFLGAIN,
203 TWL6040_REG_HFRCTL, 174 TWL6040_REG_HFRCTL,
204 TWL6040_REG_HFRGAIN, 175 TWL6040_REG_HFRGAIN,
205 TWL6040_REG_VIBCTLL,
206 TWL6040_REG_VIBDATL,
207 TWL6040_REG_VIBCTLR,
208 TWL6040_REG_VIBDATR,
209 TWL6040_REG_ALB,
210 TWL6040_REG_DLB,
211}; 176};
212 177
213/* set of rates for each pll: low-power and high-performance */ 178/* set of rates for each pll: low-power and high-performance */
@@ -275,8 +240,12 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
275 if (reg >= TWL6040_CACHEREGNUM) 240 if (reg >= TWL6040_CACHEREGNUM)
276 return -EIO; 241 return -EIO;
277 242
278 value = twl6040_reg_read(twl6040, reg); 243 if (likely(reg < TWL6040_REG_SW_SHADOW)) {
279 twl6040_write_reg_cache(codec, reg, value); 244 value = twl6040_reg_read(twl6040, reg);
245 twl6040_write_reg_cache(codec, reg, value);
246 } else {
247 value = twl6040_read_reg_cache(codec, reg);
248 }
280 249
281 return value; 250 return value;
282} 251}
@@ -293,59 +262,51 @@ static int twl6040_write(struct snd_soc_codec *codec,
293 return -EIO; 262 return -EIO;
294 263
295 twl6040_write_reg_cache(codec, reg, value); 264 twl6040_write_reg_cache(codec, reg, value);
296 return twl6040_reg_write(twl6040, reg, value); 265 if (likely(reg < TWL6040_REG_SW_SHADOW))
266 return twl6040_reg_write(twl6040, reg, value);
267 else
268 return 0;
297} 269}
298 270
299static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 271static void twl6040_init_chip(struct snd_soc_codec *codec)
300{ 272{
301 u8 *cache = codec->reg_cache; 273 struct twl6040 *twl6040 = codec->control_data;
302 int reg, i; 274 u8 val;
303 275
304 for (i = 0; i < TWL6040_VIOREGNUM; i++) { 276 /* Update reg_cache: ASICREV, and TRIM values */
305 reg = twl6040_vio_reg[i]; 277 val = twl6040_get_revid(twl6040);
306 /* 278 twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
307 * skip read-only registers (ASICID, ASICREV, STATUS) 279
308 * and registers shared among MFD children 280 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1);
309 */ 281 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2);
310 switch (reg) { 282 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3);
311 case TWL6040_REG_ASICID: 283 twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM);
312 case TWL6040_REG_ASICREV: 284 twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM);
313 case TWL6040_REG_INTID: 285
314 case TWL6040_REG_INTMR: 286 /* Change chip defaults */
315 case TWL6040_REG_NCPCTL: 287 /* No imput selected for microphone amplifiers */
316 case TWL6040_REG_LDOCTL: 288 twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
317 case TWL6040_REG_GPOCTL: 289 twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18);
318 case TWL6040_REG_ACCCTL: 290
319 case TWL6040_REG_STATUS: 291 /*
320 continue; 292 * We need to lower the default gain values, so the ramp code
321 default: 293 * can work correctly for the first playback.
322 break; 294 * This reduces the pop noise heard at the first playback.
323 } 295 */
324 twl6040_write(codec, reg, cache[reg]); 296 twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff);
325 } 297 twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e);
298 twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d);
299 twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d);
300 twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0);
326} 301}
327 302
328static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) 303static void twl6040_restore_regs(struct snd_soc_codec *codec)
329{ 304{
330 u8 *cache = codec->reg_cache; 305 u8 *cache = codec->reg_cache;
331 int reg, i; 306 int reg, i;
332 307
333 for (i = 0; i < TWL6040_VDDREGNUM; i++) { 308 for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) {
334 reg = twl6040_vdd_reg[i]; 309 reg = twl6040_restore_list[i];
335 /* skip vibra and PLL registers */
336 switch (reg) {
337 case TWL6040_REG_VIBCTLL:
338 case TWL6040_REG_VIBDATL:
339 case TWL6040_REG_VIBCTLR:
340 case TWL6040_REG_VIBDATR:
341 case TWL6040_REG_HPPLLCTL:
342 case TWL6040_REG_LPPLLCTL:
343 case TWL6040_REG_LPPLLDIV:
344 continue;
345 default:
346 break;
347 }
348
349 twl6040_write(codec, reg, cache[reg]); 310 twl6040_write(codec, reg, cache[reg]);
350 } 311 }
351} 312}
@@ -524,18 +485,17 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
524static void twl6040_pga_hs_work(struct work_struct *work) 485static void twl6040_pga_hs_work(struct work_struct *work)
525{ 486{
526 struct twl6040_data *priv = 487 struct twl6040_data *priv =
527 container_of(work, struct twl6040_data, hs_delayed_work.work); 488 container_of(work, struct twl6040_data, headset.work.work);
528 struct snd_soc_codec *codec = priv->codec; 489 struct snd_soc_codec *codec = priv->codec;
529 struct twl6040_output *headset = &priv->headset; 490 struct twl6040_output *headset = &priv->headset;
530 unsigned int delay = headset->step_delay;
531 int i, headset_complete; 491 int i, headset_complete;
532 492
533 /* do we need to ramp at all ? */ 493 /* do we need to ramp at all ? */
534 if (headset->ramp == TWL6040_RAMP_NONE) 494 if (headset->ramp == TWL6040_RAMP_NONE)
535 return; 495 return;
536 496
537 /* HS PGA volumes have 4 bits of resolution to ramp */ 497 /* HS PGA gain range: 0x0 - 0xf (0 - 15) */
538 for (i = 0; i <= 16; i++) { 498 for (i = 0; i < 16; i++) {
539 headset_complete = twl6040_hs_ramp_step(codec, 499 headset_complete = twl6040_hs_ramp_step(codec,
540 headset->left_step, 500 headset->left_step,
541 headset->right_step); 501 headset->right_step);
@@ -544,15 +504,8 @@ static void twl6040_pga_hs_work(struct work_struct *work)
544 if (headset_complete) 504 if (headset_complete)
545 break; 505 break;
546 506
547 /* 507 schedule_timeout_interruptible(
548 * TODO: tune: delay is longer over 0dB 508 msecs_to_jiffies(headset->step_delay));
549 * as increases are larger.
550 */
551 if (i >= 8)
552 schedule_timeout_interruptible(msecs_to_jiffies(delay +
553 (delay >> 1)));
554 else
555 schedule_timeout_interruptible(msecs_to_jiffies(delay));
556 } 509 }
557 510
558 if (headset->ramp == TWL6040_RAMP_DOWN) { 511 if (headset->ramp == TWL6040_RAMP_DOWN) {
@@ -567,18 +520,18 @@ static void twl6040_pga_hs_work(struct work_struct *work)
567static void twl6040_pga_hf_work(struct work_struct *work) 520static void twl6040_pga_hf_work(struct work_struct *work)
568{ 521{
569 struct twl6040_data *priv = 522 struct twl6040_data *priv =
570 container_of(work, struct twl6040_data, hf_delayed_work.work); 523 container_of(work, struct twl6040_data, handsfree.work.work);
571 struct snd_soc_codec *codec = priv->codec; 524 struct snd_soc_codec *codec = priv->codec;
572 struct twl6040_output *handsfree = &priv->handsfree; 525 struct twl6040_output *handsfree = &priv->handsfree;
573 unsigned int delay = handsfree->step_delay;
574 int i, handsfree_complete; 526 int i, handsfree_complete;
575 527
576 /* do we need to ramp at all ? */ 528 /* do we need to ramp at all ? */
577 if (handsfree->ramp == TWL6040_RAMP_NONE) 529 if (handsfree->ramp == TWL6040_RAMP_NONE)
578 return; 530 return;
579 531
580 /* HF PGA volumes have 5 bits of resolution to ramp */ 532 /*
581 for (i = 0; i <= 32; i++) { 533 * HF PGA gain range: 0x00 - 0x1d (0 - 29) */
534 for (i = 0; i < 30; i++) {
582 handsfree_complete = twl6040_hf_ramp_step(codec, 535 handsfree_complete = twl6040_hf_ramp_step(codec,
583 handsfree->left_step, 536 handsfree->left_step,
584 handsfree->right_step); 537 handsfree->right_step);
@@ -587,15 +540,8 @@ static void twl6040_pga_hf_work(struct work_struct *work)
587 if (handsfree_complete) 540 if (handsfree_complete)
588 break; 541 break;
589 542
590 /* 543 schedule_timeout_interruptible(
591 * TODO: tune: delay is longer over 0dB 544 msecs_to_jiffies(handsfree->step_delay));
592 * as increases are larger.
593 */
594 if (i >= 16)
595 schedule_timeout_interruptible(msecs_to_jiffies(delay +
596 (delay >> 1)));
597 else
598 schedule_timeout_interruptible(msecs_to_jiffies(delay));
599 } 545 }
600 546
601 547
@@ -607,36 +553,40 @@ static void twl6040_pga_hf_work(struct work_struct *work)
607 handsfree->ramp = TWL6040_RAMP_NONE; 553 handsfree->ramp = TWL6040_RAMP_NONE;
608} 554}
609 555
610static int pga_event(struct snd_soc_dapm_widget *w, 556static int out_drv_event(struct snd_soc_dapm_widget *w,
611 struct snd_kcontrol *kcontrol, int event) 557 struct snd_kcontrol *kcontrol, int event)
612{ 558{
613 struct snd_soc_codec *codec = w->codec; 559 struct snd_soc_codec *codec = w->codec;
614 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 560 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
615 struct twl6040_output *out; 561 struct twl6040_output *out;
616 struct delayed_work *work; 562 struct delayed_work *work;
617 struct workqueue_struct *queue;
618 563
619 switch (w->shift) { 564 switch (w->shift) {
620 case 2: 565 case 2: /* Headset output driver */
621 case 3:
622 out = &priv->headset; 566 out = &priv->headset;
623 work = &priv->hs_delayed_work; 567 work = &out->work;
624 queue = priv->hs_workqueue; 568 /*
569 * Make sure, that we do not mess up variables for already
570 * executing work.
571 */
572 cancel_delayed_work_sync(work);
573
625 out->left_step = priv->hs_left_step; 574 out->left_step = priv->hs_left_step;
626 out->right_step = priv->hs_right_step; 575 out->right_step = priv->hs_right_step;
627 out->step_delay = 5; /* 5 ms between volume ramp steps */ 576 out->step_delay = 5; /* 5 ms between volume ramp steps */
628 break; 577 break;
629 case 4: 578 case 4: /* Handsfree output driver */
630 out = &priv->handsfree; 579 out = &priv->handsfree;
631 work = &priv->hf_delayed_work; 580 work = &out->work;
632 queue = priv->hf_workqueue; 581 /*
582 * Make sure, that we do not mess up variables for already
583 * executing work.
584 */
585 cancel_delayed_work_sync(work);
586
633 out->left_step = priv->hf_left_step; 587 out->left_step = priv->hf_left_step;
634 out->right_step = priv->hf_right_step; 588 out->right_step = priv->hf_right_step;
635 out->step_delay = 5; /* 5 ms between volume ramp steps */ 589 out->step_delay = 5; /* 5 ms between volume ramp steps */
636 if (SND_SOC_DAPM_EVENT_ON(event))
637 priv->non_lp++;
638 else
639 priv->non_lp--;
640 break; 590 break;
641 default: 591 default:
642 return -1; 592 return -1;
@@ -648,31 +598,25 @@ static int pga_event(struct snd_soc_dapm_widget *w,
648 break; 598 break;
649 599
650 /* don't use volume ramp for power-up */ 600 /* don't use volume ramp for power-up */
601 out->ramp = TWL6040_RAMP_UP;
651 out->left_step = out->left_vol; 602 out->left_step = out->left_vol;
652 out->right_step = out->right_vol; 603 out->right_step = out->right_vol;
653 604
654 if (!delayed_work_pending(work)) { 605 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
655 out->ramp = TWL6040_RAMP_UP;
656 queue_delayed_work(queue, work,
657 msecs_to_jiffies(1));
658 }
659 break; 606 break;
660 607
661 case SND_SOC_DAPM_PRE_PMD: 608 case SND_SOC_DAPM_PRE_PMD:
662 if (!out->active) 609 if (!out->active)
663 break; 610 break;
664 611
665 if (!delayed_work_pending(work)) { 612 /* use volume ramp for power-down */
666 /* use volume ramp for power-down */ 613 out->ramp = TWL6040_RAMP_DOWN;
667 out->ramp = TWL6040_RAMP_DOWN; 614 INIT_COMPLETION(out->ramp_done);
668 INIT_COMPLETION(out->ramp_done);
669 615
670 queue_delayed_work(queue, work, 616 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
671 msecs_to_jiffies(1));
672 617
673 wait_for_completion_timeout(&out->ramp_done, 618 wait_for_completion_timeout(&out->ramp_done,
674 msecs_to_jiffies(2000)); 619 msecs_to_jiffies(2000));
675 }
676 break; 620 break;
677 } 621 }
678 622
@@ -683,7 +627,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
683static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) 627static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
684{ 628{
685 int hslctl, hsrctl; 629 int hslctl, hsrctl;
686 int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL; 630 int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
687 631
688 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); 632 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
689 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); 633 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
@@ -705,11 +649,31 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
705static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, 649static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
706 struct snd_kcontrol *kcontrol, int event) 650 struct snd_kcontrol *kcontrol, int event)
707{ 651{
652 struct snd_soc_codec *codec = w->codec;
653 u8 hslctl, hsrctl;
654
655 /*
656 * Workaround for Headset DC offset caused pop noise:
657 * Both HS DAC need to be turned on (before the HS driver) and off at
658 * the same time.
659 */
660 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
661 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
662 if (SND_SOC_DAPM_EVENT_ON(event)) {
663 hslctl |= TWL6040_HSDACENA;
664 hsrctl |= TWL6040_HSDACENA;
665 } else {
666 hslctl &= ~TWL6040_HSDACENA;
667 hsrctl &= ~TWL6040_HSDACENA;
668 }
669 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
670 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
671
708 msleep(1); 672 msleep(1);
709 return 0; 673 return 0;
710} 674}
711 675
712static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, 676static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
713 struct snd_kcontrol *kcontrol, int event) 677 struct snd_kcontrol *kcontrol, int event)
714{ 678{
715 struct snd_soc_codec *codec = w->codec; 679 struct snd_soc_codec *codec = w->codec;
@@ -717,18 +681,12 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
717 int ret = 0; 681 int ret = 0;
718 682
719 if (SND_SOC_DAPM_EVENT_ON(event)) { 683 if (SND_SOC_DAPM_EVENT_ON(event)) {
720 priv->non_lp++; 684 /* Earphone doesn't support low power mode */
721 if (!strcmp(w->name, "Earphone Driver")) { 685 priv->hs_power_mode_locked = 1;
722 /* Earphone doesn't support low power mode */ 686 ret = headset_power_mode(codec, 1);
723 priv->hs_power_mode_locked = 1;
724 ret = headset_power_mode(codec, 1);
725 }
726 } else { 687 } else {
727 priv->non_lp--; 688 priv->hs_power_mode_locked = 0;
728 if (!strcmp(w->name, "Earphone Driver")) { 689 ret = headset_power_mode(codec, priv->hs_power_mode);
729 priv->hs_power_mode_locked = 0;
730 ret = headset_power_mode(codec, priv->hs_power_mode);
731 }
732 } 690 }
733 691
734 msleep(1); 692 msleep(1);
@@ -770,7 +728,7 @@ EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
770static void twl6040_accessory_work(struct work_struct *work) 728static void twl6040_accessory_work(struct work_struct *work)
771{ 729{
772 struct twl6040_data *priv = container_of(work, 730 struct twl6040_data *priv = container_of(work,
773 struct twl6040_data, delayed_work.work); 731 struct twl6040_data, hs_jack.work.work);
774 struct snd_soc_codec *codec = priv->codec; 732 struct snd_soc_codec *codec = priv->codec;
775 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 733 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
776 734
@@ -781,15 +739,10 @@ static void twl6040_accessory_work(struct work_struct *work)
781static irqreturn_t twl6040_audio_handler(int irq, void *data) 739static irqreturn_t twl6040_audio_handler(int irq, void *data)
782{ 740{
783 struct snd_soc_codec *codec = data; 741 struct snd_soc_codec *codec = data;
784 struct twl6040 *twl6040 = codec->control_data;
785 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 742 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
786 u8 intid;
787
788 intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
789 743
790 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT)) 744 queue_delayed_work(priv->workqueue, &priv->hs_jack.work,
791 queue_delayed_work(priv->workqueue, &priv->delayed_work, 745 msecs_to_jiffies(200));
792 msecs_to_jiffies(200));
793 746
794 return IRQ_HANDLED; 747 return IRQ_HANDLED;
795} 748}
@@ -803,25 +756,27 @@ static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
803 struct soc_mixer_control *mc = 756 struct soc_mixer_control *mc =
804 (struct soc_mixer_control *)kcontrol->private_value; 757 (struct soc_mixer_control *)kcontrol->private_value;
805 int ret; 758 int ret;
806 unsigned int reg = mc->reg;
807 759
808 /* For HS and HF we shadow the values and only actually write 760 /* For HS and HF we shadow the values and only actually write
809 * them out when active in order to ensure the amplifier comes on 761 * them out when active in order to ensure the amplifier comes on
810 * as quietly as possible. */ 762 * as quietly as possible. */
811 switch (reg) { 763 switch (mc->reg) {
812 case TWL6040_REG_HSGAIN: 764 case TWL6040_REG_HSGAIN:
813 out = &twl6040_priv->headset; 765 out = &twl6040_priv->headset;
814 break; 766 break;
815 default: 767 case TWL6040_REG_HFLGAIN:
768 out = &twl6040_priv->handsfree;
816 break; 769 break;
770 default:
771 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
772 __func__, mc->reg);
773 return -EINVAL;
817 } 774 }
818 775
819 if (out) { 776 out->left_vol = ucontrol->value.integer.value[0];
820 out->left_vol = ucontrol->value.integer.value[0]; 777 out->right_vol = ucontrol->value.integer.value[1];
821 out->right_vol = ucontrol->value.integer.value[1]; 778 if (!out->active)
822 if (!out->active) 779 return 1;
823 return 1;
824 }
825 780
826 ret = snd_soc_put_volsw(kcontrol, ucontrol); 781 ret = snd_soc_put_volsw(kcontrol, ucontrol);
827 if (ret < 0) 782 if (ret < 0)
@@ -838,112 +793,42 @@ static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
838 struct twl6040_output *out = &twl6040_priv->headset; 793 struct twl6040_output *out = &twl6040_priv->headset;
839 struct soc_mixer_control *mc = 794 struct soc_mixer_control *mc =
840 (struct soc_mixer_control *)kcontrol->private_value; 795 (struct soc_mixer_control *)kcontrol->private_value;
841 unsigned int reg = mc->reg;
842 796
843 switch (reg) { 797 switch (mc->reg) {
844 case TWL6040_REG_HSGAIN: 798 case TWL6040_REG_HSGAIN:
845 out = &twl6040_priv->headset; 799 out = &twl6040_priv->headset;
846 ucontrol->value.integer.value[0] = out->left_vol;
847 ucontrol->value.integer.value[1] = out->right_vol;
848 return 0;
849
850 default:
851 break; 800 break;
852 }
853
854 return snd_soc_get_volsw(kcontrol, ucontrol);
855}
856
857static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
858 struct snd_ctl_elem_value *ucontrol)
859{
860 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
861 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
862 struct twl6040_output *out = NULL;
863 struct soc_mixer_control *mc =
864 (struct soc_mixer_control *)kcontrol->private_value;
865 int ret;
866 unsigned int reg = mc->reg;
867
868 /* For HS and HF we shadow the values and only actually write
869 * them out when active in order to ensure the amplifier comes on
870 * as quietly as possible. */
871 switch (reg) {
872 case TWL6040_REG_HFLGAIN: 801 case TWL6040_REG_HFLGAIN:
873 case TWL6040_REG_HFRGAIN:
874 out = &twl6040_priv->handsfree; 802 out = &twl6040_priv->handsfree;
875 break; 803 break;
876 default: 804 default:
877 break; 805 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
878 } 806 __func__, mc->reg);
879 807 return -EINVAL;
880 if (out) {
881 out->left_vol = ucontrol->value.integer.value[0];
882 out->right_vol = ucontrol->value.integer.value[1];
883 if (!out->active)
884 return 1;
885 } 808 }
886 809
887 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 810 ucontrol->value.integer.value[0] = out->left_vol;
888 if (ret < 0) 811 ucontrol->value.integer.value[1] = out->right_vol;
889 return ret; 812 return 0;
890
891 return 1;
892} 813}
893 814
894static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol, 815static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
895 struct snd_ctl_elem_value *ucontrol) 816 struct snd_ctl_elem_value *ucontrol)
896{ 817{
897 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 818 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
898 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); 819 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
899 struct twl6040_output *out = &twl6040_priv->handsfree; 820 struct snd_soc_codec *codec = widget->codec;
900 struct soc_mixer_control *mc = 821 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
901 (struct soc_mixer_control *)kcontrol->private_value; 822 unsigned int val;
902 unsigned int reg = mc->reg; 823
903 824 /* Do not allow changes while Input/FF efect is running */
904 /* If these are cached registers use the cache */ 825 val = twl6040_read_reg_volatile(codec, e->reg);
905 switch (reg) { 826 if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
906 case TWL6040_REG_HFLGAIN: 827 return -EBUSY;
907 case TWL6040_REG_HFRGAIN: 828
908 out = &twl6040_priv->handsfree; 829 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
909 ucontrol->value.integer.value[0] = out->left_vol;
910 ucontrol->value.integer.value[1] = out->right_vol;
911 return 0;
912
913 default:
914 break;
915 }
916
917 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
918} 830}
919 831
920/* double control with volume update */
921#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
922 xinvert, tlv_array)\
923{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
924 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
925 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
926 .tlv.p = (tlv_array), \
927 .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
928 .put = twl6040_put_volsw, \
929 .private_value = (unsigned long)&(struct soc_mixer_control) \
930 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
931 .max = xmax, .platform_max = xmax, .invert = xinvert} }
932
933/* double control with volume update */
934#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
935 xinvert, tlv_array)\
936{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
937 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
938 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
939 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
940 .tlv.p = (tlv_array), \
941 .info = snd_soc_info_volsw_2r, \
942 .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
943 .private_value = (unsigned long)&(struct soc_mixer_control) \
944 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
945 .rshift = xshift, .max = xmax, .invert = xinvert}, }
946
947/* 832/*
948 * MICATT volume control: 833 * MICATT volume control:
949 * from -6 to 0 dB in 6 dB steps 834 * from -6 to 0 dB in 6 dB steps
@@ -1015,6 +900,19 @@ static const struct soc_enum twl6040_hf_enum[] = {
1015 twl6040_hf_texts), 900 twl6040_hf_texts),
1016}; 901};
1017 902
903static const char *twl6040_vibrapath_texts[] = {
904 "Input FF", "Audio PDM"
905};
906
907static const struct soc_enum twl6040_vibra_enum[] = {
908 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1,
909 ARRAY_SIZE(twl6040_vibrapath_texts),
910 twl6040_vibrapath_texts),
911 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1,
912 ARRAY_SIZE(twl6040_vibrapath_texts),
913 twl6040_vibrapath_texts),
914};
915
1018static const struct snd_kcontrol_new amicl_control = 916static const struct snd_kcontrol_new amicl_control =
1019 SOC_DAPM_ENUM("Route", twl6040_enum[0]); 917 SOC_DAPM_ENUM("Route", twl6040_enum[0]);
1020 918
@@ -1035,8 +933,25 @@ static const struct snd_kcontrol_new hfl_mux_controls =
1035static const struct snd_kcontrol_new hfr_mux_controls = 933static const struct snd_kcontrol_new hfr_mux_controls =
1036 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); 934 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
1037 935
1038static const struct snd_kcontrol_new ep_driver_switch_controls = 936static const struct snd_kcontrol_new ep_path_enable_control =
1039 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 937 SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0);
938
939static const struct snd_kcontrol_new auxl_switch_control =
940 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0);
941
942static const struct snd_kcontrol_new auxr_switch_control =
943 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0);
944
945/* Vibra playback switches */
946static const struct snd_kcontrol_new vibral_mux_controls =
947 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0],
948 snd_soc_dapm_get_enum_double,
949 twl6040_soc_dapm_put_vibra_enum);
950
951static const struct snd_kcontrol_new vibrar_mux_controls =
952 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1],
953 snd_soc_dapm_get_enum_double,
954 twl6040_soc_dapm_put_vibra_enum);
1040 955
1041/* Headset power mode */ 956/* Headset power mode */
1042static const char *twl6040_power_mode_texts[] = { 957static const char *twl6040_power_mode_texts[] = {
@@ -1105,6 +1020,15 @@ int twl6040_get_clk_id(struct snd_soc_codec *codec)
1105} 1020}
1106EXPORT_SYMBOL_GPL(twl6040_get_clk_id); 1021EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
1107 1022
1023int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
1024{
1025 if (unlikely(trim >= TWL6040_TRIM_INVAL))
1026 return -EINVAL;
1027
1028 return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim);
1029}
1030EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
1031
1108static const struct snd_kcontrol_new twl6040_snd_controls[] = { 1032static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1109 /* Capture gains */ 1033 /* Capture gains */
1110 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 1034 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1117,10 +1041,12 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1117 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), 1041 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1118 1042
1119 /* Playback gains */ 1043 /* Playback gains */
1120 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", 1044 SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
1121 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), 1045 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, twl6040_get_volsw,
1122 SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume", 1046 twl6040_put_volsw, hs_tlv),
1123 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1047 SOC_DOUBLE_R_EXT_TLV("Handsfree Playback Volume",
1048 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1,
1049 twl6040_get_volsw, twl6040_put_volsw, hf_tlv),
1124 SOC_SINGLE_TLV("Earphone Playback Volume", 1050 SOC_SINGLE_TLV("Earphone Playback Volume",
1125 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1051 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1126 1052
@@ -1146,6 +1072,10 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1146 SND_SOC_DAPM_OUTPUT("HFL"), 1072 SND_SOC_DAPM_OUTPUT("HFL"),
1147 SND_SOC_DAPM_OUTPUT("HFR"), 1073 SND_SOC_DAPM_OUTPUT("HFR"),
1148 SND_SOC_DAPM_OUTPUT("EP"), 1074 SND_SOC_DAPM_OUTPUT("EP"),
1075 SND_SOC_DAPM_OUTPUT("AUXL"),
1076 SND_SOC_DAPM_OUTPUT("AUXR"),
1077 SND_SOC_DAPM_OUTPUT("VIBRAL"),
1078 SND_SOC_DAPM_OUTPUT("VIBRAR"),
1149 1079
1150 /* Analog input muxes for the capture amplifiers */ 1080 /* Analog input muxes for the capture amplifiers */
1151 SND_SOC_DAPM_MUX("Analog Left Capture Route", 1081 SND_SOC_DAPM_MUX("Analog Left Capture Route",
@@ -1182,59 +1112,76 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1182 TWL6040_REG_DMICBCTL, 4, 0), 1112 TWL6040_REG_DMICBCTL, 4, 0),
1183 1113
1184 /* DACs */ 1114 /* DACs */
1185 SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback", 1115 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
1186 TWL6040_REG_HSLCTL, 0, 0, 1116 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0),
1187 twl6040_hs_dac_event, 1117 SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback",
1188 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1118 TWL6040_REG_HFLCTL, 0, 0),
1189 SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback", 1119 SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback",
1190 TWL6040_REG_HSRCTL, 0, 0, 1120 TWL6040_REG_HFRCTL, 0, 0),
1191 twl6040_hs_dac_event, 1121 /* Virtual DAC for vibra path (DL4 channel) */
1192 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1122 SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback",
1193 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", 1123 SND_SOC_NOPM, 0, 0),
1194 TWL6040_REG_HFLCTL, 0, 0, 1124
1195 twl6040_power_mode_event, 1125 SND_SOC_DAPM_MUX("Handsfree Left Playback",
1196 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1197 SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
1198 TWL6040_REG_HFRCTL, 0, 0,
1199 twl6040_power_mode_event,
1200 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1201
1202 SND_SOC_DAPM_MUX("HF Left Playback",
1203 SND_SOC_NOPM, 0, 0, &hfl_mux_controls), 1126 SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
1204 SND_SOC_DAPM_MUX("HF Right Playback", 1127 SND_SOC_DAPM_MUX("Handsfree Right Playback",
1205 SND_SOC_NOPM, 0, 0, &hfr_mux_controls), 1128 SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
1206 /* Analog playback Muxes */ 1129 /* Analog playback Muxes */
1207 SND_SOC_DAPM_MUX("HS Left Playback", 1130 SND_SOC_DAPM_MUX("Headset Left Playback",
1208 SND_SOC_NOPM, 0, 0, &hsl_mux_controls), 1131 SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
1209 SND_SOC_DAPM_MUX("HS Right Playback", 1132 SND_SOC_DAPM_MUX("Headset Right Playback",
1210 SND_SOC_NOPM, 0, 0, &hsr_mux_controls), 1133 SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
1211 1134
1135 SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0,
1136 &vibral_mux_controls),
1137 SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0,
1138 &vibrar_mux_controls),
1139
1140 SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
1141 &ep_path_enable_control),
1142 SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0,
1143 &auxl_switch_control),
1144 SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0,
1145 &auxr_switch_control),
1146
1212 /* Analog playback drivers */ 1147 /* Analog playback drivers */
1213 SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", 1148 SND_SOC_DAPM_OUT_DRV_E("HF Left Driver",
1214 TWL6040_REG_HFLCTL, 4, 0, NULL, 0, 1149 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
1215 pga_event, 1150 out_drv_event,
1216 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1217 SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", 1152 SND_SOC_DAPM_OUT_DRV_E("HF Right Driver",
1218 TWL6040_REG_HFRCTL, 4, 0, NULL, 0, 1153 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
1219 pga_event, 1154 out_drv_event,
1220 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1221 SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", 1156 SND_SOC_DAPM_OUT_DRV_E("HS Left Driver",
1222 TWL6040_REG_HSLCTL, 2, 0, NULL, 0, 1157 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
1223 pga_event, 1158 out_drv_event,
1224 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1159 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1225 SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", 1160 SND_SOC_DAPM_OUT_DRV_E("HS Right Driver",
1226 TWL6040_REG_HSRCTL, 2, 0, NULL, 0, 1161 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1227 pga_event, 1162 out_drv_event,
1228 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1163 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1229 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 1164 SND_SOC_DAPM_OUT_DRV_E("Earphone Driver",
1230 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 1165 TWL6040_REG_EARCTL, 0, 0, NULL, 0,
1231 twl6040_power_mode_event, 1166 twl6040_ep_drv_event,
1232 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1167 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1168 SND_SOC_DAPM_OUT_DRV("Vibra Left Driver",
1169 TWL6040_REG_VIBCTLL, 0, 0, NULL, 0),
1170 SND_SOC_DAPM_OUT_DRV("Vibra Right Driver",
1171 TWL6040_REG_VIBCTLR, 0, 0, NULL, 0),
1172
1173 SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0,
1174 NULL, 0),
1175 SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0,
1176 NULL, 0),
1177 SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0,
1178 twl6040_hs_dac_event,
1179 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1233 1180
1234 /* Analog playback PGAs */ 1181 /* Analog playback PGAs */
1235 SND_SOC_DAPM_PGA("HFDAC Left PGA", 1182 SND_SOC_DAPM_PGA("HF Left PGA",
1236 TWL6040_REG_HFLCTL, 1, 0, NULL, 0), 1183 TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
1237 SND_SOC_DAPM_PGA("HFDAC Right PGA", 1184 SND_SOC_DAPM_PGA("HF Right PGA",
1238 TWL6040_REG_HFRCTL, 1, 0, NULL, 0), 1185 TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
1239 1186
1240}; 1187};
@@ -1256,52 +1203,62 @@ static const struct snd_soc_dapm_route intercon[] = {
1256 {"ADC Right", NULL, "MicAmpR"}, 1203 {"ADC Right", NULL, "MicAmpR"},
1257 1204
1258 /* AFM path */ 1205 /* AFM path */
1259 {"AFMAmpL", "NULL", "AFML"}, 1206 {"AFMAmpL", NULL, "AFML"},
1260 {"AFMAmpR", "NULL", "AFMR"}, 1207 {"AFMAmpR", NULL, "AFMR"},
1208
1209 {"HSDAC Left", NULL, "HSDAC Power"},
1210 {"HSDAC Right", NULL, "HSDAC Power"},
1261 1211
1262 {"HS Left Playback", "HS DAC", "HSDAC Left"}, 1212 {"Headset Left Playback", "HS DAC", "HSDAC Left"},
1263 {"HS Left Playback", "Line-In amp", "AFMAmpL"}, 1213 {"Headset Left Playback", "Line-In amp", "AFMAmpL"},
1264 1214
1265 {"HS Right Playback", "HS DAC", "HSDAC Right"}, 1215 {"Headset Right Playback", "HS DAC", "HSDAC Right"},
1266 {"HS Right Playback", "Line-In amp", "AFMAmpR"}, 1216 {"Headset Right Playback", "Line-In amp", "AFMAmpR"},
1267 1217
1268 {"Headset Left Driver", "NULL", "HS Left Playback"}, 1218 {"HS Left Driver", NULL, "Headset Left Playback"},
1269 {"Headset Right Driver", "NULL", "HS Right Playback"}, 1219 {"HS Right Driver", NULL, "Headset Right Playback"},
1270 1220
1271 {"HSOL", NULL, "Headset Left Driver"}, 1221 {"HSOL", NULL, "HS Left Driver"},
1272 {"HSOR", NULL, "Headset Right Driver"}, 1222 {"HSOR", NULL, "HS Right Driver"},
1273 1223
1274 /* Earphone playback path */ 1224 /* Earphone playback path */
1275 {"Earphone Driver", "Switch", "HSDAC Left"}, 1225 {"Earphone Playback", "Switch", "HSDAC Left"},
1226 {"Earphone Driver", NULL, "Earphone Playback"},
1276 {"EP", NULL, "Earphone Driver"}, 1227 {"EP", NULL, "Earphone Driver"},
1277 1228
1278 {"HF Left Playback", "HF DAC", "HFDAC Left"}, 1229 {"Handsfree Left Playback", "HF DAC", "HFDAC Left"},
1279 {"HF Left Playback", "Line-In amp", "AFMAmpL"}, 1230 {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"},
1280 1231
1281 {"HF Right Playback", "HF DAC", "HFDAC Right"}, 1232 {"Handsfree Right Playback", "HF DAC", "HFDAC Right"},
1282 {"HF Right Playback", "Line-In amp", "AFMAmpR"}, 1233 {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"},
1283 1234
1284 {"HFDAC Left PGA", NULL, "HF Left Playback"}, 1235 {"HF Left PGA", NULL, "Handsfree Left Playback"},
1285 {"HFDAC Right PGA", NULL, "HF Right Playback"}, 1236 {"HF Right PGA", NULL, "Handsfree Right Playback"},
1286 1237
1287 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, 1238 {"HF Left Driver", NULL, "HF Left PGA"},
1288 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, 1239 {"HF Right Driver", NULL, "HF Right PGA"},
1289 1240
1290 {"HFL", NULL, "Handsfree Left Driver"}, 1241 {"HFL", NULL, "HF Left Driver"},
1291 {"HFR", NULL, "Handsfree Right Driver"}, 1242 {"HFR", NULL, "HF Right Driver"},
1292};
1293 1243
1294static int twl6040_add_widgets(struct snd_soc_codec *codec) 1244 {"AUXL Playback", "Switch", "HF Left PGA"},
1295{ 1245 {"AUXR Playback", "Switch", "HF Right PGA"},
1296 struct snd_soc_dapm_context *dapm = &codec->dapm;
1297 1246
1298 snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets, 1247 {"AUXL", NULL, "AUXL Playback"},
1299 ARRAY_SIZE(twl6040_dapm_widgets)); 1248 {"AUXR", NULL, "AUXR Playback"},
1300 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1301 snd_soc_dapm_new_widgets(dapm);
1302 1249
1303 return 0; 1250 /* Vibrator paths */
1304} 1251 {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"},
1252 {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"},
1253
1254 {"Vibra Left Driver", NULL, "Vibra Left Playback"},
1255 {"Vibra Right Driver", NULL, "Vibra Right Playback"},
1256 {"Vibra Left Driver", NULL, "Vibra Left Control"},
1257 {"Vibra Right Driver", NULL, "Vibra Right Control"},
1258
1259 {"VIBRAL", NULL, "Vibra Left Driver"},
1260 {"VIBRAR", NULL, "Vibra Right Driver"},
1261};
1305 1262
1306static int twl6040_set_bias_level(struct snd_soc_codec *codec, 1263static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1307 enum snd_soc_bias_level level) 1264 enum snd_soc_bias_level level)
@@ -1325,8 +1282,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1325 1282
1326 priv->codec_powered = 1; 1283 priv->codec_powered = 1;
1327 1284
1328 /* initialize vdd/vss registers with reg_cache */ 1285 twl6040_restore_regs(codec);
1329 twl6040_init_vdd_regs(codec);
1330 1286
1331 /* Set external boost GPO */ 1287 /* Set external boost GPO */
1332 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); 1288 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
@@ -1380,13 +1336,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1380 rate); 1336 rate);
1381 return -EINVAL; 1337 return -EINVAL;
1382 } 1338 }
1383 /* Capture is not supported with 17.64MHz sysclk */
1384 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1385 dev_err(codec->dev,
1386 "capture mode is not supported at %dHz\n",
1387 rate);
1388 return -EINVAL;
1389 }
1390 priv->sysclk = 17640000; 1339 priv->sysclk = 17640000;
1391 break; 1340 break;
1392 case 8000: 1341 case 8000:
@@ -1419,13 +1368,6 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
1419 return -EINVAL; 1368 return -EINVAL;
1420 } 1369 }
1421 1370
1422 if ((priv->sysclk == 17640000) && priv->non_lp) {
1423 dev_err(codec->dev,
1424 "some enabled paths aren't supported at %dHz\n",
1425 priv->sysclk);
1426 return -EPERM;
1427 }
1428
1429 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); 1371 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
1430 if (ret) { 1372 if (ret) {
1431 dev_err(codec->dev, "Can not set PLL (%d)\n", ret); 1373 dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
@@ -1464,11 +1406,11 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
1464 1406
1465static struct snd_soc_dai_driver twl6040_dai[] = { 1407static struct snd_soc_dai_driver twl6040_dai[] = {
1466{ 1408{
1467 .name = "twl6040-hifi", 1409 .name = "twl6040-legacy",
1468 .playback = { 1410 .playback = {
1469 .stream_name = "Playback", 1411 .stream_name = "Playback",
1470 .channels_min = 1, 1412 .channels_min = 1,
1471 .channels_max = 2, 1413 .channels_max = 5,
1472 .rates = TWL6040_RATES, 1414 .rates = TWL6040_RATES,
1473 .formats = TWL6040_FORMATS, 1415 .formats = TWL6040_FORMATS,
1474 }, 1416 },
@@ -1518,8 +1460,8 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1518 .name = "twl6040-vib", 1460 .name = "twl6040-vib",
1519 .playback = { 1461 .playback = {
1520 .stream_name = "Vibra Playback", 1462 .stream_name = "Vibra Playback",
1521 .channels_min = 2, 1463 .channels_min = 1,
1522 .channels_max = 2, 1464 .channels_max = 1,
1523 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1465 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1524 .formats = TWL6040_FORMATS, 1466 .formats = TWL6040_FORMATS,
1525 }, 1467 },
@@ -1562,6 +1504,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1562 1504
1563 priv->codec = codec; 1505 priv->codec = codec;
1564 codec->control_data = dev_get_drvdata(codec->dev->parent); 1506 codec->control_data = dev_get_drvdata(codec->dev->parent);
1507 codec->ignore_pmdown_time = 1;
1565 1508
1566 if (pdata && pdata->hs_left_step && pdata->hs_right_step) { 1509 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1567 priv->hs_left_step = pdata->hs_left_step; 1510 priv->hs_left_step = pdata->hs_left_step;
@@ -1586,33 +1529,21 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1586 goto work_err; 1529 goto work_err;
1587 } 1530 }
1588 1531
1589 priv->workqueue = create_singlethread_workqueue("twl6040-codec"); 1532 priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0);
1590 if (!priv->workqueue) { 1533 if (!priv->workqueue) {
1591 ret = -ENOMEM; 1534 ret = -ENOMEM;
1592 goto work_err; 1535 goto work_err;
1593 } 1536 }
1594 1537
1595 INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); 1538 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1539 INIT_DELAYED_WORK(&priv->headset.work, twl6040_pga_hs_work);
1540 INIT_DELAYED_WORK(&priv->handsfree.work, twl6040_pga_hf_work);
1596 1541
1597 mutex_init(&priv->mutex); 1542 mutex_init(&priv->mutex);
1598 1543
1599 init_completion(&priv->headset.ramp_done); 1544 init_completion(&priv->headset.ramp_done);
1600 init_completion(&priv->handsfree.ramp_done); 1545 init_completion(&priv->handsfree.ramp_done);
1601 1546
1602 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1603 if (priv->hf_workqueue == NULL) {
1604 ret = -ENOMEM;
1605 goto hfwq_err;
1606 }
1607 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1608 if (priv->hs_workqueue == NULL) {
1609 ret = -ENOMEM;
1610 goto hswq_err;
1611 }
1612
1613 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1614 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1615
1616 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, 1547 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
1617 0, "twl6040_irq_plug", codec); 1548 0, "twl6040_irq_plug", codec);
1618 if (ret) { 1549 if (ret) {
@@ -1620,27 +1551,16 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1620 goto plugirq_err; 1551 goto plugirq_err;
1621 } 1552 }
1622 1553
1623 /* init vio registers */ 1554 twl6040_init_chip(codec);
1624 twl6040_init_vio_regs(codec);
1625 1555
1626 /* power on device */ 1556 /* power on device */
1627 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1557 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1628 if (ret) 1558 if (!ret)
1629 goto bias_err; 1559 return 0;
1630
1631 snd_soc_add_controls(codec, twl6040_snd_controls,
1632 ARRAY_SIZE(twl6040_snd_controls));
1633 twl6040_add_widgets(codec);
1634
1635 return 0;
1636 1560
1637bias_err: 1561 /* Error path */
1638 free_irq(priv->plug_irq, codec); 1562 free_irq(priv->plug_irq, codec);
1639plugirq_err: 1563plugirq_err:
1640 destroy_workqueue(priv->hs_workqueue);
1641hswq_err:
1642 destroy_workqueue(priv->hf_workqueue);
1643hfwq_err:
1644 destroy_workqueue(priv->workqueue); 1564 destroy_workqueue(priv->workqueue);
1645work_err: 1565work_err:
1646 kfree(priv); 1566 kfree(priv);
@@ -1654,8 +1574,6 @@ static int twl6040_remove(struct snd_soc_codec *codec)
1654 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1574 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1655 free_irq(priv->plug_irq, codec); 1575 free_irq(priv->plug_irq, codec);
1656 destroy_workqueue(priv->workqueue); 1576 destroy_workqueue(priv->workqueue);
1657 destroy_workqueue(priv->hf_workqueue);
1658 destroy_workqueue(priv->hs_workqueue);
1659 kfree(priv); 1577 kfree(priv);
1660 1578
1661 return 0; 1579 return 0;
@@ -1672,6 +1590,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1672 .reg_cache_size = ARRAY_SIZE(twl6040_reg), 1590 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1673 .reg_word_size = sizeof(u8), 1591 .reg_word_size = sizeof(u8),
1674 .reg_cache_default = twl6040_reg, 1592 .reg_cache_default = twl6040_reg,
1593
1594 .controls = twl6040_snd_controls,
1595 .num_controls = ARRAY_SIZE(twl6040_snd_controls),
1596 .dapm_widgets = twl6040_dapm_widgets,
1597 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
1598 .dapm_routes = intercon,
1599 .num_dapm_routes = ARRAY_SIZE(intercon),
1675}; 1600};
1676 1601
1677static int __devinit twl6040_codec_probe(struct platform_device *pdev) 1602static int __devinit twl6040_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index d8de67869dd9..a83277bdb851 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -22,8 +22,21 @@
22#ifndef __TWL6040_H__ 22#ifndef __TWL6040_H__
23#define __TWL6040_H__ 23#define __TWL6040_H__
24 24
25enum twl6040_trim {
26 TWL6040_TRIM_TRIM1 = 0,
27 TWL6040_TRIM_TRIM2,
28 TWL6040_TRIM_TRIM3,
29 TWL6040_TRIM_HSOTRIM,
30 TWL6040_TRIM_HFOTRIM,
31 TWL6040_TRIM_INVAL,
32};
33
34#define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f)
35#define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f)
36
25void twl6040_hs_jack_detect(struct snd_soc_codec *codec, 37void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
26 struct snd_soc_jack *jack, int report); 38 struct snd_soc_jack *jack, int report);
27int twl6040_get_clk_id(struct snd_soc_codec *codec); 39int twl6040_get_clk_id(struct snd_soc_codec *codec);
40int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
28 41
29#endif /* End of __TWL6040_H__ */ 42#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 5836201834d9..9fa14299cf2c 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -462,7 +462,6 @@ static int wl1273_probe(struct snd_soc_codec *codec)
462 wl1273->core = *core; 462 wl1273->core = *core;
463 463
464 snd_soc_codec_set_drvdata(codec, wl1273); 464 snd_soc_codec_set_drvdata(codec, wl1273);
465 mutex_init(&codec->mutex);
466 465
467 r = snd_soc_add_controls(codec, wl1273_controls, 466 r = snd_soc_add_controls(codec, wl1273_controls,
468 ARRAY_SIZE(wl1273_controls)); 467 ARRAY_SIZE(wl1273_controls));
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index bcc208967917..cd0ec0fd1dba 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -12,10 +12,59 @@
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
15#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/gpio.h>
16 18
17#include <sound/soc.h> 19#include <sound/soc.h>
18#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21#include <sound/wm1250-ev1.h>
22
23static const char *wm1250_gpio_names[WM1250_EV1_NUM_GPIOS] = {
24 "WM1250 CLK_ENA",
25 "WM1250 CLK_SEL0",
26 "WM1250 CLK_SEL1",
27 "WM1250 OSR",
28 "WM1250 MASTER",
29};
30
31struct wm1250_priv {
32 struct gpio gpios[WM1250_EV1_NUM_GPIOS];
33};
34
35static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec,
36 enum snd_soc_bias_level level)
37{
38 struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev);
39 int ena;
40
41 if (wm1250)
42 ena = wm1250->gpios[WM1250_EV1_GPIO_CLK_ENA].gpio;
43 else
44 ena = -1;
45
46 switch (level) {
47 case SND_SOC_BIAS_ON:
48 break;
49
50 case SND_SOC_BIAS_PREPARE:
51 break;
52
53 case SND_SOC_BIAS_STANDBY:
54 if (ena >= 0)
55 gpio_set_value_cansleep(ena, 1);
56 break;
57
58 case SND_SOC_BIAS_OFF:
59 if (ena >= 0)
60 gpio_set_value_cansleep(ena, 0);
61 break;
62 }
63
64 codec->dapm.bias_level = level;
65
66 return 0;
67}
19 68
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = { 69static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), 70SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
@@ -53,18 +102,103 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), 102 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes, 103 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), 104 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
105
106 .set_bias_level = wm1250_ev1_set_bias_level,
107 .idle_bias_off = true,
56}; 108};
57 109
110static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
111{
112 struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev);
113 struct wm1250_priv *wm1250;
114 int i, ret;
115
116 if (!pdata)
117 return 0;
118
119 wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL);
120 if (!wm1250) {
121 dev_err(&i2c->dev, "Unable to allocate private data\n");
122 ret = -ENOMEM;
123 goto err;
124 }
125
126 for (i = 0; i < ARRAY_SIZE(wm1250->gpios); i++) {
127 wm1250->gpios[i].gpio = pdata->gpios[i];
128 wm1250->gpios[i].label = wm1250_gpio_names[i];
129 wm1250->gpios[i].flags = GPIOF_OUT_INIT_LOW;
130 }
131 wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].flags = GPIOF_OUT_INIT_HIGH;
132 wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].flags = GPIOF_OUT_INIT_HIGH;
133
134 ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
135 if (ret != 0) {
136 dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
137 goto err_alloc;
138 }
139
140 dev_set_drvdata(&i2c->dev, wm1250);
141
142 return ret;
143
144err_alloc:
145 kfree(wm1250);
146err:
147 return ret;
148}
149
150static void wm1250_ev1_free(struct i2c_client *i2c)
151{
152 struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
153
154 if (wm1250) {
155 gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
156 kfree(wm1250);
157 }
158}
159
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, 160static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id) 161 const struct i2c_device_id *i2c_id)
60{ 162{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, 163 int id, board, rev, ret;
62 &wm1250_ev1_dai, 1); 164
165 dev_set_drvdata(&i2c->dev, NULL);
166
167 board = i2c_smbus_read_byte_data(i2c, 0);
168 if (board < 0) {
169 dev_err(&i2c->dev, "Failed to read ID: %d\n", board);
170 return board;
171 }
172
173 id = (board & 0xfe) >> 2;
174 rev = board & 0x3;
175
176 if (id != 1) {
177 dev_err(&i2c->dev, "Unknown board ID %d\n", id);
178 return -ENODEV;
179 }
180
181 dev_info(&i2c->dev, "revision %d\n", rev + 1);
182
183 ret = wm1250_ev1_pdata(i2c);
184 if (ret != 0)
185 return ret;
186
187 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
188 &wm1250_ev1_dai, 1);
189 if (ret != 0) {
190 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
191 wm1250_ev1_free(i2c);
192 return ret;
193 }
194
195 return 0;
63} 196}
64 197
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) 198static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{ 199{
67 snd_soc_unregister_codec(&i2c->dev); 200 snd_soc_unregister_codec(&i2c->dev);
201 wm1250_ev1_free(i2c);
68 202
69 return 0; 203 return 0;
70} 204}
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
new file mode 100644
index 000000000000..e9ce81a57b85
--- /dev/null
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -0,0 +1,1531 @@
1/*
2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include "wm5100.h"
15
16int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
17{
18 switch (reg) {
19 case WM5100_SOFTWARE_RESET:
20 case WM5100_DEVICE_REVISION:
21 case WM5100_FX_CTRL:
22 case WM5100_INTERRUPT_STATUS_1:
23 case WM5100_INTERRUPT_STATUS_2:
24 case WM5100_INTERRUPT_STATUS_3:
25 case WM5100_INTERRUPT_STATUS_4:
26 case WM5100_INTERRUPT_RAW_STATUS_2:
27 case WM5100_INTERRUPT_RAW_STATUS_3:
28 case WM5100_INTERRUPT_RAW_STATUS_4:
29 case WM5100_OUTPUT_STATUS_1:
30 case WM5100_OUTPUT_STATUS_2:
31 case WM5100_INPUT_ENABLES_STATUS:
32 case WM5100_MIC_DETECT_3:
33 return 1;
34 default:
35 return 0;
36 }
37}
38
39int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
40{
41 switch (reg) {
42 case WM5100_SOFTWARE_RESET:
43 case WM5100_DEVICE_REVISION:
44 case WM5100_CTRL_IF_1:
45 case WM5100_TONE_GENERATOR_1:
46 case WM5100_PWM_DRIVE_1:
47 case WM5100_PWM_DRIVE_2:
48 case WM5100_PWM_DRIVE_3:
49 case WM5100_CLOCKING_1:
50 case WM5100_CLOCKING_3:
51 case WM5100_CLOCKING_4:
52 case WM5100_CLOCKING_5:
53 case WM5100_CLOCKING_6:
54 case WM5100_CLOCKING_7:
55 case WM5100_CLOCKING_8:
56 case WM5100_ASRC_ENABLE:
57 case WM5100_ASRC_STATUS:
58 case WM5100_ASRC_RATE1:
59 case WM5100_ISRC_1_CTRL_1:
60 case WM5100_ISRC_1_CTRL_2:
61 case WM5100_ISRC_2_CTRL1:
62 case WM5100_ISRC_2_CTRL_2:
63 case WM5100_FLL1_CONTROL_1:
64 case WM5100_FLL1_CONTROL_2:
65 case WM5100_FLL1_CONTROL_3:
66 case WM5100_FLL1_CONTROL_5:
67 case WM5100_FLL1_CONTROL_6:
68 case WM5100_FLL1_EFS_1:
69 case WM5100_FLL2_CONTROL_1:
70 case WM5100_FLL2_CONTROL_2:
71 case WM5100_FLL2_CONTROL_3:
72 case WM5100_FLL2_CONTROL_5:
73 case WM5100_FLL2_CONTROL_6:
74 case WM5100_FLL2_EFS_1:
75 case WM5100_MIC_CHARGE_PUMP_1:
76 case WM5100_MIC_CHARGE_PUMP_2:
77 case WM5100_HP_CHARGE_PUMP_1:
78 case WM5100_LDO1_CONTROL:
79 case WM5100_MIC_BIAS_CTRL_1:
80 case WM5100_MIC_BIAS_CTRL_2:
81 case WM5100_MIC_BIAS_CTRL_3:
82 case WM5100_ACCESSORY_DETECT_MODE_1:
83 case WM5100_HEADPHONE_DETECT_1:
84 case WM5100_HEADPHONE_DETECT_2:
85 case WM5100_MIC_DETECT_1:
86 case WM5100_MIC_DETECT_2:
87 case WM5100_MIC_DETECT_3:
88 case WM5100_INPUT_ENABLES:
89 case WM5100_INPUT_ENABLES_STATUS:
90 case WM5100_IN1L_CONTROL:
91 case WM5100_IN1R_CONTROL:
92 case WM5100_IN2L_CONTROL:
93 case WM5100_IN2R_CONTROL:
94 case WM5100_IN3L_CONTROL:
95 case WM5100_IN3R_CONTROL:
96 case WM5100_IN4L_CONTROL:
97 case WM5100_IN4R_CONTROL:
98 case WM5100_RXANC_SRC:
99 case WM5100_INPUT_VOLUME_RAMP:
100 case WM5100_ADC_DIGITAL_VOLUME_1L:
101 case WM5100_ADC_DIGITAL_VOLUME_1R:
102 case WM5100_ADC_DIGITAL_VOLUME_2L:
103 case WM5100_ADC_DIGITAL_VOLUME_2R:
104 case WM5100_ADC_DIGITAL_VOLUME_3L:
105 case WM5100_ADC_DIGITAL_VOLUME_3R:
106 case WM5100_ADC_DIGITAL_VOLUME_4L:
107 case WM5100_ADC_DIGITAL_VOLUME_4R:
108 case WM5100_OUTPUT_ENABLES_2:
109 case WM5100_OUTPUT_STATUS_1:
110 case WM5100_OUTPUT_STATUS_2:
111 case WM5100_CHANNEL_ENABLES_1:
112 case WM5100_OUT_VOLUME_1L:
113 case WM5100_OUT_VOLUME_1R:
114 case WM5100_DAC_VOLUME_LIMIT_1L:
115 case WM5100_DAC_VOLUME_LIMIT_1R:
116 case WM5100_OUT_VOLUME_2L:
117 case WM5100_OUT_VOLUME_2R:
118 case WM5100_DAC_VOLUME_LIMIT_2L:
119 case WM5100_DAC_VOLUME_LIMIT_2R:
120 case WM5100_OUT_VOLUME_3L:
121 case WM5100_OUT_VOLUME_3R:
122 case WM5100_DAC_VOLUME_LIMIT_3L:
123 case WM5100_DAC_VOLUME_LIMIT_3R:
124 case WM5100_OUT_VOLUME_4L:
125 case WM5100_OUT_VOLUME_4R:
126 case WM5100_DAC_VOLUME_LIMIT_5L:
127 case WM5100_DAC_VOLUME_LIMIT_5R:
128 case WM5100_DAC_VOLUME_LIMIT_6L:
129 case WM5100_DAC_VOLUME_LIMIT_6R:
130 case WM5100_DAC_AEC_CONTROL_1:
131 case WM5100_OUTPUT_VOLUME_RAMP:
132 case WM5100_DAC_DIGITAL_VOLUME_1L:
133 case WM5100_DAC_DIGITAL_VOLUME_1R:
134 case WM5100_DAC_DIGITAL_VOLUME_2L:
135 case WM5100_DAC_DIGITAL_VOLUME_2R:
136 case WM5100_DAC_DIGITAL_VOLUME_3L:
137 case WM5100_DAC_DIGITAL_VOLUME_3R:
138 case WM5100_DAC_DIGITAL_VOLUME_4L:
139 case WM5100_DAC_DIGITAL_VOLUME_4R:
140 case WM5100_DAC_DIGITAL_VOLUME_5L:
141 case WM5100_DAC_DIGITAL_VOLUME_5R:
142 case WM5100_DAC_DIGITAL_VOLUME_6L:
143 case WM5100_DAC_DIGITAL_VOLUME_6R:
144 case WM5100_PDM_SPK1_CTRL_1:
145 case WM5100_PDM_SPK1_CTRL_2:
146 case WM5100_PDM_SPK2_CTRL_1:
147 case WM5100_PDM_SPK2_CTRL_2:
148 case WM5100_AUDIO_IF_1_1:
149 case WM5100_AUDIO_IF_1_2:
150 case WM5100_AUDIO_IF_1_3:
151 case WM5100_AUDIO_IF_1_4:
152 case WM5100_AUDIO_IF_1_5:
153 case WM5100_AUDIO_IF_1_6:
154 case WM5100_AUDIO_IF_1_7:
155 case WM5100_AUDIO_IF_1_8:
156 case WM5100_AUDIO_IF_1_9:
157 case WM5100_AUDIO_IF_1_10:
158 case WM5100_AUDIO_IF_1_11:
159 case WM5100_AUDIO_IF_1_12:
160 case WM5100_AUDIO_IF_1_13:
161 case WM5100_AUDIO_IF_1_14:
162 case WM5100_AUDIO_IF_1_15:
163 case WM5100_AUDIO_IF_1_16:
164 case WM5100_AUDIO_IF_1_17:
165 case WM5100_AUDIO_IF_1_18:
166 case WM5100_AUDIO_IF_1_19:
167 case WM5100_AUDIO_IF_1_20:
168 case WM5100_AUDIO_IF_1_21:
169 case WM5100_AUDIO_IF_1_22:
170 case WM5100_AUDIO_IF_1_23:
171 case WM5100_AUDIO_IF_1_24:
172 case WM5100_AUDIO_IF_1_25:
173 case WM5100_AUDIO_IF_1_26:
174 case WM5100_AUDIO_IF_1_27:
175 case WM5100_AUDIO_IF_2_1:
176 case WM5100_AUDIO_IF_2_2:
177 case WM5100_AUDIO_IF_2_3:
178 case WM5100_AUDIO_IF_2_4:
179 case WM5100_AUDIO_IF_2_5:
180 case WM5100_AUDIO_IF_2_6:
181 case WM5100_AUDIO_IF_2_7:
182 case WM5100_AUDIO_IF_2_8:
183 case WM5100_AUDIO_IF_2_9:
184 case WM5100_AUDIO_IF_2_10:
185 case WM5100_AUDIO_IF_2_11:
186 case WM5100_AUDIO_IF_2_18:
187 case WM5100_AUDIO_IF_2_19:
188 case WM5100_AUDIO_IF_2_26:
189 case WM5100_AUDIO_IF_2_27:
190 case WM5100_AUDIO_IF_3_1:
191 case WM5100_AUDIO_IF_3_2:
192 case WM5100_AUDIO_IF_3_3:
193 case WM5100_AUDIO_IF_3_4:
194 case WM5100_AUDIO_IF_3_5:
195 case WM5100_AUDIO_IF_3_6:
196 case WM5100_AUDIO_IF_3_7:
197 case WM5100_AUDIO_IF_3_8:
198 case WM5100_AUDIO_IF_3_9:
199 case WM5100_AUDIO_IF_3_10:
200 case WM5100_AUDIO_IF_3_11:
201 case WM5100_AUDIO_IF_3_18:
202 case WM5100_AUDIO_IF_3_19:
203 case WM5100_AUDIO_IF_3_26:
204 case WM5100_AUDIO_IF_3_27:
205 case WM5100_PWM1MIX_INPUT_1_SOURCE:
206 case WM5100_PWM1MIX_INPUT_1_VOLUME:
207 case WM5100_PWM1MIX_INPUT_2_SOURCE:
208 case WM5100_PWM1MIX_INPUT_2_VOLUME:
209 case WM5100_PWM1MIX_INPUT_3_SOURCE:
210 case WM5100_PWM1MIX_INPUT_3_VOLUME:
211 case WM5100_PWM1MIX_INPUT_4_SOURCE:
212 case WM5100_PWM1MIX_INPUT_4_VOLUME:
213 case WM5100_PWM2MIX_INPUT_1_SOURCE:
214 case WM5100_PWM2MIX_INPUT_1_VOLUME:
215 case WM5100_PWM2MIX_INPUT_2_SOURCE:
216 case WM5100_PWM2MIX_INPUT_2_VOLUME:
217 case WM5100_PWM2MIX_INPUT_3_SOURCE:
218 case WM5100_PWM2MIX_INPUT_3_VOLUME:
219 case WM5100_PWM2MIX_INPUT_4_SOURCE:
220 case WM5100_PWM2MIX_INPUT_4_VOLUME:
221 case WM5100_OUT1LMIX_INPUT_1_SOURCE:
222 case WM5100_OUT1LMIX_INPUT_1_VOLUME:
223 case WM5100_OUT1LMIX_INPUT_2_SOURCE:
224 case WM5100_OUT1LMIX_INPUT_2_VOLUME:
225 case WM5100_OUT1LMIX_INPUT_3_SOURCE:
226 case WM5100_OUT1LMIX_INPUT_3_VOLUME:
227 case WM5100_OUT1LMIX_INPUT_4_SOURCE:
228 case WM5100_OUT1LMIX_INPUT_4_VOLUME:
229 case WM5100_OUT1RMIX_INPUT_1_SOURCE:
230 case WM5100_OUT1RMIX_INPUT_1_VOLUME:
231 case WM5100_OUT1RMIX_INPUT_2_SOURCE:
232 case WM5100_OUT1RMIX_INPUT_2_VOLUME:
233 case WM5100_OUT1RMIX_INPUT_3_SOURCE:
234 case WM5100_OUT1RMIX_INPUT_3_VOLUME:
235 case WM5100_OUT1RMIX_INPUT_4_SOURCE:
236 case WM5100_OUT1RMIX_INPUT_4_VOLUME:
237 case WM5100_OUT2LMIX_INPUT_1_SOURCE:
238 case WM5100_OUT2LMIX_INPUT_1_VOLUME:
239 case WM5100_OUT2LMIX_INPUT_2_SOURCE:
240 case WM5100_OUT2LMIX_INPUT_2_VOLUME:
241 case WM5100_OUT2LMIX_INPUT_3_SOURCE:
242 case WM5100_OUT2LMIX_INPUT_3_VOLUME:
243 case WM5100_OUT2LMIX_INPUT_4_SOURCE:
244 case WM5100_OUT2LMIX_INPUT_4_VOLUME:
245 case WM5100_OUT2RMIX_INPUT_1_SOURCE:
246 case WM5100_OUT2RMIX_INPUT_1_VOLUME:
247 case WM5100_OUT2RMIX_INPUT_2_SOURCE:
248 case WM5100_OUT2RMIX_INPUT_2_VOLUME:
249 case WM5100_OUT2RMIX_INPUT_3_SOURCE:
250 case WM5100_OUT2RMIX_INPUT_3_VOLUME:
251 case WM5100_OUT2RMIX_INPUT_4_SOURCE:
252 case WM5100_OUT2RMIX_INPUT_4_VOLUME:
253 case WM5100_OUT3LMIX_INPUT_1_SOURCE:
254 case WM5100_OUT3LMIX_INPUT_1_VOLUME:
255 case WM5100_OUT3LMIX_INPUT_2_SOURCE:
256 case WM5100_OUT3LMIX_INPUT_2_VOLUME:
257 case WM5100_OUT3LMIX_INPUT_3_SOURCE:
258 case WM5100_OUT3LMIX_INPUT_3_VOLUME:
259 case WM5100_OUT3LMIX_INPUT_4_SOURCE:
260 case WM5100_OUT3LMIX_INPUT_4_VOLUME:
261 case WM5100_OUT3RMIX_INPUT_1_SOURCE:
262 case WM5100_OUT3RMIX_INPUT_1_VOLUME:
263 case WM5100_OUT3RMIX_INPUT_2_SOURCE:
264 case WM5100_OUT3RMIX_INPUT_2_VOLUME:
265 case WM5100_OUT3RMIX_INPUT_3_SOURCE:
266 case WM5100_OUT3RMIX_INPUT_3_VOLUME:
267 case WM5100_OUT3RMIX_INPUT_4_SOURCE:
268 case WM5100_OUT3RMIX_INPUT_4_VOLUME:
269 case WM5100_OUT4LMIX_INPUT_1_SOURCE:
270 case WM5100_OUT4LMIX_INPUT_1_VOLUME:
271 case WM5100_OUT4LMIX_INPUT_2_SOURCE:
272 case WM5100_OUT4LMIX_INPUT_2_VOLUME:
273 case WM5100_OUT4LMIX_INPUT_3_SOURCE:
274 case WM5100_OUT4LMIX_INPUT_3_VOLUME:
275 case WM5100_OUT4LMIX_INPUT_4_SOURCE:
276 case WM5100_OUT4LMIX_INPUT_4_VOLUME:
277 case WM5100_OUT4RMIX_INPUT_1_SOURCE:
278 case WM5100_OUT4RMIX_INPUT_1_VOLUME:
279 case WM5100_OUT4RMIX_INPUT_2_SOURCE:
280 case WM5100_OUT4RMIX_INPUT_2_VOLUME:
281 case WM5100_OUT4RMIX_INPUT_3_SOURCE:
282 case WM5100_OUT4RMIX_INPUT_3_VOLUME:
283 case WM5100_OUT4RMIX_INPUT_4_SOURCE:
284 case WM5100_OUT4RMIX_INPUT_4_VOLUME:
285 case WM5100_OUT5LMIX_INPUT_1_SOURCE:
286 case WM5100_OUT5LMIX_INPUT_1_VOLUME:
287 case WM5100_OUT5LMIX_INPUT_2_SOURCE:
288 case WM5100_OUT5LMIX_INPUT_2_VOLUME:
289 case WM5100_OUT5LMIX_INPUT_3_SOURCE:
290 case WM5100_OUT5LMIX_INPUT_3_VOLUME:
291 case WM5100_OUT5LMIX_INPUT_4_SOURCE:
292 case WM5100_OUT5LMIX_INPUT_4_VOLUME:
293 case WM5100_OUT5RMIX_INPUT_1_SOURCE:
294 case WM5100_OUT5RMIX_INPUT_1_VOLUME:
295 case WM5100_OUT5RMIX_INPUT_2_SOURCE:
296 case WM5100_OUT5RMIX_INPUT_2_VOLUME:
297 case WM5100_OUT5RMIX_INPUT_3_SOURCE:
298 case WM5100_OUT5RMIX_INPUT_3_VOLUME:
299 case WM5100_OUT5RMIX_INPUT_4_SOURCE:
300 case WM5100_OUT5RMIX_INPUT_4_VOLUME:
301 case WM5100_OUT6LMIX_INPUT_1_SOURCE:
302 case WM5100_OUT6LMIX_INPUT_1_VOLUME:
303 case WM5100_OUT6LMIX_INPUT_2_SOURCE:
304 case WM5100_OUT6LMIX_INPUT_2_VOLUME:
305 case WM5100_OUT6LMIX_INPUT_3_SOURCE:
306 case WM5100_OUT6LMIX_INPUT_3_VOLUME:
307 case WM5100_OUT6LMIX_INPUT_4_SOURCE:
308 case WM5100_OUT6LMIX_INPUT_4_VOLUME:
309 case WM5100_OUT6RMIX_INPUT_1_SOURCE:
310 case WM5100_OUT6RMIX_INPUT_1_VOLUME:
311 case WM5100_OUT6RMIX_INPUT_2_SOURCE:
312 case WM5100_OUT6RMIX_INPUT_2_VOLUME:
313 case WM5100_OUT6RMIX_INPUT_3_SOURCE:
314 case WM5100_OUT6RMIX_INPUT_3_VOLUME:
315 case WM5100_OUT6RMIX_INPUT_4_SOURCE:
316 case WM5100_OUT6RMIX_INPUT_4_VOLUME:
317 case WM5100_AIF1TX1MIX_INPUT_1_SOURCE:
318 case WM5100_AIF1TX1MIX_INPUT_1_VOLUME:
319 case WM5100_AIF1TX1MIX_INPUT_2_SOURCE:
320 case WM5100_AIF1TX1MIX_INPUT_2_VOLUME:
321 case WM5100_AIF1TX1MIX_INPUT_3_SOURCE:
322 case WM5100_AIF1TX1MIX_INPUT_3_VOLUME:
323 case WM5100_AIF1TX1MIX_INPUT_4_SOURCE:
324 case WM5100_AIF1TX1MIX_INPUT_4_VOLUME:
325 case WM5100_AIF1TX2MIX_INPUT_1_SOURCE:
326 case WM5100_AIF1TX2MIX_INPUT_1_VOLUME:
327 case WM5100_AIF1TX2MIX_INPUT_2_SOURCE:
328 case WM5100_AIF1TX2MIX_INPUT_2_VOLUME:
329 case WM5100_AIF1TX2MIX_INPUT_3_SOURCE:
330 case WM5100_AIF1TX2MIX_INPUT_3_VOLUME:
331 case WM5100_AIF1TX2MIX_INPUT_4_SOURCE:
332 case WM5100_AIF1TX2MIX_INPUT_4_VOLUME:
333 case WM5100_AIF1TX3MIX_INPUT_1_SOURCE:
334 case WM5100_AIF1TX3MIX_INPUT_1_VOLUME:
335 case WM5100_AIF1TX3MIX_INPUT_2_SOURCE:
336 case WM5100_AIF1TX3MIX_INPUT_2_VOLUME:
337 case WM5100_AIF1TX3MIX_INPUT_3_SOURCE:
338 case WM5100_AIF1TX3MIX_INPUT_3_VOLUME:
339 case WM5100_AIF1TX3MIX_INPUT_4_SOURCE:
340 case WM5100_AIF1TX3MIX_INPUT_4_VOLUME:
341 case WM5100_AIF1TX4MIX_INPUT_1_SOURCE:
342 case WM5100_AIF1TX4MIX_INPUT_1_VOLUME:
343 case WM5100_AIF1TX4MIX_INPUT_2_SOURCE:
344 case WM5100_AIF1TX4MIX_INPUT_2_VOLUME:
345 case WM5100_AIF1TX4MIX_INPUT_3_SOURCE:
346 case WM5100_AIF1TX4MIX_INPUT_3_VOLUME:
347 case WM5100_AIF1TX4MIX_INPUT_4_SOURCE:
348 case WM5100_AIF1TX4MIX_INPUT_4_VOLUME:
349 case WM5100_AIF1TX5MIX_INPUT_1_SOURCE:
350 case WM5100_AIF1TX5MIX_INPUT_1_VOLUME:
351 case WM5100_AIF1TX5MIX_INPUT_2_SOURCE:
352 case WM5100_AIF1TX5MIX_INPUT_2_VOLUME:
353 case WM5100_AIF1TX5MIX_INPUT_3_SOURCE:
354 case WM5100_AIF1TX5MIX_INPUT_3_VOLUME:
355 case WM5100_AIF1TX5MIX_INPUT_4_SOURCE:
356 case WM5100_AIF1TX5MIX_INPUT_4_VOLUME:
357 case WM5100_AIF1TX6MIX_INPUT_1_SOURCE:
358 case WM5100_AIF1TX6MIX_INPUT_1_VOLUME:
359 case WM5100_AIF1TX6MIX_INPUT_2_SOURCE:
360 case WM5100_AIF1TX6MIX_INPUT_2_VOLUME:
361 case WM5100_AIF1TX6MIX_INPUT_3_SOURCE:
362 case WM5100_AIF1TX6MIX_INPUT_3_VOLUME:
363 case WM5100_AIF1TX6MIX_INPUT_4_SOURCE:
364 case WM5100_AIF1TX6MIX_INPUT_4_VOLUME:
365 case WM5100_AIF1TX7MIX_INPUT_1_SOURCE:
366 case WM5100_AIF1TX7MIX_INPUT_1_VOLUME:
367 case WM5100_AIF1TX7MIX_INPUT_2_SOURCE:
368 case WM5100_AIF1TX7MIX_INPUT_2_VOLUME:
369 case WM5100_AIF1TX7MIX_INPUT_3_SOURCE:
370 case WM5100_AIF1TX7MIX_INPUT_3_VOLUME:
371 case WM5100_AIF1TX7MIX_INPUT_4_SOURCE:
372 case WM5100_AIF1TX7MIX_INPUT_4_VOLUME:
373 case WM5100_AIF1TX8MIX_INPUT_1_SOURCE:
374 case WM5100_AIF1TX8MIX_INPUT_1_VOLUME:
375 case WM5100_AIF1TX8MIX_INPUT_2_SOURCE:
376 case WM5100_AIF1TX8MIX_INPUT_2_VOLUME:
377 case WM5100_AIF1TX8MIX_INPUT_3_SOURCE:
378 case WM5100_AIF1TX8MIX_INPUT_3_VOLUME:
379 case WM5100_AIF1TX8MIX_INPUT_4_SOURCE:
380 case WM5100_AIF1TX8MIX_INPUT_4_VOLUME:
381 case WM5100_AIF2TX1MIX_INPUT_1_SOURCE:
382 case WM5100_AIF2TX1MIX_INPUT_1_VOLUME:
383 case WM5100_AIF2TX1MIX_INPUT_2_SOURCE:
384 case WM5100_AIF2TX1MIX_INPUT_2_VOLUME:
385 case WM5100_AIF2TX1MIX_INPUT_3_SOURCE:
386 case WM5100_AIF2TX1MIX_INPUT_3_VOLUME:
387 case WM5100_AIF2TX1MIX_INPUT_4_SOURCE:
388 case WM5100_AIF2TX1MIX_INPUT_4_VOLUME:
389 case WM5100_AIF2TX2MIX_INPUT_1_SOURCE:
390 case WM5100_AIF2TX2MIX_INPUT_1_VOLUME:
391 case WM5100_AIF2TX2MIX_INPUT_2_SOURCE:
392 case WM5100_AIF2TX2MIX_INPUT_2_VOLUME:
393 case WM5100_AIF2TX2MIX_INPUT_3_SOURCE:
394 case WM5100_AIF2TX2MIX_INPUT_3_VOLUME:
395 case WM5100_AIF2TX2MIX_INPUT_4_SOURCE:
396 case WM5100_AIF2TX2MIX_INPUT_4_VOLUME:
397 case WM5100_AIF3TX1MIX_INPUT_1_SOURCE:
398 case WM5100_AIF3TX1MIX_INPUT_1_VOLUME:
399 case WM5100_AIF3TX1MIX_INPUT_2_SOURCE:
400 case WM5100_AIF3TX1MIX_INPUT_2_VOLUME:
401 case WM5100_AIF3TX1MIX_INPUT_3_SOURCE:
402 case WM5100_AIF3TX1MIX_INPUT_3_VOLUME:
403 case WM5100_AIF3TX1MIX_INPUT_4_SOURCE:
404 case WM5100_AIF3TX1MIX_INPUT_4_VOLUME:
405 case WM5100_AIF3TX2MIX_INPUT_1_SOURCE:
406 case WM5100_AIF3TX2MIX_INPUT_1_VOLUME:
407 case WM5100_AIF3TX2MIX_INPUT_2_SOURCE:
408 case WM5100_AIF3TX2MIX_INPUT_2_VOLUME:
409 case WM5100_AIF3TX2MIX_INPUT_3_SOURCE:
410 case WM5100_AIF3TX2MIX_INPUT_3_VOLUME:
411 case WM5100_AIF3TX2MIX_INPUT_4_SOURCE:
412 case WM5100_AIF3TX2MIX_INPUT_4_VOLUME:
413 case WM5100_EQ1MIX_INPUT_1_SOURCE:
414 case WM5100_EQ1MIX_INPUT_1_VOLUME:
415 case WM5100_EQ1MIX_INPUT_2_SOURCE:
416 case WM5100_EQ1MIX_INPUT_2_VOLUME:
417 case WM5100_EQ1MIX_INPUT_3_SOURCE:
418 case WM5100_EQ1MIX_INPUT_3_VOLUME:
419 case WM5100_EQ1MIX_INPUT_4_SOURCE:
420 case WM5100_EQ1MIX_INPUT_4_VOLUME:
421 case WM5100_EQ2MIX_INPUT_1_SOURCE:
422 case WM5100_EQ2MIX_INPUT_1_VOLUME:
423 case WM5100_EQ2MIX_INPUT_2_SOURCE:
424 case WM5100_EQ2MIX_INPUT_2_VOLUME:
425 case WM5100_EQ2MIX_INPUT_3_SOURCE:
426 case WM5100_EQ2MIX_INPUT_3_VOLUME:
427 case WM5100_EQ2MIX_INPUT_4_SOURCE:
428 case WM5100_EQ2MIX_INPUT_4_VOLUME:
429 case WM5100_EQ3MIX_INPUT_1_SOURCE:
430 case WM5100_EQ3MIX_INPUT_1_VOLUME:
431 case WM5100_EQ3MIX_INPUT_2_SOURCE:
432 case WM5100_EQ3MIX_INPUT_2_VOLUME:
433 case WM5100_EQ3MIX_INPUT_3_SOURCE:
434 case WM5100_EQ3MIX_INPUT_3_VOLUME:
435 case WM5100_EQ3MIX_INPUT_4_SOURCE:
436 case WM5100_EQ3MIX_INPUT_4_VOLUME:
437 case WM5100_EQ4MIX_INPUT_1_SOURCE:
438 case WM5100_EQ4MIX_INPUT_1_VOLUME:
439 case WM5100_EQ4MIX_INPUT_2_SOURCE:
440 case WM5100_EQ4MIX_INPUT_2_VOLUME:
441 case WM5100_EQ4MIX_INPUT_3_SOURCE:
442 case WM5100_EQ4MIX_INPUT_3_VOLUME:
443 case WM5100_EQ4MIX_INPUT_4_SOURCE:
444 case WM5100_EQ4MIX_INPUT_4_VOLUME:
445 case WM5100_DRC1LMIX_INPUT_1_SOURCE:
446 case WM5100_DRC1LMIX_INPUT_1_VOLUME:
447 case WM5100_DRC1LMIX_INPUT_2_SOURCE:
448 case WM5100_DRC1LMIX_INPUT_2_VOLUME:
449 case WM5100_DRC1LMIX_INPUT_3_SOURCE:
450 case WM5100_DRC1LMIX_INPUT_3_VOLUME:
451 case WM5100_DRC1LMIX_INPUT_4_SOURCE:
452 case WM5100_DRC1LMIX_INPUT_4_VOLUME:
453 case WM5100_DRC1RMIX_INPUT_1_SOURCE:
454 case WM5100_DRC1RMIX_INPUT_1_VOLUME:
455 case WM5100_DRC1RMIX_INPUT_2_SOURCE:
456 case WM5100_DRC1RMIX_INPUT_2_VOLUME:
457 case WM5100_DRC1RMIX_INPUT_3_SOURCE:
458 case WM5100_DRC1RMIX_INPUT_3_VOLUME:
459 case WM5100_DRC1RMIX_INPUT_4_SOURCE:
460 case WM5100_DRC1RMIX_INPUT_4_VOLUME:
461 case WM5100_HPLP1MIX_INPUT_1_SOURCE:
462 case WM5100_HPLP1MIX_INPUT_1_VOLUME:
463 case WM5100_HPLP1MIX_INPUT_2_SOURCE:
464 case WM5100_HPLP1MIX_INPUT_2_VOLUME:
465 case WM5100_HPLP1MIX_INPUT_3_SOURCE:
466 case WM5100_HPLP1MIX_INPUT_3_VOLUME:
467 case WM5100_HPLP1MIX_INPUT_4_SOURCE:
468 case WM5100_HPLP1MIX_INPUT_4_VOLUME:
469 case WM5100_HPLP2MIX_INPUT_1_SOURCE:
470 case WM5100_HPLP2MIX_INPUT_1_VOLUME:
471 case WM5100_HPLP2MIX_INPUT_2_SOURCE:
472 case WM5100_HPLP2MIX_INPUT_2_VOLUME:
473 case WM5100_HPLP2MIX_INPUT_3_SOURCE:
474 case WM5100_HPLP2MIX_INPUT_3_VOLUME:
475 case WM5100_HPLP2MIX_INPUT_4_SOURCE:
476 case WM5100_HPLP2MIX_INPUT_4_VOLUME:
477 case WM5100_HPLP3MIX_INPUT_1_SOURCE:
478 case WM5100_HPLP3MIX_INPUT_1_VOLUME:
479 case WM5100_HPLP3MIX_INPUT_2_SOURCE:
480 case WM5100_HPLP3MIX_INPUT_2_VOLUME:
481 case WM5100_HPLP3MIX_INPUT_3_SOURCE:
482 case WM5100_HPLP3MIX_INPUT_3_VOLUME:
483 case WM5100_HPLP3MIX_INPUT_4_SOURCE:
484 case WM5100_HPLP3MIX_INPUT_4_VOLUME:
485 case WM5100_HPLP4MIX_INPUT_1_SOURCE:
486 case WM5100_HPLP4MIX_INPUT_1_VOLUME:
487 case WM5100_HPLP4MIX_INPUT_2_SOURCE:
488 case WM5100_HPLP4MIX_INPUT_2_VOLUME:
489 case WM5100_HPLP4MIX_INPUT_3_SOURCE:
490 case WM5100_HPLP4MIX_INPUT_3_VOLUME:
491 case WM5100_HPLP4MIX_INPUT_4_SOURCE:
492 case WM5100_HPLP4MIX_INPUT_4_VOLUME:
493 case WM5100_DSP1LMIX_INPUT_1_SOURCE:
494 case WM5100_DSP1LMIX_INPUT_1_VOLUME:
495 case WM5100_DSP1LMIX_INPUT_2_SOURCE:
496 case WM5100_DSP1LMIX_INPUT_2_VOLUME:
497 case WM5100_DSP1LMIX_INPUT_3_SOURCE:
498 case WM5100_DSP1LMIX_INPUT_3_VOLUME:
499 case WM5100_DSP1LMIX_INPUT_4_SOURCE:
500 case WM5100_DSP1LMIX_INPUT_4_VOLUME:
501 case WM5100_DSP1RMIX_INPUT_1_SOURCE:
502 case WM5100_DSP1RMIX_INPUT_1_VOLUME:
503 case WM5100_DSP1RMIX_INPUT_2_SOURCE:
504 case WM5100_DSP1RMIX_INPUT_2_VOLUME:
505 case WM5100_DSP1RMIX_INPUT_3_SOURCE:
506 case WM5100_DSP1RMIX_INPUT_3_VOLUME:
507 case WM5100_DSP1RMIX_INPUT_4_SOURCE:
508 case WM5100_DSP1RMIX_INPUT_4_VOLUME:
509 case WM5100_DSP1AUX1MIX_INPUT_1_SOURCE:
510 case WM5100_DSP1AUX2MIX_INPUT_1_SOURCE:
511 case WM5100_DSP1AUX3MIX_INPUT_1_SOURCE:
512 case WM5100_DSP1AUX4MIX_INPUT_1_SOURCE:
513 case WM5100_DSP1AUX5MIX_INPUT_1_SOURCE:
514 case WM5100_DSP1AUX6MIX_INPUT_1_SOURCE:
515 case WM5100_DSP2LMIX_INPUT_1_SOURCE:
516 case WM5100_DSP2LMIX_INPUT_1_VOLUME:
517 case WM5100_DSP2LMIX_INPUT_2_SOURCE:
518 case WM5100_DSP2LMIX_INPUT_2_VOLUME:
519 case WM5100_DSP2LMIX_INPUT_3_SOURCE:
520 case WM5100_DSP2LMIX_INPUT_3_VOLUME:
521 case WM5100_DSP2LMIX_INPUT_4_SOURCE:
522 case WM5100_DSP2LMIX_INPUT_4_VOLUME:
523 case WM5100_DSP2RMIX_INPUT_1_SOURCE:
524 case WM5100_DSP2RMIX_INPUT_1_VOLUME:
525 case WM5100_DSP2RMIX_INPUT_2_SOURCE:
526 case WM5100_DSP2RMIX_INPUT_2_VOLUME:
527 case WM5100_DSP2RMIX_INPUT_3_SOURCE:
528 case WM5100_DSP2RMIX_INPUT_3_VOLUME:
529 case WM5100_DSP2RMIX_INPUT_4_SOURCE:
530 case WM5100_DSP2RMIX_INPUT_4_VOLUME:
531 case WM5100_DSP2AUX1MIX_INPUT_1_SOURCE:
532 case WM5100_DSP2AUX2MIX_INPUT_1_SOURCE:
533 case WM5100_DSP2AUX3MIX_INPUT_1_SOURCE:
534 case WM5100_DSP2AUX4MIX_INPUT_1_SOURCE:
535 case WM5100_DSP2AUX5MIX_INPUT_1_SOURCE:
536 case WM5100_DSP2AUX6MIX_INPUT_1_SOURCE:
537 case WM5100_DSP3LMIX_INPUT_1_SOURCE:
538 case WM5100_DSP3LMIX_INPUT_1_VOLUME:
539 case WM5100_DSP3LMIX_INPUT_2_SOURCE:
540 case WM5100_DSP3LMIX_INPUT_2_VOLUME:
541 case WM5100_DSP3LMIX_INPUT_3_SOURCE:
542 case WM5100_DSP3LMIX_INPUT_3_VOLUME:
543 case WM5100_DSP3LMIX_INPUT_4_SOURCE:
544 case WM5100_DSP3LMIX_INPUT_4_VOLUME:
545 case WM5100_DSP3RMIX_INPUT_1_SOURCE:
546 case WM5100_DSP3RMIX_INPUT_1_VOLUME:
547 case WM5100_DSP3RMIX_INPUT_2_SOURCE:
548 case WM5100_DSP3RMIX_INPUT_2_VOLUME:
549 case WM5100_DSP3RMIX_INPUT_3_SOURCE:
550 case WM5100_DSP3RMIX_INPUT_3_VOLUME:
551 case WM5100_DSP3RMIX_INPUT_4_SOURCE:
552 case WM5100_DSP3RMIX_INPUT_4_VOLUME:
553 case WM5100_DSP3AUX1MIX_INPUT_1_SOURCE:
554 case WM5100_DSP3AUX2MIX_INPUT_1_SOURCE:
555 case WM5100_DSP3AUX3MIX_INPUT_1_SOURCE:
556 case WM5100_DSP3AUX4MIX_INPUT_1_SOURCE:
557 case WM5100_DSP3AUX5MIX_INPUT_1_SOURCE:
558 case WM5100_DSP3AUX6MIX_INPUT_1_SOURCE:
559 case WM5100_ASRC1LMIX_INPUT_1_SOURCE:
560 case WM5100_ASRC1RMIX_INPUT_1_SOURCE:
561 case WM5100_ASRC2LMIX_INPUT_1_SOURCE:
562 case WM5100_ASRC2RMIX_INPUT_1_SOURCE:
563 case WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE:
564 case WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE:
565 case WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE:
566 case WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE:
567 case WM5100_ISRC1INT1MIX_INPUT_1_SOURCE:
568 case WM5100_ISRC1INT2MIX_INPUT_1_SOURCE:
569 case WM5100_ISRC1INT3MIX_INPUT_1_SOURCE:
570 case WM5100_ISRC1INT4MIX_INPUT_1_SOURCE:
571 case WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE:
572 case WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE:
573 case WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE:
574 case WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE:
575 case WM5100_ISRC2INT1MIX_INPUT_1_SOURCE:
576 case WM5100_ISRC2INT2MIX_INPUT_1_SOURCE:
577 case WM5100_ISRC2INT3MIX_INPUT_1_SOURCE:
578 case WM5100_ISRC2INT4MIX_INPUT_1_SOURCE:
579 case WM5100_GPIO_CTRL_1:
580 case WM5100_GPIO_CTRL_2:
581 case WM5100_GPIO_CTRL_3:
582 case WM5100_GPIO_CTRL_4:
583 case WM5100_GPIO_CTRL_5:
584 case WM5100_GPIO_CTRL_6:
585 case WM5100_MISC_PAD_CTRL_1:
586 case WM5100_MISC_PAD_CTRL_2:
587 case WM5100_MISC_PAD_CTRL_3:
588 case WM5100_MISC_PAD_CTRL_4:
589 case WM5100_MISC_PAD_CTRL_5:
590 case WM5100_MISC_GPIO_1:
591 case WM5100_INTERRUPT_STATUS_1:
592 case WM5100_INTERRUPT_STATUS_2:
593 case WM5100_INTERRUPT_STATUS_3:
594 case WM5100_INTERRUPT_STATUS_4:
595 case WM5100_INTERRUPT_RAW_STATUS_2:
596 case WM5100_INTERRUPT_RAW_STATUS_3:
597 case WM5100_INTERRUPT_RAW_STATUS_4:
598 case WM5100_INTERRUPT_STATUS_1_MASK:
599 case WM5100_INTERRUPT_STATUS_2_MASK:
600 case WM5100_INTERRUPT_STATUS_3_MASK:
601 case WM5100_INTERRUPT_STATUS_4_MASK:
602 case WM5100_INTERRUPT_CONTROL:
603 case WM5100_IRQ_DEBOUNCE_1:
604 case WM5100_IRQ_DEBOUNCE_2:
605 case WM5100_FX_CTRL:
606 case WM5100_EQ1_1:
607 case WM5100_EQ1_2:
608 case WM5100_EQ1_3:
609 case WM5100_EQ1_4:
610 case WM5100_EQ1_5:
611 case WM5100_EQ1_6:
612 case WM5100_EQ1_7:
613 case WM5100_EQ1_8:
614 case WM5100_EQ1_9:
615 case WM5100_EQ1_10:
616 case WM5100_EQ1_11:
617 case WM5100_EQ1_12:
618 case WM5100_EQ1_13:
619 case WM5100_EQ1_14:
620 case WM5100_EQ1_15:
621 case WM5100_EQ1_16:
622 case WM5100_EQ1_17:
623 case WM5100_EQ1_18:
624 case WM5100_EQ1_19:
625 case WM5100_EQ1_20:
626 case WM5100_EQ2_1:
627 case WM5100_EQ2_2:
628 case WM5100_EQ2_3:
629 case WM5100_EQ2_4:
630 case WM5100_EQ2_5:
631 case WM5100_EQ2_6:
632 case WM5100_EQ2_7:
633 case WM5100_EQ2_8:
634 case WM5100_EQ2_9:
635 case WM5100_EQ2_10:
636 case WM5100_EQ2_11:
637 case WM5100_EQ2_12:
638 case WM5100_EQ2_13:
639 case WM5100_EQ2_14:
640 case WM5100_EQ2_15:
641 case WM5100_EQ2_16:
642 case WM5100_EQ2_17:
643 case WM5100_EQ2_18:
644 case WM5100_EQ2_19:
645 case WM5100_EQ2_20:
646 case WM5100_EQ3_1:
647 case WM5100_EQ3_2:
648 case WM5100_EQ3_3:
649 case WM5100_EQ3_4:
650 case WM5100_EQ3_5:
651 case WM5100_EQ3_6:
652 case WM5100_EQ3_7:
653 case WM5100_EQ3_8:
654 case WM5100_EQ3_9:
655 case WM5100_EQ3_10:
656 case WM5100_EQ3_11:
657 case WM5100_EQ3_12:
658 case WM5100_EQ3_13:
659 case WM5100_EQ3_14:
660 case WM5100_EQ3_15:
661 case WM5100_EQ3_16:
662 case WM5100_EQ3_17:
663 case WM5100_EQ3_18:
664 case WM5100_EQ3_19:
665 case WM5100_EQ3_20:
666 case WM5100_EQ4_1:
667 case WM5100_EQ4_2:
668 case WM5100_EQ4_3:
669 case WM5100_EQ4_4:
670 case WM5100_EQ4_5:
671 case WM5100_EQ4_6:
672 case WM5100_EQ4_7:
673 case WM5100_EQ4_8:
674 case WM5100_EQ4_9:
675 case WM5100_EQ4_10:
676 case WM5100_EQ4_11:
677 case WM5100_EQ4_12:
678 case WM5100_EQ4_13:
679 case WM5100_EQ4_14:
680 case WM5100_EQ4_15:
681 case WM5100_EQ4_16:
682 case WM5100_EQ4_17:
683 case WM5100_EQ4_18:
684 case WM5100_EQ4_19:
685 case WM5100_EQ4_20:
686 case WM5100_DRC1_CTRL1:
687 case WM5100_DRC1_CTRL2:
688 case WM5100_DRC1_CTRL3:
689 case WM5100_DRC1_CTRL4:
690 case WM5100_DRC1_CTRL5:
691 case WM5100_HPLPF1_1:
692 case WM5100_HPLPF1_2:
693 case WM5100_HPLPF2_1:
694 case WM5100_HPLPF2_2:
695 case WM5100_HPLPF3_1:
696 case WM5100_HPLPF3_2:
697 case WM5100_HPLPF4_1:
698 case WM5100_HPLPF4_2:
699 case WM5100_DSP1_DM_0:
700 case WM5100_DSP1_DM_1:
701 case WM5100_DSP1_DM_2:
702 case WM5100_DSP1_DM_3:
703 case WM5100_DSP1_DM_508:
704 case WM5100_DSP1_DM_509:
705 case WM5100_DSP1_DM_510:
706 case WM5100_DSP1_DM_511:
707 case WM5100_DSP1_PM_0:
708 case WM5100_DSP1_PM_1:
709 case WM5100_DSP1_PM_2:
710 case WM5100_DSP1_PM_3:
711 case WM5100_DSP1_PM_4:
712 case WM5100_DSP1_PM_5:
713 case WM5100_DSP1_PM_1530:
714 case WM5100_DSP1_PM_1531:
715 case WM5100_DSP1_PM_1532:
716 case WM5100_DSP1_PM_1533:
717 case WM5100_DSP1_PM_1534:
718 case WM5100_DSP1_PM_1535:
719 case WM5100_DSP1_ZM_0:
720 case WM5100_DSP1_ZM_1:
721 case WM5100_DSP1_ZM_2:
722 case WM5100_DSP1_ZM_3:
723 case WM5100_DSP1_ZM_2044:
724 case WM5100_DSP1_ZM_2045:
725 case WM5100_DSP1_ZM_2046:
726 case WM5100_DSP1_ZM_2047:
727 case WM5100_DSP2_DM_0:
728 case WM5100_DSP2_DM_1:
729 case WM5100_DSP2_DM_2:
730 case WM5100_DSP2_DM_3:
731 case WM5100_DSP2_DM_508:
732 case WM5100_DSP2_DM_509:
733 case WM5100_DSP2_DM_510:
734 case WM5100_DSP2_DM_511:
735 case WM5100_DSP2_PM_0:
736 case WM5100_DSP2_PM_1:
737 case WM5100_DSP2_PM_2:
738 case WM5100_DSP2_PM_3:
739 case WM5100_DSP2_PM_4:
740 case WM5100_DSP2_PM_5:
741 case WM5100_DSP2_PM_1530:
742 case WM5100_DSP2_PM_1531:
743 case WM5100_DSP2_PM_1532:
744 case WM5100_DSP2_PM_1533:
745 case WM5100_DSP2_PM_1534:
746 case WM5100_DSP2_PM_1535:
747 case WM5100_DSP2_ZM_0:
748 case WM5100_DSP2_ZM_1:
749 case WM5100_DSP2_ZM_2:
750 case WM5100_DSP2_ZM_3:
751 case WM5100_DSP2_ZM_2044:
752 case WM5100_DSP2_ZM_2045:
753 case WM5100_DSP2_ZM_2046:
754 case WM5100_DSP2_ZM_2047:
755 case WM5100_DSP3_DM_0:
756 case WM5100_DSP3_DM_1:
757 case WM5100_DSP3_DM_2:
758 case WM5100_DSP3_DM_3:
759 case WM5100_DSP3_DM_508:
760 case WM5100_DSP3_DM_509:
761 case WM5100_DSP3_DM_510:
762 case WM5100_DSP3_DM_511:
763 case WM5100_DSP3_PM_0:
764 case WM5100_DSP3_PM_1:
765 case WM5100_DSP3_PM_2:
766 case WM5100_DSP3_PM_3:
767 case WM5100_DSP3_PM_4:
768 case WM5100_DSP3_PM_5:
769 case WM5100_DSP3_PM_1530:
770 case WM5100_DSP3_PM_1531:
771 case WM5100_DSP3_PM_1532:
772 case WM5100_DSP3_PM_1533:
773 case WM5100_DSP3_PM_1534:
774 case WM5100_DSP3_PM_1535:
775 case WM5100_DSP3_ZM_0:
776 case WM5100_DSP3_ZM_1:
777 case WM5100_DSP3_ZM_2:
778 case WM5100_DSP3_ZM_3:
779 case WM5100_DSP3_ZM_2044:
780 case WM5100_DSP3_ZM_2045:
781 case WM5100_DSP3_ZM_2046:
782 case WM5100_DSP3_ZM_2047:
783 return 1;
784 default:
785 return 0;
786 }
787}
788
789u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = {
790 [0x0000] = 0x0000, /* R0 - software reset */
791 [0x0001] = 0x0000, /* R1 - Device Revision */
792 [0x0010] = 0x0801, /* R16 - Ctrl IF 1 */
793 [0x0020] = 0x0000, /* R32 - Tone Generator 1 */
794 [0x0030] = 0x0000, /* R48 - PWM Drive 1 */
795 [0x0031] = 0x0100, /* R49 - PWM Drive 2 */
796 [0x0032] = 0x0100, /* R50 - PWM Drive 3 */
797 [0x0100] = 0x0002, /* R256 - Clocking 1 */
798 [0x0101] = 0x0000, /* R257 - Clocking 3 */
799 [0x0102] = 0x0011, /* R258 - Clocking 4 */
800 [0x0103] = 0x0011, /* R259 - Clocking 5 */
801 [0x0104] = 0x0011, /* R260 - Clocking 6 */
802 [0x0107] = 0x0000, /* R263 - Clocking 7 */
803 [0x0108] = 0x0000, /* R264 - Clocking 8 */
804 [0x0120] = 0x0000, /* R288 - ASRC_ENABLE */
805 [0x0121] = 0x0000, /* R289 - ASRC_STATUS */
806 [0x0122] = 0x0000, /* R290 - ASRC_RATE1 */
807 [0x0141] = 0x8000, /* R321 - ISRC 1 CTRL 1 */
808 [0x0142] = 0x0000, /* R322 - ISRC 1 CTRL 2 */
809 [0x0143] = 0x8000, /* R323 - ISRC 2 CTRL1 */
810 [0x0144] = 0x0000, /* R324 - ISRC 2 CTRL 2 */
811 [0x0182] = 0x0000, /* R386 - FLL1 Control 1 */
812 [0x0183] = 0x0000, /* R387 - FLL1 Control 2 */
813 [0x0184] = 0x0000, /* R388 - FLL1 Control 3 */
814 [0x0186] = 0x0177, /* R390 - FLL1 Control 5 */
815 [0x0187] = 0x0001, /* R391 - FLL1 Control 6 */
816 [0x0188] = 0x0000, /* R392 - FLL1 EFS 1 */
817 [0x01A2] = 0x0000, /* R418 - FLL2 Control 1 */
818 [0x01A3] = 0x0000, /* R419 - FLL2 Control 2 */
819 [0x01A4] = 0x0000, /* R420 - FLL2 Control 3 */
820 [0x01A6] = 0x0177, /* R422 - FLL2 Control 5 */
821 [0x01A7] = 0x0001, /* R423 - FLL2 Control 6 */
822 [0x01A8] = 0x0000, /* R424 - FLL2 EFS 1 */
823 [0x0200] = 0x0020, /* R512 - Mic Charge Pump 1 */
824 [0x0201] = 0xB084, /* R513 - Mic Charge Pump 2 */
825 [0x0202] = 0xBBDE, /* R514 - HP Charge Pump 1 */
826 [0x0211] = 0x20D4, /* R529 - LDO1 Control */
827 [0x0215] = 0x0062, /* R533 - Mic Bias Ctrl 1 */
828 [0x0216] = 0x0062, /* R534 - Mic Bias Ctrl 2 */
829 [0x0217] = 0x0062, /* R535 - Mic Bias Ctrl 3 */
830 [0x0280] = 0x0004, /* R640 - Accessory Detect Mode 1 */
831 [0x0288] = 0x0020, /* R648 - Headphone Detect 1 */
832 [0x0289] = 0x0000, /* R649 - Headphone Detect 2 */
833 [0x0290] = 0x1100, /* R656 - Mic Detect 1 */
834 [0x0291] = 0x009F, /* R657 - Mic Detect 2 */
835 [0x0292] = 0x0000, /* R658 - Mic Detect 3 */
836 [0x0301] = 0x0000, /* R769 - Input Enables */
837 [0x0302] = 0x0000, /* R770 - Input Enables Status */
838 [0x0310] = 0x2280, /* R784 - Status */
839 [0x0311] = 0x0080, /* R785 - IN1R Control */
840 [0x0312] = 0x2280, /* R786 - IN2L Control */
841 [0x0313] = 0x0080, /* R787 - IN2R Control */
842 [0x0314] = 0x2280, /* R788 - IN3L Control */
843 [0x0315] = 0x0080, /* R789 - IN3R Control */
844 [0x0316] = 0x2280, /* R790 - IN4L Control */
845 [0x0317] = 0x0080, /* R791 - IN4R Control */
846 [0x0318] = 0x0000, /* R792 - RXANC_SRC */
847 [0x0319] = 0x0022, /* R793 - Input Volume Ramp */
848 [0x0320] = 0x0180, /* R800 - ADC Digital Volume 1L */
849 [0x0321] = 0x0180, /* R801 - ADC Digital Volume 1R */
850 [0x0322] = 0x0180, /* R802 - ADC Digital Volume 2L */
851 [0x0323] = 0x0180, /* R803 - ADC Digital Volume 2R */
852 [0x0324] = 0x0180, /* R804 - ADC Digital Volume 3L */
853 [0x0325] = 0x0180, /* R805 - ADC Digital Volume 3R */
854 [0x0326] = 0x0180, /* R806 - ADC Digital Volume 4L */
855 [0x0327] = 0x0180, /* R807 - ADC Digital Volume 4R */
856 [0x0401] = 0x0000, /* R1025 - Output Enables 2 */
857 [0x0402] = 0x0000, /* R1026 - Output Status 1 */
858 [0x0403] = 0x0000, /* R1027 - Output Status 2 */
859 [0x0408] = 0x0000, /* R1032 - Channel Enables 1 */
860 [0x0410] = 0x0080, /* R1040 - Out Volume 1L */
861 [0x0411] = 0x0080, /* R1041 - Out Volume 1R */
862 [0x0412] = 0x0080, /* R1042 - DAC Volume Limit 1L */
863 [0x0413] = 0x0080, /* R1043 - DAC Volume Limit 1R */
864 [0x0414] = 0x0080, /* R1044 - Out Volume 2L */
865 [0x0415] = 0x0080, /* R1045 - Out Volume 2R */
866 [0x0416] = 0x0080, /* R1046 - DAC Volume Limit 2L */
867 [0x0417] = 0x0080, /* R1047 - DAC Volume Limit 2R */
868 [0x0418] = 0x0080, /* R1048 - Out Volume 3L */
869 [0x0419] = 0x0080, /* R1049 - Out Volume 3R */
870 [0x041A] = 0x0080, /* R1050 - DAC Volume Limit 3L */
871 [0x041B] = 0x0080, /* R1051 - DAC Volume Limit 3R */
872 [0x041C] = 0x0080, /* R1052 - Out Volume 4L */
873 [0x041D] = 0x0080, /* R1053 - Out Volume 4R */
874 [0x041E] = 0x0080, /* R1054 - DAC Volume Limit 5L */
875 [0x041F] = 0x0080, /* R1055 - DAC Volume Limit 5R */
876 [0x0420] = 0x0080, /* R1056 - DAC Volume Limit 6L */
877 [0x0421] = 0x0080, /* R1057 - DAC Volume Limit 6R */
878 [0x0440] = 0x0000, /* R1088 - DAC AEC Control 1 */
879 [0x0441] = 0x0022, /* R1089 - Output Volume Ramp */
880 [0x0480] = 0x0180, /* R1152 - DAC Digital Volume 1L */
881 [0x0481] = 0x0180, /* R1153 - DAC Digital Volume 1R */
882 [0x0482] = 0x0180, /* R1154 - DAC Digital Volume 2L */
883 [0x0483] = 0x0180, /* R1155 - DAC Digital Volume 2R */
884 [0x0484] = 0x0180, /* R1156 - DAC Digital Volume 3L */
885 [0x0485] = 0x0180, /* R1157 - DAC Digital Volume 3R */
886 [0x0486] = 0x0180, /* R1158 - DAC Digital Volume 4L */
887 [0x0487] = 0x0180, /* R1159 - DAC Digital Volume 4R */
888 [0x0488] = 0x0180, /* R1160 - DAC Digital Volume 5L */
889 [0x0489] = 0x0180, /* R1161 - DAC Digital Volume 5R */
890 [0x048A] = 0x0180, /* R1162 - DAC Digital Volume 6L */
891 [0x048B] = 0x0180, /* R1163 - DAC Digital Volume 6R */
892 [0x04C0] = 0x0069, /* R1216 - PDM SPK1 CTRL 1 */
893 [0x04C1] = 0x0000, /* R1217 - PDM SPK1 CTRL 2 */
894 [0x04C2] = 0x0069, /* R1218 - PDM SPK2 CTRL 1 */
895 [0x04C3] = 0x0000, /* R1219 - PDM SPK2 CTRL 2 */
896 [0x0500] = 0x000C, /* R1280 - Audio IF 1_1 */
897 [0x0501] = 0x0008, /* R1281 - Audio IF 1_2 */
898 [0x0502] = 0x0000, /* R1282 - Audio IF 1_3 */
899 [0x0503] = 0x0000, /* R1283 - Audio IF 1_4 */
900 [0x0504] = 0x0000, /* R1284 - Audio IF 1_5 */
901 [0x0505] = 0x0300, /* R1285 - Audio IF 1_6 */
902 [0x0506] = 0x0300, /* R1286 - Audio IF 1_7 */
903 [0x0507] = 0x1820, /* R1287 - Audio IF 1_8 */
904 [0x0508] = 0x1820, /* R1288 - Audio IF 1_9 */
905 [0x0509] = 0x0000, /* R1289 - Audio IF 1_10 */
906 [0x050A] = 0x0001, /* R1290 - Audio IF 1_11 */
907 [0x050B] = 0x0002, /* R1291 - Audio IF 1_12 */
908 [0x050C] = 0x0003, /* R1292 - Audio IF 1_13 */
909 [0x050D] = 0x0004, /* R1293 - Audio IF 1_14 */
910 [0x050E] = 0x0005, /* R1294 - Audio IF 1_15 */
911 [0x050F] = 0x0006, /* R1295 - Audio IF 1_16 */
912 [0x0510] = 0x0007, /* R1296 - Audio IF 1_17 */
913 [0x0511] = 0x0000, /* R1297 - Audio IF 1_18 */
914 [0x0512] = 0x0001, /* R1298 - Audio IF 1_19 */
915 [0x0513] = 0x0002, /* R1299 - Audio IF 1_20 */
916 [0x0514] = 0x0003, /* R1300 - Audio IF 1_21 */
917 [0x0515] = 0x0004, /* R1301 - Audio IF 1_22 */
918 [0x0516] = 0x0005, /* R1302 - Audio IF 1_23 */
919 [0x0517] = 0x0006, /* R1303 - Audio IF 1_24 */
920 [0x0518] = 0x0007, /* R1304 - Audio IF 1_25 */
921 [0x0519] = 0x0000, /* R1305 - Audio IF 1_26 */
922 [0x051A] = 0x0000, /* R1306 - Audio IF 1_27 */
923 [0x0540] = 0x000C, /* R1344 - Audio IF 2_1 */
924 [0x0541] = 0x0008, /* R1345 - Audio IF 2_2 */
925 [0x0542] = 0x0000, /* R1346 - Audio IF 2_3 */
926 [0x0543] = 0x0000, /* R1347 - Audio IF 2_4 */
927 [0x0544] = 0x0000, /* R1348 - Audio IF 2_5 */
928 [0x0545] = 0x0300, /* R1349 - Audio IF 2_6 */
929 [0x0546] = 0x0300, /* R1350 - Audio IF 2_7 */
930 [0x0547] = 0x1820, /* R1351 - Audio IF 2_8 */
931 [0x0548] = 0x1820, /* R1352 - Audio IF 2_9 */
932 [0x0549] = 0x0000, /* R1353 - Audio IF 2_10 */
933 [0x054A] = 0x0001, /* R1354 - Audio IF 2_11 */
934 [0x0551] = 0x0000, /* R1361 - Audio IF 2_18 */
935 [0x0552] = 0x0001, /* R1362 - Audio IF 2_19 */
936 [0x0559] = 0x0000, /* R1369 - Audio IF 2_26 */
937 [0x055A] = 0x0000, /* R1370 - Audio IF 2_27 */
938 [0x0580] = 0x000C, /* R1408 - Audio IF 3_1 */
939 [0x0581] = 0x0008, /* R1409 - Audio IF 3_2 */
940 [0x0582] = 0x0000, /* R1410 - Audio IF 3_3 */
941 [0x0583] = 0x0000, /* R1411 - Audio IF 3_4 */
942 [0x0584] = 0x0000, /* R1412 - Audio IF 3_5 */
943 [0x0585] = 0x0300, /* R1413 - Audio IF 3_6 */
944 [0x0586] = 0x0300, /* R1414 - Audio IF 3_7 */
945 [0x0587] = 0x1820, /* R1415 - Audio IF 3_8 */
946 [0x0588] = 0x1820, /* R1416 - Audio IF 3_9 */
947 [0x0589] = 0x0000, /* R1417 - Audio IF 3_10 */
948 [0x058A] = 0x0001, /* R1418 - Audio IF 3_11 */
949 [0x0591] = 0x0000, /* R1425 - Audio IF 3_18 */
950 [0x0592] = 0x0001, /* R1426 - Audio IF 3_19 */
951 [0x0599] = 0x0000, /* R1433 - Audio IF 3_26 */
952 [0x059A] = 0x0000, /* R1434 - Audio IF 3_27 */
953 [0x0640] = 0x0000, /* R1600 - PWM1MIX Input 1 Source */
954 [0x0641] = 0x0080, /* R1601 - PWM1MIX Input 1 Volume */
955 [0x0642] = 0x0000, /* R1602 - PWM1MIX Input 2 Source */
956 [0x0643] = 0x0080, /* R1603 - PWM1MIX Input 2 Volume */
957 [0x0644] = 0x0000, /* R1604 - PWM1MIX Input 3 Source */
958 [0x0645] = 0x0080, /* R1605 - PWM1MIX Input 3 Volume */
959 [0x0646] = 0x0000, /* R1606 - PWM1MIX Input 4 Source */
960 [0x0647] = 0x0080, /* R1607 - PWM1MIX Input 4 Volume */
961 [0x0648] = 0x0000, /* R1608 - PWM2MIX Input 1 Source */
962 [0x0649] = 0x0080, /* R1609 - PWM2MIX Input 1 Volume */
963 [0x064A] = 0x0000, /* R1610 - PWM2MIX Input 2 Source */
964 [0x064B] = 0x0080, /* R1611 - PWM2MIX Input 2 Volume */
965 [0x064C] = 0x0000, /* R1612 - PWM2MIX Input 3 Source */
966 [0x064D] = 0x0080, /* R1613 - PWM2MIX Input 3 Volume */
967 [0x064E] = 0x0000, /* R1614 - PWM2MIX Input 4 Source */
968 [0x064F] = 0x0080, /* R1615 - PWM2MIX Input 4 Volume */
969 [0x0680] = 0x0000, /* R1664 - OUT1LMIX Input 1 Source */
970 [0x0681] = 0x0080, /* R1665 - OUT1LMIX Input 1 Volume */
971 [0x0682] = 0x0000, /* R1666 - OUT1LMIX Input 2 Source */
972 [0x0683] = 0x0080, /* R1667 - OUT1LMIX Input 2 Volume */
973 [0x0684] = 0x0000, /* R1668 - OUT1LMIX Input 3 Source */
974 [0x0685] = 0x0080, /* R1669 - OUT1LMIX Input 3 Volume */
975 [0x0686] = 0x0000, /* R1670 - OUT1LMIX Input 4 Source */
976 [0x0687] = 0x0080, /* R1671 - OUT1LMIX Input 4 Volume */
977 [0x0688] = 0x0000, /* R1672 - OUT1RMIX Input 1 Source */
978 [0x0689] = 0x0080, /* R1673 - OUT1RMIX Input 1 Volume */
979 [0x068A] = 0x0000, /* R1674 - OUT1RMIX Input 2 Source */
980 [0x068B] = 0x0080, /* R1675 - OUT1RMIX Input 2 Volume */
981 [0x068C] = 0x0000, /* R1676 - OUT1RMIX Input 3 Source */
982 [0x068D] = 0x0080, /* R1677 - OUT1RMIX Input 3 Volume */
983 [0x068E] = 0x0000, /* R1678 - OUT1RMIX Input 4 Source */
984 [0x068F] = 0x0080, /* R1679 - OUT1RMIX Input 4 Volume */
985 [0x0690] = 0x0000, /* R1680 - OUT2LMIX Input 1 Source */
986 [0x0691] = 0x0080, /* R1681 - OUT2LMIX Input 1 Volume */
987 [0x0692] = 0x0000, /* R1682 - OUT2LMIX Input 2 Source */
988 [0x0693] = 0x0080, /* R1683 - OUT2LMIX Input 2 Volume */
989 [0x0694] = 0x0000, /* R1684 - OUT2LMIX Input 3 Source */
990 [0x0695] = 0x0080, /* R1685 - OUT2LMIX Input 3 Volume */
991 [0x0696] = 0x0000, /* R1686 - OUT2LMIX Input 4 Source */
992 [0x0697] = 0x0080, /* R1687 - OUT2LMIX Input 4 Volume */
993 [0x0698] = 0x0000, /* R1688 - OUT2RMIX Input 1 Source */
994 [0x0699] = 0x0080, /* R1689 - OUT2RMIX Input 1 Volume */
995 [0x069A] = 0x0000, /* R1690 - OUT2RMIX Input 2 Source */
996 [0x069B] = 0x0080, /* R1691 - OUT2RMIX Input 2 Volume */
997 [0x069C] = 0x0000, /* R1692 - OUT2RMIX Input 3 Source */
998 [0x069D] = 0x0080, /* R1693 - OUT2RMIX Input 3 Volume */
999 [0x069E] = 0x0000, /* R1694 - OUT2RMIX Input 4 Source */
1000 [0x069F] = 0x0080, /* R1695 - OUT2RMIX Input 4 Volume */
1001 [0x06A0] = 0x0000, /* R1696 - OUT3LMIX Input 1 Source */
1002 [0x06A1] = 0x0080, /* R1697 - OUT3LMIX Input 1 Volume */
1003 [0x06A2] = 0x0000, /* R1698 - OUT3LMIX Input 2 Source */
1004 [0x06A3] = 0x0080, /* R1699 - OUT3LMIX Input 2 Volume */
1005 [0x06A4] = 0x0000, /* R1700 - OUT3LMIX Input 3 Source */
1006 [0x06A5] = 0x0080, /* R1701 - OUT3LMIX Input 3 Volume */
1007 [0x06A6] = 0x0000, /* R1702 - OUT3LMIX Input 4 Source */
1008 [0x06A7] = 0x0080, /* R1703 - OUT3LMIX Input 4 Volume */
1009 [0x06A8] = 0x0000, /* R1704 - OUT3RMIX Input 1 Source */
1010 [0x06A9] = 0x0080, /* R1705 - OUT3RMIX Input 1 Volume */
1011 [0x06AA] = 0x0000, /* R1706 - OUT3RMIX Input 2 Source */
1012 [0x06AB] = 0x0080, /* R1707 - OUT3RMIX Input 2 Volume */
1013 [0x06AC] = 0x0000, /* R1708 - OUT3RMIX Input 3 Source */
1014 [0x06AD] = 0x0080, /* R1709 - OUT3RMIX Input 3 Volume */
1015 [0x06AE] = 0x0000, /* R1710 - OUT3RMIX Input 4 Source */
1016 [0x06AF] = 0x0080, /* R1711 - OUT3RMIX Input 4 Volume */
1017 [0x06B0] = 0x0000, /* R1712 - OUT4LMIX Input 1 Source */
1018 [0x06B1] = 0x0080, /* R1713 - OUT4LMIX Input 1 Volume */
1019 [0x06B2] = 0x0000, /* R1714 - OUT4LMIX Input 2 Source */
1020 [0x06B3] = 0x0080, /* R1715 - OUT4LMIX Input 2 Volume */
1021 [0x06B4] = 0x0000, /* R1716 - OUT4LMIX Input 3 Source */
1022 [0x06B5] = 0x0080, /* R1717 - OUT4LMIX Input 3 Volume */
1023 [0x06B6] = 0x0000, /* R1718 - OUT4LMIX Input 4 Source */
1024 [0x06B7] = 0x0080, /* R1719 - OUT4LMIX Input 4 Volume */
1025 [0x06B8] = 0x0000, /* R1720 - OUT4RMIX Input 1 Source */
1026 [0x06B9] = 0x0080, /* R1721 - OUT4RMIX Input 1 Volume */
1027 [0x06BA] = 0x0000, /* R1722 - OUT4RMIX Input 2 Source */
1028 [0x06BB] = 0x0080, /* R1723 - OUT4RMIX Input 2 Volume */
1029 [0x06BC] = 0x0000, /* R1724 - OUT4RMIX Input 3 Source */
1030 [0x06BD] = 0x0080, /* R1725 - OUT4RMIX Input 3 Volume */
1031 [0x06BE] = 0x0000, /* R1726 - OUT4RMIX Input 4 Source */
1032 [0x06BF] = 0x0080, /* R1727 - OUT4RMIX Input 4 Volume */
1033 [0x06C0] = 0x0000, /* R1728 - OUT5LMIX Input 1 Source */
1034 [0x06C1] = 0x0080, /* R1729 - OUT5LMIX Input 1 Volume */
1035 [0x06C2] = 0x0000, /* R1730 - OUT5LMIX Input 2 Source */
1036 [0x06C3] = 0x0080, /* R1731 - OUT5LMIX Input 2 Volume */
1037 [0x06C4] = 0x0000, /* R1732 - OUT5LMIX Input 3 Source */
1038 [0x06C5] = 0x0080, /* R1733 - OUT5LMIX Input 3 Volume */
1039 [0x06C6] = 0x0000, /* R1734 - OUT5LMIX Input 4 Source */
1040 [0x06C7] = 0x0080, /* R1735 - OUT5LMIX Input 4 Volume */
1041 [0x06C8] = 0x0000, /* R1736 - OUT5RMIX Input 1 Source */
1042 [0x06C9] = 0x0080, /* R1737 - OUT5RMIX Input 1 Volume */
1043 [0x06CA] = 0x0000, /* R1738 - OUT5RMIX Input 2 Source */
1044 [0x06CB] = 0x0080, /* R1739 - OUT5RMIX Input 2 Volume */
1045 [0x06CC] = 0x0000, /* R1740 - OUT5RMIX Input 3 Source */
1046 [0x06CD] = 0x0080, /* R1741 - OUT5RMIX Input 3 Volume */
1047 [0x06CE] = 0x0000, /* R1742 - OUT5RMIX Input 4 Source */
1048 [0x06CF] = 0x0080, /* R1743 - OUT5RMIX Input 4 Volume */
1049 [0x06D0] = 0x0000, /* R1744 - OUT6LMIX Input 1 Source */
1050 [0x06D1] = 0x0080, /* R1745 - OUT6LMIX Input 1 Volume */
1051 [0x06D2] = 0x0000, /* R1746 - OUT6LMIX Input 2 Source */
1052 [0x06D3] = 0x0080, /* R1747 - OUT6LMIX Input 2 Volume */
1053 [0x06D4] = 0x0000, /* R1748 - OUT6LMIX Input 3 Source */
1054 [0x06D5] = 0x0080, /* R1749 - OUT6LMIX Input 3 Volume */
1055 [0x06D6] = 0x0000, /* R1750 - OUT6LMIX Input 4 Source */
1056 [0x06D7] = 0x0080, /* R1751 - OUT6LMIX Input 4 Volume */
1057 [0x06D8] = 0x0000, /* R1752 - OUT6RMIX Input 1 Source */
1058 [0x06D9] = 0x0080, /* R1753 - OUT6RMIX Input 1 Volume */
1059 [0x06DA] = 0x0000, /* R1754 - OUT6RMIX Input 2 Source */
1060 [0x06DB] = 0x0080, /* R1755 - OUT6RMIX Input 2 Volume */
1061 [0x06DC] = 0x0000, /* R1756 - OUT6RMIX Input 3 Source */
1062 [0x06DD] = 0x0080, /* R1757 - OUT6RMIX Input 3 Volume */
1063 [0x06DE] = 0x0000, /* R1758 - OUT6RMIX Input 4 Source */
1064 [0x06DF] = 0x0080, /* R1759 - OUT6RMIX Input 4 Volume */
1065 [0x0700] = 0x0000, /* R1792 - AIF1TX1MIX Input 1 Source */
1066 [0x0701] = 0x0080, /* R1793 - AIF1TX1MIX Input 1 Volume */
1067 [0x0702] = 0x0000, /* R1794 - AIF1TX1MIX Input 2 Source */
1068 [0x0703] = 0x0080, /* R1795 - AIF1TX1MIX Input 2 Volume */
1069 [0x0704] = 0x0000, /* R1796 - AIF1TX1MIX Input 3 Source */
1070 [0x0705] = 0x0080, /* R1797 - AIF1TX1MIX Input 3 Volume */
1071 [0x0706] = 0x0000, /* R1798 - AIF1TX1MIX Input 4 Source */
1072 [0x0707] = 0x0080, /* R1799 - AIF1TX1MIX Input 4 Volume */
1073 [0x0708] = 0x0000, /* R1800 - AIF1TX2MIX Input 1 Source */
1074 [0x0709] = 0x0080, /* R1801 - AIF1TX2MIX Input 1 Volume */
1075 [0x070A] = 0x0000, /* R1802 - AIF1TX2MIX Input 2 Source */
1076 [0x070B] = 0x0080, /* R1803 - AIF1TX2MIX Input 2 Volume */
1077 [0x070C] = 0x0000, /* R1804 - AIF1TX2MIX Input 3 Source */
1078 [0x070D] = 0x0080, /* R1805 - AIF1TX2MIX Input 3 Volume */
1079 [0x070E] = 0x0000, /* R1806 - AIF1TX2MIX Input 4 Source */
1080 [0x070F] = 0x0080, /* R1807 - AIF1TX2MIX Input 4 Volume */
1081 [0x0710] = 0x0000, /* R1808 - AIF1TX3MIX Input 1 Source */
1082 [0x0711] = 0x0080, /* R1809 - AIF1TX3MIX Input 1 Volume */
1083 [0x0712] = 0x0000, /* R1810 - AIF1TX3MIX Input 2 Source */
1084 [0x0713] = 0x0080, /* R1811 - AIF1TX3MIX Input 2 Volume */
1085 [0x0714] = 0x0000, /* R1812 - AIF1TX3MIX Input 3 Source */
1086 [0x0715] = 0x0080, /* R1813 - AIF1TX3MIX Input 3 Volume */
1087 [0x0716] = 0x0000, /* R1814 - AIF1TX3MIX Input 4 Source */
1088 [0x0717] = 0x0080, /* R1815 - AIF1TX3MIX Input 4 Volume */
1089 [0x0718] = 0x0000, /* R1816 - AIF1TX4MIX Input 1 Source */
1090 [0x0719] = 0x0080, /* R1817 - AIF1TX4MIX Input 1 Volume */
1091 [0x071A] = 0x0000, /* R1818 - AIF1TX4MIX Input 2 Source */
1092 [0x071B] = 0x0080, /* R1819 - AIF1TX4MIX Input 2 Volume */
1093 [0x071C] = 0x0000, /* R1820 - AIF1TX4MIX Input 3 Source */
1094 [0x071D] = 0x0080, /* R1821 - AIF1TX4MIX Input 3 Volume */
1095 [0x071E] = 0x0000, /* R1822 - AIF1TX4MIX Input 4 Source */
1096 [0x071F] = 0x0080, /* R1823 - AIF1TX4MIX Input 4 Volume */
1097 [0x0720] = 0x0000, /* R1824 - AIF1TX5MIX Input 1 Source */
1098 [0x0721] = 0x0080, /* R1825 - AIF1TX5MIX Input 1 Volume */
1099 [0x0722] = 0x0000, /* R1826 - AIF1TX5MIX Input 2 Source */
1100 [0x0723] = 0x0080, /* R1827 - AIF1TX5MIX Input 2 Volume */
1101 [0x0724] = 0x0000, /* R1828 - AIF1TX5MIX Input 3 Source */
1102 [0x0725] = 0x0080, /* R1829 - AIF1TX5MIX Input 3 Volume */
1103 [0x0726] = 0x0000, /* R1830 - AIF1TX5MIX Input 4 Source */
1104 [0x0727] = 0x0080, /* R1831 - AIF1TX5MIX Input 4 Volume */
1105 [0x0728] = 0x0000, /* R1832 - AIF1TX6MIX Input 1 Source */
1106 [0x0729] = 0x0080, /* R1833 - AIF1TX6MIX Input 1 Volume */
1107 [0x072A] = 0x0000, /* R1834 - AIF1TX6MIX Input 2 Source */
1108 [0x072B] = 0x0080, /* R1835 - AIF1TX6MIX Input 2 Volume */
1109 [0x072C] = 0x0000, /* R1836 - AIF1TX6MIX Input 3 Source */
1110 [0x072D] = 0x0080, /* R1837 - AIF1TX6MIX Input 3 Volume */
1111 [0x072E] = 0x0000, /* R1838 - AIF1TX6MIX Input 4 Source */
1112 [0x072F] = 0x0080, /* R1839 - AIF1TX6MIX Input 4 Volume */
1113 [0x0730] = 0x0000, /* R1840 - AIF1TX7MIX Input 1 Source */
1114 [0x0731] = 0x0080, /* R1841 - AIF1TX7MIX Input 1 Volume */
1115 [0x0732] = 0x0000, /* R1842 - AIF1TX7MIX Input 2 Source */
1116 [0x0733] = 0x0080, /* R1843 - AIF1TX7MIX Input 2 Volume */
1117 [0x0734] = 0x0000, /* R1844 - AIF1TX7MIX Input 3 Source */
1118 [0x0735] = 0x0080, /* R1845 - AIF1TX7MIX Input 3 Volume */
1119 [0x0736] = 0x0000, /* R1846 - AIF1TX7MIX Input 4 Source */
1120 [0x0737] = 0x0080, /* R1847 - AIF1TX7MIX Input 4 Volume */
1121 [0x0738] = 0x0000, /* R1848 - AIF1TX8MIX Input 1 Source */
1122 [0x0739] = 0x0080, /* R1849 - AIF1TX8MIX Input 1 Volume */
1123 [0x073A] = 0x0000, /* R1850 - AIF1TX8MIX Input 2 Source */
1124 [0x073B] = 0x0080, /* R1851 - AIF1TX8MIX Input 2 Volume */
1125 [0x073C] = 0x0000, /* R1852 - AIF1TX8MIX Input 3 Source */
1126 [0x073D] = 0x0080, /* R1853 - AIF1TX8MIX Input 3 Volume */
1127 [0x073E] = 0x0000, /* R1854 - AIF1TX8MIX Input 4 Source */
1128 [0x073F] = 0x0080, /* R1855 - AIF1TX8MIX Input 4 Volume */
1129 [0x0740] = 0x0000, /* R1856 - AIF2TX1MIX Input 1 Source */
1130 [0x0741] = 0x0080, /* R1857 - AIF2TX1MIX Input 1 Volume */
1131 [0x0742] = 0x0000, /* R1858 - AIF2TX1MIX Input 2 Source */
1132 [0x0743] = 0x0080, /* R1859 - AIF2TX1MIX Input 2 Volume */
1133 [0x0744] = 0x0000, /* R1860 - AIF2TX1MIX Input 3 Source */
1134 [0x0745] = 0x0080, /* R1861 - AIF2TX1MIX Input 3 Volume */
1135 [0x0746] = 0x0000, /* R1862 - AIF2TX1MIX Input 4 Source */
1136 [0x0747] = 0x0080, /* R1863 - AIF2TX1MIX Input 4 Volume */
1137 [0x0748] = 0x0000, /* R1864 - AIF2TX2MIX Input 1 Source */
1138 [0x0749] = 0x0080, /* R1865 - AIF2TX2MIX Input 1 Volume */
1139 [0x074A] = 0x0000, /* R1866 - AIF2TX2MIX Input 2 Source */
1140 [0x074B] = 0x0080, /* R1867 - AIF2TX2MIX Input 2 Volume */
1141 [0x074C] = 0x0000, /* R1868 - AIF2TX2MIX Input 3 Source */
1142 [0x074D] = 0x0080, /* R1869 - AIF2TX2MIX Input 3 Volume */
1143 [0x074E] = 0x0000, /* R1870 - AIF2TX2MIX Input 4 Source */
1144 [0x074F] = 0x0080, /* R1871 - AIF2TX2MIX Input 4 Volume */
1145 [0x0780] = 0x0000, /* R1920 - AIF3TX1MIX Input 1 Source */
1146 [0x0781] = 0x0080, /* R1921 - AIF3TX1MIX Input 1 Volume */
1147 [0x0782] = 0x0000, /* R1922 - AIF3TX1MIX Input 2 Source */
1148 [0x0783] = 0x0080, /* R1923 - AIF3TX1MIX Input 2 Volume */
1149 [0x0784] = 0x0000, /* R1924 - AIF3TX1MIX Input 3 Source */
1150 [0x0785] = 0x0080, /* R1925 - AIF3TX1MIX Input 3 Volume */
1151 [0x0786] = 0x0000, /* R1926 - AIF3TX1MIX Input 4 Source */
1152 [0x0787] = 0x0080, /* R1927 - AIF3TX1MIX Input 4 Volume */
1153 [0x0788] = 0x0000, /* R1928 - AIF3TX2MIX Input 1 Source */
1154 [0x0789] = 0x0080, /* R1929 - AIF3TX2MIX Input 1 Volume */
1155 [0x078A] = 0x0000, /* R1930 - AIF3TX2MIX Input 2 Source */
1156 [0x078B] = 0x0080, /* R1931 - AIF3TX2MIX Input 2 Volume */
1157 [0x078C] = 0x0000, /* R1932 - AIF3TX2MIX Input 3 Source */
1158 [0x078D] = 0x0080, /* R1933 - AIF3TX2MIX Input 3 Volume */
1159 [0x078E] = 0x0000, /* R1934 - AIF3TX2MIX Input 4 Source */
1160 [0x078F] = 0x0080, /* R1935 - AIF3TX2MIX Input 4 Volume */
1161 [0x0880] = 0x0000, /* R2176 - EQ1MIX Input 1 Source */
1162 [0x0881] = 0x0080, /* R2177 - EQ1MIX Input 1 Volume */
1163 [0x0882] = 0x0000, /* R2178 - EQ1MIX Input 2 Source */
1164 [0x0883] = 0x0080, /* R2179 - EQ1MIX Input 2 Volume */
1165 [0x0884] = 0x0000, /* R2180 - EQ1MIX Input 3 Source */
1166 [0x0885] = 0x0080, /* R2181 - EQ1MIX Input 3 Volume */
1167 [0x0886] = 0x0000, /* R2182 - EQ1MIX Input 4 Source */
1168 [0x0887] = 0x0080, /* R2183 - EQ1MIX Input 4 Volume */
1169 [0x0888] = 0x0000, /* R2184 - EQ2MIX Input 1 Source */
1170 [0x0889] = 0x0080, /* R2185 - EQ2MIX Input 1 Volume */
1171 [0x088A] = 0x0000, /* R2186 - EQ2MIX Input 2 Source */
1172 [0x088B] = 0x0080, /* R2187 - EQ2MIX Input 2 Volume */
1173 [0x088C] = 0x0000, /* R2188 - EQ2MIX Input 3 Source */
1174 [0x088D] = 0x0080, /* R2189 - EQ2MIX Input 3 Volume */
1175 [0x088E] = 0x0000, /* R2190 - EQ2MIX Input 4 Source */
1176 [0x088F] = 0x0080, /* R2191 - EQ2MIX Input 4 Volume */
1177 [0x0890] = 0x0000, /* R2192 - EQ3MIX Input 1 Source */
1178 [0x0891] = 0x0080, /* R2193 - EQ3MIX Input 1 Volume */
1179 [0x0892] = 0x0000, /* R2194 - EQ3MIX Input 2 Source */
1180 [0x0893] = 0x0080, /* R2195 - EQ3MIX Input 2 Volume */
1181 [0x0894] = 0x0000, /* R2196 - EQ3MIX Input 3 Source */
1182 [0x0895] = 0x0080, /* R2197 - EQ3MIX Input 3 Volume */
1183 [0x0896] = 0x0000, /* R2198 - EQ3MIX Input 4 Source */
1184 [0x0897] = 0x0080, /* R2199 - EQ3MIX Input 4 Volume */
1185 [0x0898] = 0x0000, /* R2200 - EQ4MIX Input 1 Source */
1186 [0x0899] = 0x0080, /* R2201 - EQ4MIX Input 1 Volume */
1187 [0x089A] = 0x0000, /* R2202 - EQ4MIX Input 2 Source */
1188 [0x089B] = 0x0080, /* R2203 - EQ4MIX Input 2 Volume */
1189 [0x089C] = 0x0000, /* R2204 - EQ4MIX Input 3 Source */
1190 [0x089D] = 0x0080, /* R2205 - EQ4MIX Input 3 Volume */
1191 [0x089E] = 0x0000, /* R2206 - EQ4MIX Input 4 Source */
1192 [0x089F] = 0x0080, /* R2207 - EQ4MIX Input 4 Volume */
1193 [0x08C0] = 0x0000, /* R2240 - DRC1LMIX Input 1 Source */
1194 [0x08C1] = 0x0080, /* R2241 - DRC1LMIX Input 1 Volume */
1195 [0x08C2] = 0x0000, /* R2242 - DRC1LMIX Input 2 Source */
1196 [0x08C3] = 0x0080, /* R2243 - DRC1LMIX Input 2 Volume */
1197 [0x08C4] = 0x0000, /* R2244 - DRC1LMIX Input 3 Source */
1198 [0x08C5] = 0x0080, /* R2245 - DRC1LMIX Input 3 Volume */
1199 [0x08C6] = 0x0000, /* R2246 - DRC1LMIX Input 4 Source */
1200 [0x08C7] = 0x0080, /* R2247 - DRC1LMIX Input 4 Volume */
1201 [0x08C8] = 0x0000, /* R2248 - DRC1RMIX Input 1 Source */
1202 [0x08C9] = 0x0080, /* R2249 - DRC1RMIX Input 1 Volume */
1203 [0x08CA] = 0x0000, /* R2250 - DRC1RMIX Input 2 Source */
1204 [0x08CB] = 0x0080, /* R2251 - DRC1RMIX Input 2 Volume */
1205 [0x08CC] = 0x0000, /* R2252 - DRC1RMIX Input 3 Source */
1206 [0x08CD] = 0x0080, /* R2253 - DRC1RMIX Input 3 Volume */
1207 [0x08CE] = 0x0000, /* R2254 - DRC1RMIX Input 4 Source */
1208 [0x08CF] = 0x0080, /* R2255 - DRC1RMIX Input 4 Volume */
1209 [0x0900] = 0x0000, /* R2304 - HPLP1MIX Input 1 Source */
1210 [0x0901] = 0x0080, /* R2305 - HPLP1MIX Input 1 Volume */
1211 [0x0902] = 0x0000, /* R2306 - HPLP1MIX Input 2 Source */
1212 [0x0903] = 0x0080, /* R2307 - HPLP1MIX Input 2 Volume */
1213 [0x0904] = 0x0000, /* R2308 - HPLP1MIX Input 3 Source */
1214 [0x0905] = 0x0080, /* R2309 - HPLP1MIX Input 3 Volume */
1215 [0x0906] = 0x0000, /* R2310 - HPLP1MIX Input 4 Source */
1216 [0x0907] = 0x0080, /* R2311 - HPLP1MIX Input 4 Volume */
1217 [0x0908] = 0x0000, /* R2312 - HPLP2MIX Input 1 Source */
1218 [0x0909] = 0x0080, /* R2313 - HPLP2MIX Input 1 Volume */
1219 [0x090A] = 0x0000, /* R2314 - HPLP2MIX Input 2 Source */
1220 [0x090B] = 0x0080, /* R2315 - HPLP2MIX Input 2 Volume */
1221 [0x090C] = 0x0000, /* R2316 - HPLP2MIX Input 3 Source */
1222 [0x090D] = 0x0080, /* R2317 - HPLP2MIX Input 3 Volume */
1223 [0x090E] = 0x0000, /* R2318 - HPLP2MIX Input 4 Source */
1224 [0x090F] = 0x0080, /* R2319 - HPLP2MIX Input 4 Volume */
1225 [0x0910] = 0x0000, /* R2320 - HPLP3MIX Input 1 Source */
1226 [0x0911] = 0x0080, /* R2321 - HPLP3MIX Input 1 Volume */
1227 [0x0912] = 0x0000, /* R2322 - HPLP3MIX Input 2 Source */
1228 [0x0913] = 0x0080, /* R2323 - HPLP3MIX Input 2 Volume */
1229 [0x0914] = 0x0000, /* R2324 - HPLP3MIX Input 3 Source */
1230 [0x0915] = 0x0080, /* R2325 - HPLP3MIX Input 3 Volume */
1231 [0x0916] = 0x0000, /* R2326 - HPLP3MIX Input 4 Source */
1232 [0x0917] = 0x0080, /* R2327 - HPLP3MIX Input 4 Volume */
1233 [0x0918] = 0x0000, /* R2328 - HPLP4MIX Input 1 Source */
1234 [0x0919] = 0x0080, /* R2329 - HPLP4MIX Input 1 Volume */
1235 [0x091A] = 0x0000, /* R2330 - HPLP4MIX Input 2 Source */
1236 [0x091B] = 0x0080, /* R2331 - HPLP4MIX Input 2 Volume */
1237 [0x091C] = 0x0000, /* R2332 - HPLP4MIX Input 3 Source */
1238 [0x091D] = 0x0080, /* R2333 - HPLP4MIX Input 3 Volume */
1239 [0x091E] = 0x0000, /* R2334 - HPLP4MIX Input 4 Source */
1240 [0x091F] = 0x0080, /* R2335 - HPLP4MIX Input 4 Volume */
1241 [0x0940] = 0x0000, /* R2368 - DSP1LMIX Input 1 Source */
1242 [0x0941] = 0x0080, /* R2369 - DSP1LMIX Input 1 Volume */
1243 [0x0942] = 0x0000, /* R2370 - DSP1LMIX Input 2 Source */
1244 [0x0943] = 0x0080, /* R2371 - DSP1LMIX Input 2 Volume */
1245 [0x0944] = 0x0000, /* R2372 - DSP1LMIX Input 3 Source */
1246 [0x0945] = 0x0080, /* R2373 - DSP1LMIX Input 3 Volume */
1247 [0x0946] = 0x0000, /* R2374 - DSP1LMIX Input 4 Source */
1248 [0x0947] = 0x0080, /* R2375 - DSP1LMIX Input 4 Volume */
1249 [0x0948] = 0x0000, /* R2376 - DSP1RMIX Input 1 Source */
1250 [0x0949] = 0x0080, /* R2377 - DSP1RMIX Input 1 Volume */
1251 [0x094A] = 0x0000, /* R2378 - DSP1RMIX Input 2 Source */
1252 [0x094B] = 0x0080, /* R2379 - DSP1RMIX Input 2 Volume */
1253 [0x094C] = 0x0000, /* R2380 - DSP1RMIX Input 3 Source */
1254 [0x094D] = 0x0080, /* R2381 - DSP1RMIX Input 3 Volume */
1255 [0x094E] = 0x0000, /* R2382 - DSP1RMIX Input 4 Source */
1256 [0x094F] = 0x0080, /* R2383 - DSP1RMIX Input 4 Volume */
1257 [0x0950] = 0x0000, /* R2384 - DSP1AUX1MIX Input 1 Source */
1258 [0x0958] = 0x0000, /* R2392 - DSP1AUX2MIX Input 1 Source */
1259 [0x0960] = 0x0000, /* R2400 - DSP1AUX3MIX Input 1 Source */
1260 [0x0968] = 0x0000, /* R2408 - DSP1AUX4MIX Input 1 Source */
1261 [0x0970] = 0x0000, /* R2416 - DSP1AUX5MIX Input 1 Source */
1262 [0x0978] = 0x0000, /* R2424 - DSP1AUX6MIX Input 1 Source */
1263 [0x0980] = 0x0000, /* R2432 - DSP2LMIX Input 1 Source */
1264 [0x0981] = 0x0080, /* R2433 - DSP2LMIX Input 1 Volume */
1265 [0x0982] = 0x0000, /* R2434 - DSP2LMIX Input 2 Source */
1266 [0x0983] = 0x0080, /* R2435 - DSP2LMIX Input 2 Volume */
1267 [0x0984] = 0x0000, /* R2436 - DSP2LMIX Input 3 Source */
1268 [0x0985] = 0x0080, /* R2437 - DSP2LMIX Input 3 Volume */
1269 [0x0986] = 0x0000, /* R2438 - DSP2LMIX Input 4 Source */
1270 [0x0987] = 0x0080, /* R2439 - DSP2LMIX Input 4 Volume */
1271 [0x0988] = 0x0000, /* R2440 - DSP2RMIX Input 1 Source */
1272 [0x0989] = 0x0080, /* R2441 - DSP2RMIX Input 1 Volume */
1273 [0x098A] = 0x0000, /* R2442 - DSP2RMIX Input 2 Source */
1274 [0x098B] = 0x0080, /* R2443 - DSP2RMIX Input 2 Volume */
1275 [0x098C] = 0x0000, /* R2444 - DSP2RMIX Input 3 Source */
1276 [0x098D] = 0x0080, /* R2445 - DSP2RMIX Input 3 Volume */
1277 [0x098E] = 0x0000, /* R2446 - DSP2RMIX Input 4 Source */
1278 [0x098F] = 0x0080, /* R2447 - DSP2RMIX Input 4 Volume */
1279 [0x0990] = 0x0000, /* R2448 - DSP2AUX1MIX Input 1 Source */
1280 [0x0998] = 0x0000, /* R2456 - DSP2AUX2MIX Input 1 Source */
1281 [0x09A0] = 0x0000, /* R2464 - DSP2AUX3MIX Input 1 Source */
1282 [0x09A8] = 0x0000, /* R2472 - DSP2AUX4MIX Input 1 Source */
1283 [0x09B0] = 0x0000, /* R2480 - DSP2AUX5MIX Input 1 Source */
1284 [0x09B8] = 0x0000, /* R2488 - DSP2AUX6MIX Input 1 Source */
1285 [0x09C0] = 0x0000, /* R2496 - DSP3LMIX Input 1 Source */
1286 [0x09C1] = 0x0080, /* R2497 - DSP3LMIX Input 1 Volume */
1287 [0x09C2] = 0x0000, /* R2498 - DSP3LMIX Input 2 Source */
1288 [0x09C3] = 0x0080, /* R2499 - DSP3LMIX Input 2 Volume */
1289 [0x09C4] = 0x0000, /* R2500 - DSP3LMIX Input 3 Source */
1290 [0x09C5] = 0x0080, /* R2501 - DSP3LMIX Input 3 Volume */
1291 [0x09C6] = 0x0000, /* R2502 - DSP3LMIX Input 4 Source */
1292 [0x09C7] = 0x0080, /* R2503 - DSP3LMIX Input 4 Volume */
1293 [0x09C8] = 0x0000, /* R2504 - DSP3RMIX Input 1 Source */
1294 [0x09C9] = 0x0080, /* R2505 - DSP3RMIX Input 1 Volume */
1295 [0x09CA] = 0x0000, /* R2506 - DSP3RMIX Input 2 Source */
1296 [0x09CB] = 0x0080, /* R2507 - DSP3RMIX Input 2 Volume */
1297 [0x09CC] = 0x0000, /* R2508 - DSP3RMIX Input 3 Source */
1298 [0x09CD] = 0x0080, /* R2509 - DSP3RMIX Input 3 Volume */
1299 [0x09CE] = 0x0000, /* R2510 - DSP3RMIX Input 4 Source */
1300 [0x09CF] = 0x0080, /* R2511 - DSP3RMIX Input 4 Volume */
1301 [0x09D0] = 0x0000, /* R2512 - DSP3AUX1MIX Input 1 Source */
1302 [0x09D8] = 0x0000, /* R2520 - DSP3AUX2MIX Input 1 Source */
1303 [0x09E0] = 0x0000, /* R2528 - DSP3AUX3MIX Input 1 Source */
1304 [0x09E8] = 0x0000, /* R2536 - DSP3AUX4MIX Input 1 Source */
1305 [0x09F0] = 0x0000, /* R2544 - DSP3AUX5MIX Input 1 Source */
1306 [0x09F8] = 0x0000, /* R2552 - DSP3AUX6MIX Input 1 Source */
1307 [0x0A80] = 0x0000, /* R2688 - ASRC1LMIX Input 1 Source */
1308 [0x0A88] = 0x0000, /* R2696 - ASRC1RMIX Input 1 Source */
1309 [0x0A90] = 0x0000, /* R2704 - ASRC2LMIX Input 1 Source */
1310 [0x0A98] = 0x0000, /* R2712 - ASRC2RMIX Input 1 Source */
1311 [0x0B00] = 0x0000, /* R2816 - ISRC1DEC1MIX Input 1 Source */
1312 [0x0B08] = 0x0000, /* R2824 - ISRC1DEC2MIX Input 1 Source */
1313 [0x0B10] = 0x0000, /* R2832 - ISRC1DEC3MIX Input 1 Source */
1314 [0x0B18] = 0x0000, /* R2840 - ISRC1DEC4MIX Input 1 Source */
1315 [0x0B20] = 0x0000, /* R2848 - ISRC1INT1MIX Input 1 Source */
1316 [0x0B28] = 0x0000, /* R2856 - ISRC1INT2MIX Input 1 Source */
1317 [0x0B30] = 0x0000, /* R2864 - ISRC1INT3MIX Input 1 Source */
1318 [0x0B38] = 0x0000, /* R2872 - ISRC1INT4MIX Input 1 Source */
1319 [0x0B40] = 0x0000, /* R2880 - ISRC2DEC1MIX Input 1 Source */
1320 [0x0B48] = 0x0000, /* R2888 - ISRC2DEC2MIX Input 1 Source */
1321 [0x0B50] = 0x0000, /* R2896 - ISRC2DEC3MIX Input 1 Source */
1322 [0x0B58] = 0x0000, /* R2904 - ISRC2DEC4MIX Input 1 Source */
1323 [0x0B60] = 0x0000, /* R2912 - ISRC2INT1MIX Input 1 Source */
1324 [0x0B68] = 0x0000, /* R2920 - ISRC2INT2MIX Input 1 Source */
1325 [0x0B70] = 0x0000, /* R2928 - ISRC2INT3MIX Input 1 Source */
1326 [0x0B78] = 0x0000, /* R2936 - ISRC2INT4MIX Input 1 Source */
1327 [0x0C00] = 0xA001, /* R3072 - GPIO CTRL 1 */
1328 [0x0C01] = 0xA001, /* R3073 - GPIO CTRL 2 */
1329 [0x0C02] = 0xA001, /* R3074 - GPIO CTRL 3 */
1330 [0x0C03] = 0xA001, /* R3075 - GPIO CTRL 4 */
1331 [0x0C04] = 0xA001, /* R3076 - GPIO CTRL 5 */
1332 [0x0C05] = 0xA001, /* R3077 - GPIO CTRL 6 */
1333 [0x0C23] = 0x4003, /* R3107 - Misc Pad Ctrl 1 */
1334 [0x0C24] = 0x0000, /* R3108 - Misc Pad Ctrl 2 */
1335 [0x0C25] = 0x0000, /* R3109 - Misc Pad Ctrl 3 */
1336 [0x0C26] = 0x0000, /* R3110 - Misc Pad Ctrl 4 */
1337 [0x0C27] = 0x0000, /* R3111 - Misc Pad Ctrl 5 */
1338 [0x0C28] = 0x0000, /* R3112 - Misc GPIO 1 */
1339 [0x0D00] = 0x0000, /* R3328 - Interrupt Status 1 */
1340 [0x0D01] = 0x0000, /* R3329 - Interrupt Status 2 */
1341 [0x0D02] = 0x0000, /* R3330 - Interrupt Status 3 */
1342 [0x0D03] = 0x0000, /* R3331 - Interrupt Status 4 */
1343 [0x0D04] = 0x0000, /* R3332 - Interrupt Raw Status 2 */
1344 [0x0D05] = 0x0000, /* R3333 - Interrupt Raw Status 3 */
1345 [0x0D06] = 0x0000, /* R3334 - Interrupt Raw Status 4 */
1346 [0x0D07] = 0xFFFF, /* R3335 - Interrupt Status 1 Mask */
1347 [0x0D08] = 0xFFFF, /* R3336 - Interrupt Status 2 Mask */
1348 [0x0D09] = 0xFFFF, /* R3337 - Interrupt Status 3 Mask */
1349 [0x0D0A] = 0xFFFF, /* R3338 - Interrupt Status 4 Mask */
1350 [0x0D1F] = 0x0000, /* R3359 - Interrupt Control */
1351 [0x0D20] = 0xFFFF, /* R3360 - IRQ Debounce 1 */
1352 [0x0D21] = 0xFFFF, /* R3361 - IRQ Debounce 2 */
1353 [0x0E00] = 0x0000, /* R3584 - FX_Ctrl */
1354 [0x0E10] = 0x6318, /* R3600 - EQ1_1 */
1355 [0x0E11] = 0x6300, /* R3601 - EQ1_2 */
1356 [0x0E12] = 0x0FC8, /* R3602 - EQ1_3 */
1357 [0x0E13] = 0x03FE, /* R3603 - EQ1_4 */
1358 [0x0E14] = 0x00E0, /* R3604 - EQ1_5 */
1359 [0x0E15] = 0x1EC4, /* R3605 - EQ1_6 */
1360 [0x0E16] = 0xF136, /* R3606 - EQ1_7 */
1361 [0x0E17] = 0x0409, /* R3607 - EQ1_8 */
1362 [0x0E18] = 0x04CC, /* R3608 - EQ1_9 */
1363 [0x0E19] = 0x1C9B, /* R3609 - EQ1_10 */
1364 [0x0E1A] = 0xF337, /* R3610 - EQ1_11 */
1365 [0x0E1B] = 0x040B, /* R3611 - EQ1_12 */
1366 [0x0E1C] = 0x0CBB, /* R3612 - EQ1_13 */
1367 [0x0E1D] = 0x16F8, /* R3613 - EQ1_14 */
1368 [0x0E1E] = 0xF7D9, /* R3614 - EQ1_15 */
1369 [0x0E1F] = 0x040A, /* R3615 - EQ1_16 */
1370 [0x0E20] = 0x1F14, /* R3616 - EQ1_17 */
1371 [0x0E21] = 0x058C, /* R3617 - EQ1_18 */
1372 [0x0E22] = 0x0563, /* R3618 - EQ1_19 */
1373 [0x0E23] = 0x4000, /* R3619 - EQ1_20 */
1374 [0x0E26] = 0x6318, /* R3622 - EQ2_1 */
1375 [0x0E27] = 0x6300, /* R3623 - EQ2_2 */
1376 [0x0E28] = 0x0FC8, /* R3624 - EQ2_3 */
1377 [0x0E29] = 0x03FE, /* R3625 - EQ2_4 */
1378 [0x0E2A] = 0x00E0, /* R3626 - EQ2_5 */
1379 [0x0E2B] = 0x1EC4, /* R3627 - EQ2_6 */
1380 [0x0E2C] = 0xF136, /* R3628 - EQ2_7 */
1381 [0x0E2D] = 0x0409, /* R3629 - EQ2_8 */
1382 [0x0E2E] = 0x04CC, /* R3630 - EQ2_9 */
1383 [0x0E2F] = 0x1C9B, /* R3631 - EQ2_10 */
1384 [0x0E30] = 0xF337, /* R3632 - EQ2_11 */
1385 [0x0E31] = 0x040B, /* R3633 - EQ2_12 */
1386 [0x0E32] = 0x0CBB, /* R3634 - EQ2_13 */
1387 [0x0E33] = 0x16F8, /* R3635 - EQ2_14 */
1388 [0x0E34] = 0xF7D9, /* R3636 - EQ2_15 */
1389 [0x0E35] = 0x040A, /* R3637 - EQ2_16 */
1390 [0x0E36] = 0x1F14, /* R3638 - EQ2_17 */
1391 [0x0E37] = 0x058C, /* R3639 - EQ2_18 */
1392 [0x0E38] = 0x0563, /* R3640 - EQ2_19 */
1393 [0x0E39] = 0x4000, /* R3641 - EQ2_20 */
1394 [0x0E3C] = 0x6318, /* R3644 - EQ3_1 */
1395 [0x0E3D] = 0x6300, /* R3645 - EQ3_2 */
1396 [0x0E3E] = 0x0FC8, /* R3646 - EQ3_3 */
1397 [0x0E3F] = 0x03FE, /* R3647 - EQ3_4 */
1398 [0x0E40] = 0x00E0, /* R3648 - EQ3_5 */
1399 [0x0E41] = 0x1EC4, /* R3649 - EQ3_6 */
1400 [0x0E42] = 0xF136, /* R3650 - EQ3_7 */
1401 [0x0E43] = 0x0409, /* R3651 - EQ3_8 */
1402 [0x0E44] = 0x04CC, /* R3652 - EQ3_9 */
1403 [0x0E45] = 0x1C9B, /* R3653 - EQ3_10 */
1404 [0x0E46] = 0xF337, /* R3654 - EQ3_11 */
1405 [0x0E47] = 0x040B, /* R3655 - EQ3_12 */
1406 [0x0E48] = 0x0CBB, /* R3656 - EQ3_13 */
1407 [0x0E49] = 0x16F8, /* R3657 - EQ3_14 */
1408 [0x0E4A] = 0xF7D9, /* R3658 - EQ3_15 */
1409 [0x0E4B] = 0x040A, /* R3659 - EQ3_16 */
1410 [0x0E4C] = 0x1F14, /* R3660 - EQ3_17 */
1411 [0x0E4D] = 0x058C, /* R3661 - EQ3_18 */
1412 [0x0E4E] = 0x0563, /* R3662 - EQ3_19 */
1413 [0x0E4F] = 0x4000, /* R3663 - EQ3_20 */
1414 [0x0E52] = 0x6318, /* R3666 - EQ4_1 */
1415 [0x0E53] = 0x6300, /* R3667 - EQ4_2 */
1416 [0x0E54] = 0x0FC8, /* R3668 - EQ4_3 */
1417 [0x0E55] = 0x03FE, /* R3669 - EQ4_4 */
1418 [0x0E56] = 0x00E0, /* R3670 - EQ4_5 */
1419 [0x0E57] = 0x1EC4, /* R3671 - EQ4_6 */
1420 [0x0E58] = 0xF136, /* R3672 - EQ4_7 */
1421 [0x0E59] = 0x0409, /* R3673 - EQ4_8 */
1422 [0x0E5A] = 0x04CC, /* R3674 - EQ4_9 */
1423 [0x0E5B] = 0x1C9B, /* R3675 - EQ4_10 */
1424 [0x0E5C] = 0xF337, /* R3676 - EQ4_11 */
1425 [0x0E5D] = 0x040B, /* R3677 - EQ4_12 */
1426 [0x0E5E] = 0x0CBB, /* R3678 - EQ4_13 */
1427 [0x0E5F] = 0x16F8, /* R3679 - EQ4_14 */
1428 [0x0E60] = 0xF7D9, /* R3680 - EQ4_15 */
1429 [0x0E61] = 0x040A, /* R3681 - EQ4_16 */
1430 [0x0E62] = 0x1F14, /* R3682 - EQ4_17 */
1431 [0x0E63] = 0x058C, /* R3683 - EQ4_18 */
1432 [0x0E64] = 0x0563, /* R3684 - EQ4_19 */
1433 [0x0E65] = 0x4000, /* R3685 - EQ4_20 */
1434 [0x0E80] = 0x0018, /* R3712 - DRC1 ctrl1 */
1435 [0x0E81] = 0x0933, /* R3713 - DRC1 ctrl2 */
1436 [0x0E82] = 0x0018, /* R3714 - DRC1 ctrl3 */
1437 [0x0E83] = 0x0000, /* R3715 - DRC1 ctrl4 */
1438 [0x0E84] = 0x0000, /* R3716 - DRC1 ctrl5 */
1439 [0x0EC0] = 0x0000, /* R3776 - HPLPF1_1 */
1440 [0x0EC1] = 0x0000, /* R3777 - HPLPF1_2 */
1441 [0x0EC4] = 0x0000, /* R3780 - HPLPF2_1 */
1442 [0x0EC5] = 0x0000, /* R3781 - HPLPF2_2 */
1443 [0x0EC8] = 0x0000, /* R3784 - HPLPF3_1 */
1444 [0x0EC9] = 0x0000, /* R3785 - HPLPF3_2 */
1445 [0x0ECC] = 0x0000, /* R3788 - HPLPF4_1 */
1446 [0x0ECD] = 0x0000, /* R3789 - HPLPF4_2 */
1447 [0x4000] = 0x0000, /* R16384 - DSP1 DM 0 */
1448 [0x4001] = 0x0000, /* R16385 - DSP1 DM 1 */
1449 [0x4002] = 0x0000, /* R16386 - DSP1 DM 2 */
1450 [0x4003] = 0x0000, /* R16387 - DSP1 DM 3 */
1451 [0x41FC] = 0x0000, /* R16892 - DSP1 DM 508 */
1452 [0x41FD] = 0x0000, /* R16893 - DSP1 DM 509 */
1453 [0x41FE] = 0x0000, /* R16894 - DSP1 DM 510 */
1454 [0x41FF] = 0x0000, /* R16895 - DSP1 DM 511 */
1455 [0x4800] = 0x0000, /* R18432 - DSP1 PM 0 */
1456 [0x4801] = 0x0000, /* R18433 - DSP1 PM 1 */
1457 [0x4802] = 0x0000, /* R18434 - DSP1 PM 2 */
1458 [0x4803] = 0x0000, /* R18435 - DSP1 PM 3 */
1459 [0x4804] = 0x0000, /* R18436 - DSP1 PM 4 */
1460 [0x4805] = 0x0000, /* R18437 - DSP1 PM 5 */
1461 [0x4DFA] = 0x0000, /* R19962 - DSP1 PM 1530 */
1462 [0x4DFB] = 0x0000, /* R19963 - DSP1 PM 1531 */
1463 [0x4DFC] = 0x0000, /* R19964 - DSP1 PM 1532 */
1464 [0x4DFD] = 0x0000, /* R19965 - DSP1 PM 1533 */
1465 [0x4DFE] = 0x0000, /* R19966 - DSP1 PM 1534 */
1466 [0x4DFF] = 0x0000, /* R19967 - DSP1 PM 1535 */
1467 [0x5000] = 0x0000, /* R20480 - DSP1 ZM 0 */
1468 [0x5001] = 0x0000, /* R20481 - DSP1 ZM 1 */
1469 [0x5002] = 0x0000, /* R20482 - DSP1 ZM 2 */
1470 [0x5003] = 0x0000, /* R20483 - DSP1 ZM 3 */
1471 [0x57FC] = 0x0000, /* R22524 - DSP1 ZM 2044 */
1472 [0x57FD] = 0x0000, /* R22525 - DSP1 ZM 2045 */
1473 [0x57FE] = 0x0000, /* R22526 - DSP1 ZM 2046 */
1474 [0x57FF] = 0x0000, /* R22527 - DSP1 ZM 2047 */
1475 [0x6000] = 0x0000, /* R24576 - DSP2 DM 0 */
1476 [0x6001] = 0x0000, /* R24577 - DSP2 DM 1 */
1477 [0x6002] = 0x0000, /* R24578 - DSP2 DM 2 */
1478 [0x6003] = 0x0000, /* R24579 - DSP2 DM 3 */
1479 [0x61FC] = 0x0000, /* R25084 - DSP2 DM 508 */
1480 [0x61FD] = 0x0000, /* R25085 - DSP2 DM 509 */
1481 [0x61FE] = 0x0000, /* R25086 - DSP2 DM 510 */
1482 [0x61FF] = 0x0000, /* R25087 - DSP2 DM 511 */
1483 [0x6800] = 0x0000, /* R26624 - DSP2 PM 0 */
1484 [0x6801] = 0x0000, /* R26625 - DSP2 PM 1 */
1485 [0x6802] = 0x0000, /* R26626 - DSP2 PM 2 */
1486 [0x6803] = 0x0000, /* R26627 - DSP2 PM 3 */
1487 [0x6804] = 0x0000, /* R26628 - DSP2 PM 4 */
1488 [0x6805] = 0x0000, /* R26629 - DSP2 PM 5 */
1489 [0x6DFA] = 0x0000, /* R28154 - DSP2 PM 1530 */
1490 [0x6DFB] = 0x0000, /* R28155 - DSP2 PM 1531 */
1491 [0x6DFC] = 0x0000, /* R28156 - DSP2 PM 1532 */
1492 [0x6DFD] = 0x0000, /* R28157 - DSP2 PM 1533 */
1493 [0x6DFE] = 0x0000, /* R28158 - DSP2 PM 1534 */
1494 [0x6DFF] = 0x0000, /* R28159 - DSP2 PM 1535 */
1495 [0x7000] = 0x0000, /* R28672 - DSP2 ZM 0 */
1496 [0x7001] = 0x0000, /* R28673 - DSP2 ZM 1 */
1497 [0x7002] = 0x0000, /* R28674 - DSP2 ZM 2 */
1498 [0x7003] = 0x0000, /* R28675 - DSP2 ZM 3 */
1499 [0x77FC] = 0x0000, /* R30716 - DSP2 ZM 2044 */
1500 [0x77FD] = 0x0000, /* R30717 - DSP2 ZM 2045 */
1501 [0x77FE] = 0x0000, /* R30718 - DSP2 ZM 2046 */
1502 [0x77FF] = 0x0000, /* R30719 - DSP2 ZM 2047 */
1503 [0x8000] = 0x0000, /* R32768 - DSP3 DM 0 */
1504 [0x8001] = 0x0000, /* R32769 - DSP3 DM 1 */
1505 [0x8002] = 0x0000, /* R32770 - DSP3 DM 2 */
1506 [0x8003] = 0x0000, /* R32771 - DSP3 DM 3 */
1507 [0x81FC] = 0x0000, /* R33276 - DSP3 DM 508 */
1508 [0x81FD] = 0x0000, /* R33277 - DSP3 DM 509 */
1509 [0x81FE] = 0x0000, /* R33278 - DSP3 DM 510 */
1510 [0x81FF] = 0x0000, /* R33279 - DSP3 DM 511 */
1511 [0x8800] = 0x0000, /* R34816 - DSP3 PM 0 */
1512 [0x8801] = 0x0000, /* R34817 - DSP3 PM 1 */
1513 [0x8802] = 0x0000, /* R34818 - DSP3 PM 2 */
1514 [0x8803] = 0x0000, /* R34819 - DSP3 PM 3 */
1515 [0x8804] = 0x0000, /* R34820 - DSP3 PM 4 */
1516 [0x8805] = 0x0000, /* R34821 - DSP3 PM 5 */
1517 [0x8DFA] = 0x0000, /* R36346 - DSP3 PM 1530 */
1518 [0x8DFB] = 0x0000, /* R36347 - DSP3 PM 1531 */
1519 [0x8DFC] = 0x0000, /* R36348 - DSP3 PM 1532 */
1520 [0x8DFD] = 0x0000, /* R36349 - DSP3 PM 1533 */
1521 [0x8DFE] = 0x0000, /* R36350 - DSP3 PM 1534 */
1522 [0x8DFF] = 0x0000, /* R36351 - DSP3 PM 1535 */
1523 [0x9000] = 0x0000, /* R36864 - DSP3 ZM 0 */
1524 [0x9001] = 0x0000, /* R36865 - DSP3 ZM 1 */
1525 [0x9002] = 0x0000, /* R36866 - DSP3 ZM 2 */
1526 [0x9003] = 0x0000, /* R36867 - DSP3 ZM 3 */
1527 [0x97FC] = 0x0000, /* R38908 - DSP3 ZM 2044 */
1528 [0x97FD] = 0x0000, /* R38909 - DSP3 ZM 2045 */
1529 [0x97FE] = 0x0000, /* R38910 - DSP3 ZM 2046 */
1530 [0x97FF] = 0x0000 /* R38911 - DSP3 ZM 2047 */
1531};
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
new file mode 100644
index 000000000000..5d88c99aaea6
--- /dev/null
+++ b/sound/soc/codecs/wm5100.c
@@ -0,0 +1,2809 @@
1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 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/platform_device.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/wm5100.h>
33
34#include "wm5100.h"
35
36#define WM5100_NUM_CORE_SUPPLIES 2
37static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
38 "DBVDD1",
39 "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
40};
41
42#define WM5100_AIFS 3
43#define WM5100_SYNC_SRS 3
44
45struct wm5100_fll {
46 int fref;
47 int fout;
48 int src;
49 struct completion lock;
50};
51
52/* codec private data */
53struct wm5100_priv {
54 struct snd_soc_codec *codec;
55
56 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
57 struct regulator *cpvdd;
58 struct regulator *dbvdd2;
59 struct regulator *dbvdd3;
60
61 int rev;
62
63 int sysclk;
64 int asyncclk;
65
66 bool aif_async[WM5100_AIFS];
67 bool aif_symmetric[WM5100_AIFS];
68 int sr_ref[WM5100_SYNC_SRS];
69
70 bool out_ena[2];
71
72 struct snd_soc_jack *jack;
73 bool jack_detecting;
74 bool jack_mic;
75 int jack_mode;
76
77 struct wm5100_fll fll[2];
78
79 struct wm5100_pdata pdata;
80
81#ifdef CONFIG_GPIOLIB
82 struct gpio_chip gpio_chip;
83#endif
84};
85
86static int wm5100_sr_code[] = {
87 0,
88 12000,
89 24000,
90 48000,
91 96000,
92 192000,
93 384000,
94 768000,
95 0,
96 11025,
97 22050,
98 44100,
99 88200,
100 176400,
101 352800,
102 705600,
103 4000,
104 8000,
105 16000,
106 32000,
107 64000,
108 128000,
109 256000,
110 512000,
111};
112
113static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
114 WM5100_CLOCKING_4,
115 WM5100_CLOCKING_5,
116 WM5100_CLOCKING_6,
117};
118
119static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
120{
121 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
122 int sr_code, sr_free, i;
123
124 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
125 if (wm5100_sr_code[i] == rate)
126 break;
127 if (i == ARRAY_SIZE(wm5100_sr_code)) {
128 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
129 return -EINVAL;
130 }
131 sr_code = i;
132
133 if ((wm5100->sysclk % rate) == 0) {
134 /* Is this rate already in use? */
135 sr_free = -1;
136 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
137 if (!wm5100->sr_ref[i] && sr_free == -1) {
138 sr_free = i;
139 continue;
140 }
141 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
142 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
143 break;
144 }
145
146 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
147 wm5100->sr_ref[i]++;
148 dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
149 rate, i, wm5100->sr_ref[i]);
150 return i;
151 }
152
153 if (sr_free == -1) {
154 dev_err(codec->dev, "All SR slots already in use\n");
155 return -EBUSY;
156 }
157
158 dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
159 sr_free, rate);
160 wm5100->sr_ref[sr_free]++;
161 snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
162 WM5100_SAMPLE_RATE_1_MASK,
163 sr_code);
164
165 return sr_free;
166
167 } else {
168 dev_err(codec->dev,
169 "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
170 rate, wm5100->sysclk, wm5100->asyncclk);
171 return -EINVAL;
172 }
173}
174
175static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
176{
177 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
178 int i, sr_code;
179
180 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
181 if (wm5100_sr_code[i] == rate)
182 break;
183 if (i == ARRAY_SIZE(wm5100_sr_code)) {
184 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
185 return;
186 }
187 sr_code = wm5100_sr_code[i];
188
189 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
190 if (!wm5100->sr_ref[i])
191 continue;
192
193 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
194 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
195 break;
196 }
197 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
198 wm5100->sr_ref[i]--;
199 dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
200 rate, wm5100->sr_ref[i]);
201 } else {
202 dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
203 rate);
204 }
205}
206
207static int wm5100_reset(struct snd_soc_codec *codec)
208{
209 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
210
211 if (wm5100->pdata.reset) {
212 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
213 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
214
215 return 0;
216 } else {
217 return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
218 }
219}
220
221static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
222static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
223static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0);
224static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
225static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
226
227static const char *wm5100_mixer_texts[] = {
228 "None",
229 "Tone Generator 1",
230 "Tone Generator 2",
231 "AEC loopback",
232 "IN1L",
233 "IN1R",
234 "IN2L",
235 "IN2R",
236 "IN3L",
237 "IN3R",
238 "IN4L",
239 "IN4R",
240 "AIF1RX1",
241 "AIF1RX2",
242 "AIF1RX3",
243 "AIF1RX4",
244 "AIF1RX5",
245 "AIF1RX6",
246 "AIF1RX7",
247 "AIF1RX8",
248 "AIF2RX1",
249 "AIF2RX2",
250 "AIF3RX1",
251 "AIF3RX2",
252 "EQ1",
253 "EQ2",
254 "EQ3",
255 "EQ4",
256 "DRC1L",
257 "DRC1R",
258 "LHPF1",
259 "LHPF2",
260 "LHPF3",
261 "LHPF4",
262 "DSP1.1",
263 "DSP1.2",
264 "DSP1.3",
265 "DSP1.4",
266 "DSP1.5",
267 "DSP1.6",
268 "DSP2.1",
269 "DSP2.2",
270 "DSP2.3",
271 "DSP2.4",
272 "DSP2.5",
273 "DSP2.6",
274 "DSP3.1",
275 "DSP3.2",
276 "DSP3.3",
277 "DSP3.4",
278 "DSP3.5",
279 "DSP3.6",
280 "ASRC1L",
281 "ASRC1R",
282 "ASRC2L",
283 "ASRC2R",
284 "ISRC1INT1",
285 "ISRC1INT2",
286 "ISRC1INT3",
287 "ISRC1INT4",
288 "ISRC2INT1",
289 "ISRC2INT2",
290 "ISRC2INT3",
291 "ISRC2INT4",
292 "ISRC1DEC1",
293 "ISRC1DEC2",
294 "ISRC1DEC3",
295 "ISRC1DEC4",
296 "ISRC2DEC1",
297 "ISRC2DEC2",
298 "ISRC2DEC3",
299 "ISRC2DEC4",
300};
301
302static int wm5100_mixer_values[] = {
303 0x00,
304 0x04, /* Tone */
305 0x05,
306 0x08, /* AEC */
307 0x10, /* Input */
308 0x11,
309 0x12,
310 0x13,
311 0x14,
312 0x15,
313 0x16,
314 0x17,
315 0x20, /* AIF */
316 0x21,
317 0x22,
318 0x23,
319 0x24,
320 0x25,
321 0x26,
322 0x27,
323 0x28,
324 0x29,
325 0x30, /* AIF3 - check */
326 0x31,
327 0x50, /* EQ */
328 0x51,
329 0x52,
330 0x53,
331 0x54,
332 0x58, /* DRC */
333 0x59,
334 0x60, /* LHPF1 */
335 0x61, /* LHPF2 */
336 0x62, /* LHPF3 */
337 0x63, /* LHPF4 */
338 0x68, /* DSP1 */
339 0x69,
340 0x6a,
341 0x6b,
342 0x6c,
343 0x6d,
344 0x70, /* DSP2 */
345 0x71,
346 0x72,
347 0x73,
348 0x74,
349 0x75,
350 0x78, /* DSP3 */
351 0x79,
352 0x7a,
353 0x7b,
354 0x7c,
355 0x7d,
356 0x90, /* ASRC1 */
357 0x91,
358 0x92, /* ASRC2 */
359 0x93,
360 0xa0, /* ISRC1DEC1 */
361 0xa1,
362 0xa2,
363 0xa3,
364 0xa4, /* ISRC1INT1 */
365 0xa5,
366 0xa6,
367 0xa7,
368 0xa8, /* ISRC2DEC1 */
369 0xa9,
370 0xaa,
371 0xab,
372 0xac, /* ISRC2INT1 */
373 0xad,
374 0xae,
375 0xaf,
376};
377
378#define WM5100_MIXER_CONTROLS(name, base) \
379 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
380 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
381 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
382 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
383 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
384 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
385 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
386 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
387
388#define WM5100_MUX_ENUM_DECL(name, reg) \
389 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
390 wm5100_mixer_texts, wm5100_mixer_values)
391
392#define WM5100_MUX_CTL_DECL(name) \
393 const struct snd_kcontrol_new name##_mux = \
394 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
395
396#define WM5100_MIXER_ENUMS(name, base_reg) \
397 static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
398 static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
399 static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
400 static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
401 static WM5100_MUX_CTL_DECL(name##_in1); \
402 static WM5100_MUX_CTL_DECL(name##_in2); \
403 static WM5100_MUX_CTL_DECL(name##_in3); \
404 static WM5100_MUX_CTL_DECL(name##_in4)
405
406WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE);
407WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE);
408WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE);
409WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE);
410WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE);
411WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE);
412
413WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE);
414WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE);
415WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE);
416WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE);
417WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE);
418WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE);
419
420WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE);
421WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE);
422
423WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
424WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
425WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE);
426WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE);
427WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE);
428WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE);
429WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE);
430WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE);
431
432WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE);
433WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE);
434
435WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
436WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
437
438WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE);
439WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE);
440WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE);
441WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE);
442
443WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE);
444WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE);
445
446WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE);
447WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE);
448WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE);
449WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE);
450
451#define WM5100_MUX(name, ctrl) \
452 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
453
454#define WM5100_MIXER_WIDGETS(name, name_str) \
455 WM5100_MUX(name_str " Input 1", &name##_in1_mux), \
456 WM5100_MUX(name_str " Input 2", &name##_in2_mux), \
457 WM5100_MUX(name_str " Input 3", &name##_in3_mux), \
458 WM5100_MUX(name_str " Input 4", &name##_in4_mux), \
459 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
460
461#define WM5100_MIXER_INPUT_ROUTES(name) \
462 { name, "Tone Generator 1", "Tone Generator 1" }, \
463 { name, "Tone Generator 2", "Tone Generator 2" }, \
464 { name, "IN1L", "IN1L PGA" }, \
465 { name, "IN1R", "IN1R PGA" }, \
466 { name, "IN2L", "IN2L PGA" }, \
467 { name, "IN2R", "IN2R PGA" }, \
468 { name, "IN3L", "IN3L PGA" }, \
469 { name, "IN3R", "IN3R PGA" }, \
470 { name, "IN4L", "IN4L PGA" }, \
471 { name, "IN4R", "IN4R PGA" }, \
472 { name, "AIF1RX1", "AIF1RX1" }, \
473 { name, "AIF1RX2", "AIF1RX2" }, \
474 { name, "AIF1RX3", "AIF1RX3" }, \
475 { name, "AIF1RX4", "AIF1RX4" }, \
476 { name, "AIF1RX5", "AIF1RX5" }, \
477 { name, "AIF1RX6", "AIF1RX6" }, \
478 { name, "AIF1RX7", "AIF1RX7" }, \
479 { name, "AIF1RX8", "AIF1RX8" }, \
480 { name, "AIF2RX1", "AIF2RX1" }, \
481 { name, "AIF2RX2", "AIF2RX2" }, \
482 { name, "AIF3RX1", "AIF3RX1" }, \
483 { name, "AIF3RX2", "AIF3RX2" }, \
484 { name, "EQ1", "EQ1" }, \
485 { name, "EQ2", "EQ2" }, \
486 { name, "EQ3", "EQ3" }, \
487 { name, "EQ4", "EQ4" }, \
488 { name, "DRC1L", "DRC1L" }, \
489 { name, "DRC1R", "DRC1R" }, \
490 { name, "LHPF1", "LHPF1" }, \
491 { name, "LHPF2", "LHPF2" }, \
492 { name, "LHPF3", "LHPF3" }, \
493 { name, "LHPF4", "LHPF4" }
494
495#define WM5100_MIXER_ROUTES(widget, name) \
496 { widget, NULL, name " Mixer" }, \
497 { name " Mixer", NULL, name " Input 1" }, \
498 { name " Mixer", NULL, name " Input 2" }, \
499 { name " Mixer", NULL, name " Input 3" }, \
500 { name " Mixer", NULL, name " Input 4" }, \
501 WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \
502 WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \
503 WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \
504 WM5100_MIXER_INPUT_ROUTES(name " Input 4")
505
506static const char *wm5100_lhpf_mode_text[] = {
507 "Low-pass", "High-pass"
508};
509
510static const struct soc_enum wm5100_lhpf1_mode =
511 SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2,
512 wm5100_lhpf_mode_text);
513
514static const struct soc_enum wm5100_lhpf2_mode =
515 SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2,
516 wm5100_lhpf_mode_text);
517
518static const struct soc_enum wm5100_lhpf3_mode =
519 SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2,
520 wm5100_lhpf_mode_text);
521
522static const struct soc_enum wm5100_lhpf4_mode =
523 SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2,
524 wm5100_lhpf_mode_text);
525
526static const struct snd_kcontrol_new wm5100_snd_controls[] = {
527SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL,
528 WM5100_IN1_OSR_SHIFT, 1, 0),
529SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL,
530 WM5100_IN2_OSR_SHIFT, 1, 0),
531SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL,
532 WM5100_IN3_OSR_SHIFT, 1, 0),
533SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL,
534 WM5100_IN4_OSR_SHIFT, 1, 0),
535
536/* Only applicable for analogue inputs */
537SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL,
538 WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv),
539SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL,
540 WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv),
541SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL,
542 WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv),
543SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL,
544 WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv),
545
546SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L,
547 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191,
548 0, digital_tlv),
549SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L,
550 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191,
551 0, digital_tlv),
552SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L,
553 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191,
554 0, digital_tlv),
555SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L,
556 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191,
557 0, digital_tlv),
558
559SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L,
560 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1),
561SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L,
562 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1),
563SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
564 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1),
565SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
566 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
567
568SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
569 WM5100_OUT1_OSR_SHIFT, 1, 0),
570SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
571 WM5100_OUT2_OSR_SHIFT, 1, 0),
572SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L,
573 WM5100_OUT3_OSR_SHIFT, 1, 0),
574SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L,
575 WM5100_OUT4_OSR_SHIFT, 1, 0),
576SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L,
577 WM5100_OUT5_OSR_SHIFT, 1, 0),
578SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L,
579 WM5100_OUT6_OSR_SHIFT, 1, 0),
580
581SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L,
582 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0,
583 digital_tlv),
584SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L,
585 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0,
586 digital_tlv),
587SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L,
588 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0,
589 digital_tlv),
590SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L,
591 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0,
592 digital_tlv),
593SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L,
594 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0,
595 digital_tlv),
596SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L,
597 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0,
598 digital_tlv),
599
600SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L,
601 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1),
602SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L,
603 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1),
604SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L,
605 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1),
606SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L,
607 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1),
608SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L,
609 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1),
610SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L,
611 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1),
612
613/* FIXME: Only valid from -12dB to 0dB (52-64) */
614SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R,
615 WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv),
616SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R,
617 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
618SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R,
619 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
620
621SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT,
622 WM5100_SPK1R_MUTE_SHIFT, 1, 1),
623SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT,
624 WM5100_SPK2R_MUTE_SHIFT, 1, 1),
625
626SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT,
627 24, 0, eq_tlv),
628SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT,
629 24, 0, eq_tlv),
630SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT,
631 24, 0, eq_tlv),
632SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT,
633 24, 0, eq_tlv),
634SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT,
635 24, 0, eq_tlv),
636
637SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT,
638 24, 0, eq_tlv),
639SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT,
640 24, 0, eq_tlv),
641SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT,
642 24, 0, eq_tlv),
643SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT,
644 24, 0, eq_tlv),
645SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT,
646 24, 0, eq_tlv),
647
648SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT,
649 24, 0, eq_tlv),
650SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT,
651 24, 0, eq_tlv),
652SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT,
653 24, 0, eq_tlv),
654SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT,
655 24, 0, eq_tlv),
656SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT,
657 24, 0, eq_tlv),
658
659SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT,
660 24, 0, eq_tlv),
661SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT,
662 24, 0, eq_tlv),
663SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT,
664 24, 0, eq_tlv),
665SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT,
666 24, 0, eq_tlv),
667SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT,
668 24, 0, eq_tlv),
669
670SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode),
671SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode),
672SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode),
673SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode),
674
675WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE),
676WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE),
677WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE),
678WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE),
679WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE),
680WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE),
681
682WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE),
683WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE),
684WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE),
685WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE),
686WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE),
687WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE),
688
689WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE),
690WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE),
691
692WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE),
693WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE),
694WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE),
695WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE),
696WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE),
697WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE),
698WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE),
699WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE),
700
701WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE),
702WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE),
703
704WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE),
705WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE),
706
707WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE),
708WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE),
709WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE),
710WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
711
712WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
713WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
714
715WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
716WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
717WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
718WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
719};
720
721static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
722 enum snd_soc_dapm_type event, int subseq)
723{
724 struct snd_soc_codec *codec = container_of(dapm,
725 struct snd_soc_codec, dapm);
726 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
727 u16 val, expect, i;
728
729 /* Wait for the outputs to flag themselves as enabled */
730 if (wm5100->out_ena[0]) {
731 expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
732 for (i = 0; i < 200; i++) {
733 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
734 if (val == expect) {
735 wm5100->out_ena[0] = false;
736 break;
737 }
738 }
739 if (i == 200) {
740 dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
741 expect);
742 }
743 }
744
745 if (wm5100->out_ena[1]) {
746 expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
747 for (i = 0; i < 200; i++) {
748 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
749 if (val == expect) {
750 wm5100->out_ena[1] = false;
751 break;
752 }
753 }
754 if (i == 200) {
755 dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
756 expect);
757 }
758 }
759}
760
761static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
762 struct snd_kcontrol *kcontrol,
763 int event)
764{
765 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
766
767 switch (w->reg) {
768 case WM5100_CHANNEL_ENABLES_1:
769 wm5100->out_ena[0] = true;
770 break;
771 case WM5100_OUTPUT_ENABLES_2:
772 wm5100->out_ena[0] = true;
773 break;
774 default:
775 break;
776 }
777
778 return 0;
779}
780
781static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
782 struct snd_kcontrol *kcontrol,
783 int event)
784{
785 struct snd_soc_codec *codec = w->codec;
786 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
787 int ret;
788
789 switch (event) {
790 case SND_SOC_DAPM_PRE_PMU:
791 ret = regulator_enable(wm5100->cpvdd);
792 if (ret != 0) {
793 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
794 ret);
795 return ret;
796 }
797 return ret;
798
799 case SND_SOC_DAPM_POST_PMD:
800 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
801 if (ret != 0) {
802 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
803 ret);
804 return ret;
805 }
806 return ret;
807
808 default:
809 BUG();
810 return 0;
811 }
812}
813
814static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
815 struct snd_kcontrol *kcontrol,
816 int event)
817{
818 struct snd_soc_codec *codec = w->codec;
819 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
820 struct regulator *regulator;
821 int ret;
822
823 switch (w->shift) {
824 case 2:
825 regulator = wm5100->dbvdd2;
826 break;
827 case 3:
828 regulator = wm5100->dbvdd3;
829 break;
830 default:
831 BUG();
832 return 0;
833 }
834
835 switch (event) {
836 case SND_SOC_DAPM_PRE_PMU:
837 ret = regulator_enable(regulator);
838 if (ret != 0) {
839 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
840 w->shift, ret);
841 return ret;
842 }
843 return ret;
844
845 case SND_SOC_DAPM_POST_PMD:
846 ret = regulator_disable(regulator);
847 if (ret != 0) {
848 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
849 w->shift, ret);
850 return ret;
851 }
852 return ret;
853
854 default:
855 BUG();
856 return 0;
857 }
858}
859
860static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
861{
862 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
863 dev_crit(codec->dev, "Speaker shutdown warning\n");
864 if (val & WM5100_SPK_SHUTDOWN_EINT)
865 dev_crit(codec->dev, "Speaker shutdown\n");
866 if (val & WM5100_CLKGEN_ERR_EINT)
867 dev_crit(codec->dev, "SYSCLK underclocked\n");
868 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
869 dev_crit(codec->dev, "ASYNCCLK underclocked\n");
870}
871
872static void wm5100_log_status4(struct snd_soc_codec *codec, int val)
873{
874 if (val & WM5100_AIF3_ERR_EINT)
875 dev_err(codec->dev, "AIF3 configuration error\n");
876 if (val & WM5100_AIF2_ERR_EINT)
877 dev_err(codec->dev, "AIF2 configuration error\n");
878 if (val & WM5100_AIF1_ERR_EINT)
879 dev_err(codec->dev, "AIF1 configuration error\n");
880 if (val & WM5100_CTRLIF_ERR_EINT)
881 dev_err(codec->dev, "Control interface error\n");
882 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
883 dev_err(codec->dev, "ISRC2 underclocked\n");
884 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
885 dev_err(codec->dev, "ISRC1 underclocked\n");
886 if (val & WM5100_FX_UNDERCLOCKED_EINT)
887 dev_err(codec->dev, "FX underclocked\n");
888 if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
889 dev_err(codec->dev, "AIF3 underclocked\n");
890 if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
891 dev_err(codec->dev, "AIF2 underclocked\n");
892 if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
893 dev_err(codec->dev, "AIF1 underclocked\n");
894 if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
895 dev_err(codec->dev, "ASRC underclocked\n");
896 if (val & WM5100_DAC_UNDERCLOCKED_EINT)
897 dev_err(codec->dev, "DAC underclocked\n");
898 if (val & WM5100_ADC_UNDERCLOCKED_EINT)
899 dev_err(codec->dev, "ADC underclocked\n");
900 if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
901 dev_err(codec->dev, "Mixer underclocked\n");
902}
903
904static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
905 struct snd_kcontrol *kcontrol,
906 int event)
907{
908 struct snd_soc_codec *codec = w->codec;
909 int ret;
910
911 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
912 ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
913 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
914 WM5100_CLKGEN_ERR_ASYNC_STS;
915 wm5100_log_status3(codec, ret);
916
917 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
918 wm5100_log_status4(codec, ret);
919
920 return 0;
921}
922
923static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = {
924SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
925 NULL, 0),
926SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
927 0, NULL, 0),
928
929SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
930 wm5100_cp_ev,
931 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
932SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
933 NULL, 0),
934SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
935 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev,
936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
937SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
939SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
940 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
941
942SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
943 0, NULL, 0),
944SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT,
945 0, NULL, 0),
946SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT,
947 0, NULL, 0),
948
949SND_SOC_DAPM_INPUT("IN1L"),
950SND_SOC_DAPM_INPUT("IN1R"),
951SND_SOC_DAPM_INPUT("IN2L"),
952SND_SOC_DAPM_INPUT("IN2R"),
953SND_SOC_DAPM_INPUT("IN3L"),
954SND_SOC_DAPM_INPUT("IN3R"),
955SND_SOC_DAPM_INPUT("IN4L"),
956SND_SOC_DAPM_INPUT("IN4R"),
957SND_SOC_DAPM_INPUT("TONE"),
958
959SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
960 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
961SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0,
962 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
963SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0,
964 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
965SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0,
966 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
967SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0,
968 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
969SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0,
970 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
971SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0,
972 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
973SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0,
974 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
975
976SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1,
977 WM5100_TONE1_ENA_SHIFT, 0, NULL, 0),
978SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1,
979 WM5100_TONE2_ENA_SHIFT, 0, NULL, 0),
980
981SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0,
982 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0),
983SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1,
984 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0),
985SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2,
986 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0),
987SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3,
988 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0),
989SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4,
990 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0),
991SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5,
992 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0),
993SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6,
994 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0),
995SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7,
996 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0),
997
998SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
999 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0),
1000SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1,
1001 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0),
1002
1003SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0,
1004 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0),
1005SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1,
1006 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0),
1007
1008SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0,
1009 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0),
1010SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1,
1011 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0),
1012SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2,
1013 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0),
1014SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3,
1015 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0),
1016SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4,
1017 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0),
1018SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5,
1019 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0),
1020SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6,
1021 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0),
1022SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7,
1023 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0),
1024
1025SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1026 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0),
1027SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1,
1028 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0),
1029
1030SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0,
1031 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0),
1032SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1,
1033 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0),
1034
1035SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0,
1036 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1037SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0,
1038 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1039SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0,
1040 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1041SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0,
1042 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1043SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0,
1044 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1045SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0,
1046 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1047SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0,
1048 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1049SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0,
1050 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1051SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0,
1052 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1053SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0,
1054 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1055SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0,
1056 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1057SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0,
1058 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1059SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0,
1060 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1061SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0,
1062 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1063
1064SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0),
1065SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0),
1066SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0),
1067SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0),
1068
1069SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0,
1070 NULL, 0),
1071SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0,
1072 NULL, 0),
1073
1074SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0,
1075 NULL, 0),
1076SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0,
1077 NULL, 0),
1078SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0,
1079 NULL, 0),
1080SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0,
1081 NULL, 0),
1082
1083WM5100_MIXER_WIDGETS(EQ1, "EQ1"),
1084WM5100_MIXER_WIDGETS(EQ2, "EQ2"),
1085WM5100_MIXER_WIDGETS(EQ3, "EQ3"),
1086WM5100_MIXER_WIDGETS(EQ4, "EQ4"),
1087
1088WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"),
1089WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"),
1090
1091WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"),
1092WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"),
1093WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"),
1094WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"),
1095
1096WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1097WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1098WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1099WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1100WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1101WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1102WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1103WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1104
1105WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1106WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1107
1108WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1109WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1110
1111WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"),
1112WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"),
1113WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"),
1114WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"),
1115WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"),
1116WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"),
1117
1118WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
1119WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
1120WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1121WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1122WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
1123WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
1124
1125WM5100_MIXER_WIDGETS(PWM1, "PWM1"),
1126WM5100_MIXER_WIDGETS(PWM2, "PWM2"),
1127
1128SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1129SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1130SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1131SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1132SND_SOC_DAPM_OUTPUT("HPOUT3L"),
1133SND_SOC_DAPM_OUTPUT("HPOUT3R"),
1134SND_SOC_DAPM_OUTPUT("SPKOUTL"),
1135SND_SOC_DAPM_OUTPUT("SPKOUTR"),
1136SND_SOC_DAPM_OUTPUT("SPKDAT1"),
1137SND_SOC_DAPM_OUTPUT("SPKDAT2"),
1138SND_SOC_DAPM_OUTPUT("PWM1"),
1139SND_SOC_DAPM_OUTPUT("PWM2"),
1140};
1141
1142/* We register a _POST event if we don't have IRQ support so we can
1143 * look at the error status from the CODEC - if we've got the IRQ
1144 * hooked up then we will get prompted to look by an interrupt.
1145 */
1146static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = {
1147SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1148};
1149
1150static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1151 { "IN1L", NULL, "SYSCLK" },
1152 { "IN1R", NULL, "SYSCLK" },
1153 { "IN2L", NULL, "SYSCLK" },
1154 { "IN2R", NULL, "SYSCLK" },
1155 { "IN3L", NULL, "SYSCLK" },
1156 { "IN3R", NULL, "SYSCLK" },
1157 { "IN4L", NULL, "SYSCLK" },
1158 { "IN4R", NULL, "SYSCLK" },
1159
1160 { "OUT1L", NULL, "SYSCLK" },
1161 { "OUT1R", NULL, "SYSCLK" },
1162 { "OUT2L", NULL, "SYSCLK" },
1163 { "OUT2R", NULL, "SYSCLK" },
1164 { "OUT3L", NULL, "SYSCLK" },
1165 { "OUT3R", NULL, "SYSCLK" },
1166 { "OUT4L", NULL, "SYSCLK" },
1167 { "OUT4R", NULL, "SYSCLK" },
1168 { "OUT5L", NULL, "SYSCLK" },
1169 { "OUT5R", NULL, "SYSCLK" },
1170 { "OUT6L", NULL, "SYSCLK" },
1171 { "OUT6R", NULL, "SYSCLK" },
1172
1173 { "AIF1RX1", NULL, "SYSCLK" },
1174 { "AIF1RX2", NULL, "SYSCLK" },
1175 { "AIF1RX3", NULL, "SYSCLK" },
1176 { "AIF1RX4", NULL, "SYSCLK" },
1177 { "AIF1RX5", NULL, "SYSCLK" },
1178 { "AIF1RX6", NULL, "SYSCLK" },
1179 { "AIF1RX7", NULL, "SYSCLK" },
1180 { "AIF1RX8", NULL, "SYSCLK" },
1181
1182 { "AIF2RX1", NULL, "SYSCLK" },
1183 { "AIF2RX1", NULL, "DBVDD2" },
1184 { "AIF2RX2", NULL, "SYSCLK" },
1185 { "AIF2RX2", NULL, "DBVDD2" },
1186
1187 { "AIF3RX1", NULL, "SYSCLK" },
1188 { "AIF3RX1", NULL, "DBVDD3" },
1189 { "AIF3RX2", NULL, "SYSCLK" },
1190 { "AIF3RX2", NULL, "DBVDD3" },
1191
1192 { "AIF1TX1", NULL, "SYSCLK" },
1193 { "AIF1TX2", NULL, "SYSCLK" },
1194 { "AIF1TX3", NULL, "SYSCLK" },
1195 { "AIF1TX4", NULL, "SYSCLK" },
1196 { "AIF1TX5", NULL, "SYSCLK" },
1197 { "AIF1TX6", NULL, "SYSCLK" },
1198 { "AIF1TX7", NULL, "SYSCLK" },
1199 { "AIF1TX8", NULL, "SYSCLK" },
1200
1201 { "AIF2TX1", NULL, "SYSCLK" },
1202 { "AIF2TX1", NULL, "DBVDD2" },
1203 { "AIF2TX2", NULL, "SYSCLK" },
1204 { "AIF2TX2", NULL, "DBVDD2" },
1205
1206 { "AIF3TX1", NULL, "SYSCLK" },
1207 { "AIF3TX1", NULL, "DBVDD3" },
1208 { "AIF3TX2", NULL, "SYSCLK" },
1209 { "AIF3TX2", NULL, "DBVDD3" },
1210
1211 { "MICBIAS1", NULL, "CP2" },
1212 { "MICBIAS2", NULL, "CP2" },
1213 { "MICBIAS3", NULL, "CP2" },
1214
1215 { "IN1L PGA", NULL, "CP2" },
1216 { "IN1R PGA", NULL, "CP2" },
1217 { "IN2L PGA", NULL, "CP2" },
1218 { "IN2R PGA", NULL, "CP2" },
1219 { "IN3L PGA", NULL, "CP2" },
1220 { "IN3R PGA", NULL, "CP2" },
1221 { "IN4L PGA", NULL, "CP2" },
1222 { "IN4R PGA", NULL, "CP2" },
1223
1224 { "IN1L PGA", NULL, "CP2 Active" },
1225 { "IN1R PGA", NULL, "CP2 Active" },
1226 { "IN2L PGA", NULL, "CP2 Active" },
1227 { "IN2R PGA", NULL, "CP2 Active" },
1228 { "IN3L PGA", NULL, "CP2 Active" },
1229 { "IN3R PGA", NULL, "CP2 Active" },
1230 { "IN4L PGA", NULL, "CP2 Active" },
1231 { "IN4R PGA", NULL, "CP2 Active" },
1232
1233 { "OUT1L", NULL, "CP1" },
1234 { "OUT1R", NULL, "CP1" },
1235 { "OUT2L", NULL, "CP1" },
1236 { "OUT2R", NULL, "CP1" },
1237 { "OUT3L", NULL, "CP1" },
1238 { "OUT3R", NULL, "CP1" },
1239
1240 { "Tone Generator 1", NULL, "TONE" },
1241 { "Tone Generator 2", NULL, "TONE" },
1242
1243 { "IN1L PGA", NULL, "IN1L" },
1244 { "IN1R PGA", NULL, "IN1R" },
1245 { "IN2L PGA", NULL, "IN2L" },
1246 { "IN2R PGA", NULL, "IN2R" },
1247 { "IN3L PGA", NULL, "IN3L" },
1248 { "IN3R PGA", NULL, "IN3R" },
1249 { "IN4L PGA", NULL, "IN4L" },
1250 { "IN4R PGA", NULL, "IN4R" },
1251
1252 WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1253 WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1254 WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1255 WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1256 WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"),
1257 WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"),
1258
1259 WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1260 WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1261 WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1262 WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1263 WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
1264 WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
1265
1266 WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1267 WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1268
1269 WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1270 WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1271 WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1272 WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1273 WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1274 WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1275 WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1276 WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1277
1278 WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1279 WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1280
1281 WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1282 WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1283
1284 WM5100_MIXER_ROUTES("EQ1", "EQ1"),
1285 WM5100_MIXER_ROUTES("EQ2", "EQ2"),
1286 WM5100_MIXER_ROUTES("EQ3", "EQ3"),
1287 WM5100_MIXER_ROUTES("EQ4", "EQ4"),
1288
1289 WM5100_MIXER_ROUTES("DRC1L", "DRC1L"),
1290 WM5100_MIXER_ROUTES("DRC1R", "DRC1R"),
1291
1292 WM5100_MIXER_ROUTES("LHPF1", "LHPF1"),
1293 WM5100_MIXER_ROUTES("LHPF2", "LHPF2"),
1294 WM5100_MIXER_ROUTES("LHPF3", "LHPF3"),
1295 WM5100_MIXER_ROUTES("LHPF4", "LHPF4"),
1296
1297 { "HPOUT1L", NULL, "OUT1L" },
1298 { "HPOUT1R", NULL, "OUT1R" },
1299 { "HPOUT2L", NULL, "OUT2L" },
1300 { "HPOUT2R", NULL, "OUT2R" },
1301 { "HPOUT3L", NULL, "OUT3L" },
1302 { "HPOUT3R", NULL, "OUT3R" },
1303 { "SPKOUTL", NULL, "OUT4L" },
1304 { "SPKOUTR", NULL, "OUT4R" },
1305 { "SPKDAT1", NULL, "OUT5L" },
1306 { "SPKDAT1", NULL, "OUT5R" },
1307 { "SPKDAT2", NULL, "OUT6L" },
1308 { "SPKDAT2", NULL, "OUT6R" },
1309 { "PWM1", NULL, "PWM1 Driver" },
1310 { "PWM2", NULL, "PWM2 Driver" },
1311};
1312
1313static struct {
1314 int reg;
1315 int val;
1316} wm5100_reva_patches[] = {
1317 { WM5100_AUDIO_IF_1_10, 0 },
1318 { WM5100_AUDIO_IF_1_11, 1 },
1319 { WM5100_AUDIO_IF_1_12, 2 },
1320 { WM5100_AUDIO_IF_1_13, 3 },
1321 { WM5100_AUDIO_IF_1_14, 4 },
1322 { WM5100_AUDIO_IF_1_15, 5 },
1323 { WM5100_AUDIO_IF_1_16, 6 },
1324 { WM5100_AUDIO_IF_1_17, 7 },
1325
1326 { WM5100_AUDIO_IF_1_18, 0 },
1327 { WM5100_AUDIO_IF_1_19, 1 },
1328 { WM5100_AUDIO_IF_1_20, 2 },
1329 { WM5100_AUDIO_IF_1_21, 3 },
1330 { WM5100_AUDIO_IF_1_22, 4 },
1331 { WM5100_AUDIO_IF_1_23, 5 },
1332 { WM5100_AUDIO_IF_1_24, 6 },
1333 { WM5100_AUDIO_IF_1_25, 7 },
1334
1335 { WM5100_AUDIO_IF_2_10, 0 },
1336 { WM5100_AUDIO_IF_2_11, 1 },
1337
1338 { WM5100_AUDIO_IF_2_18, 0 },
1339 { WM5100_AUDIO_IF_2_19, 1 },
1340
1341 { WM5100_AUDIO_IF_3_10, 0 },
1342 { WM5100_AUDIO_IF_3_11, 1 },
1343
1344 { WM5100_AUDIO_IF_3_18, 0 },
1345 { WM5100_AUDIO_IF_3_19, 1 },
1346};
1347
1348static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1349 enum snd_soc_bias_level level)
1350{
1351 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1352 int ret, i;
1353
1354 switch (level) {
1355 case SND_SOC_BIAS_ON:
1356 break;
1357
1358 case SND_SOC_BIAS_PREPARE:
1359 break;
1360
1361 case SND_SOC_BIAS_STANDBY:
1362 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1363 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1364 wm5100->core_supplies);
1365 if (ret != 0) {
1366 dev_err(codec->dev,
1367 "Failed to enable supplies: %d\n",
1368 ret);
1369 return ret;
1370 }
1371
1372 if (wm5100->pdata.ldo_ena) {
1373 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1374 1);
1375 msleep(2);
1376 }
1377
1378 codec->cache_only = false;
1379
1380 switch (wm5100->rev) {
1381 case 0:
1382 snd_soc_write(codec, 0x11, 0x3);
1383 snd_soc_write(codec, 0x203, 0xc);
1384 snd_soc_write(codec, 0x206, 0);
1385 snd_soc_write(codec, 0x207, 0xf0);
1386 snd_soc_write(codec, 0x208, 0x3c);
1387 snd_soc_write(codec, 0x209, 0);
1388 snd_soc_write(codec, 0x211, 0x20d8);
1389 snd_soc_write(codec, 0x11, 0);
1390
1391 for (i = 0;
1392 i < ARRAY_SIZE(wm5100_reva_patches);
1393 i++)
1394 snd_soc_write(codec,
1395 wm5100_reva_patches[i].reg,
1396 wm5100_reva_patches[i].val);
1397 break;
1398 default:
1399 break;
1400 }
1401
1402 snd_soc_cache_sync(codec);
1403 }
1404 break;
1405
1406 case SND_SOC_BIAS_OFF:
1407 if (wm5100->pdata.ldo_ena)
1408 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1409 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1410 wm5100->core_supplies);
1411 break;
1412 }
1413 codec->dapm.bias_level = level;
1414
1415 return 0;
1416}
1417
1418static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1419{
1420 switch (dai->id) {
1421 case 0:
1422 return WM5100_AUDIO_IF_1_1 - 1;
1423 case 1:
1424 return WM5100_AUDIO_IF_2_1 - 1;
1425 case 2:
1426 return WM5100_AUDIO_IF_3_1 - 1;
1427 default:
1428 BUG();
1429 return -EINVAL;
1430 }
1431}
1432
1433static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1434{
1435 struct snd_soc_codec *codec = dai->codec;
1436 int lrclk, bclk, mask, base;
1437
1438 base = wm5100_dai_to_base(dai);
1439 if (base < 0)
1440 return base;
1441
1442 lrclk = 0;
1443 bclk = 0;
1444
1445 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1446 case SND_SOC_DAIFMT_DSP_A:
1447 mask = 0;
1448 break;
1449 case SND_SOC_DAIFMT_DSP_B:
1450 mask = 1;
1451 break;
1452 case SND_SOC_DAIFMT_I2S:
1453 mask = 2;
1454 break;
1455 case SND_SOC_DAIFMT_LEFT_J:
1456 mask = 3;
1457 break;
1458 default:
1459 dev_err(codec->dev, "Unsupported DAI format %d\n",
1460 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1461 return -EINVAL;
1462 }
1463
1464 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1465 case SND_SOC_DAIFMT_CBS_CFS:
1466 break;
1467 case SND_SOC_DAIFMT_CBS_CFM:
1468 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1469 break;
1470 case SND_SOC_DAIFMT_CBM_CFS:
1471 bclk |= WM5100_AIF1_BCLK_MSTR;
1472 break;
1473 case SND_SOC_DAIFMT_CBM_CFM:
1474 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1475 bclk |= WM5100_AIF1_BCLK_MSTR;
1476 break;
1477 default:
1478 dev_err(codec->dev, "Unsupported master mode %d\n",
1479 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1480 return -EINVAL;
1481 }
1482
1483 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1484 case SND_SOC_DAIFMT_NB_NF:
1485 break;
1486 case SND_SOC_DAIFMT_IB_IF:
1487 bclk |= WM5100_AIF1_BCLK_INV;
1488 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1489 break;
1490 case SND_SOC_DAIFMT_IB_NF:
1491 bclk |= WM5100_AIF1_BCLK_INV;
1492 break;
1493 case SND_SOC_DAIFMT_NB_IF:
1494 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1495 break;
1496 default:
1497 return -EINVAL;
1498 }
1499
1500 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
1501 WM5100_AIF1_BCLK_INV, bclk);
1502 snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
1503 WM5100_AIF1TX_LRCLK_INV, lrclk);
1504 snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
1505 WM5100_AIF1TX_LRCLK_INV, lrclk);
1506 snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
1507
1508 return 0;
1509}
1510
1511#define WM5100_NUM_BCLK_RATES 19
1512
1513static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
1514 32000,
1515 48000,
1516 64000,
1517 96000,
1518 128000,
1519 192000,
1520 256000,
1521 384000,
1522 512000,
1523 768000,
1524 1024000,
1525 1536000,
1526 2048000,
1527 3072000,
1528 4096000,
1529 6144000,
1530 8192000,
1531 12288000,
1532 24576000,
1533};
1534
1535static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1536 29400,
1537 44100,
1538 58800,
1539 88200,
1540 117600,
1541 176400,
1542 235200,
1543 352800,
1544 470400,
1545 705600,
1546 940800,
1547 1411200,
1548 1881600,
1549 2882400,
1550 3763200,
1551 5644800,
1552 7526400,
1553 11289600,
1554 22579600,
1555};
1556
1557static int wm5100_hw_params(struct snd_pcm_substream *substream,
1558 struct snd_pcm_hw_params *params,
1559 struct snd_soc_dai *dai)
1560{
1561 struct snd_soc_codec *codec = dai->codec;
1562 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1563 bool async = wm5100->aif_async[dai->id];
1564 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1565 int *bclk_rates;
1566
1567 base = wm5100_dai_to_base(dai);
1568 if (base < 0)
1569 return base;
1570
1571 /* Data sizes if not using TDM */
1572 wl = snd_pcm_format_width(params_format(params));
1573 if (wl < 0)
1574 return wl;
1575 fl = snd_soc_params_to_frame_size(params);
1576 if (fl < 0)
1577 return fl;
1578
1579 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1580 wl, fl);
1581
1582 /* Target BCLK rate */
1583 bclk = snd_soc_params_to_bclk(params);
1584 if (bclk < 0)
1585 return bclk;
1586
1587 /* Root for BCLK depends on SYS/ASYNCCLK */
1588 if (!async) {
1589 aif_rate = wm5100->sysclk;
1590 sr = wm5100_alloc_sr(codec, params_rate(params));
1591 if (sr < 0)
1592 return sr;
1593 } else {
1594 /* If we're in ASYNCCLK set the ASYNC sample rate */
1595 aif_rate = wm5100->asyncclk;
1596 sr = 3;
1597
1598 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1599 if (params_rate(params) == wm5100_sr_code[i])
1600 break;
1601 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1602 dev_err(codec->dev, "Invalid rate %dHzn",
1603 params_rate(params));
1604 return -EINVAL;
1605 }
1606
1607 /* TODO: We should really check for symmetry */
1608 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1609 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1610 }
1611
1612 if (!aif_rate) {
1613 dev_err(codec->dev, "%s has no rate set\n",
1614 async ? "ASYNCCLK" : "SYSCLK");
1615 return -EINVAL;
1616 }
1617
1618 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1619 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1620
1621 if (aif_rate % 4000)
1622 bclk_rates = wm5100_bclk_rates_cd;
1623 else
1624 bclk_rates = wm5100_bclk_rates_dat;
1625
1626 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1627 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1628 break;
1629 if (i == WM5100_NUM_BCLK_RATES) {
1630 dev_err(codec->dev,
1631 "No valid BCLK for %dHz found from %dHz %s\n",
1632 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1633 return -EINVAL;
1634 }
1635
1636 bclk = i;
1637 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1638 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1639
1640 lrclk = bclk_rates[bclk] / params_rate(params);
1641 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1642 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1643 wm5100->aif_symmetric[dai->id])
1644 snd_soc_update_bits(codec, base + 7,
1645 WM5100_AIF1RX_BCPF_MASK, lrclk);
1646 else
1647 snd_soc_update_bits(codec, base + 6,
1648 WM5100_AIF1TX_BCPF_MASK, lrclk);
1649
1650 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1651 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1652 snd_soc_update_bits(codec, base + 9,
1653 WM5100_AIF1RX_WL_MASK |
1654 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1655 else
1656 snd_soc_update_bits(codec, base + 8,
1657 WM5100_AIF1TX_WL_MASK |
1658 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1659
1660 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1661
1662 return 0;
1663}
1664
1665static struct snd_soc_dai_ops wm5100_dai_ops = {
1666 .set_fmt = wm5100_set_fmt,
1667 .hw_params = wm5100_hw_params,
1668};
1669
1670static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1671 int source, unsigned int freq, int dir)
1672{
1673 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1674 int *rate_store;
1675 int fval, audio_rate, ret, reg;
1676
1677 switch (clk_id) {
1678 case WM5100_CLK_SYSCLK:
1679 reg = WM5100_CLOCKING_3;
1680 rate_store = &wm5100->sysclk;
1681 break;
1682 case WM5100_CLK_ASYNCCLK:
1683 reg = WM5100_CLOCKING_7;
1684 rate_store = &wm5100->asyncclk;
1685 break;
1686 case WM5100_CLK_32KHZ:
1687 /* The 32kHz clock is slightly different to the others */
1688 switch (source) {
1689 case WM5100_CLKSRC_MCLK1:
1690 case WM5100_CLKSRC_MCLK2:
1691 case WM5100_CLKSRC_SYSCLK:
1692 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1693 WM5100_CLK_32K_SRC_MASK,
1694 source);
1695 break;
1696 default:
1697 return -EINVAL;
1698 }
1699 return 0;
1700
1701 case WM5100_CLK_AIF1:
1702 case WM5100_CLK_AIF2:
1703 case WM5100_CLK_AIF3:
1704 /* Not real clocks, record which clock domain they're in */
1705 switch (source) {
1706 case WM5100_CLKSRC_SYSCLK:
1707 wm5100->aif_async[clk_id - 1] = false;
1708 break;
1709 case WM5100_CLKSRC_ASYNCCLK:
1710 wm5100->aif_async[clk_id - 1] = true;
1711 break;
1712 default:
1713 dev_err(codec->dev, "Invalid source %d\n", source);
1714 return -EINVAL;
1715 }
1716 return 0;
1717
1718 case WM5100_CLK_OPCLK:
1719 switch (freq) {
1720 case 5644800:
1721 case 6144000:
1722 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1723 WM5100_OPCLK_SEL_MASK, 0);
1724 break;
1725 case 11289600:
1726 case 12288000:
1727 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1728 WM5100_OPCLK_SEL_MASK, 0);
1729 break;
1730 case 22579200:
1731 case 24576000:
1732 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1733 WM5100_OPCLK_SEL_MASK, 0);
1734 break;
1735 default:
1736 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1737 freq);
1738 return -EINVAL;
1739 }
1740 return 0;
1741
1742 default:
1743 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1744 return -EINVAL;
1745 }
1746
1747 switch (source) {
1748 case WM5100_CLKSRC_SYSCLK:
1749 case WM5100_CLKSRC_ASYNCCLK:
1750 dev_err(codec->dev, "Invalid source %d\n", source);
1751 return -EINVAL;
1752 }
1753
1754 switch (freq) {
1755 case 5644800:
1756 case 6144000:
1757 fval = 0;
1758 break;
1759 case 11289600:
1760 case 12288000:
1761 fval = 1;
1762 break;
1763 case 22579200:
1764 case 24576000:
1765 fval = 2;
1766 break;
1767 default:
1768 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1769 return -EINVAL;
1770 }
1771
1772 switch (freq) {
1773 case 5644800:
1774 case 11289600:
1775 case 22579200:
1776 audio_rate = 44100;
1777 break;
1778
1779 case 6144000:
1780 case 12288000:
1781 case 24576000:
1782 audio_rate = 48000;
1783 break;
1784
1785 default:
1786 BUG();
1787 audio_rate = 0;
1788 break;
1789 }
1790
1791 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1792 * match.
1793 */
1794
1795 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1796 WM5100_SYSCLK_SRC_MASK,
1797 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1798
1799 /* If this is SYSCLK then configure the clock rate for the
1800 * internal audio functions to the natural sample rate for
1801 * this clock rate.
1802 */
1803 if (clk_id == WM5100_CLK_SYSCLK) {
1804 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1805 audio_rate);
1806 if (0 && *rate_store)
1807 wm5100_free_sr(codec, audio_rate);
1808 ret = wm5100_alloc_sr(codec, audio_rate);
1809 if (ret != 0)
1810 dev_warn(codec->dev, "Primary audio slot is %d\n",
1811 ret);
1812 }
1813
1814 *rate_store = freq;
1815
1816 return 0;
1817}
1818
1819struct _fll_div {
1820 u16 fll_fratio;
1821 u16 fll_outdiv;
1822 u16 fll_refclk_div;
1823 u16 n;
1824 u16 theta;
1825 u16 lambda;
1826};
1827
1828static struct {
1829 unsigned int min;
1830 unsigned int max;
1831 u16 fll_fratio;
1832 int ratio;
1833} fll_fratios[] = {
1834 { 0, 64000, 4, 16 },
1835 { 64000, 128000, 3, 8 },
1836 { 128000, 256000, 2, 4 },
1837 { 256000, 1000000, 1, 2 },
1838 { 1000000, 13500000, 0, 1 },
1839};
1840
1841static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1842 unsigned int Fout)
1843{
1844 unsigned int target;
1845 unsigned int div;
1846 unsigned int fratio, gcd_fll;
1847 int i;
1848
1849 /* Fref must be <=13.5MHz */
1850 div = 1;
1851 fll_div->fll_refclk_div = 0;
1852 while ((Fref / div) > 13500000) {
1853 div *= 2;
1854 fll_div->fll_refclk_div++;
1855
1856 if (div > 8) {
1857 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1858 Fref);
1859 return -EINVAL;
1860 }
1861 }
1862
1863 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1864
1865 /* Apply the division for our remaining calculations */
1866 Fref /= div;
1867
1868 /* Fvco should be 90-100MHz; don't check the upper bound */
1869 div = 2;
1870 while (Fout * div < 90000000) {
1871 div++;
1872 if (div > 64) {
1873 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1874 Fout);
1875 return -EINVAL;
1876 }
1877 }
1878 target = Fout * div;
1879 fll_div->fll_outdiv = div - 1;
1880
1881 pr_debug("FLL Fvco=%dHz\n", target);
1882
1883 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1884 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1885 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1886 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1887 fratio = fll_fratios[i].ratio;
1888 break;
1889 }
1890 }
1891 if (i == ARRAY_SIZE(fll_fratios)) {
1892 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1893 return -EINVAL;
1894 }
1895
1896 fll_div->n = target / (fratio * Fref);
1897
1898 if (target % Fref == 0) {
1899 fll_div->theta = 0;
1900 fll_div->lambda = 0;
1901 } else {
1902 gcd_fll = gcd(target, fratio * Fref);
1903
1904 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1905 / gcd_fll;
1906 fll_div->lambda = (fratio * Fref) / gcd_fll;
1907 }
1908
1909 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1910 fll_div->n, fll_div->theta, fll_div->lambda);
1911 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1912 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1913 fll_div->fll_refclk_div);
1914
1915 return 0;
1916}
1917
1918static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1919 unsigned int Fref, unsigned int Fout)
1920{
1921 struct i2c_client *i2c = to_i2c_client(codec->dev);
1922 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1923 struct _fll_div factors;
1924 struct wm5100_fll *fll;
1925 int ret, base, lock, i, timeout;
1926
1927 switch (fll_id) {
1928 case WM5100_FLL1:
1929 fll = &wm5100->fll[0];
1930 base = WM5100_FLL1_CONTROL_1 - 1;
1931 lock = WM5100_FLL1_LOCK_STS;
1932 break;
1933 case WM5100_FLL2:
1934 fll = &wm5100->fll[1];
1935 base = WM5100_FLL2_CONTROL_2 - 1;
1936 lock = WM5100_FLL2_LOCK_STS;
1937 break;
1938 default:
1939 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1940 return -EINVAL;
1941 }
1942
1943 if (!Fout) {
1944 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1945 fll->fout = 0;
1946 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1947 return 0;
1948 }
1949
1950 switch (source) {
1951 case WM5100_FLL_SRC_MCLK1:
1952 case WM5100_FLL_SRC_MCLK2:
1953 case WM5100_FLL_SRC_FLL1:
1954 case WM5100_FLL_SRC_FLL2:
1955 case WM5100_FLL_SRC_AIF1BCLK:
1956 case WM5100_FLL_SRC_AIF2BCLK:
1957 case WM5100_FLL_SRC_AIF3BCLK:
1958 break;
1959 default:
1960 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1961 return -EINVAL;
1962 }
1963
1964 ret = fll_factors(&factors, Fref, Fout);
1965 if (ret < 0)
1966 return ret;
1967
1968 /* Disable the FLL while we reconfigure */
1969 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1970
1971 snd_soc_update_bits(codec, base + 2,
1972 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1973 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1974 factors.fll_fratio);
1975 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1976 factors.theta);
1977 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1978 snd_soc_update_bits(codec, base + 6,
1979 WM5100_FLL1_REFCLK_DIV_MASK |
1980 WM5100_FLL1_REFCLK_SRC_MASK,
1981 (factors.fll_refclk_div
1982 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1983 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1984 factors.lambda);
1985
1986 /* Clear any pending completions */
1987 try_wait_for_completion(&fll->lock);
1988
1989 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1990
1991 if (i2c->irq)
1992 timeout = 2;
1993 else
1994 timeout = 50;
1995
1996 /* Poll for the lock; will use interrupt when we can test */
1997 for (i = 0; i < timeout; i++) {
1998 if (i2c->irq) {
1999 ret = wait_for_completion_timeout(&fll->lock,
2000 msecs_to_jiffies(25));
2001 if (ret > 0)
2002 break;
2003 } else {
2004 msleep(1);
2005 }
2006
2007 ret = snd_soc_read(codec,
2008 WM5100_INTERRUPT_RAW_STATUS_3);
2009 if (ret < 0) {
2010 dev_err(codec->dev,
2011 "Failed to read FLL status: %d\n",
2012 ret);
2013 continue;
2014 }
2015 if (ret & lock)
2016 break;
2017 }
2018 if (i == timeout) {
2019 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
2020 return -ETIMEDOUT;
2021 }
2022
2023 fll->src = source;
2024 fll->fref = Fref;
2025 fll->fout = Fout;
2026
2027 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
2028 Fref, Fout);
2029
2030 return 0;
2031}
2032
2033/* Actually go much higher */
2034#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
2035
2036#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2037 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2038
2039static struct snd_soc_dai_driver wm5100_dai[] = {
2040 {
2041 .name = "wm5100-aif1",
2042 .playback = {
2043 .stream_name = "AIF1 Playback",
2044 .channels_min = 2,
2045 .channels_max = 2,
2046 .rates = WM5100_RATES,
2047 .formats = WM5100_FORMATS,
2048 },
2049 .capture = {
2050 .stream_name = "AIF1 Capture",
2051 .channels_min = 2,
2052 .channels_max = 2,
2053 .rates = WM5100_RATES,
2054 .formats = WM5100_FORMATS,
2055 },
2056 .ops = &wm5100_dai_ops,
2057 },
2058 {
2059 .name = "wm5100-aif2",
2060 .id = 1,
2061 .playback = {
2062 .stream_name = "AIF2 Playback",
2063 .channels_min = 2,
2064 .channels_max = 2,
2065 .rates = WM5100_RATES,
2066 .formats = WM5100_FORMATS,
2067 },
2068 .capture = {
2069 .stream_name = "AIF2 Capture",
2070 .channels_min = 2,
2071 .channels_max = 2,
2072 .rates = WM5100_RATES,
2073 .formats = WM5100_FORMATS,
2074 },
2075 .ops = &wm5100_dai_ops,
2076 },
2077 {
2078 .name = "wm5100-aif3",
2079 .id = 2,
2080 .playback = {
2081 .stream_name = "AIF3 Playback",
2082 .channels_min = 2,
2083 .channels_max = 2,
2084 .rates = WM5100_RATES,
2085 .formats = WM5100_FORMATS,
2086 },
2087 .capture = {
2088 .stream_name = "AIF3 Capture",
2089 .channels_min = 2,
2090 .channels_max = 2,
2091 .rates = WM5100_RATES,
2092 .formats = WM5100_FORMATS,
2093 },
2094 .ops = &wm5100_dai_ops,
2095 },
2096};
2097
2098static int wm5100_dig_vu[] = {
2099 WM5100_ADC_DIGITAL_VOLUME_1L,
2100 WM5100_ADC_DIGITAL_VOLUME_1R,
2101 WM5100_ADC_DIGITAL_VOLUME_2L,
2102 WM5100_ADC_DIGITAL_VOLUME_2R,
2103 WM5100_ADC_DIGITAL_VOLUME_3L,
2104 WM5100_ADC_DIGITAL_VOLUME_3R,
2105 WM5100_ADC_DIGITAL_VOLUME_4L,
2106 WM5100_ADC_DIGITAL_VOLUME_4R,
2107
2108 WM5100_DAC_DIGITAL_VOLUME_1L,
2109 WM5100_DAC_DIGITAL_VOLUME_1R,
2110 WM5100_DAC_DIGITAL_VOLUME_2L,
2111 WM5100_DAC_DIGITAL_VOLUME_2R,
2112 WM5100_DAC_DIGITAL_VOLUME_3L,
2113 WM5100_DAC_DIGITAL_VOLUME_3R,
2114 WM5100_DAC_DIGITAL_VOLUME_4L,
2115 WM5100_DAC_DIGITAL_VOLUME_4R,
2116 WM5100_DAC_DIGITAL_VOLUME_5L,
2117 WM5100_DAC_DIGITAL_VOLUME_5R,
2118 WM5100_DAC_DIGITAL_VOLUME_6L,
2119 WM5100_DAC_DIGITAL_VOLUME_6R,
2120};
2121
2122static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode)
2123{
2124 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2125 struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
2126
2127 BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
2128
2129 gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
2130 snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1,
2131 WM5100_ACCDET_BIAS_SRC_MASK |
2132 WM5100_ACCDET_SRC,
2133 (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
2134 mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
2135 snd_soc_update_bits(codec, WM5100_MISC_CONTROL,
2136 WM5100_HPCOM_SRC,
2137 mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
2138
2139 wm5100->jack_mode = the_mode;
2140
2141 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2142 wm5100->jack_mode);
2143}
2144
2145static void wm5100_micd_irq(struct snd_soc_codec *codec)
2146{
2147 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2148 int val;
2149
2150 val = snd_soc_read(codec, WM5100_MIC_DETECT_3);
2151
2152 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2153
2154 if (!(val & WM5100_ACCDET_VALID)) {
2155 dev_warn(codec->dev, "Microphone detection state invalid\n");
2156 return;
2157 }
2158
2159 /* No accessory, reset everything and report removal */
2160 if (!(val & WM5100_ACCDET_STS)) {
2161 dev_dbg(codec->dev, "Jack removal detected\n");
2162 wm5100->jack_mic = false;
2163 wm5100->jack_detecting = true;
2164 snd_soc_jack_report(wm5100->jack, 0,
2165 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2166 SND_JACK_BTN_0);
2167
2168 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2169 WM5100_ACCDET_RATE_MASK,
2170 WM5100_ACCDET_RATE_MASK);
2171 return;
2172 }
2173
2174 /* If the measurement is very high we've got a microphone,
2175 * either we just detected one or if we already reported then
2176 * we've got a button release event.
2177 */
2178 if (val & 0x400) {
2179 if (wm5100->jack_detecting) {
2180 dev_dbg(codec->dev, "Microphone detected\n");
2181 wm5100->jack_mic = true;
2182 snd_soc_jack_report(wm5100->jack,
2183 SND_JACK_HEADSET,
2184 SND_JACK_HEADSET | SND_JACK_BTN_0);
2185
2186 /* Increase poll rate to give better responsiveness
2187 * for buttons */
2188 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2189 WM5100_ACCDET_RATE_MASK,
2190 5 << WM5100_ACCDET_RATE_SHIFT);
2191 } else {
2192 dev_dbg(codec->dev, "Mic button up\n");
2193 snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
2194 }
2195
2196 return;
2197 }
2198
2199 /* If we detected a lower impedence during initial startup
2200 * then we probably have the wrong polarity, flip it. Don't
2201 * do this for the lowest impedences to speed up detection of
2202 * plain headphones.
2203 */
2204 if (wm5100->jack_detecting && (val & 0x3f8)) {
2205 wm5100_set_detect_mode(codec, !wm5100->jack_mode);
2206
2207 return;
2208 }
2209
2210 /* Don't distinguish between buttons, just report any low
2211 * impedence as BTN_0.
2212 */
2213 if (val & 0x3fc) {
2214 if (wm5100->jack_mic) {
2215 dev_dbg(codec->dev, "Mic button detected\n");
2216 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2217 SND_JACK_BTN_0);
2218 } else if (wm5100->jack_detecting) {
2219 dev_dbg(codec->dev, "Headphone detected\n");
2220 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2221 SND_JACK_HEADPHONE);
2222
2223 /* Increase the detection rate a bit for
2224 * responsiveness.
2225 */
2226 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2227 WM5100_ACCDET_RATE_MASK,
2228 7 << WM5100_ACCDET_RATE_SHIFT);
2229 }
2230 }
2231}
2232
2233int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2234{
2235 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2236
2237 if (jack) {
2238 wm5100->jack = jack;
2239 wm5100->jack_detecting = true;
2240
2241 wm5100_set_detect_mode(codec, 0);
2242
2243 /* Slowest detection rate, gives debounce for initial
2244 * detection */
2245 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2246 WM5100_ACCDET_BIAS_STARTTIME_MASK |
2247 WM5100_ACCDET_RATE_MASK,
2248 (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
2249 WM5100_ACCDET_RATE_MASK);
2250
2251 /* We need the charge pump to power MICBIAS */
2252 snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2");
2253 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2254 snd_soc_dapm_sync(&codec->dapm);
2255
2256 /* We start off just enabling microphone detection - even a
2257 * plain headphone will trigger detection.
2258 */
2259 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2260 WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
2261
2262 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2263 WM5100_IM_ACCDET_EINT, 0);
2264 } else {
2265 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2266 WM5100_IM_HPDET_EINT |
2267 WM5100_IM_ACCDET_EINT,
2268 WM5100_IM_HPDET_EINT |
2269 WM5100_IM_ACCDET_EINT);
2270 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2271 WM5100_ACCDET_ENA, 0);
2272 wm5100->jack = NULL;
2273 }
2274
2275 return 0;
2276}
2277
2278static irqreturn_t wm5100_irq(int irq, void *data)
2279{
2280 struct snd_soc_codec *codec = data;
2281 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2282 irqreturn_t status = IRQ_NONE;
2283 int irq_val;
2284
2285 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
2286 if (irq_val < 0) {
2287 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
2288 irq_val);
2289 irq_val = 0;
2290 }
2291 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2292
2293 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
2294
2295 if (irq_val)
2296 status = IRQ_HANDLED;
2297
2298 wm5100_log_status3(codec, irq_val);
2299
2300 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2301 dev_dbg(codec->dev, "FLL1 locked\n");
2302 complete(&wm5100->fll[0].lock);
2303 }
2304 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2305 dev_dbg(codec->dev, "FLL2 locked\n");
2306 complete(&wm5100->fll[1].lock);
2307 }
2308
2309 if (irq_val & WM5100_ACCDET_EINT)
2310 wm5100_micd_irq(codec);
2311
2312 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
2313 if (irq_val < 0) {
2314 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
2315 irq_val);
2316 irq_val = 0;
2317 }
2318 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
2319
2320 if (irq_val)
2321 status = IRQ_HANDLED;
2322
2323 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
2324
2325 wm5100_log_status4(codec, irq_val);
2326
2327 return status;
2328}
2329
2330static irqreturn_t wm5100_edge_irq(int irq, void *data)
2331{
2332 irqreturn_t ret = IRQ_NONE;
2333 irqreturn_t val;
2334
2335 do {
2336 val = wm5100_irq(irq, data);
2337 if (val != IRQ_NONE)
2338 ret = val;
2339 } while (val != IRQ_NONE);
2340
2341 return ret;
2342}
2343
2344#ifdef CONFIG_GPIOLIB
2345static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2346{
2347 return container_of(chip, struct wm5100_priv, gpio_chip);
2348}
2349
2350static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2351{
2352 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2353 struct snd_soc_codec *codec = wm5100->codec;
2354
2355 snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2356 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
2357}
2358
2359static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2360 unsigned offset, int value)
2361{
2362 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2363 struct snd_soc_codec *codec = wm5100->codec;
2364 int val;
2365
2366 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2367
2368 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2369 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2370 WM5100_GP1_LVL, val);
2371}
2372
2373static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2374{
2375 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2376 struct snd_soc_codec *codec = wm5100->codec;
2377 int ret;
2378
2379 ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
2380 if (ret < 0)
2381 return ret;
2382
2383 return (ret & WM5100_GP1_LVL) != 0;
2384}
2385
2386static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2387{
2388 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2389 struct snd_soc_codec *codec = wm5100->codec;
2390
2391 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2392 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2393 (1 << WM5100_GP1_FN_SHIFT) |
2394 (1 << WM5100_GP1_DIR_SHIFT));
2395}
2396
2397static struct gpio_chip wm5100_template_chip = {
2398 .label = "wm5100",
2399 .owner = THIS_MODULE,
2400 .direction_output = wm5100_gpio_direction_out,
2401 .set = wm5100_gpio_set,
2402 .direction_input = wm5100_gpio_direction_in,
2403 .get = wm5100_gpio_get,
2404 .can_sleep = 1,
2405};
2406
2407static void wm5100_init_gpio(struct snd_soc_codec *codec)
2408{
2409 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2410 int ret;
2411
2412 wm5100->gpio_chip = wm5100_template_chip;
2413 wm5100->gpio_chip.ngpio = 6;
2414 wm5100->gpio_chip.dev = codec->dev;
2415
2416 if (wm5100->pdata.gpio_base)
2417 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2418 else
2419 wm5100->gpio_chip.base = -1;
2420
2421 ret = gpiochip_add(&wm5100->gpio_chip);
2422 if (ret != 0)
2423 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2424}
2425
2426static void wm5100_free_gpio(struct snd_soc_codec *codec)
2427{
2428 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2429 int ret;
2430
2431 ret = gpiochip_remove(&wm5100->gpio_chip);
2432 if (ret != 0)
2433 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2434}
2435#else
2436static void wm5100_init_gpio(struct snd_soc_codec *codec)
2437{
2438}
2439
2440static void wm5100_free_gpio(struct snd_soc_codec *codec)
2441{
2442}
2443#endif
2444
2445static int wm5100_probe(struct snd_soc_codec *codec)
2446{
2447 struct i2c_client *i2c = to_i2c_client(codec->dev);
2448 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2449 int ret, i, irq_flags;
2450
2451 wm5100->codec = codec;
2452
2453 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2454 if (ret != 0) {
2455 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2456 return ret;
2457 }
2458
2459 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2460 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2461
2462 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
2463 wm5100->core_supplies);
2464 if (ret != 0) {
2465 dev_err(codec->dev, "Failed to request core supplies: %d\n",
2466 ret);
2467 return ret;
2468 }
2469
2470 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2471 if (IS_ERR(wm5100->cpvdd)) {
2472 ret = PTR_ERR(wm5100->cpvdd);
2473 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2474 goto err_core;
2475 }
2476
2477 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2478 if (IS_ERR(wm5100->dbvdd2)) {
2479 ret = PTR_ERR(wm5100->dbvdd2);
2480 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2481 goto err_cpvdd;
2482 }
2483
2484 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2485 if (IS_ERR(wm5100->dbvdd3)) {
2486 ret = PTR_ERR(wm5100->dbvdd3);
2487 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2488 goto err_dbvdd2;
2489 }
2490
2491 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2492 wm5100->core_supplies);
2493 if (ret != 0) {
2494 dev_err(codec->dev, "Failed to enable core supplies: %d\n",
2495 ret);
2496 goto err_dbvdd3;
2497 }
2498
2499 if (wm5100->pdata.ldo_ena) {
2500 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2501 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2502 if (ret < 0) {
2503 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2504 wm5100->pdata.ldo_ena, ret);
2505 goto err_enable;
2506 }
2507 msleep(2);
2508 }
2509
2510 if (wm5100->pdata.reset) {
2511 ret = gpio_request_one(wm5100->pdata.reset,
2512 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2513 if (ret < 0) {
2514 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2515 wm5100->pdata.reset, ret);
2516 goto err_ldo;
2517 }
2518 }
2519
2520 ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
2521 if (ret < 0) {
2522 dev_err(codec->dev, "Failed to read ID register\n");
2523 goto err_reset;
2524 }
2525 switch (ret) {
2526 case 0x8997:
2527 case 0x5100:
2528 break;
2529
2530 default:
2531 dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
2532 ret = -EINVAL;
2533 goto err_reset;
2534 }
2535
2536 ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
2537 if (ret < 0) {
2538 dev_err(codec->dev, "Failed to read revision register\n");
2539 goto err_reset;
2540 }
2541 wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
2542
2543 dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
2544
2545 ret = wm5100_reset(codec);
2546 if (ret < 0) {
2547 dev_err(codec->dev, "Failed to issue reset\n");
2548 goto err_reset;
2549 }
2550
2551 codec->cache_only = true;
2552
2553 wm5100_init_gpio(codec);
2554
2555 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2556 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2557 WM5100_OUT_VU);
2558
2559 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2560 snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
2561 WM5100_IN1_MODE_MASK |
2562 WM5100_IN1_DMIC_SUP_MASK,
2563 (wm5100->pdata.in_mode[i] <<
2564 WM5100_IN1_MODE_SHIFT) |
2565 (wm5100->pdata.dmic_sup[i] <<
2566 WM5100_IN1_DMIC_SUP_SHIFT));
2567 }
2568
2569 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2570 if (!wm5100->pdata.gpio_defaults[i])
2571 continue;
2572
2573 snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
2574 wm5100->pdata.gpio_defaults[i]);
2575 }
2576
2577 /* Don't debounce interrupts to support use of SYSCLK only */
2578 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2579 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2580
2581 /* TODO: check if we're symmetric */
2582
2583 if (i2c->irq) {
2584 if (wm5100->pdata.irq_flags)
2585 irq_flags = wm5100->pdata.irq_flags;
2586 else
2587 irq_flags = IRQF_TRIGGER_LOW;
2588
2589 irq_flags |= IRQF_ONESHOT;
2590
2591 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2592 ret = request_threaded_irq(i2c->irq, NULL,
2593 wm5100_edge_irq,
2594 irq_flags, "wm5100", codec);
2595 else
2596 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2597 irq_flags, "wm5100", codec);
2598
2599 if (ret != 0) {
2600 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2601 i2c->irq, ret);
2602 } else {
2603 /* Enable default interrupts */
2604 snd_soc_update_bits(codec,
2605 WM5100_INTERRUPT_STATUS_3_MASK,
2606 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2607 WM5100_IM_SPK_SHUTDOWN_EINT |
2608 WM5100_IM_ASRC2_LOCK_EINT |
2609 WM5100_IM_ASRC1_LOCK_EINT |
2610 WM5100_IM_FLL2_LOCK_EINT |
2611 WM5100_IM_FLL1_LOCK_EINT |
2612 WM5100_CLKGEN_ERR_EINT |
2613 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2614
2615 snd_soc_update_bits(codec,
2616 WM5100_INTERRUPT_STATUS_4_MASK,
2617 WM5100_AIF3_ERR_EINT |
2618 WM5100_AIF2_ERR_EINT |
2619 WM5100_AIF1_ERR_EINT |
2620 WM5100_CTRLIF_ERR_EINT |
2621 WM5100_ISRC2_UNDERCLOCKED_EINT |
2622 WM5100_ISRC1_UNDERCLOCKED_EINT |
2623 WM5100_FX_UNDERCLOCKED_EINT |
2624 WM5100_AIF3_UNDERCLOCKED_EINT |
2625 WM5100_AIF2_UNDERCLOCKED_EINT |
2626 WM5100_AIF1_UNDERCLOCKED_EINT |
2627 WM5100_ASRC_UNDERCLOCKED_EINT |
2628 WM5100_DAC_UNDERCLOCKED_EINT |
2629 WM5100_ADC_UNDERCLOCKED_EINT |
2630 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2631 }
2632 } else {
2633 snd_soc_dapm_new_controls(&codec->dapm,
2634 wm5100_dapm_widgets_noirq,
2635 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2636 }
2637
2638 if (wm5100->pdata.hp_pol) {
2639 ret = gpio_request_one(wm5100->pdata.hp_pol,
2640 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2641 if (ret < 0) {
2642 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2643 wm5100->pdata.hp_pol, ret);
2644 goto err_gpio;
2645 }
2646 }
2647
2648 /* We'll get woken up again when the system has something useful
2649 * for us to do.
2650 */
2651 if (wm5100->pdata.ldo_ena)
2652 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2653 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2654 wm5100->core_supplies);
2655
2656 return 0;
2657
2658err_gpio:
2659 if (i2c->irq)
2660 free_irq(i2c->irq, codec);
2661 wm5100_free_gpio(codec);
2662err_reset:
2663 if (wm5100->pdata.reset) {
2664 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2665 gpio_free(wm5100->pdata.reset);
2666 }
2667err_ldo:
2668 if (wm5100->pdata.ldo_ena) {
2669 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2670 gpio_free(wm5100->pdata.ldo_ena);
2671 }
2672err_enable:
2673 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2674 wm5100->core_supplies);
2675err_dbvdd3:
2676 regulator_put(wm5100->dbvdd3);
2677err_dbvdd2:
2678 regulator_put(wm5100->dbvdd2);
2679err_cpvdd:
2680 regulator_put(wm5100->cpvdd);
2681err_core:
2682 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2683 wm5100->core_supplies);
2684
2685 return ret;
2686}
2687
2688static int wm5100_remove(struct snd_soc_codec *codec)
2689{
2690 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2691 struct i2c_client *i2c = to_i2c_client(codec->dev);
2692
2693 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2694 if (wm5100->pdata.hp_pol) {
2695 gpio_free(wm5100->pdata.hp_pol);
2696 }
2697 if (i2c->irq)
2698 free_irq(i2c->irq, codec);
2699 wm5100_free_gpio(codec);
2700 if (wm5100->pdata.reset) {
2701 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2702 gpio_free(wm5100->pdata.reset);
2703 }
2704 if (wm5100->pdata.ldo_ena) {
2705 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2706 gpio_free(wm5100->pdata.ldo_ena);
2707 }
2708 regulator_put(wm5100->dbvdd3);
2709 regulator_put(wm5100->dbvdd2);
2710 regulator_put(wm5100->cpvdd);
2711 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2712 wm5100->core_supplies);
2713 return 0;
2714}
2715
2716static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2717 .probe = wm5100_probe,
2718 .remove = wm5100_remove,
2719
2720 .set_sysclk = wm5100_set_sysclk,
2721 .set_pll = wm5100_set_fll,
2722 .set_bias_level = wm5100_set_bias_level,
2723 .idle_bias_off = 1,
2724
2725 .seq_notifier = wm5100_seq_notifier,
2726 .controls = wm5100_snd_controls,
2727 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2728 .dapm_widgets = wm5100_dapm_widgets,
2729 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2730 .dapm_routes = wm5100_dapm_routes,
2731 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2732
2733 .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
2734 .reg_word_size = sizeof(u16),
2735 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2736 .reg_cache_default = wm5100_reg_defaults,
2737
2738 .volatile_register = wm5100_volatile_register,
2739 .readable_register = wm5100_readable_register,
2740};
2741
2742static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2743 const struct i2c_device_id *id)
2744{
2745 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2746 struct wm5100_priv *wm5100;
2747 int ret, i;
2748
2749 wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
2750 if (wm5100 == NULL)
2751 return -ENOMEM;
2752
2753 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2754 init_completion(&wm5100->fll[i].lock);
2755
2756 if (pdata)
2757 wm5100->pdata = *pdata;
2758
2759 i2c_set_clientdata(i2c, wm5100);
2760
2761 ret = snd_soc_register_codec(&i2c->dev,
2762 &soc_codec_dev_wm5100, wm5100_dai,
2763 ARRAY_SIZE(wm5100_dai));
2764 if (ret < 0) {
2765 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
2766 kfree(wm5100);
2767 }
2768
2769 return ret;
2770}
2771
2772static __devexit int wm5100_i2c_remove(struct i2c_client *client)
2773{
2774 snd_soc_unregister_codec(&client->dev);
2775 kfree(i2c_get_clientdata(client));
2776 return 0;
2777}
2778
2779static const struct i2c_device_id wm5100_i2c_id[] = {
2780 { "wm5100", 0 },
2781 { }
2782};
2783MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2784
2785static struct i2c_driver wm5100_i2c_driver = {
2786 .driver = {
2787 .name = "wm5100",
2788 .owner = THIS_MODULE,
2789 },
2790 .probe = wm5100_i2c_probe,
2791 .remove = __devexit_p(wm5100_i2c_remove),
2792 .id_table = wm5100_i2c_id,
2793};
2794
2795static int __init wm5100_modinit(void)
2796{
2797 return i2c_add_driver(&wm5100_i2c_driver);
2798}
2799module_init(wm5100_modinit);
2800
2801static void __exit wm5100_exit(void)
2802{
2803 i2c_del_driver(&wm5100_i2c_driver);
2804}
2805module_exit(wm5100_exit);
2806
2807MODULE_DESCRIPTION("ASoC WM5100 driver");
2808MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2809MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h
new file mode 100644
index 000000000000..970759636bdc
--- /dev/null
+++ b/sound/soc/codecs/wm5100.h
@@ -0,0 +1,5155 @@
1/*
2 * wm5100.h -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef WM5100_ASOC_H
15#define WM5100_ASOC_H
16
17#include <sound/soc.h>
18
19int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
20
21#define WM5100_CLK_AIF1 1
22#define WM5100_CLK_AIF2 2
23#define WM5100_CLK_AIF3 3
24#define WM5100_CLK_SYSCLK 4
25#define WM5100_CLK_ASYNCCLK 5
26#define WM5100_CLK_32KHZ 6
27#define WM5100_CLK_OPCLK 7
28
29#define WM5100_CLKSRC_MCLK1 0
30#define WM5100_CLKSRC_MCLK2 1
31#define WM5100_CLKSRC_SYSCLK 2
32#define WM5100_CLKSRC_FLL1 4
33#define WM5100_CLKSRC_FLL2 5
34#define WM5100_CLKSRC_AIF1BCLK 8
35#define WM5100_CLKSRC_AIF2BCLK 9
36#define WM5100_CLKSRC_AIF3BCLK 10
37#define WM5100_CLKSRC_ASYNCCLK 0x100
38
39#define WM5100_FLL1 1
40#define WM5100_FLL2 2
41
42#define WM5100_FLL_SRC_MCLK1 0x0
43#define WM5100_FLL_SRC_MCLK2 0x1
44#define WM5100_FLL_SRC_FLL1 0x4
45#define WM5100_FLL_SRC_FLL2 0x5
46#define WM5100_FLL_SRC_AIF1BCLK 0x8
47#define WM5100_FLL_SRC_AIF2BCLK 0x9
48#define WM5100_FLL_SRC_AIF3BCLK 0xa
49
50/*
51 * Register values.
52 */
53#define WM5100_SOFTWARE_RESET 0x00
54#define WM5100_DEVICE_REVISION 0x01
55#define WM5100_CTRL_IF_1 0x10
56#define WM5100_TONE_GENERATOR_1 0x20
57#define WM5100_PWM_DRIVE_1 0x30
58#define WM5100_PWM_DRIVE_2 0x31
59#define WM5100_PWM_DRIVE_3 0x32
60#define WM5100_CLOCKING_1 0x100
61#define WM5100_CLOCKING_3 0x101
62#define WM5100_CLOCKING_4 0x102
63#define WM5100_CLOCKING_5 0x103
64#define WM5100_CLOCKING_6 0x104
65#define WM5100_CLOCKING_7 0x107
66#define WM5100_CLOCKING_8 0x108
67#define WM5100_ASRC_ENABLE 0x120
68#define WM5100_ASRC_STATUS 0x121
69#define WM5100_ASRC_RATE1 0x122
70#define WM5100_ISRC_1_CTRL_1 0x141
71#define WM5100_ISRC_1_CTRL_2 0x142
72#define WM5100_ISRC_2_CTRL1 0x143
73#define WM5100_ISRC_2_CTRL_2 0x144
74#define WM5100_FLL1_CONTROL_1 0x182
75#define WM5100_FLL1_CONTROL_2 0x183
76#define WM5100_FLL1_CONTROL_3 0x184
77#define WM5100_FLL1_CONTROL_5 0x186
78#define WM5100_FLL1_CONTROL_6 0x187
79#define WM5100_FLL1_EFS_1 0x188
80#define WM5100_FLL2_CONTROL_1 0x1A2
81#define WM5100_FLL2_CONTROL_2 0x1A3
82#define WM5100_FLL2_CONTROL_3 0x1A4
83#define WM5100_FLL2_CONTROL_5 0x1A6
84#define WM5100_FLL2_CONTROL_6 0x1A7
85#define WM5100_FLL2_EFS_1 0x1A8
86#define WM5100_MIC_CHARGE_PUMP_1 0x200
87#define WM5100_MIC_CHARGE_PUMP_2 0x201
88#define WM5100_HP_CHARGE_PUMP_1 0x202
89#define WM5100_LDO1_CONTROL 0x211
90#define WM5100_MIC_BIAS_CTRL_1 0x215
91#define WM5100_MIC_BIAS_CTRL_2 0x216
92#define WM5100_MIC_BIAS_CTRL_3 0x217
93#define WM5100_ACCESSORY_DETECT_MODE_1 0x280
94#define WM5100_HEADPHONE_DETECT_1 0x288
95#define WM5100_HEADPHONE_DETECT_2 0x289
96#define WM5100_MIC_DETECT_1 0x290
97#define WM5100_MIC_DETECT_2 0x291
98#define WM5100_MIC_DETECT_3 0x292
99#define WM5100_MISC_CONTROL 0x2BB
100#define WM5100_INPUT_ENABLES 0x301
101#define WM5100_INPUT_ENABLES_STATUS 0x302
102#define WM5100_IN1L_CONTROL 0x310
103#define WM5100_IN1R_CONTROL 0x311
104#define WM5100_IN2L_CONTROL 0x312
105#define WM5100_IN2R_CONTROL 0x313
106#define WM5100_IN3L_CONTROL 0x314
107#define WM5100_IN3R_CONTROL 0x315
108#define WM5100_IN4L_CONTROL 0x316
109#define WM5100_IN4R_CONTROL 0x317
110#define WM5100_RXANC_SRC 0x318
111#define WM5100_INPUT_VOLUME_RAMP 0x319
112#define WM5100_ADC_DIGITAL_VOLUME_1L 0x320
113#define WM5100_ADC_DIGITAL_VOLUME_1R 0x321
114#define WM5100_ADC_DIGITAL_VOLUME_2L 0x322
115#define WM5100_ADC_DIGITAL_VOLUME_2R 0x323
116#define WM5100_ADC_DIGITAL_VOLUME_3L 0x324
117#define WM5100_ADC_DIGITAL_VOLUME_3R 0x325
118#define WM5100_ADC_DIGITAL_VOLUME_4L 0x326
119#define WM5100_ADC_DIGITAL_VOLUME_4R 0x327
120#define WM5100_OUTPUT_ENABLES_2 0x401
121#define WM5100_OUTPUT_STATUS_1 0x402
122#define WM5100_OUTPUT_STATUS_2 0x403
123#define WM5100_CHANNEL_ENABLES_1 0x408
124#define WM5100_OUT_VOLUME_1L 0x410
125#define WM5100_OUT_VOLUME_1R 0x411
126#define WM5100_DAC_VOLUME_LIMIT_1L 0x412
127#define WM5100_DAC_VOLUME_LIMIT_1R 0x413
128#define WM5100_OUT_VOLUME_2L 0x414
129#define WM5100_OUT_VOLUME_2R 0x415
130#define WM5100_DAC_VOLUME_LIMIT_2L 0x416
131#define WM5100_DAC_VOLUME_LIMIT_2R 0x417
132#define WM5100_OUT_VOLUME_3L 0x418
133#define WM5100_OUT_VOLUME_3R 0x419
134#define WM5100_DAC_VOLUME_LIMIT_3L 0x41A
135#define WM5100_DAC_VOLUME_LIMIT_3R 0x41B
136#define WM5100_OUT_VOLUME_4L 0x41C
137#define WM5100_OUT_VOLUME_4R 0x41D
138#define WM5100_DAC_VOLUME_LIMIT_5L 0x41E
139#define WM5100_DAC_VOLUME_LIMIT_5R 0x41F
140#define WM5100_DAC_VOLUME_LIMIT_6L 0x420
141#define WM5100_DAC_VOLUME_LIMIT_6R 0x421
142#define WM5100_DAC_AEC_CONTROL_1 0x440
143#define WM5100_OUTPUT_VOLUME_RAMP 0x441
144#define WM5100_DAC_DIGITAL_VOLUME_1L 0x480
145#define WM5100_DAC_DIGITAL_VOLUME_1R 0x481
146#define WM5100_DAC_DIGITAL_VOLUME_2L 0x482
147#define WM5100_DAC_DIGITAL_VOLUME_2R 0x483
148#define WM5100_DAC_DIGITAL_VOLUME_3L 0x484
149#define WM5100_DAC_DIGITAL_VOLUME_3R 0x485
150#define WM5100_DAC_DIGITAL_VOLUME_4L 0x486
151#define WM5100_DAC_DIGITAL_VOLUME_4R 0x487
152#define WM5100_DAC_DIGITAL_VOLUME_5L 0x488
153#define WM5100_DAC_DIGITAL_VOLUME_5R 0x489
154#define WM5100_DAC_DIGITAL_VOLUME_6L 0x48A
155#define WM5100_DAC_DIGITAL_VOLUME_6R 0x48B
156#define WM5100_PDM_SPK1_CTRL_1 0x4C0
157#define WM5100_PDM_SPK1_CTRL_2 0x4C1
158#define WM5100_PDM_SPK2_CTRL_1 0x4C2
159#define WM5100_PDM_SPK2_CTRL_2 0x4C3
160#define WM5100_AUDIO_IF_1_1 0x500
161#define WM5100_AUDIO_IF_1_2 0x501
162#define WM5100_AUDIO_IF_1_3 0x502
163#define WM5100_AUDIO_IF_1_4 0x503
164#define WM5100_AUDIO_IF_1_5 0x504
165#define WM5100_AUDIO_IF_1_6 0x505
166#define WM5100_AUDIO_IF_1_7 0x506
167#define WM5100_AUDIO_IF_1_8 0x507
168#define WM5100_AUDIO_IF_1_9 0x508
169#define WM5100_AUDIO_IF_1_10 0x509
170#define WM5100_AUDIO_IF_1_11 0x50A
171#define WM5100_AUDIO_IF_1_12 0x50B
172#define WM5100_AUDIO_IF_1_13 0x50C
173#define WM5100_AUDIO_IF_1_14 0x50D
174#define WM5100_AUDIO_IF_1_15 0x50E
175#define WM5100_AUDIO_IF_1_16 0x50F
176#define WM5100_AUDIO_IF_1_17 0x510
177#define WM5100_AUDIO_IF_1_18 0x511
178#define WM5100_AUDIO_IF_1_19 0x512
179#define WM5100_AUDIO_IF_1_20 0x513
180#define WM5100_AUDIO_IF_1_21 0x514
181#define WM5100_AUDIO_IF_1_22 0x515
182#define WM5100_AUDIO_IF_1_23 0x516
183#define WM5100_AUDIO_IF_1_24 0x517
184#define WM5100_AUDIO_IF_1_25 0x518
185#define WM5100_AUDIO_IF_1_26 0x519
186#define WM5100_AUDIO_IF_1_27 0x51A
187#define WM5100_AUDIO_IF_2_1 0x540
188#define WM5100_AUDIO_IF_2_2 0x541
189#define WM5100_AUDIO_IF_2_3 0x542
190#define WM5100_AUDIO_IF_2_4 0x543
191#define WM5100_AUDIO_IF_2_5 0x544
192#define WM5100_AUDIO_IF_2_6 0x545
193#define WM5100_AUDIO_IF_2_7 0x546
194#define WM5100_AUDIO_IF_2_8 0x547
195#define WM5100_AUDIO_IF_2_9 0x548
196#define WM5100_AUDIO_IF_2_10 0x549
197#define WM5100_AUDIO_IF_2_11 0x54A
198#define WM5100_AUDIO_IF_2_18 0x551
199#define WM5100_AUDIO_IF_2_19 0x552
200#define WM5100_AUDIO_IF_2_26 0x559
201#define WM5100_AUDIO_IF_2_27 0x55A
202#define WM5100_AUDIO_IF_3_1 0x580
203#define WM5100_AUDIO_IF_3_2 0x581
204#define WM5100_AUDIO_IF_3_3 0x582
205#define WM5100_AUDIO_IF_3_4 0x583
206#define WM5100_AUDIO_IF_3_5 0x584
207#define WM5100_AUDIO_IF_3_6 0x585
208#define WM5100_AUDIO_IF_3_7 0x586
209#define WM5100_AUDIO_IF_3_8 0x587
210#define WM5100_AUDIO_IF_3_9 0x588
211#define WM5100_AUDIO_IF_3_10 0x589
212#define WM5100_AUDIO_IF_3_11 0x58A
213#define WM5100_AUDIO_IF_3_18 0x591
214#define WM5100_AUDIO_IF_3_19 0x592
215#define WM5100_AUDIO_IF_3_26 0x599
216#define WM5100_AUDIO_IF_3_27 0x59A
217#define WM5100_PWM1MIX_INPUT_1_SOURCE 0x640
218#define WM5100_PWM1MIX_INPUT_1_VOLUME 0x641
219#define WM5100_PWM1MIX_INPUT_2_SOURCE 0x642
220#define WM5100_PWM1MIX_INPUT_2_VOLUME 0x643
221#define WM5100_PWM1MIX_INPUT_3_SOURCE 0x644
222#define WM5100_PWM1MIX_INPUT_3_VOLUME 0x645
223#define WM5100_PWM1MIX_INPUT_4_SOURCE 0x646
224#define WM5100_PWM1MIX_INPUT_4_VOLUME 0x647
225#define WM5100_PWM2MIX_INPUT_1_SOURCE 0x648
226#define WM5100_PWM2MIX_INPUT_1_VOLUME 0x649
227#define WM5100_PWM2MIX_INPUT_2_SOURCE 0x64A
228#define WM5100_PWM2MIX_INPUT_2_VOLUME 0x64B
229#define WM5100_PWM2MIX_INPUT_3_SOURCE 0x64C
230#define WM5100_PWM2MIX_INPUT_3_VOLUME 0x64D
231#define WM5100_PWM2MIX_INPUT_4_SOURCE 0x64E
232#define WM5100_PWM2MIX_INPUT_4_VOLUME 0x64F
233#define WM5100_OUT1LMIX_INPUT_1_SOURCE 0x680
234#define WM5100_OUT1LMIX_INPUT_1_VOLUME 0x681
235#define WM5100_OUT1LMIX_INPUT_2_SOURCE 0x682
236#define WM5100_OUT1LMIX_INPUT_2_VOLUME 0x683
237#define WM5100_OUT1LMIX_INPUT_3_SOURCE 0x684
238#define WM5100_OUT1LMIX_INPUT_3_VOLUME 0x685
239#define WM5100_OUT1LMIX_INPUT_4_SOURCE 0x686
240#define WM5100_OUT1LMIX_INPUT_4_VOLUME 0x687
241#define WM5100_OUT1RMIX_INPUT_1_SOURCE 0x688
242#define WM5100_OUT1RMIX_INPUT_1_VOLUME 0x689
243#define WM5100_OUT1RMIX_INPUT_2_SOURCE 0x68A
244#define WM5100_OUT1RMIX_INPUT_2_VOLUME 0x68B
245#define WM5100_OUT1RMIX_INPUT_3_SOURCE 0x68C
246#define WM5100_OUT1RMIX_INPUT_3_VOLUME 0x68D
247#define WM5100_OUT1RMIX_INPUT_4_SOURCE 0x68E
248#define WM5100_OUT1RMIX_INPUT_4_VOLUME 0x68F
249#define WM5100_OUT2LMIX_INPUT_1_SOURCE 0x690
250#define WM5100_OUT2LMIX_INPUT_1_VOLUME 0x691
251#define WM5100_OUT2LMIX_INPUT_2_SOURCE 0x692
252#define WM5100_OUT2LMIX_INPUT_2_VOLUME 0x693
253#define WM5100_OUT2LMIX_INPUT_3_SOURCE 0x694
254#define WM5100_OUT2LMIX_INPUT_3_VOLUME 0x695
255#define WM5100_OUT2LMIX_INPUT_4_SOURCE 0x696
256#define WM5100_OUT2LMIX_INPUT_4_VOLUME 0x697
257#define WM5100_OUT2RMIX_INPUT_1_SOURCE 0x698
258#define WM5100_OUT2RMIX_INPUT_1_VOLUME 0x699
259#define WM5100_OUT2RMIX_INPUT_2_SOURCE 0x69A
260#define WM5100_OUT2RMIX_INPUT_2_VOLUME 0x69B
261#define WM5100_OUT2RMIX_INPUT_3_SOURCE 0x69C
262#define WM5100_OUT2RMIX_INPUT_3_VOLUME 0x69D
263#define WM5100_OUT2RMIX_INPUT_4_SOURCE 0x69E
264#define WM5100_OUT2RMIX_INPUT_4_VOLUME 0x69F
265#define WM5100_OUT3LMIX_INPUT_1_SOURCE 0x6A0
266#define WM5100_OUT3LMIX_INPUT_1_VOLUME 0x6A1
267#define WM5100_OUT3LMIX_INPUT_2_SOURCE 0x6A2
268#define WM5100_OUT3LMIX_INPUT_2_VOLUME 0x6A3
269#define WM5100_OUT3LMIX_INPUT_3_SOURCE 0x6A4
270#define WM5100_OUT3LMIX_INPUT_3_VOLUME 0x6A5
271#define WM5100_OUT3LMIX_INPUT_4_SOURCE 0x6A6
272#define WM5100_OUT3LMIX_INPUT_4_VOLUME 0x6A7
273#define WM5100_OUT3RMIX_INPUT_1_SOURCE 0x6A8
274#define WM5100_OUT3RMIX_INPUT_1_VOLUME 0x6A9
275#define WM5100_OUT3RMIX_INPUT_2_SOURCE 0x6AA
276#define WM5100_OUT3RMIX_INPUT_2_VOLUME 0x6AB
277#define WM5100_OUT3RMIX_INPUT_3_SOURCE 0x6AC
278#define WM5100_OUT3RMIX_INPUT_3_VOLUME 0x6AD
279#define WM5100_OUT3RMIX_INPUT_4_SOURCE 0x6AE
280#define WM5100_OUT3RMIX_INPUT_4_VOLUME 0x6AF
281#define WM5100_OUT4LMIX_INPUT_1_SOURCE 0x6B0
282#define WM5100_OUT4LMIX_INPUT_1_VOLUME 0x6B1
283#define WM5100_OUT4LMIX_INPUT_2_SOURCE 0x6B2
284#define WM5100_OUT4LMIX_INPUT_2_VOLUME 0x6B3
285#define WM5100_OUT4LMIX_INPUT_3_SOURCE 0x6B4
286#define WM5100_OUT4LMIX_INPUT_3_VOLUME 0x6B5
287#define WM5100_OUT4LMIX_INPUT_4_SOURCE 0x6B6
288#define WM5100_OUT4LMIX_INPUT_4_VOLUME 0x6B7
289#define WM5100_OUT4RMIX_INPUT_1_SOURCE 0x6B8
290#define WM5100_OUT4RMIX_INPUT_1_VOLUME 0x6B9
291#define WM5100_OUT4RMIX_INPUT_2_SOURCE 0x6BA
292#define WM5100_OUT4RMIX_INPUT_2_VOLUME 0x6BB
293#define WM5100_OUT4RMIX_INPUT_3_SOURCE 0x6BC
294#define WM5100_OUT4RMIX_INPUT_3_VOLUME 0x6BD
295#define WM5100_OUT4RMIX_INPUT_4_SOURCE 0x6BE
296#define WM5100_OUT4RMIX_INPUT_4_VOLUME 0x6BF
297#define WM5100_OUT5LMIX_INPUT_1_SOURCE 0x6C0
298#define WM5100_OUT5LMIX_INPUT_1_VOLUME 0x6C1
299#define WM5100_OUT5LMIX_INPUT_2_SOURCE 0x6C2
300#define WM5100_OUT5LMIX_INPUT_2_VOLUME 0x6C3
301#define WM5100_OUT5LMIX_INPUT_3_SOURCE 0x6C4
302#define WM5100_OUT5LMIX_INPUT_3_VOLUME 0x6C5
303#define WM5100_OUT5LMIX_INPUT_4_SOURCE 0x6C6
304#define WM5100_OUT5LMIX_INPUT_4_VOLUME 0x6C7
305#define WM5100_OUT5RMIX_INPUT_1_SOURCE 0x6C8
306#define WM5100_OUT5RMIX_INPUT_1_VOLUME 0x6C9
307#define WM5100_OUT5RMIX_INPUT_2_SOURCE 0x6CA
308#define WM5100_OUT5RMIX_INPUT_2_VOLUME 0x6CB
309#define WM5100_OUT5RMIX_INPUT_3_SOURCE 0x6CC
310#define WM5100_OUT5RMIX_INPUT_3_VOLUME 0x6CD
311#define WM5100_OUT5RMIX_INPUT_4_SOURCE 0x6CE
312#define WM5100_OUT5RMIX_INPUT_4_VOLUME 0x6CF
313#define WM5100_OUT6LMIX_INPUT_1_SOURCE 0x6D0
314#define WM5100_OUT6LMIX_INPUT_1_VOLUME 0x6D1
315#define WM5100_OUT6LMIX_INPUT_2_SOURCE 0x6D2
316#define WM5100_OUT6LMIX_INPUT_2_VOLUME 0x6D3
317#define WM5100_OUT6LMIX_INPUT_3_SOURCE 0x6D4
318#define WM5100_OUT6LMIX_INPUT_3_VOLUME 0x6D5
319#define WM5100_OUT6LMIX_INPUT_4_SOURCE 0x6D6
320#define WM5100_OUT6LMIX_INPUT_4_VOLUME 0x6D7
321#define WM5100_OUT6RMIX_INPUT_1_SOURCE 0x6D8
322#define WM5100_OUT6RMIX_INPUT_1_VOLUME 0x6D9
323#define WM5100_OUT6RMIX_INPUT_2_SOURCE 0x6DA
324#define WM5100_OUT6RMIX_INPUT_2_VOLUME 0x6DB
325#define WM5100_OUT6RMIX_INPUT_3_SOURCE 0x6DC
326#define WM5100_OUT6RMIX_INPUT_3_VOLUME 0x6DD
327#define WM5100_OUT6RMIX_INPUT_4_SOURCE 0x6DE
328#define WM5100_OUT6RMIX_INPUT_4_VOLUME 0x6DF
329#define WM5100_AIF1TX1MIX_INPUT_1_SOURCE 0x700
330#define WM5100_AIF1TX1MIX_INPUT_1_VOLUME 0x701
331#define WM5100_AIF1TX1MIX_INPUT_2_SOURCE 0x702
332#define WM5100_AIF1TX1MIX_INPUT_2_VOLUME 0x703
333#define WM5100_AIF1TX1MIX_INPUT_3_SOURCE 0x704
334#define WM5100_AIF1TX1MIX_INPUT_3_VOLUME 0x705
335#define WM5100_AIF1TX1MIX_INPUT_4_SOURCE 0x706
336#define WM5100_AIF1TX1MIX_INPUT_4_VOLUME 0x707
337#define WM5100_AIF1TX2MIX_INPUT_1_SOURCE 0x708
338#define WM5100_AIF1TX2MIX_INPUT_1_VOLUME 0x709
339#define WM5100_AIF1TX2MIX_INPUT_2_SOURCE 0x70A
340#define WM5100_AIF1TX2MIX_INPUT_2_VOLUME 0x70B
341#define WM5100_AIF1TX2MIX_INPUT_3_SOURCE 0x70C
342#define WM5100_AIF1TX2MIX_INPUT_3_VOLUME 0x70D
343#define WM5100_AIF1TX2MIX_INPUT_4_SOURCE 0x70E
344#define WM5100_AIF1TX2MIX_INPUT_4_VOLUME 0x70F
345#define WM5100_AIF1TX3MIX_INPUT_1_SOURCE 0x710
346#define WM5100_AIF1TX3MIX_INPUT_1_VOLUME 0x711
347#define WM5100_AIF1TX3MIX_INPUT_2_SOURCE 0x712
348#define WM5100_AIF1TX3MIX_INPUT_2_VOLUME 0x713
349#define WM5100_AIF1TX3MIX_INPUT_3_SOURCE 0x714
350#define WM5100_AIF1TX3MIX_INPUT_3_VOLUME 0x715
351#define WM5100_AIF1TX3MIX_INPUT_4_SOURCE 0x716
352#define WM5100_AIF1TX3MIX_INPUT_4_VOLUME 0x717
353#define WM5100_AIF1TX4MIX_INPUT_1_SOURCE 0x718
354#define WM5100_AIF1TX4MIX_INPUT_1_VOLUME 0x719
355#define WM5100_AIF1TX4MIX_INPUT_2_SOURCE 0x71A
356#define WM5100_AIF1TX4MIX_INPUT_2_VOLUME 0x71B
357#define WM5100_AIF1TX4MIX_INPUT_3_SOURCE 0x71C
358#define WM5100_AIF1TX4MIX_INPUT_3_VOLUME 0x71D
359#define WM5100_AIF1TX4MIX_INPUT_4_SOURCE 0x71E
360#define WM5100_AIF1TX4MIX_INPUT_4_VOLUME 0x71F
361#define WM5100_AIF1TX5MIX_INPUT_1_SOURCE 0x720
362#define WM5100_AIF1TX5MIX_INPUT_1_VOLUME 0x721
363#define WM5100_AIF1TX5MIX_INPUT_2_SOURCE 0x722
364#define WM5100_AIF1TX5MIX_INPUT_2_VOLUME 0x723
365#define WM5100_AIF1TX5MIX_INPUT_3_SOURCE 0x724
366#define WM5100_AIF1TX5MIX_INPUT_3_VOLUME 0x725
367#define WM5100_AIF1TX5MIX_INPUT_4_SOURCE 0x726
368#define WM5100_AIF1TX5MIX_INPUT_4_VOLUME 0x727
369#define WM5100_AIF1TX6MIX_INPUT_1_SOURCE 0x728
370#define WM5100_AIF1TX6MIX_INPUT_1_VOLUME 0x729
371#define WM5100_AIF1TX6MIX_INPUT_2_SOURCE 0x72A
372#define WM5100_AIF1TX6MIX_INPUT_2_VOLUME 0x72B
373#define WM5100_AIF1TX6MIX_INPUT_3_SOURCE 0x72C
374#define WM5100_AIF1TX6MIX_INPUT_3_VOLUME 0x72D
375#define WM5100_AIF1TX6MIX_INPUT_4_SOURCE 0x72E
376#define WM5100_AIF1TX6MIX_INPUT_4_VOLUME 0x72F
377#define WM5100_AIF1TX7MIX_INPUT_1_SOURCE 0x730
378#define WM5100_AIF1TX7MIX_INPUT_1_VOLUME 0x731
379#define WM5100_AIF1TX7MIX_INPUT_2_SOURCE 0x732
380#define WM5100_AIF1TX7MIX_INPUT_2_VOLUME 0x733
381#define WM5100_AIF1TX7MIX_INPUT_3_SOURCE 0x734
382#define WM5100_AIF1TX7MIX_INPUT_3_VOLUME 0x735
383#define WM5100_AIF1TX7MIX_INPUT_4_SOURCE 0x736
384#define WM5100_AIF1TX7MIX_INPUT_4_VOLUME 0x737
385#define WM5100_AIF1TX8MIX_INPUT_1_SOURCE 0x738
386#define WM5100_AIF1TX8MIX_INPUT_1_VOLUME 0x739
387#define WM5100_AIF1TX8MIX_INPUT_2_SOURCE 0x73A
388#define WM5100_AIF1TX8MIX_INPUT_2_VOLUME 0x73B
389#define WM5100_AIF1TX8MIX_INPUT_3_SOURCE 0x73C
390#define WM5100_AIF1TX8MIX_INPUT_3_VOLUME 0x73D
391#define WM5100_AIF1TX8MIX_INPUT_4_SOURCE 0x73E
392#define WM5100_AIF1TX8MIX_INPUT_4_VOLUME 0x73F
393#define WM5100_AIF2TX1MIX_INPUT_1_SOURCE 0x740
394#define WM5100_AIF2TX1MIX_INPUT_1_VOLUME 0x741
395#define WM5100_AIF2TX1MIX_INPUT_2_SOURCE 0x742
396#define WM5100_AIF2TX1MIX_INPUT_2_VOLUME 0x743
397#define WM5100_AIF2TX1MIX_INPUT_3_SOURCE 0x744
398#define WM5100_AIF2TX1MIX_INPUT_3_VOLUME 0x745
399#define WM5100_AIF2TX1MIX_INPUT_4_SOURCE 0x746
400#define WM5100_AIF2TX1MIX_INPUT_4_VOLUME 0x747
401#define WM5100_AIF2TX2MIX_INPUT_1_SOURCE 0x748
402#define WM5100_AIF2TX2MIX_INPUT_1_VOLUME 0x749
403#define WM5100_AIF2TX2MIX_INPUT_2_SOURCE 0x74A
404#define WM5100_AIF2TX2MIX_INPUT_2_VOLUME 0x74B
405#define WM5100_AIF2TX2MIX_INPUT_3_SOURCE 0x74C
406#define WM5100_AIF2TX2MIX_INPUT_3_VOLUME 0x74D
407#define WM5100_AIF2TX2MIX_INPUT_4_SOURCE 0x74E
408#define WM5100_AIF2TX2MIX_INPUT_4_VOLUME 0x74F
409#define WM5100_AIF3TX1MIX_INPUT_1_SOURCE 0x780
410#define WM5100_AIF3TX1MIX_INPUT_1_VOLUME 0x781
411#define WM5100_AIF3TX1MIX_INPUT_2_SOURCE 0x782
412#define WM5100_AIF3TX1MIX_INPUT_2_VOLUME 0x783
413#define WM5100_AIF3TX1MIX_INPUT_3_SOURCE 0x784
414#define WM5100_AIF3TX1MIX_INPUT_3_VOLUME 0x785
415#define WM5100_AIF3TX1MIX_INPUT_4_SOURCE 0x786
416#define WM5100_AIF3TX1MIX_INPUT_4_VOLUME 0x787
417#define WM5100_AIF3TX2MIX_INPUT_1_SOURCE 0x788
418#define WM5100_AIF3TX2MIX_INPUT_1_VOLUME 0x789
419#define WM5100_AIF3TX2MIX_INPUT_2_SOURCE 0x78A
420#define WM5100_AIF3TX2MIX_INPUT_2_VOLUME 0x78B
421#define WM5100_AIF3TX2MIX_INPUT_3_SOURCE 0x78C
422#define WM5100_AIF3TX2MIX_INPUT_3_VOLUME 0x78D
423#define WM5100_AIF3TX2MIX_INPUT_4_SOURCE 0x78E
424#define WM5100_AIF3TX2MIX_INPUT_4_VOLUME 0x78F
425#define WM5100_EQ1MIX_INPUT_1_SOURCE 0x880
426#define WM5100_EQ1MIX_INPUT_1_VOLUME 0x881
427#define WM5100_EQ1MIX_INPUT_2_SOURCE 0x882
428#define WM5100_EQ1MIX_INPUT_2_VOLUME 0x883
429#define WM5100_EQ1MIX_INPUT_3_SOURCE 0x884
430#define WM5100_EQ1MIX_INPUT_3_VOLUME 0x885
431#define WM5100_EQ1MIX_INPUT_4_SOURCE 0x886
432#define WM5100_EQ1MIX_INPUT_4_VOLUME 0x887
433#define WM5100_EQ2MIX_INPUT_1_SOURCE 0x888
434#define WM5100_EQ2MIX_INPUT_1_VOLUME 0x889
435#define WM5100_EQ2MIX_INPUT_2_SOURCE 0x88A
436#define WM5100_EQ2MIX_INPUT_2_VOLUME 0x88B
437#define WM5100_EQ2MIX_INPUT_3_SOURCE 0x88C
438#define WM5100_EQ2MIX_INPUT_3_VOLUME 0x88D
439#define WM5100_EQ2MIX_INPUT_4_SOURCE 0x88E
440#define WM5100_EQ2MIX_INPUT_4_VOLUME 0x88F
441#define WM5100_EQ3MIX_INPUT_1_SOURCE 0x890
442#define WM5100_EQ3MIX_INPUT_1_VOLUME 0x891
443#define WM5100_EQ3MIX_INPUT_2_SOURCE 0x892
444#define WM5100_EQ3MIX_INPUT_2_VOLUME 0x893
445#define WM5100_EQ3MIX_INPUT_3_SOURCE 0x894
446#define WM5100_EQ3MIX_INPUT_3_VOLUME 0x895
447#define WM5100_EQ3MIX_INPUT_4_SOURCE 0x896
448#define WM5100_EQ3MIX_INPUT_4_VOLUME 0x897
449#define WM5100_EQ4MIX_INPUT_1_SOURCE 0x898
450#define WM5100_EQ4MIX_INPUT_1_VOLUME 0x899
451#define WM5100_EQ4MIX_INPUT_2_SOURCE 0x89A
452#define WM5100_EQ4MIX_INPUT_2_VOLUME 0x89B
453#define WM5100_EQ4MIX_INPUT_3_SOURCE 0x89C
454#define WM5100_EQ4MIX_INPUT_3_VOLUME 0x89D
455#define WM5100_EQ4MIX_INPUT_4_SOURCE 0x89E
456#define WM5100_EQ4MIX_INPUT_4_VOLUME 0x89F
457#define WM5100_DRC1LMIX_INPUT_1_SOURCE 0x8C0
458#define WM5100_DRC1LMIX_INPUT_1_VOLUME 0x8C1
459#define WM5100_DRC1LMIX_INPUT_2_SOURCE 0x8C2
460#define WM5100_DRC1LMIX_INPUT_2_VOLUME 0x8C3
461#define WM5100_DRC1LMIX_INPUT_3_SOURCE 0x8C4
462#define WM5100_DRC1LMIX_INPUT_3_VOLUME 0x8C5
463#define WM5100_DRC1LMIX_INPUT_4_SOURCE 0x8C6
464#define WM5100_DRC1LMIX_INPUT_4_VOLUME 0x8C7
465#define WM5100_DRC1RMIX_INPUT_1_SOURCE 0x8C8
466#define WM5100_DRC1RMIX_INPUT_1_VOLUME 0x8C9
467#define WM5100_DRC1RMIX_INPUT_2_SOURCE 0x8CA
468#define WM5100_DRC1RMIX_INPUT_2_VOLUME 0x8CB
469#define WM5100_DRC1RMIX_INPUT_3_SOURCE 0x8CC
470#define WM5100_DRC1RMIX_INPUT_3_VOLUME 0x8CD
471#define WM5100_DRC1RMIX_INPUT_4_SOURCE 0x8CE
472#define WM5100_DRC1RMIX_INPUT_4_VOLUME 0x8CF
473#define WM5100_HPLP1MIX_INPUT_1_SOURCE 0x900
474#define WM5100_HPLP1MIX_INPUT_1_VOLUME 0x901
475#define WM5100_HPLP1MIX_INPUT_2_SOURCE 0x902
476#define WM5100_HPLP1MIX_INPUT_2_VOLUME 0x903
477#define WM5100_HPLP1MIX_INPUT_3_SOURCE 0x904
478#define WM5100_HPLP1MIX_INPUT_3_VOLUME 0x905
479#define WM5100_HPLP1MIX_INPUT_4_SOURCE 0x906
480#define WM5100_HPLP1MIX_INPUT_4_VOLUME 0x907
481#define WM5100_HPLP2MIX_INPUT_1_SOURCE 0x908
482#define WM5100_HPLP2MIX_INPUT_1_VOLUME 0x909
483#define WM5100_HPLP2MIX_INPUT_2_SOURCE 0x90A
484#define WM5100_HPLP2MIX_INPUT_2_VOLUME 0x90B
485#define WM5100_HPLP2MIX_INPUT_3_SOURCE 0x90C
486#define WM5100_HPLP2MIX_INPUT_3_VOLUME 0x90D
487#define WM5100_HPLP2MIX_INPUT_4_SOURCE 0x90E
488#define WM5100_HPLP2MIX_INPUT_4_VOLUME 0x90F
489#define WM5100_HPLP3MIX_INPUT_1_SOURCE 0x910
490#define WM5100_HPLP3MIX_INPUT_1_VOLUME 0x911
491#define WM5100_HPLP3MIX_INPUT_2_SOURCE 0x912
492#define WM5100_HPLP3MIX_INPUT_2_VOLUME 0x913
493#define WM5100_HPLP3MIX_INPUT_3_SOURCE 0x914
494#define WM5100_HPLP3MIX_INPUT_3_VOLUME 0x915
495#define WM5100_HPLP3MIX_INPUT_4_SOURCE 0x916
496#define WM5100_HPLP3MIX_INPUT_4_VOLUME 0x917
497#define WM5100_HPLP4MIX_INPUT_1_SOURCE 0x918
498#define WM5100_HPLP4MIX_INPUT_1_VOLUME 0x919
499#define WM5100_HPLP4MIX_INPUT_2_SOURCE 0x91A
500#define WM5100_HPLP4MIX_INPUT_2_VOLUME 0x91B
501#define WM5100_HPLP4MIX_INPUT_3_SOURCE 0x91C
502#define WM5100_HPLP4MIX_INPUT_3_VOLUME 0x91D
503#define WM5100_HPLP4MIX_INPUT_4_SOURCE 0x91E
504#define WM5100_HPLP4MIX_INPUT_4_VOLUME 0x91F
505#define WM5100_DSP1LMIX_INPUT_1_SOURCE 0x940
506#define WM5100_DSP1LMIX_INPUT_1_VOLUME 0x941
507#define WM5100_DSP1LMIX_INPUT_2_SOURCE 0x942
508#define WM5100_DSP1LMIX_INPUT_2_VOLUME 0x943
509#define WM5100_DSP1LMIX_INPUT_3_SOURCE 0x944
510#define WM5100_DSP1LMIX_INPUT_3_VOLUME 0x945
511#define WM5100_DSP1LMIX_INPUT_4_SOURCE 0x946
512#define WM5100_DSP1LMIX_INPUT_4_VOLUME 0x947
513#define WM5100_DSP1RMIX_INPUT_1_SOURCE 0x948
514#define WM5100_DSP1RMIX_INPUT_1_VOLUME 0x949
515#define WM5100_DSP1RMIX_INPUT_2_SOURCE 0x94A
516#define WM5100_DSP1RMIX_INPUT_2_VOLUME 0x94B
517#define WM5100_DSP1RMIX_INPUT_3_SOURCE 0x94C
518#define WM5100_DSP1RMIX_INPUT_3_VOLUME 0x94D
519#define WM5100_DSP1RMIX_INPUT_4_SOURCE 0x94E
520#define WM5100_DSP1RMIX_INPUT_4_VOLUME 0x94F
521#define WM5100_DSP1AUX1MIX_INPUT_1_SOURCE 0x950
522#define WM5100_DSP1AUX2MIX_INPUT_1_SOURCE 0x958
523#define WM5100_DSP1AUX3MIX_INPUT_1_SOURCE 0x960
524#define WM5100_DSP1AUX4MIX_INPUT_1_SOURCE 0x968
525#define WM5100_DSP1AUX5MIX_INPUT_1_SOURCE 0x970
526#define WM5100_DSP1AUX6MIX_INPUT_1_SOURCE 0x978
527#define WM5100_DSP2LMIX_INPUT_1_SOURCE 0x980
528#define WM5100_DSP2LMIX_INPUT_1_VOLUME 0x981
529#define WM5100_DSP2LMIX_INPUT_2_SOURCE 0x982
530#define WM5100_DSP2LMIX_INPUT_2_VOLUME 0x983
531#define WM5100_DSP2LMIX_INPUT_3_SOURCE 0x984
532#define WM5100_DSP2LMIX_INPUT_3_VOLUME 0x985
533#define WM5100_DSP2LMIX_INPUT_4_SOURCE 0x986
534#define WM5100_DSP2LMIX_INPUT_4_VOLUME 0x987
535#define WM5100_DSP2RMIX_INPUT_1_SOURCE 0x988
536#define WM5100_DSP2RMIX_INPUT_1_VOLUME 0x989
537#define WM5100_DSP2RMIX_INPUT_2_SOURCE 0x98A
538#define WM5100_DSP2RMIX_INPUT_2_VOLUME 0x98B
539#define WM5100_DSP2RMIX_INPUT_3_SOURCE 0x98C
540#define WM5100_DSP2RMIX_INPUT_3_VOLUME 0x98D
541#define WM5100_DSP2RMIX_INPUT_4_SOURCE 0x98E
542#define WM5100_DSP2RMIX_INPUT_4_VOLUME 0x98F
543#define WM5100_DSP2AUX1MIX_INPUT_1_SOURCE 0x990
544#define WM5100_DSP2AUX2MIX_INPUT_1_SOURCE 0x998
545#define WM5100_DSP2AUX3MIX_INPUT_1_SOURCE 0x9A0
546#define WM5100_DSP2AUX4MIX_INPUT_1_SOURCE 0x9A8
547#define WM5100_DSP2AUX5MIX_INPUT_1_SOURCE 0x9B0
548#define WM5100_DSP2AUX6MIX_INPUT_1_SOURCE 0x9B8
549#define WM5100_DSP3LMIX_INPUT_1_SOURCE 0x9C0
550#define WM5100_DSP3LMIX_INPUT_1_VOLUME 0x9C1
551#define WM5100_DSP3LMIX_INPUT_2_SOURCE 0x9C2
552#define WM5100_DSP3LMIX_INPUT_2_VOLUME 0x9C3
553#define WM5100_DSP3LMIX_INPUT_3_SOURCE 0x9C4
554#define WM5100_DSP3LMIX_INPUT_3_VOLUME 0x9C5
555#define WM5100_DSP3LMIX_INPUT_4_SOURCE 0x9C6
556#define WM5100_DSP3LMIX_INPUT_4_VOLUME 0x9C7
557#define WM5100_DSP3RMIX_INPUT_1_SOURCE 0x9C8
558#define WM5100_DSP3RMIX_INPUT_1_VOLUME 0x9C9
559#define WM5100_DSP3RMIX_INPUT_2_SOURCE 0x9CA
560#define WM5100_DSP3RMIX_INPUT_2_VOLUME 0x9CB
561#define WM5100_DSP3RMIX_INPUT_3_SOURCE 0x9CC
562#define WM5100_DSP3RMIX_INPUT_3_VOLUME 0x9CD
563#define WM5100_DSP3RMIX_INPUT_4_SOURCE 0x9CE
564#define WM5100_DSP3RMIX_INPUT_4_VOLUME 0x9CF
565#define WM5100_DSP3AUX1MIX_INPUT_1_SOURCE 0x9D0
566#define WM5100_DSP3AUX2MIX_INPUT_1_SOURCE 0x9D8
567#define WM5100_DSP3AUX3MIX_INPUT_1_SOURCE 0x9E0
568#define WM5100_DSP3AUX4MIX_INPUT_1_SOURCE 0x9E8
569#define WM5100_DSP3AUX5MIX_INPUT_1_SOURCE 0x9F0
570#define WM5100_DSP3AUX6MIX_INPUT_1_SOURCE 0x9F8
571#define WM5100_ASRC1LMIX_INPUT_1_SOURCE 0xA80
572#define WM5100_ASRC1RMIX_INPUT_1_SOURCE 0xA88
573#define WM5100_ASRC2LMIX_INPUT_1_SOURCE 0xA90
574#define WM5100_ASRC2RMIX_INPUT_1_SOURCE 0xA98
575#define WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE 0xB00
576#define WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE 0xB08
577#define WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE 0xB10
578#define WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE 0xB18
579#define WM5100_ISRC1INT1MIX_INPUT_1_SOURCE 0xB20
580#define WM5100_ISRC1INT2MIX_INPUT_1_SOURCE 0xB28
581#define WM5100_ISRC1INT3MIX_INPUT_1_SOURCE 0xB30
582#define WM5100_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38
583#define WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40
584#define WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48
585#define WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE 0xB50
586#define WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE 0xB58
587#define WM5100_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60
588#define WM5100_ISRC2INT2MIX_INPUT_1_SOURCE 0xB68
589#define WM5100_ISRC2INT3MIX_INPUT_1_SOURCE 0xB70
590#define WM5100_ISRC2INT4MIX_INPUT_1_SOURCE 0xB78
591#define WM5100_GPIO_CTRL_1 0xC00
592#define WM5100_GPIO_CTRL_2 0xC01
593#define WM5100_GPIO_CTRL_3 0xC02
594#define WM5100_GPIO_CTRL_4 0xC03
595#define WM5100_GPIO_CTRL_5 0xC04
596#define WM5100_GPIO_CTRL_6 0xC05
597#define WM5100_MISC_PAD_CTRL_1 0xC23
598#define WM5100_MISC_PAD_CTRL_2 0xC24
599#define WM5100_MISC_PAD_CTRL_3 0xC25
600#define WM5100_MISC_PAD_CTRL_4 0xC26
601#define WM5100_MISC_PAD_CTRL_5 0xC27
602#define WM5100_MISC_GPIO_1 0xC28
603#define WM5100_INTERRUPT_STATUS_1 0xD00
604#define WM5100_INTERRUPT_STATUS_2 0xD01
605#define WM5100_INTERRUPT_STATUS_3 0xD02
606#define WM5100_INTERRUPT_STATUS_4 0xD03
607#define WM5100_INTERRUPT_RAW_STATUS_2 0xD04
608#define WM5100_INTERRUPT_RAW_STATUS_3 0xD05
609#define WM5100_INTERRUPT_RAW_STATUS_4 0xD06
610#define WM5100_INTERRUPT_STATUS_1_MASK 0xD07
611#define WM5100_INTERRUPT_STATUS_2_MASK 0xD08
612#define WM5100_INTERRUPT_STATUS_3_MASK 0xD09
613#define WM5100_INTERRUPT_STATUS_4_MASK 0xD0A
614#define WM5100_INTERRUPT_CONTROL 0xD1F
615#define WM5100_IRQ_DEBOUNCE_1 0xD20
616#define WM5100_IRQ_DEBOUNCE_2 0xD21
617#define WM5100_FX_CTRL 0xE00
618#define WM5100_EQ1_1 0xE10
619#define WM5100_EQ1_2 0xE11
620#define WM5100_EQ1_3 0xE12
621#define WM5100_EQ1_4 0xE13
622#define WM5100_EQ1_5 0xE14
623#define WM5100_EQ1_6 0xE15
624#define WM5100_EQ1_7 0xE16
625#define WM5100_EQ1_8 0xE17
626#define WM5100_EQ1_9 0xE18
627#define WM5100_EQ1_10 0xE19
628#define WM5100_EQ1_11 0xE1A
629#define WM5100_EQ1_12 0xE1B
630#define WM5100_EQ1_13 0xE1C
631#define WM5100_EQ1_14 0xE1D
632#define WM5100_EQ1_15 0xE1E
633#define WM5100_EQ1_16 0xE1F
634#define WM5100_EQ1_17 0xE20
635#define WM5100_EQ1_18 0xE21
636#define WM5100_EQ1_19 0xE22
637#define WM5100_EQ1_20 0xE23
638#define WM5100_EQ2_1 0xE26
639#define WM5100_EQ2_2 0xE27
640#define WM5100_EQ2_3 0xE28
641#define WM5100_EQ2_4 0xE29
642#define WM5100_EQ2_5 0xE2A
643#define WM5100_EQ2_6 0xE2B
644#define WM5100_EQ2_7 0xE2C
645#define WM5100_EQ2_8 0xE2D
646#define WM5100_EQ2_9 0xE2E
647#define WM5100_EQ2_10 0xE2F
648#define WM5100_EQ2_11 0xE30
649#define WM5100_EQ2_12 0xE31
650#define WM5100_EQ2_13 0xE32
651#define WM5100_EQ2_14 0xE33
652#define WM5100_EQ2_15 0xE34
653#define WM5100_EQ2_16 0xE35
654#define WM5100_EQ2_17 0xE36
655#define WM5100_EQ2_18 0xE37
656#define WM5100_EQ2_19 0xE38
657#define WM5100_EQ2_20 0xE39
658#define WM5100_EQ3_1 0xE3C
659#define WM5100_EQ3_2 0xE3D
660#define WM5100_EQ3_3 0xE3E
661#define WM5100_EQ3_4 0xE3F
662#define WM5100_EQ3_5 0xE40
663#define WM5100_EQ3_6 0xE41
664#define WM5100_EQ3_7 0xE42
665#define WM5100_EQ3_8 0xE43
666#define WM5100_EQ3_9 0xE44
667#define WM5100_EQ3_10 0xE45
668#define WM5100_EQ3_11 0xE46
669#define WM5100_EQ3_12 0xE47
670#define WM5100_EQ3_13 0xE48
671#define WM5100_EQ3_14 0xE49
672#define WM5100_EQ3_15 0xE4A
673#define WM5100_EQ3_16 0xE4B
674#define WM5100_EQ3_17 0xE4C
675#define WM5100_EQ3_18 0xE4D
676#define WM5100_EQ3_19 0xE4E
677#define WM5100_EQ3_20 0xE4F
678#define WM5100_EQ4_1 0xE52
679#define WM5100_EQ4_2 0xE53
680#define WM5100_EQ4_3 0xE54
681#define WM5100_EQ4_4 0xE55
682#define WM5100_EQ4_5 0xE56
683#define WM5100_EQ4_6 0xE57
684#define WM5100_EQ4_7 0xE58
685#define WM5100_EQ4_8 0xE59
686#define WM5100_EQ4_9 0xE5A
687#define WM5100_EQ4_10 0xE5B
688#define WM5100_EQ4_11 0xE5C
689#define WM5100_EQ4_12 0xE5D
690#define WM5100_EQ4_13 0xE5E
691#define WM5100_EQ4_14 0xE5F
692#define WM5100_EQ4_15 0xE60
693#define WM5100_EQ4_16 0xE61
694#define WM5100_EQ4_17 0xE62
695#define WM5100_EQ4_18 0xE63
696#define WM5100_EQ4_19 0xE64
697#define WM5100_EQ4_20 0xE65
698#define WM5100_DRC1_CTRL1 0xE80
699#define WM5100_DRC1_CTRL2 0xE81
700#define WM5100_DRC1_CTRL3 0xE82
701#define WM5100_DRC1_CTRL4 0xE83
702#define WM5100_DRC1_CTRL5 0xE84
703#define WM5100_HPLPF1_1 0xEC0
704#define WM5100_HPLPF1_2 0xEC1
705#define WM5100_HPLPF2_1 0xEC4
706#define WM5100_HPLPF2_2 0xEC5
707#define WM5100_HPLPF3_1 0xEC8
708#define WM5100_HPLPF3_2 0xEC9
709#define WM5100_HPLPF4_1 0xECC
710#define WM5100_HPLPF4_2 0xECD
711#define WM5100_DSP1_DM_0 0x4000
712#define WM5100_DSP1_DM_1 0x4001
713#define WM5100_DSP1_DM_2 0x4002
714#define WM5100_DSP1_DM_3 0x4003
715#define WM5100_DSP1_DM_508 0x41FC
716#define WM5100_DSP1_DM_509 0x41FD
717#define WM5100_DSP1_DM_510 0x41FE
718#define WM5100_DSP1_DM_511 0x41FF
719#define WM5100_DSP1_PM_0 0x4800
720#define WM5100_DSP1_PM_1 0x4801
721#define WM5100_DSP1_PM_2 0x4802
722#define WM5100_DSP1_PM_3 0x4803
723#define WM5100_DSP1_PM_4 0x4804
724#define WM5100_DSP1_PM_5 0x4805
725#define WM5100_DSP1_PM_1530 0x4DFA
726#define WM5100_DSP1_PM_1531 0x4DFB
727#define WM5100_DSP1_PM_1532 0x4DFC
728#define WM5100_DSP1_PM_1533 0x4DFD
729#define WM5100_DSP1_PM_1534 0x4DFE
730#define WM5100_DSP1_PM_1535 0x4DFF
731#define WM5100_DSP1_ZM_0 0x5000
732#define WM5100_DSP1_ZM_1 0x5001
733#define WM5100_DSP1_ZM_2 0x5002
734#define WM5100_DSP1_ZM_3 0x5003
735#define WM5100_DSP1_ZM_2044 0x57FC
736#define WM5100_DSP1_ZM_2045 0x57FD
737#define WM5100_DSP1_ZM_2046 0x57FE
738#define WM5100_DSP1_ZM_2047 0x57FF
739#define WM5100_DSP2_DM_0 0x6000
740#define WM5100_DSP2_DM_1 0x6001
741#define WM5100_DSP2_DM_2 0x6002
742#define WM5100_DSP2_DM_3 0x6003
743#define WM5100_DSP2_DM_508 0x61FC
744#define WM5100_DSP2_DM_509 0x61FD
745#define WM5100_DSP2_DM_510 0x61FE
746#define WM5100_DSP2_DM_511 0x61FF
747#define WM5100_DSP2_PM_0 0x6800
748#define WM5100_DSP2_PM_1 0x6801
749#define WM5100_DSP2_PM_2 0x6802
750#define WM5100_DSP2_PM_3 0x6803
751#define WM5100_DSP2_PM_4 0x6804
752#define WM5100_DSP2_PM_5 0x6805
753#define WM5100_DSP2_PM_1530 0x6DFA
754#define WM5100_DSP2_PM_1531 0x6DFB
755#define WM5100_DSP2_PM_1532 0x6DFC
756#define WM5100_DSP2_PM_1533 0x6DFD
757#define WM5100_DSP2_PM_1534 0x6DFE
758#define WM5100_DSP2_PM_1535 0x6DFF
759#define WM5100_DSP2_ZM_0 0x7000
760#define WM5100_DSP2_ZM_1 0x7001
761#define WM5100_DSP2_ZM_2 0x7002
762#define WM5100_DSP2_ZM_3 0x7003
763#define WM5100_DSP2_ZM_2044 0x77FC
764#define WM5100_DSP2_ZM_2045 0x77FD
765#define WM5100_DSP2_ZM_2046 0x77FE
766#define WM5100_DSP2_ZM_2047 0x77FF
767#define WM5100_DSP3_DM_0 0x8000
768#define WM5100_DSP3_DM_1 0x8001
769#define WM5100_DSP3_DM_2 0x8002
770#define WM5100_DSP3_DM_3 0x8003
771#define WM5100_DSP3_DM_508 0x81FC
772#define WM5100_DSP3_DM_509 0x81FD
773#define WM5100_DSP3_DM_510 0x81FE
774#define WM5100_DSP3_DM_511 0x81FF
775#define WM5100_DSP3_PM_0 0x8800
776#define WM5100_DSP3_PM_1 0x8801
777#define WM5100_DSP3_PM_2 0x8802
778#define WM5100_DSP3_PM_3 0x8803
779#define WM5100_DSP3_PM_4 0x8804
780#define WM5100_DSP3_PM_5 0x8805
781#define WM5100_DSP3_PM_1530 0x8DFA
782#define WM5100_DSP3_PM_1531 0x8DFB
783#define WM5100_DSP3_PM_1532 0x8DFC
784#define WM5100_DSP3_PM_1533 0x8DFD
785#define WM5100_DSP3_PM_1534 0x8DFE
786#define WM5100_DSP3_PM_1535 0x8DFF
787#define WM5100_DSP3_ZM_0 0x9000
788#define WM5100_DSP3_ZM_1 0x9001
789#define WM5100_DSP3_ZM_2 0x9002
790#define WM5100_DSP3_ZM_3 0x9003
791#define WM5100_DSP3_ZM_2044 0x97FC
792#define WM5100_DSP3_ZM_2045 0x97FD
793#define WM5100_DSP3_ZM_2046 0x97FE
794#define WM5100_DSP3_ZM_2047 0x97FF
795
796#define WM5100_REGISTER_COUNT 1435
797#define WM5100_MAX_REGISTER 0x97FF
798
799/*
800 * Field Definitions.
801 */
802
803/*
804 * R0 (0x00) - software reset
805 */
806#define WM5100_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
807#define WM5100_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
808#define WM5100_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
809
810/*
811 * R1 (0x01) - Device Revision
812 */
813#define WM5100_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
814#define WM5100_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
815#define WM5100_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
816
817/*
818 * R16 (0x10) - Ctrl IF 1
819 */
820#define WM5100_AUTO_INC 0x0001 /* AUTO_INC */
821#define WM5100_AUTO_INC_MASK 0x0001 /* AUTO_INC */
822#define WM5100_AUTO_INC_SHIFT 0 /* AUTO_INC */
823#define WM5100_AUTO_INC_WIDTH 1 /* AUTO_INC */
824
825/*
826 * R32 (0x20) - Tone Generator 1
827 */
828#define WM5100_TONE_RATE_MASK 0x3000 /* TONE_RATE - [13:12] */
829#define WM5100_TONE_RATE_SHIFT 12 /* TONE_RATE - [13:12] */
830#define WM5100_TONE_RATE_WIDTH 2 /* TONE_RATE - [13:12] */
831#define WM5100_TONE_OFFSET_MASK 0x0300 /* TONE_OFFSET - [9:8] */
832#define WM5100_TONE_OFFSET_SHIFT 8 /* TONE_OFFSET - [9:8] */
833#define WM5100_TONE_OFFSET_WIDTH 2 /* TONE_OFFSET - [9:8] */
834#define WM5100_TONE2_ENA 0x0002 /* TONE2_ENA */
835#define WM5100_TONE2_ENA_MASK 0x0002 /* TONE2_ENA */
836#define WM5100_TONE2_ENA_SHIFT 1 /* TONE2_ENA */
837#define WM5100_TONE2_ENA_WIDTH 1 /* TONE2_ENA */
838#define WM5100_TONE1_ENA 0x0001 /* TONE1_ENA */
839#define WM5100_TONE1_ENA_MASK 0x0001 /* TONE1_ENA */
840#define WM5100_TONE1_ENA_SHIFT 0 /* TONE1_ENA */
841#define WM5100_TONE1_ENA_WIDTH 1 /* TONE1_ENA */
842
843/*
844 * R48 (0x30) - PWM Drive 1
845 */
846#define WM5100_PWM_RATE_MASK 0x3000 /* PWM_RATE - [13:12] */
847#define WM5100_PWM_RATE_SHIFT 12 /* PWM_RATE - [13:12] */
848#define WM5100_PWM_RATE_WIDTH 2 /* PWM_RATE - [13:12] */
849#define WM5100_PWM_CLK_SEL_MASK 0x0300 /* PWM_CLK_SEL - [9:8] */
850#define WM5100_PWM_CLK_SEL_SHIFT 8 /* PWM_CLK_SEL - [9:8] */
851#define WM5100_PWM_CLK_SEL_WIDTH 2 /* PWM_CLK_SEL - [9:8] */
852#define WM5100_PWM2_OVD 0x0020 /* PWM2_OVD */
853#define WM5100_PWM2_OVD_MASK 0x0020 /* PWM2_OVD */
854#define WM5100_PWM2_OVD_SHIFT 5 /* PWM2_OVD */
855#define WM5100_PWM2_OVD_WIDTH 1 /* PWM2_OVD */
856#define WM5100_PWM1_OVD 0x0010 /* PWM1_OVD */
857#define WM5100_PWM1_OVD_MASK 0x0010 /* PWM1_OVD */
858#define WM5100_PWM1_OVD_SHIFT 4 /* PWM1_OVD */
859#define WM5100_PWM1_OVD_WIDTH 1 /* PWM1_OVD */
860#define WM5100_PWM2_ENA 0x0002 /* PWM2_ENA */
861#define WM5100_PWM2_ENA_MASK 0x0002 /* PWM2_ENA */
862#define WM5100_PWM2_ENA_SHIFT 1 /* PWM2_ENA */
863#define WM5100_PWM2_ENA_WIDTH 1 /* PWM2_ENA */
864#define WM5100_PWM1_ENA 0x0001 /* PWM1_ENA */
865#define WM5100_PWM1_ENA_MASK 0x0001 /* PWM1_ENA */
866#define WM5100_PWM1_ENA_SHIFT 0 /* PWM1_ENA */
867#define WM5100_PWM1_ENA_WIDTH 1 /* PWM1_ENA */
868
869/*
870 * R49 (0x31) - PWM Drive 2
871 */
872#define WM5100_PWM1_LVL_MASK 0x03FF /* PWM1_LVL - [9:0] */
873#define WM5100_PWM1_LVL_SHIFT 0 /* PWM1_LVL - [9:0] */
874#define WM5100_PWM1_LVL_WIDTH 10 /* PWM1_LVL - [9:0] */
875
876/*
877 * R50 (0x32) - PWM Drive 3
878 */
879#define WM5100_PWM2_LVL_MASK 0x03FF /* PWM2_LVL - [9:0] */
880#define WM5100_PWM2_LVL_SHIFT 0 /* PWM2_LVL - [9:0] */
881#define WM5100_PWM2_LVL_WIDTH 10 /* PWM2_LVL - [9:0] */
882
883/*
884 * R256 (0x100) - Clocking 1
885 */
886#define WM5100_CLK_32K_SRC_MASK 0x000F /* CLK_32K_SRC - [3:0] */
887#define WM5100_CLK_32K_SRC_SHIFT 0 /* CLK_32K_SRC - [3:0] */
888#define WM5100_CLK_32K_SRC_WIDTH 4 /* CLK_32K_SRC - [3:0] */
889
890/*
891 * R257 (0x101) - Clocking 3
892 */
893#define WM5100_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
894#define WM5100_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
895#define WM5100_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
896#define WM5100_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
897#define WM5100_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
898#define WM5100_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
899#define WM5100_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
900#define WM5100_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
901#define WM5100_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
902#define WM5100_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
903
904/*
905 * R258 (0x102) - Clocking 4
906 */
907#define WM5100_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
908#define WM5100_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
909#define WM5100_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
910
911/*
912 * R259 (0x103) - Clocking 5
913 */
914#define WM5100_SAMPLE_RATE_2_MASK 0x001F /* SAMPLE_RATE_2 - [4:0] */
915#define WM5100_SAMPLE_RATE_2_SHIFT 0 /* SAMPLE_RATE_2 - [4:0] */
916#define WM5100_SAMPLE_RATE_2_WIDTH 5 /* SAMPLE_RATE_2 - [4:0] */
917
918/*
919 * R260 (0x104) - Clocking 6
920 */
921#define WM5100_SAMPLE_RATE_3_MASK 0x001F /* SAMPLE_RATE_3 - [4:0] */
922#define WM5100_SAMPLE_RATE_3_SHIFT 0 /* SAMPLE_RATE_3 - [4:0] */
923#define WM5100_SAMPLE_RATE_3_WIDTH 5 /* SAMPLE_RATE_3 - [4:0] */
924
925/*
926 * R263 (0x107) - Clocking 7
927 */
928#define WM5100_ASYNC_CLK_FREQ_MASK 0x0700 /* ASYNC_CLK_FREQ - [10:8] */
929#define WM5100_ASYNC_CLK_FREQ_SHIFT 8 /* ASYNC_CLK_FREQ - [10:8] */
930#define WM5100_ASYNC_CLK_FREQ_WIDTH 3 /* ASYNC_CLK_FREQ - [10:8] */
931#define WM5100_ASYNC_CLK_ENA 0x0040 /* ASYNC_CLK_ENA */
932#define WM5100_ASYNC_CLK_ENA_MASK 0x0040 /* ASYNC_CLK_ENA */
933#define WM5100_ASYNC_CLK_ENA_SHIFT 6 /* ASYNC_CLK_ENA */
934#define WM5100_ASYNC_CLK_ENA_WIDTH 1 /* ASYNC_CLK_ENA */
935#define WM5100_ASYNC_CLK_SRC_MASK 0x000F /* ASYNC_CLK_SRC - [3:0] */
936#define WM5100_ASYNC_CLK_SRC_SHIFT 0 /* ASYNC_CLK_SRC - [3:0] */
937#define WM5100_ASYNC_CLK_SRC_WIDTH 4 /* ASYNC_CLK_SRC - [3:0] */
938
939/*
940 * R264 (0x108) - Clocking 8
941 */
942#define WM5100_ASYNC_SAMPLE_RATE_MASK 0x001F /* ASYNC_SAMPLE_RATE - [4:0] */
943#define WM5100_ASYNC_SAMPLE_RATE_SHIFT 0 /* ASYNC_SAMPLE_RATE - [4:0] */
944#define WM5100_ASYNC_SAMPLE_RATE_WIDTH 5 /* ASYNC_SAMPLE_RATE - [4:0] */
945
946/*
947 * R288 (0x120) - ASRC_ENABLE
948 */
949#define WM5100_ASRC2L_ENA 0x0008 /* ASRC2L_ENA */
950#define WM5100_ASRC2L_ENA_MASK 0x0008 /* ASRC2L_ENA */
951#define WM5100_ASRC2L_ENA_SHIFT 3 /* ASRC2L_ENA */
952#define WM5100_ASRC2L_ENA_WIDTH 1 /* ASRC2L_ENA */
953#define WM5100_ASRC2R_ENA 0x0004 /* ASRC2R_ENA */
954#define WM5100_ASRC2R_ENA_MASK 0x0004 /* ASRC2R_ENA */
955#define WM5100_ASRC2R_ENA_SHIFT 2 /* ASRC2R_ENA */
956#define WM5100_ASRC2R_ENA_WIDTH 1 /* ASRC2R_ENA */
957#define WM5100_ASRC1L_ENA 0x0002 /* ASRC1L_ENA */
958#define WM5100_ASRC1L_ENA_MASK 0x0002 /* ASRC1L_ENA */
959#define WM5100_ASRC1L_ENA_SHIFT 1 /* ASRC1L_ENA */
960#define WM5100_ASRC1L_ENA_WIDTH 1 /* ASRC1L_ENA */
961#define WM5100_ASRC1R_ENA 0x0001 /* ASRC1R_ENA */
962#define WM5100_ASRC1R_ENA_MASK 0x0001 /* ASRC1R_ENA */
963#define WM5100_ASRC1R_ENA_SHIFT 0 /* ASRC1R_ENA */
964#define WM5100_ASRC1R_ENA_WIDTH 1 /* ASRC1R_ENA */
965
966/*
967 * R289 (0x121) - ASRC_STATUS
968 */
969#define WM5100_ASRC2L_ENA_STS 0x0008 /* ASRC2L_ENA_STS */
970#define WM5100_ASRC2L_ENA_STS_MASK 0x0008 /* ASRC2L_ENA_STS */
971#define WM5100_ASRC2L_ENA_STS_SHIFT 3 /* ASRC2L_ENA_STS */
972#define WM5100_ASRC2L_ENA_STS_WIDTH 1 /* ASRC2L_ENA_STS */
973#define WM5100_ASRC2R_ENA_STS 0x0004 /* ASRC2R_ENA_STS */
974#define WM5100_ASRC2R_ENA_STS_MASK 0x0004 /* ASRC2R_ENA_STS */
975#define WM5100_ASRC2R_ENA_STS_SHIFT 2 /* ASRC2R_ENA_STS */
976#define WM5100_ASRC2R_ENA_STS_WIDTH 1 /* ASRC2R_ENA_STS */
977#define WM5100_ASRC1L_ENA_STS 0x0002 /* ASRC1L_ENA_STS */
978#define WM5100_ASRC1L_ENA_STS_MASK 0x0002 /* ASRC1L_ENA_STS */
979#define WM5100_ASRC1L_ENA_STS_SHIFT 1 /* ASRC1L_ENA_STS */
980#define WM5100_ASRC1L_ENA_STS_WIDTH 1 /* ASRC1L_ENA_STS */
981#define WM5100_ASRC1R_ENA_STS 0x0001 /* ASRC1R_ENA_STS */
982#define WM5100_ASRC1R_ENA_STS_MASK 0x0001 /* ASRC1R_ENA_STS */
983#define WM5100_ASRC1R_ENA_STS_SHIFT 0 /* ASRC1R_ENA_STS */
984#define WM5100_ASRC1R_ENA_STS_WIDTH 1 /* ASRC1R_ENA_STS */
985
986/*
987 * R290 (0x122) - ASRC_RATE1
988 */
989#define WM5100_ASRC_RATE1_MASK 0x0006 /* ASRC_RATE1 - [2:1] */
990#define WM5100_ASRC_RATE1_SHIFT 1 /* ASRC_RATE1 - [2:1] */
991#define WM5100_ASRC_RATE1_WIDTH 2 /* ASRC_RATE1 - [2:1] */
992
993/*
994 * R321 (0x141) - ISRC 1 CTRL 1
995 */
996#define WM5100_ISRC1_DFS_ENA 0x2000 /* ISRC1_DFS_ENA */
997#define WM5100_ISRC1_DFS_ENA_MASK 0x2000 /* ISRC1_DFS_ENA */
998#define WM5100_ISRC1_DFS_ENA_SHIFT 13 /* ISRC1_DFS_ENA */
999#define WM5100_ISRC1_DFS_ENA_WIDTH 1 /* ISRC1_DFS_ENA */
1000#define WM5100_ISRC1_CLK_SEL_MASK 0x0300 /* ISRC1_CLK_SEL - [9:8] */
1001#define WM5100_ISRC1_CLK_SEL_SHIFT 8 /* ISRC1_CLK_SEL - [9:8] */
1002#define WM5100_ISRC1_CLK_SEL_WIDTH 2 /* ISRC1_CLK_SEL - [9:8] */
1003#define WM5100_ISRC1_FSH_MASK 0x000C /* ISRC1_FSH - [3:2] */
1004#define WM5100_ISRC1_FSH_SHIFT 2 /* ISRC1_FSH - [3:2] */
1005#define WM5100_ISRC1_FSH_WIDTH 2 /* ISRC1_FSH - [3:2] */
1006#define WM5100_ISRC1_FSL_MASK 0x0003 /* ISRC1_FSL - [1:0] */
1007#define WM5100_ISRC1_FSL_SHIFT 0 /* ISRC1_FSL - [1:0] */
1008#define WM5100_ISRC1_FSL_WIDTH 2 /* ISRC1_FSL - [1:0] */
1009
1010/*
1011 * R322 (0x142) - ISRC 1 CTRL 2
1012 */
1013#define WM5100_ISRC1_INT1_ENA 0x8000 /* ISRC1_INT1_ENA */
1014#define WM5100_ISRC1_INT1_ENA_MASK 0x8000 /* ISRC1_INT1_ENA */
1015#define WM5100_ISRC1_INT1_ENA_SHIFT 15 /* ISRC1_INT1_ENA */
1016#define WM5100_ISRC1_INT1_ENA_WIDTH 1 /* ISRC1_INT1_ENA */
1017#define WM5100_ISRC1_INT2_ENA 0x4000 /* ISRC1_INT2_ENA */
1018#define WM5100_ISRC1_INT2_ENA_MASK 0x4000 /* ISRC1_INT2_ENA */
1019#define WM5100_ISRC1_INT2_ENA_SHIFT 14 /* ISRC1_INT2_ENA */
1020#define WM5100_ISRC1_INT2_ENA_WIDTH 1 /* ISRC1_INT2_ENA */
1021#define WM5100_ISRC1_INT3_ENA 0x2000 /* ISRC1_INT3_ENA */
1022#define WM5100_ISRC1_INT3_ENA_MASK 0x2000 /* ISRC1_INT3_ENA */
1023#define WM5100_ISRC1_INT3_ENA_SHIFT 13 /* ISRC1_INT3_ENA */
1024#define WM5100_ISRC1_INT3_ENA_WIDTH 1 /* ISRC1_INT3_ENA */
1025#define WM5100_ISRC1_INT4_ENA 0x1000 /* ISRC1_INT4_ENA */
1026#define WM5100_ISRC1_INT4_ENA_MASK 0x1000 /* ISRC1_INT4_ENA */
1027#define WM5100_ISRC1_INT4_ENA_SHIFT 12 /* ISRC1_INT4_ENA */
1028#define WM5100_ISRC1_INT4_ENA_WIDTH 1 /* ISRC1_INT4_ENA */
1029#define WM5100_ISRC1_DEC1_ENA 0x0200 /* ISRC1_DEC1_ENA */
1030#define WM5100_ISRC1_DEC1_ENA_MASK 0x0200 /* ISRC1_DEC1_ENA */
1031#define WM5100_ISRC1_DEC1_ENA_SHIFT 9 /* ISRC1_DEC1_ENA */
1032#define WM5100_ISRC1_DEC1_ENA_WIDTH 1 /* ISRC1_DEC1_ENA */
1033#define WM5100_ISRC1_DEC2_ENA 0x0100 /* ISRC1_DEC2_ENA */
1034#define WM5100_ISRC1_DEC2_ENA_MASK 0x0100 /* ISRC1_DEC2_ENA */
1035#define WM5100_ISRC1_DEC2_ENA_SHIFT 8 /* ISRC1_DEC2_ENA */
1036#define WM5100_ISRC1_DEC2_ENA_WIDTH 1 /* ISRC1_DEC2_ENA */
1037#define WM5100_ISRC1_DEC3_ENA 0x0080 /* ISRC1_DEC3_ENA */
1038#define WM5100_ISRC1_DEC3_ENA_MASK 0x0080 /* ISRC1_DEC3_ENA */
1039#define WM5100_ISRC1_DEC3_ENA_SHIFT 7 /* ISRC1_DEC3_ENA */
1040#define WM5100_ISRC1_DEC3_ENA_WIDTH 1 /* ISRC1_DEC3_ENA */
1041#define WM5100_ISRC1_DEC4_ENA 0x0040 /* ISRC1_DEC4_ENA */
1042#define WM5100_ISRC1_DEC4_ENA_MASK 0x0040 /* ISRC1_DEC4_ENA */
1043#define WM5100_ISRC1_DEC4_ENA_SHIFT 6 /* ISRC1_DEC4_ENA */
1044#define WM5100_ISRC1_DEC4_ENA_WIDTH 1 /* ISRC1_DEC4_ENA */
1045#define WM5100_ISRC1_NOTCH_ENA 0x0001 /* ISRC1_NOTCH_ENA */
1046#define WM5100_ISRC1_NOTCH_ENA_MASK 0x0001 /* ISRC1_NOTCH_ENA */
1047#define WM5100_ISRC1_NOTCH_ENA_SHIFT 0 /* ISRC1_NOTCH_ENA */
1048#define WM5100_ISRC1_NOTCH_ENA_WIDTH 1 /* ISRC1_NOTCH_ENA */
1049
1050/*
1051 * R323 (0x143) - ISRC 2 CTRL1
1052 */
1053#define WM5100_ISRC2_DFS_ENA 0x2000 /* ISRC2_DFS_ENA */
1054#define WM5100_ISRC2_DFS_ENA_MASK 0x2000 /* ISRC2_DFS_ENA */
1055#define WM5100_ISRC2_DFS_ENA_SHIFT 13 /* ISRC2_DFS_ENA */
1056#define WM5100_ISRC2_DFS_ENA_WIDTH 1 /* ISRC2_DFS_ENA */
1057#define WM5100_ISRC2_CLK_SEL_MASK 0x0300 /* ISRC2_CLK_SEL - [9:8] */
1058#define WM5100_ISRC2_CLK_SEL_SHIFT 8 /* ISRC2_CLK_SEL - [9:8] */
1059#define WM5100_ISRC2_CLK_SEL_WIDTH 2 /* ISRC2_CLK_SEL - [9:8] */
1060#define WM5100_ISRC2_FSH_MASK 0x000C /* ISRC2_FSH - [3:2] */
1061#define WM5100_ISRC2_FSH_SHIFT 2 /* ISRC2_FSH - [3:2] */
1062#define WM5100_ISRC2_FSH_WIDTH 2 /* ISRC2_FSH - [3:2] */
1063#define WM5100_ISRC2_FSL_MASK 0x0003 /* ISRC2_FSL - [1:0] */
1064#define WM5100_ISRC2_FSL_SHIFT 0 /* ISRC2_FSL - [1:0] */
1065#define WM5100_ISRC2_FSL_WIDTH 2 /* ISRC2_FSL - [1:0] */
1066
1067/*
1068 * R324 (0x144) - ISRC 2 CTRL 2
1069 */
1070#define WM5100_ISRC2_INT1_ENA 0x8000 /* ISRC2_INT1_ENA */
1071#define WM5100_ISRC2_INT1_ENA_MASK 0x8000 /* ISRC2_INT1_ENA */
1072#define WM5100_ISRC2_INT1_ENA_SHIFT 15 /* ISRC2_INT1_ENA */
1073#define WM5100_ISRC2_INT1_ENA_WIDTH 1 /* ISRC2_INT1_ENA */
1074#define WM5100_ISRC2_INT2_ENA 0x4000 /* ISRC2_INT2_ENA */
1075#define WM5100_ISRC2_INT2_ENA_MASK 0x4000 /* ISRC2_INT2_ENA */
1076#define WM5100_ISRC2_INT2_ENA_SHIFT 14 /* ISRC2_INT2_ENA */
1077#define WM5100_ISRC2_INT2_ENA_WIDTH 1 /* ISRC2_INT2_ENA */
1078#define WM5100_ISRC2_INT3_ENA 0x2000 /* ISRC2_INT3_ENA */
1079#define WM5100_ISRC2_INT3_ENA_MASK 0x2000 /* ISRC2_INT3_ENA */
1080#define WM5100_ISRC2_INT3_ENA_SHIFT 13 /* ISRC2_INT3_ENA */
1081#define WM5100_ISRC2_INT3_ENA_WIDTH 1 /* ISRC2_INT3_ENA */
1082#define WM5100_ISRC2_INT4_ENA 0x1000 /* ISRC2_INT4_ENA */
1083#define WM5100_ISRC2_INT4_ENA_MASK 0x1000 /* ISRC2_INT4_ENA */
1084#define WM5100_ISRC2_INT4_ENA_SHIFT 12 /* ISRC2_INT4_ENA */
1085#define WM5100_ISRC2_INT4_ENA_WIDTH 1 /* ISRC2_INT4_ENA */
1086#define WM5100_ISRC2_DEC1_ENA 0x0200 /* ISRC2_DEC1_ENA */
1087#define WM5100_ISRC2_DEC1_ENA_MASK 0x0200 /* ISRC2_DEC1_ENA */
1088#define WM5100_ISRC2_DEC1_ENA_SHIFT 9 /* ISRC2_DEC1_ENA */
1089#define WM5100_ISRC2_DEC1_ENA_WIDTH 1 /* ISRC2_DEC1_ENA */
1090#define WM5100_ISRC2_DEC2_ENA 0x0100 /* ISRC2_DEC2_ENA */
1091#define WM5100_ISRC2_DEC2_ENA_MASK 0x0100 /* ISRC2_DEC2_ENA */
1092#define WM5100_ISRC2_DEC2_ENA_SHIFT 8 /* ISRC2_DEC2_ENA */
1093#define WM5100_ISRC2_DEC2_ENA_WIDTH 1 /* ISRC2_DEC2_ENA */
1094#define WM5100_ISRC2_DEC3_ENA 0x0080 /* ISRC2_DEC3_ENA */
1095#define WM5100_ISRC2_DEC3_ENA_MASK 0x0080 /* ISRC2_DEC3_ENA */
1096#define WM5100_ISRC2_DEC3_ENA_SHIFT 7 /* ISRC2_DEC3_ENA */
1097#define WM5100_ISRC2_DEC3_ENA_WIDTH 1 /* ISRC2_DEC3_ENA */
1098#define WM5100_ISRC2_DEC4_ENA 0x0040 /* ISRC2_DEC4_ENA */
1099#define WM5100_ISRC2_DEC4_ENA_MASK 0x0040 /* ISRC2_DEC4_ENA */
1100#define WM5100_ISRC2_DEC4_ENA_SHIFT 6 /* ISRC2_DEC4_ENA */
1101#define WM5100_ISRC2_DEC4_ENA_WIDTH 1 /* ISRC2_DEC4_ENA */
1102#define WM5100_ISRC2_NOTCH_ENA 0x0001 /* ISRC2_NOTCH_ENA */
1103#define WM5100_ISRC2_NOTCH_ENA_MASK 0x0001 /* ISRC2_NOTCH_ENA */
1104#define WM5100_ISRC2_NOTCH_ENA_SHIFT 0 /* ISRC2_NOTCH_ENA */
1105#define WM5100_ISRC2_NOTCH_ENA_WIDTH 1 /* ISRC2_NOTCH_ENA */
1106
1107/*
1108 * R386 (0x182) - FLL1 Control 1
1109 */
1110#define WM5100_FLL1_ENA 0x0001 /* FLL1_ENA */
1111#define WM5100_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
1112#define WM5100_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
1113#define WM5100_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
1114
1115/*
1116 * R387 (0x183) - FLL1 Control 2
1117 */
1118#define WM5100_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
1119#define WM5100_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
1120#define WM5100_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
1121#define WM5100_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
1122#define WM5100_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
1123#define WM5100_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
1124
1125/*
1126 * R388 (0x184) - FLL1 Control 3
1127 */
1128#define WM5100_FLL1_THETA_MASK 0xFFFF /* FLL1_THETA - [15:0] */
1129#define WM5100_FLL1_THETA_SHIFT 0 /* FLL1_THETA - [15:0] */
1130#define WM5100_FLL1_THETA_WIDTH 16 /* FLL1_THETA - [15:0] */
1131
1132/*
1133 * R390 (0x186) - FLL1 Control 5
1134 */
1135#define WM5100_FLL1_N_MASK 0x03FF /* FLL1_N - [9:0] */
1136#define WM5100_FLL1_N_SHIFT 0 /* FLL1_N - [9:0] */
1137#define WM5100_FLL1_N_WIDTH 10 /* FLL1_N - [9:0] */
1138
1139/*
1140 * R391 (0x187) - FLL1 Control 6
1141 */
1142#define WM5100_FLL1_REFCLK_DIV_MASK 0x00C0 /* FLL1_REFCLK_DIV - [7:6] */
1143#define WM5100_FLL1_REFCLK_DIV_SHIFT 6 /* FLL1_REFCLK_DIV - [7:6] */
1144#define WM5100_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [7:6] */
1145#define WM5100_FLL1_REFCLK_SRC_MASK 0x000F /* FLL1_REFCLK_SRC - [3:0] */
1146#define WM5100_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [3:0] */
1147#define WM5100_FLL1_REFCLK_SRC_WIDTH 4 /* FLL1_REFCLK_SRC - [3:0] */
1148
1149/*
1150 * R392 (0x188) - FLL1 EFS 1
1151 */
1152#define WM5100_FLL1_LAMBDA_MASK 0xFFFF /* FLL1_LAMBDA - [15:0] */
1153#define WM5100_FLL1_LAMBDA_SHIFT 0 /* FLL1_LAMBDA - [15:0] */
1154#define WM5100_FLL1_LAMBDA_WIDTH 16 /* FLL1_LAMBDA - [15:0] */
1155
1156/*
1157 * R418 (0x1A2) - FLL2 Control 1
1158 */
1159#define WM5100_FLL2_ENA 0x0001 /* FLL2_ENA */
1160#define WM5100_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
1161#define WM5100_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
1162#define WM5100_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
1163
1164/*
1165 * R419 (0x1A3) - FLL2 Control 2
1166 */
1167#define WM5100_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
1168#define WM5100_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
1169#define WM5100_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
1170#define WM5100_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
1171#define WM5100_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
1172#define WM5100_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
1173
1174/*
1175 * R420 (0x1A4) - FLL2 Control 3
1176 */
1177#define WM5100_FLL2_THETA_MASK 0xFFFF /* FLL2_THETA - [15:0] */
1178#define WM5100_FLL2_THETA_SHIFT 0 /* FLL2_THETA - [15:0] */
1179#define WM5100_FLL2_THETA_WIDTH 16 /* FLL2_THETA - [15:0] */
1180
1181/*
1182 * R422 (0x1A6) - FLL2 Control 5
1183 */
1184#define WM5100_FLL2_N_MASK 0x03FF /* FLL2_N - [9:0] */
1185#define WM5100_FLL2_N_SHIFT 0 /* FLL2_N - [9:0] */
1186#define WM5100_FLL2_N_WIDTH 10 /* FLL2_N - [9:0] */
1187
1188/*
1189 * R423 (0x1A7) - FLL2 Control 6
1190 */
1191#define WM5100_FLL2_REFCLK_DIV_MASK 0x00C0 /* FLL2_REFCLK_DIV - [7:6] */
1192#define WM5100_FLL2_REFCLK_DIV_SHIFT 6 /* FLL2_REFCLK_DIV - [7:6] */
1193#define WM5100_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [7:6] */
1194#define WM5100_FLL2_REFCLK_SRC_MASK 0x000F /* FLL2_REFCLK_SRC - [3:0] */
1195#define WM5100_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [3:0] */
1196#define WM5100_FLL2_REFCLK_SRC_WIDTH 4 /* FLL2_REFCLK_SRC - [3:0] */
1197
1198/*
1199 * R424 (0x1A8) - FLL2 EFS 1
1200 */
1201#define WM5100_FLL2_LAMBDA_MASK 0xFFFF /* FLL2_LAMBDA - [15:0] */
1202#define WM5100_FLL2_LAMBDA_SHIFT 0 /* FLL2_LAMBDA - [15:0] */
1203#define WM5100_FLL2_LAMBDA_WIDTH 16 /* FLL2_LAMBDA - [15:0] */
1204
1205/*
1206 * R512 (0x200) - Mic Charge Pump 1
1207 */
1208#define WM5100_CP2_BYPASS 0x0020 /* CP2_BYPASS */
1209#define WM5100_CP2_BYPASS_MASK 0x0020 /* CP2_BYPASS */
1210#define WM5100_CP2_BYPASS_SHIFT 5 /* CP2_BYPASS */
1211#define WM5100_CP2_BYPASS_WIDTH 1 /* CP2_BYPASS */
1212#define WM5100_CP2_ENA 0x0001 /* CP2_ENA */
1213#define WM5100_CP2_ENA_MASK 0x0001 /* CP2_ENA */
1214#define WM5100_CP2_ENA_SHIFT 0 /* CP2_ENA */
1215#define WM5100_CP2_ENA_WIDTH 1 /* CP2_ENA */
1216
1217/*
1218 * R513 (0x201) - Mic Charge Pump 2
1219 */
1220#define WM5100_LDO2_VSEL_MASK 0xF800 /* LDO2_VSEL - [15:11] */
1221#define WM5100_LDO2_VSEL_SHIFT 11 /* LDO2_VSEL - [15:11] */
1222#define WM5100_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [15:11] */
1223
1224/*
1225 * R514 (0x202) - HP Charge Pump 1
1226 */
1227#define WM5100_CP1_ENA 0x0001 /* CP1_ENA */
1228#define WM5100_CP1_ENA_MASK 0x0001 /* CP1_ENA */
1229#define WM5100_CP1_ENA_SHIFT 0 /* CP1_ENA */
1230#define WM5100_CP1_ENA_WIDTH 1 /* CP1_ENA */
1231
1232/*
1233 * R529 (0x211) - LDO1 Control
1234 */
1235#define WM5100_LDO1_BYPASS 0x0002 /* LDO1_BYPASS */
1236#define WM5100_LDO1_BYPASS_MASK 0x0002 /* LDO1_BYPASS */
1237#define WM5100_LDO1_BYPASS_SHIFT 1 /* LDO1_BYPASS */
1238#define WM5100_LDO1_BYPASS_WIDTH 1 /* LDO1_BYPASS */
1239
1240/*
1241 * R533 (0x215) - Mic Bias Ctrl 1
1242 */
1243#define WM5100_MICB1_DISCH 0x0040 /* MICB1_DISCH */
1244#define WM5100_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
1245#define WM5100_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
1246#define WM5100_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1247#define WM5100_MICB1_RATE 0x0020 /* MICB1_RATE */
1248#define WM5100_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1249#define WM5100_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1250#define WM5100_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1251#define WM5100_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
1252#define WM5100_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
1253#define WM5100_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
1254#define WM5100_MICB1_BYPASS 0x0002 /* MICB1_BYPASS */
1255#define WM5100_MICB1_BYPASS_MASK 0x0002 /* MICB1_BYPASS */
1256#define WM5100_MICB1_BYPASS_SHIFT 1 /* MICB1_BYPASS */
1257#define WM5100_MICB1_BYPASS_WIDTH 1 /* MICB1_BYPASS */
1258#define WM5100_MICB1_ENA 0x0001 /* MICB1_ENA */
1259#define WM5100_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
1260#define WM5100_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
1261#define WM5100_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
1262
1263/*
1264 * R534 (0x216) - Mic Bias Ctrl 2
1265 */
1266#define WM5100_MICB2_DISCH 0x0040 /* MICB2_DISCH */
1267#define WM5100_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
1268#define WM5100_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
1269#define WM5100_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1270#define WM5100_MICB2_RATE 0x0020 /* MICB2_RATE */
1271#define WM5100_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1272#define WM5100_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1273#define WM5100_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1274#define WM5100_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
1275#define WM5100_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
1276#define WM5100_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
1277#define WM5100_MICB2_BYPASS 0x0002 /* MICB2_BYPASS */
1278#define WM5100_MICB2_BYPASS_MASK 0x0002 /* MICB2_BYPASS */
1279#define WM5100_MICB2_BYPASS_SHIFT 1 /* MICB2_BYPASS */
1280#define WM5100_MICB2_BYPASS_WIDTH 1 /* MICB2_BYPASS */
1281#define WM5100_MICB2_ENA 0x0001 /* MICB2_ENA */
1282#define WM5100_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
1283#define WM5100_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
1284#define WM5100_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
1285
1286/*
1287 * R535 (0x217) - Mic Bias Ctrl 3
1288 */
1289#define WM5100_MICB3_DISCH 0x0040 /* MICB3_DISCH */
1290#define WM5100_MICB3_DISCH_MASK 0x0040 /* MICB3_DISCH */
1291#define WM5100_MICB3_DISCH_SHIFT 6 /* MICB3_DISCH */
1292#define WM5100_MICB3_DISCH_WIDTH 1 /* MICB3_DISCH */
1293#define WM5100_MICB3_RATE 0x0020 /* MICB3_RATE */
1294#define WM5100_MICB3_RATE_MASK 0x0020 /* MICB3_RATE */
1295#define WM5100_MICB3_RATE_SHIFT 5 /* MICB3_RATE */
1296#define WM5100_MICB3_RATE_WIDTH 1 /* MICB3_RATE */
1297#define WM5100_MICB3_LVL_MASK 0x001C /* MICB3_LVL - [4:2] */
1298#define WM5100_MICB3_LVL_SHIFT 2 /* MICB3_LVL - [4:2] */
1299#define WM5100_MICB3_LVL_WIDTH 3 /* MICB3_LVL - [4:2] */
1300#define WM5100_MICB3_BYPASS 0x0002 /* MICB3_BYPASS */
1301#define WM5100_MICB3_BYPASS_MASK 0x0002 /* MICB3_BYPASS */
1302#define WM5100_MICB3_BYPASS_SHIFT 1 /* MICB3_BYPASS */
1303#define WM5100_MICB3_BYPASS_WIDTH 1 /* MICB3_BYPASS */
1304#define WM5100_MICB3_ENA 0x0001 /* MICB3_ENA */
1305#define WM5100_MICB3_ENA_MASK 0x0001 /* MICB3_ENA */
1306#define WM5100_MICB3_ENA_SHIFT 0 /* MICB3_ENA */
1307#define WM5100_MICB3_ENA_WIDTH 1 /* MICB3_ENA */
1308
1309/*
1310 * R640 (0x280) - Accessory Detect Mode 1
1311 */
1312#define WM5100_ACCDET_BIAS_SRC_MASK 0xC000 /* ACCDET_BIAS_SRC - [15:14] */
1313#define WM5100_ACCDET_BIAS_SRC_SHIFT 14 /* ACCDET_BIAS_SRC - [15:14] */
1314#define WM5100_ACCDET_BIAS_SRC_WIDTH 2 /* ACCDET_BIAS_SRC - [15:14] */
1315#define WM5100_ACCDET_SRC 0x2000 /* ACCDET_SRC */
1316#define WM5100_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */
1317#define WM5100_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */
1318#define WM5100_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */
1319#define WM5100_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */
1320#define WM5100_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */
1321#define WM5100_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */
1322
1323/*
1324 * R648 (0x288) - Headphone Detect 1
1325 */
1326#define WM5100_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1327#define WM5100_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1328#define WM5100_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1329#define WM5100_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1330#define WM5100_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1331#define WM5100_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1332#define WM5100_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1333#define WM5100_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1334#define WM5100_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1335#define WM5100_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1336#define WM5100_HP_POLL 0x0001 /* HP_POLL */
1337#define WM5100_HP_POLL_MASK 0x0001 /* HP_POLL */
1338#define WM5100_HP_POLL_SHIFT 0 /* HP_POLL */
1339#define WM5100_HP_POLL_WIDTH 1 /* HP_POLL */
1340
1341/*
1342 * R649 (0x289) - Headphone Detect 2
1343 */
1344#define WM5100_HP_DONE 0x0080 /* HP_DONE */
1345#define WM5100_HP_DONE_MASK 0x0080 /* HP_DONE */
1346#define WM5100_HP_DONE_SHIFT 7 /* HP_DONE */
1347#define WM5100_HP_DONE_WIDTH 1 /* HP_DONE */
1348#define WM5100_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1349#define WM5100_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1350#define WM5100_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1351
1352/*
1353 * R656 (0x290) - Mic Detect 1
1354 */
1355#define WM5100_ACCDET_BIAS_STARTTIME_MASK 0xF000 /* ACCDET_BIAS_STARTTIME - [15:12] */
1356#define WM5100_ACCDET_BIAS_STARTTIME_SHIFT 12 /* ACCDET_BIAS_STARTTIME - [15:12] */
1357#define WM5100_ACCDET_BIAS_STARTTIME_WIDTH 4 /* ACCDET_BIAS_STARTTIME - [15:12] */
1358#define WM5100_ACCDET_RATE_MASK 0x0F00 /* ACCDET_RATE - [11:8] */
1359#define WM5100_ACCDET_RATE_SHIFT 8 /* ACCDET_RATE - [11:8] */
1360#define WM5100_ACCDET_RATE_WIDTH 4 /* ACCDET_RATE - [11:8] */
1361#define WM5100_ACCDET_DBTIME 0x0002 /* ACCDET_DBTIME */
1362#define WM5100_ACCDET_DBTIME_MASK 0x0002 /* ACCDET_DBTIME */
1363#define WM5100_ACCDET_DBTIME_SHIFT 1 /* ACCDET_DBTIME */
1364#define WM5100_ACCDET_DBTIME_WIDTH 1 /* ACCDET_DBTIME */
1365#define WM5100_ACCDET_ENA 0x0001 /* ACCDET_ENA */
1366#define WM5100_ACCDET_ENA_MASK 0x0001 /* ACCDET_ENA */
1367#define WM5100_ACCDET_ENA_SHIFT 0 /* ACCDET_ENA */
1368#define WM5100_ACCDET_ENA_WIDTH 1 /* ACCDET_ENA */
1369
1370/*
1371 * R657 (0x291) - Mic Detect 2
1372 */
1373#define WM5100_ACCDET_LVL_SEL_MASK 0x00FF /* ACCDET_LVL_SEL - [7:0] */
1374#define WM5100_ACCDET_LVL_SEL_SHIFT 0 /* ACCDET_LVL_SEL - [7:0] */
1375#define WM5100_ACCDET_LVL_SEL_WIDTH 8 /* ACCDET_LVL_SEL - [7:0] */
1376
1377/*
1378 * R658 (0x292) - Mic Detect 3
1379 */
1380#define WM5100_ACCDET_LVL_MASK 0x07FC /* ACCDET_LVL - [10:2] */
1381#define WM5100_ACCDET_LVL_SHIFT 2 /* ACCDET_LVL - [10:2] */
1382#define WM5100_ACCDET_LVL_WIDTH 9 /* ACCDET_LVL - [10:2] */
1383#define WM5100_ACCDET_VALID 0x0002 /* ACCDET_VALID */
1384#define WM5100_ACCDET_VALID_MASK 0x0002 /* ACCDET_VALID */
1385#define WM5100_ACCDET_VALID_SHIFT 1 /* ACCDET_VALID */
1386#define WM5100_ACCDET_VALID_WIDTH 1 /* ACCDET_VALID */
1387#define WM5100_ACCDET_STS 0x0001 /* ACCDET_STS */
1388#define WM5100_ACCDET_STS_MASK 0x0001 /* ACCDET_STS */
1389#define WM5100_ACCDET_STS_SHIFT 0 /* ACCDET_STS */
1390#define WM5100_ACCDET_STS_WIDTH 1 /* ACCDET_STS */
1391
1392/*
1393 * R699 (0x2BB) - Misc Control
1394 */
1395#define WM5100_HPCOM_SRC 0x200 /* HPCOM_SRC */
1396#define WM5100_HPCOM_SRC_SHIFT 9 /* HPCOM_SRC */
1397
1398/*
1399 * R769 (0x301) - Input Enables
1400 */
1401#define WM5100_IN4L_ENA 0x0080 /* IN4L_ENA */
1402#define WM5100_IN4L_ENA_MASK 0x0080 /* IN4L_ENA */
1403#define WM5100_IN4L_ENA_SHIFT 7 /* IN4L_ENA */
1404#define WM5100_IN4L_ENA_WIDTH 1 /* IN4L_ENA */
1405#define WM5100_IN4R_ENA 0x0040 /* IN4R_ENA */
1406#define WM5100_IN4R_ENA_MASK 0x0040 /* IN4R_ENA */
1407#define WM5100_IN4R_ENA_SHIFT 6 /* IN4R_ENA */
1408#define WM5100_IN4R_ENA_WIDTH 1 /* IN4R_ENA */
1409#define WM5100_IN3L_ENA 0x0020 /* IN3L_ENA */
1410#define WM5100_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
1411#define WM5100_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
1412#define WM5100_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
1413#define WM5100_IN3R_ENA 0x0010 /* IN3R_ENA */
1414#define WM5100_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
1415#define WM5100_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
1416#define WM5100_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
1417#define WM5100_IN2L_ENA 0x0008 /* IN2L_ENA */
1418#define WM5100_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
1419#define WM5100_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
1420#define WM5100_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
1421#define WM5100_IN2R_ENA 0x0004 /* IN2R_ENA */
1422#define WM5100_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
1423#define WM5100_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
1424#define WM5100_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
1425#define WM5100_IN1L_ENA 0x0002 /* IN1L_ENA */
1426#define WM5100_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
1427#define WM5100_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
1428#define WM5100_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
1429#define WM5100_IN1R_ENA 0x0001 /* IN1R_ENA */
1430#define WM5100_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
1431#define WM5100_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
1432#define WM5100_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
1433
1434/*
1435 * R770 (0x302) - Input Enables Status
1436 */
1437#define WM5100_IN4L_ENA_STS 0x0080 /* IN4L_ENA_STS */
1438#define WM5100_IN4L_ENA_STS_MASK 0x0080 /* IN4L_ENA_STS */
1439#define WM5100_IN4L_ENA_STS_SHIFT 7 /* IN4L_ENA_STS */
1440#define WM5100_IN4L_ENA_STS_WIDTH 1 /* IN4L_ENA_STS */
1441#define WM5100_IN4R_ENA_STS 0x0040 /* IN4R_ENA_STS */
1442#define WM5100_IN4R_ENA_STS_MASK 0x0040 /* IN4R_ENA_STS */
1443#define WM5100_IN4R_ENA_STS_SHIFT 6 /* IN4R_ENA_STS */
1444#define WM5100_IN4R_ENA_STS_WIDTH 1 /* IN4R_ENA_STS */
1445#define WM5100_IN3L_ENA_STS 0x0020 /* IN3L_ENA_STS */
1446#define WM5100_IN3L_ENA_STS_MASK 0x0020 /* IN3L_ENA_STS */
1447#define WM5100_IN3L_ENA_STS_SHIFT 5 /* IN3L_ENA_STS */
1448#define WM5100_IN3L_ENA_STS_WIDTH 1 /* IN3L_ENA_STS */
1449#define WM5100_IN3R_ENA_STS 0x0010 /* IN3R_ENA_STS */
1450#define WM5100_IN3R_ENA_STS_MASK 0x0010 /* IN3R_ENA_STS */
1451#define WM5100_IN3R_ENA_STS_SHIFT 4 /* IN3R_ENA_STS */
1452#define WM5100_IN3R_ENA_STS_WIDTH 1 /* IN3R_ENA_STS */
1453#define WM5100_IN2L_ENA_STS 0x0008 /* IN2L_ENA_STS */
1454#define WM5100_IN2L_ENA_STS_MASK 0x0008 /* IN2L_ENA_STS */
1455#define WM5100_IN2L_ENA_STS_SHIFT 3 /* IN2L_ENA_STS */
1456#define WM5100_IN2L_ENA_STS_WIDTH 1 /* IN2L_ENA_STS */
1457#define WM5100_IN2R_ENA_STS 0x0004 /* IN2R_ENA_STS */
1458#define WM5100_IN2R_ENA_STS_MASK 0x0004 /* IN2R_ENA_STS */
1459#define WM5100_IN2R_ENA_STS_SHIFT 2 /* IN2R_ENA_STS */
1460#define WM5100_IN2R_ENA_STS_WIDTH 1 /* IN2R_ENA_STS */
1461#define WM5100_IN1L_ENA_STS 0x0002 /* IN1L_ENA_STS */
1462#define WM5100_IN1L_ENA_STS_MASK 0x0002 /* IN1L_ENA_STS */
1463#define WM5100_IN1L_ENA_STS_SHIFT 1 /* IN1L_ENA_STS */
1464#define WM5100_IN1L_ENA_STS_WIDTH 1 /* IN1L_ENA_STS */
1465#define WM5100_IN1R_ENA_STS 0x0001 /* IN1R_ENA_STS */
1466#define WM5100_IN1R_ENA_STS_MASK 0x0001 /* IN1R_ENA_STS */
1467#define WM5100_IN1R_ENA_STS_SHIFT 0 /* IN1R_ENA_STS */
1468#define WM5100_IN1R_ENA_STS_WIDTH 1 /* IN1R_ENA_STS */
1469
1470/*
1471 * R784 (0x310) - IN1L Control
1472 */
1473#define WM5100_IN_RATE_MASK 0xC000 /* IN_RATE - [15:14] */
1474#define WM5100_IN_RATE_SHIFT 14 /* IN_RATE - [15:14] */
1475#define WM5100_IN_RATE_WIDTH 2 /* IN_RATE - [15:14] */
1476#define WM5100_IN1_OSR 0x2000 /* IN1_OSR */
1477#define WM5100_IN1_OSR_MASK 0x2000 /* IN1_OSR */
1478#define WM5100_IN1_OSR_SHIFT 13 /* IN1_OSR */
1479#define WM5100_IN1_OSR_WIDTH 1 /* IN1_OSR */
1480#define WM5100_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
1481#define WM5100_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
1482#define WM5100_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
1483#define WM5100_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
1484#define WM5100_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
1485#define WM5100_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
1486#define WM5100_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
1487#define WM5100_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
1488#define WM5100_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
1489
1490/*
1491 * R785 (0x311) - IN1R Control
1492 */
1493#define WM5100_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
1494#define WM5100_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
1495#define WM5100_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
1496
1497/*
1498 * R786 (0x312) - IN2L Control
1499 */
1500#define WM5100_IN2_OSR 0x2000 /* IN2_OSR */
1501#define WM5100_IN2_OSR_MASK 0x2000 /* IN2_OSR */
1502#define WM5100_IN2_OSR_SHIFT 13 /* IN2_OSR */
1503#define WM5100_IN2_OSR_WIDTH 1 /* IN2_OSR */
1504#define WM5100_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
1505#define WM5100_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
1506#define WM5100_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
1507#define WM5100_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
1508#define WM5100_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
1509#define WM5100_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
1510#define WM5100_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
1511#define WM5100_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
1512#define WM5100_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
1513
1514/*
1515 * R787 (0x313) - IN2R Control
1516 */
1517#define WM5100_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
1518#define WM5100_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
1519#define WM5100_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
1520
1521/*
1522 * R788 (0x314) - IN3L Control
1523 */
1524#define WM5100_IN3_OSR 0x2000 /* IN3_OSR */
1525#define WM5100_IN3_OSR_MASK 0x2000 /* IN3_OSR */
1526#define WM5100_IN3_OSR_SHIFT 13 /* IN3_OSR */
1527#define WM5100_IN3_OSR_WIDTH 1 /* IN3_OSR */
1528#define WM5100_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
1529#define WM5100_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
1530#define WM5100_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
1531#define WM5100_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
1532#define WM5100_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
1533#define WM5100_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
1534#define WM5100_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
1535#define WM5100_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
1536#define WM5100_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
1537
1538/*
1539 * R789 (0x315) - IN3R Control
1540 */
1541#define WM5100_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
1542#define WM5100_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
1543#define WM5100_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
1544
1545/*
1546 * R790 (0x316) - IN4L Control
1547 */
1548#define WM5100_IN4_OSR 0x2000 /* IN4_OSR */
1549#define WM5100_IN4_OSR_MASK 0x2000 /* IN4_OSR */
1550#define WM5100_IN4_OSR_SHIFT 13 /* IN4_OSR */
1551#define WM5100_IN4_OSR_WIDTH 1 /* IN4_OSR */
1552#define WM5100_IN4_DMIC_SUP_MASK 0x1800 /* IN4_DMIC_SUP - [12:11] */
1553#define WM5100_IN4_DMIC_SUP_SHIFT 11 /* IN4_DMIC_SUP - [12:11] */
1554#define WM5100_IN4_DMIC_SUP_WIDTH 2 /* IN4_DMIC_SUP - [12:11] */
1555#define WM5100_IN4_MODE_MASK 0x0600 /* IN4_MODE - [10:9] */
1556#define WM5100_IN4_MODE_SHIFT 9 /* IN4_MODE - [10:9] */
1557#define WM5100_IN4_MODE_WIDTH 2 /* IN4_MODE - [10:9] */
1558#define WM5100_IN4L_PGA_VOL_MASK 0x00FE /* IN4L_PGA_VOL - [7:1] */
1559#define WM5100_IN4L_PGA_VOL_SHIFT 1 /* IN4L_PGA_VOL - [7:1] */
1560#define WM5100_IN4L_PGA_VOL_WIDTH 7 /* IN4L_PGA_VOL - [7:1] */
1561
1562/*
1563 * R791 (0x317) - IN4R Control
1564 */
1565#define WM5100_IN4R_PGA_VOL_MASK 0x00FE /* IN4R_PGA_VOL - [7:1] */
1566#define WM5100_IN4R_PGA_VOL_SHIFT 1 /* IN4R_PGA_VOL - [7:1] */
1567#define WM5100_IN4R_PGA_VOL_WIDTH 7 /* IN4R_PGA_VOL - [7:1] */
1568
1569/*
1570 * R792 (0x318) - RXANC_SRC
1571 */
1572#define WM5100_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
1573#define WM5100_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
1574#define WM5100_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
1575
1576/*
1577 * R793 (0x319) - Input Volume Ramp
1578 */
1579#define WM5100_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
1580#define WM5100_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
1581#define WM5100_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
1582#define WM5100_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
1583#define WM5100_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
1584#define WM5100_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
1585
1586/*
1587 * R800 (0x320) - ADC Digital Volume 1L
1588 */
1589#define WM5100_IN_VU 0x0200 /* IN_VU */
1590#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1591#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1592#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1593#define WM5100_IN1L_MUTE 0x0100 /* IN1L_MUTE */
1594#define WM5100_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
1595#define WM5100_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
1596#define WM5100_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
1597#define WM5100_IN1L_VOL_MASK 0x00FF /* IN1L_VOL - [7:0] */
1598#define WM5100_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [7:0] */
1599#define WM5100_IN1L_VOL_WIDTH 8 /* IN1L_VOL - [7:0] */
1600
1601/*
1602 * R801 (0x321) - ADC Digital Volume 1R
1603 */
1604#define WM5100_IN_VU 0x0200 /* IN_VU */
1605#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1606#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1607#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1608#define WM5100_IN1R_MUTE 0x0100 /* IN1R_MUTE */
1609#define WM5100_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
1610#define WM5100_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
1611#define WM5100_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
1612#define WM5100_IN1R_VOL_MASK 0x00FF /* IN1R_VOL - [7:0] */
1613#define WM5100_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [7:0] */
1614#define WM5100_IN1R_VOL_WIDTH 8 /* IN1R_VOL - [7:0] */
1615
1616/*
1617 * R802 (0x322) - ADC Digital Volume 2L
1618 */
1619#define WM5100_IN_VU 0x0200 /* IN_VU */
1620#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1621#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1622#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1623#define WM5100_IN2L_MUTE 0x0100 /* IN2L_MUTE */
1624#define WM5100_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
1625#define WM5100_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
1626#define WM5100_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
1627#define WM5100_IN2L_VOL_MASK 0x00FF /* IN2L_VOL - [7:0] */
1628#define WM5100_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [7:0] */
1629#define WM5100_IN2L_VOL_WIDTH 8 /* IN2L_VOL - [7:0] */
1630
1631/*
1632 * R803 (0x323) - ADC Digital Volume 2R
1633 */
1634#define WM5100_IN_VU 0x0200 /* IN_VU */
1635#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1636#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1637#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1638#define WM5100_IN2R_MUTE 0x0100 /* IN2R_MUTE */
1639#define WM5100_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
1640#define WM5100_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
1641#define WM5100_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
1642#define WM5100_IN2R_VOL_MASK 0x00FF /* IN2R_VOL - [7:0] */
1643#define WM5100_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [7:0] */
1644#define WM5100_IN2R_VOL_WIDTH 8 /* IN2R_VOL - [7:0] */
1645
1646/*
1647 * R804 (0x324) - ADC Digital Volume 3L
1648 */
1649#define WM5100_IN_VU 0x0200 /* IN_VU */
1650#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1651#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1652#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1653#define WM5100_IN3L_MUTE 0x0100 /* IN3L_MUTE */
1654#define WM5100_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
1655#define WM5100_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
1656#define WM5100_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
1657#define WM5100_IN3L_VOL_MASK 0x00FF /* IN3L_VOL - [7:0] */
1658#define WM5100_IN3L_VOL_SHIFT 0 /* IN3L_VOL - [7:0] */
1659#define WM5100_IN3L_VOL_WIDTH 8 /* IN3L_VOL - [7:0] */
1660
1661/*
1662 * R805 (0x325) - ADC Digital Volume 3R
1663 */
1664#define WM5100_IN_VU 0x0200 /* IN_VU */
1665#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1666#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1667#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1668#define WM5100_IN3R_MUTE 0x0100 /* IN3R_MUTE */
1669#define WM5100_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
1670#define WM5100_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
1671#define WM5100_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
1672#define WM5100_IN3R_VOL_MASK 0x00FF /* IN3R_VOL - [7:0] */
1673#define WM5100_IN3R_VOL_SHIFT 0 /* IN3R_VOL - [7:0] */
1674#define WM5100_IN3R_VOL_WIDTH 8 /* IN3R_VOL - [7:0] */
1675
1676/*
1677 * R806 (0x326) - ADC Digital Volume 4L
1678 */
1679#define WM5100_IN_VU 0x0200 /* IN_VU */
1680#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1681#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1682#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1683#define WM5100_IN4L_MUTE 0x0100 /* IN4L_MUTE */
1684#define WM5100_IN4L_MUTE_MASK 0x0100 /* IN4L_MUTE */
1685#define WM5100_IN4L_MUTE_SHIFT 8 /* IN4L_MUTE */
1686#define WM5100_IN4L_MUTE_WIDTH 1 /* IN4L_MUTE */
1687#define WM5100_IN4L_VOL_MASK 0x00FF /* IN4L_VOL - [7:0] */
1688#define WM5100_IN4L_VOL_SHIFT 0 /* IN4L_VOL - [7:0] */
1689#define WM5100_IN4L_VOL_WIDTH 8 /* IN4L_VOL - [7:0] */
1690
1691/*
1692 * R807 (0x327) - ADC Digital Volume 4R
1693 */
1694#define WM5100_IN_VU 0x0200 /* IN_VU */
1695#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1696#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1697#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1698#define WM5100_IN4R_MUTE 0x0100 /* IN4R_MUTE */
1699#define WM5100_IN4R_MUTE_MASK 0x0100 /* IN4R_MUTE */
1700#define WM5100_IN4R_MUTE_SHIFT 8 /* IN4R_MUTE */
1701#define WM5100_IN4R_MUTE_WIDTH 1 /* IN4R_MUTE */
1702#define WM5100_IN4R_VOL_MASK 0x00FF /* IN4R_VOL - [7:0] */
1703#define WM5100_IN4R_VOL_SHIFT 0 /* IN4R_VOL - [7:0] */
1704#define WM5100_IN4R_VOL_WIDTH 8 /* IN4R_VOL - [7:0] */
1705
1706/*
1707 * R1025 (0x401) - Output Enables 2
1708 */
1709#define WM5100_OUT6L_ENA 0x0800 /* OUT6L_ENA */
1710#define WM5100_OUT6L_ENA_MASK 0x0800 /* OUT6L_ENA */
1711#define WM5100_OUT6L_ENA_SHIFT 11 /* OUT6L_ENA */
1712#define WM5100_OUT6L_ENA_WIDTH 1 /* OUT6L_ENA */
1713#define WM5100_OUT6R_ENA 0x0400 /* OUT6R_ENA */
1714#define WM5100_OUT6R_ENA_MASK 0x0400 /* OUT6R_ENA */
1715#define WM5100_OUT6R_ENA_SHIFT 10 /* OUT6R_ENA */
1716#define WM5100_OUT6R_ENA_WIDTH 1 /* OUT6R_ENA */
1717#define WM5100_OUT5L_ENA 0x0200 /* OUT5L_ENA */
1718#define WM5100_OUT5L_ENA_MASK 0x0200 /* OUT5L_ENA */
1719#define WM5100_OUT5L_ENA_SHIFT 9 /* OUT5L_ENA */
1720#define WM5100_OUT5L_ENA_WIDTH 1 /* OUT5L_ENA */
1721#define WM5100_OUT5R_ENA 0x0100 /* OUT5R_ENA */
1722#define WM5100_OUT5R_ENA_MASK 0x0100 /* OUT5R_ENA */
1723#define WM5100_OUT5R_ENA_SHIFT 8 /* OUT5R_ENA */
1724#define WM5100_OUT5R_ENA_WIDTH 1 /* OUT5R_ENA */
1725#define WM5100_OUT4L_ENA 0x0080 /* OUT4L_ENA */
1726#define WM5100_OUT4L_ENA_MASK 0x0080 /* OUT4L_ENA */
1727#define WM5100_OUT4L_ENA_SHIFT 7 /* OUT4L_ENA */
1728#define WM5100_OUT4L_ENA_WIDTH 1 /* OUT4L_ENA */
1729#define WM5100_OUT4R_ENA 0x0040 /* OUT4R_ENA */
1730#define WM5100_OUT4R_ENA_MASK 0x0040 /* OUT4R_ENA */
1731#define WM5100_OUT4R_ENA_SHIFT 6 /* OUT4R_ENA */
1732#define WM5100_OUT4R_ENA_WIDTH 1 /* OUT4R_ENA */
1733
1734/*
1735 * R1026 (0x402) - Output Status 1
1736 */
1737#define WM5100_OUT3L_ENA_STS 0x0020 /* OUT3L_ENA_STS */
1738#define WM5100_OUT3L_ENA_STS_MASK 0x0020 /* OUT3L_ENA_STS */
1739#define WM5100_OUT3L_ENA_STS_SHIFT 5 /* OUT3L_ENA_STS */
1740#define WM5100_OUT3L_ENA_STS_WIDTH 1 /* OUT3L_ENA_STS */
1741#define WM5100_OUT3R_ENA_STS 0x0010 /* OUT3R_ENA_STS */
1742#define WM5100_OUT3R_ENA_STS_MASK 0x0010 /* OUT3R_ENA_STS */
1743#define WM5100_OUT3R_ENA_STS_SHIFT 4 /* OUT3R_ENA_STS */
1744#define WM5100_OUT3R_ENA_STS_WIDTH 1 /* OUT3R_ENA_STS */
1745#define WM5100_OUT2L_ENA_STS 0x0008 /* OUT2L_ENA_STS */
1746#define WM5100_OUT2L_ENA_STS_MASK 0x0008 /* OUT2L_ENA_STS */
1747#define WM5100_OUT2L_ENA_STS_SHIFT 3 /* OUT2L_ENA_STS */
1748#define WM5100_OUT2L_ENA_STS_WIDTH 1 /* OUT2L_ENA_STS */
1749#define WM5100_OUT2R_ENA_STS 0x0004 /* OUT2R_ENA_STS */
1750#define WM5100_OUT2R_ENA_STS_MASK 0x0004 /* OUT2R_ENA_STS */
1751#define WM5100_OUT2R_ENA_STS_SHIFT 2 /* OUT2R_ENA_STS */
1752#define WM5100_OUT2R_ENA_STS_WIDTH 1 /* OUT2R_ENA_STS */
1753#define WM5100_OUT1L_ENA_STS 0x0002 /* OUT1L_ENA_STS */
1754#define WM5100_OUT1L_ENA_STS_MASK 0x0002 /* OUT1L_ENA_STS */
1755#define WM5100_OUT1L_ENA_STS_SHIFT 1 /* OUT1L_ENA_STS */
1756#define WM5100_OUT1L_ENA_STS_WIDTH 1 /* OUT1L_ENA_STS */
1757#define WM5100_OUT1R_ENA_STS 0x0001 /* OUT1R_ENA_STS */
1758#define WM5100_OUT1R_ENA_STS_MASK 0x0001 /* OUT1R_ENA_STS */
1759#define WM5100_OUT1R_ENA_STS_SHIFT 0 /* OUT1R_ENA_STS */
1760#define WM5100_OUT1R_ENA_STS_WIDTH 1 /* OUT1R_ENA_STS */
1761
1762/*
1763 * R1027 (0x403) - Output Status 2
1764 */
1765#define WM5100_OUT6L_ENA_STS 0x0800 /* OUT6L_ENA_STS */
1766#define WM5100_OUT6L_ENA_STS_MASK 0x0800 /* OUT6L_ENA_STS */
1767#define WM5100_OUT6L_ENA_STS_SHIFT 11 /* OUT6L_ENA_STS */
1768#define WM5100_OUT6L_ENA_STS_WIDTH 1 /* OUT6L_ENA_STS */
1769#define WM5100_OUT6R_ENA_STS 0x0400 /* OUT6R_ENA_STS */
1770#define WM5100_OUT6R_ENA_STS_MASK 0x0400 /* OUT6R_ENA_STS */
1771#define WM5100_OUT6R_ENA_STS_SHIFT 10 /* OUT6R_ENA_STS */
1772#define WM5100_OUT6R_ENA_STS_WIDTH 1 /* OUT6R_ENA_STS */
1773#define WM5100_OUT5L_ENA_STS 0x0200 /* OUT5L_ENA_STS */
1774#define WM5100_OUT5L_ENA_STS_MASK 0x0200 /* OUT5L_ENA_STS */
1775#define WM5100_OUT5L_ENA_STS_SHIFT 9 /* OUT5L_ENA_STS */
1776#define WM5100_OUT5L_ENA_STS_WIDTH 1 /* OUT5L_ENA_STS */
1777#define WM5100_OUT5R_ENA_STS 0x0100 /* OUT5R_ENA_STS */
1778#define WM5100_OUT5R_ENA_STS_MASK 0x0100 /* OUT5R_ENA_STS */
1779#define WM5100_OUT5R_ENA_STS_SHIFT 8 /* OUT5R_ENA_STS */
1780#define WM5100_OUT5R_ENA_STS_WIDTH 1 /* OUT5R_ENA_STS */
1781#define WM5100_OUT4L_ENA_STS 0x0080 /* OUT4L_ENA_STS */
1782#define WM5100_OUT4L_ENA_STS_MASK 0x0080 /* OUT4L_ENA_STS */
1783#define WM5100_OUT4L_ENA_STS_SHIFT 7 /* OUT4L_ENA_STS */
1784#define WM5100_OUT4L_ENA_STS_WIDTH 1 /* OUT4L_ENA_STS */
1785#define WM5100_OUT4R_ENA_STS 0x0040 /* OUT4R_ENA_STS */
1786#define WM5100_OUT4R_ENA_STS_MASK 0x0040 /* OUT4R_ENA_STS */
1787#define WM5100_OUT4R_ENA_STS_SHIFT 6 /* OUT4R_ENA_STS */
1788#define WM5100_OUT4R_ENA_STS_WIDTH 1 /* OUT4R_ENA_STS */
1789
1790/*
1791 * R1032 (0x408) - Channel Enables 1
1792 */
1793#define WM5100_HP3L_ENA 0x0020 /* HP3L_ENA */
1794#define WM5100_HP3L_ENA_MASK 0x0020 /* HP3L_ENA */
1795#define WM5100_HP3L_ENA_SHIFT 5 /* HP3L_ENA */
1796#define WM5100_HP3L_ENA_WIDTH 1 /* HP3L_ENA */
1797#define WM5100_HP3R_ENA 0x0010 /* HP3R_ENA */
1798#define WM5100_HP3R_ENA_MASK 0x0010 /* HP3R_ENA */
1799#define WM5100_HP3R_ENA_SHIFT 4 /* HP3R_ENA */
1800#define WM5100_HP3R_ENA_WIDTH 1 /* HP3R_ENA */
1801#define WM5100_HP2L_ENA 0x0008 /* HP2L_ENA */
1802#define WM5100_HP2L_ENA_MASK 0x0008 /* HP2L_ENA */
1803#define WM5100_HP2L_ENA_SHIFT 3 /* HP2L_ENA */
1804#define WM5100_HP2L_ENA_WIDTH 1 /* HP2L_ENA */
1805#define WM5100_HP2R_ENA 0x0004 /* HP2R_ENA */
1806#define WM5100_HP2R_ENA_MASK 0x0004 /* HP2R_ENA */
1807#define WM5100_HP2R_ENA_SHIFT 2 /* HP2R_ENA */
1808#define WM5100_HP2R_ENA_WIDTH 1 /* HP2R_ENA */
1809#define WM5100_HP1L_ENA 0x0002 /* HP1L_ENA */
1810#define WM5100_HP1L_ENA_MASK 0x0002 /* HP1L_ENA */
1811#define WM5100_HP1L_ENA_SHIFT 1 /* HP1L_ENA */
1812#define WM5100_HP1L_ENA_WIDTH 1 /* HP1L_ENA */
1813#define WM5100_HP1R_ENA 0x0001 /* HP1R_ENA */
1814#define WM5100_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */
1815#define WM5100_HP1R_ENA_SHIFT 0 /* HP1R_ENA */
1816#define WM5100_HP1R_ENA_WIDTH 1 /* HP1R_ENA */
1817
1818/*
1819 * R1040 (0x410) - Out Volume 1L
1820 */
1821#define WM5100_OUT_RATE_MASK 0xC000 /* OUT_RATE - [15:14] */
1822#define WM5100_OUT_RATE_SHIFT 14 /* OUT_RATE - [15:14] */
1823#define WM5100_OUT_RATE_WIDTH 2 /* OUT_RATE - [15:14] */
1824#define WM5100_OUT1_OSR 0x2000 /* OUT1_OSR */
1825#define WM5100_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
1826#define WM5100_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
1827#define WM5100_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
1828#define WM5100_OUT1_MONO 0x1000 /* OUT1_MONO */
1829#define WM5100_OUT1_MONO_MASK 0x1000 /* OUT1_MONO */
1830#define WM5100_OUT1_MONO_SHIFT 12 /* OUT1_MONO */
1831#define WM5100_OUT1_MONO_WIDTH 1 /* OUT1_MONO */
1832#define WM5100_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
1833#define WM5100_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
1834#define WM5100_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
1835#define WM5100_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
1836#define WM5100_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
1837#define WM5100_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
1838#define WM5100_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
1839
1840/*
1841 * R1041 (0x411) - Out Volume 1R
1842 */
1843#define WM5100_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
1844#define WM5100_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
1845#define WM5100_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
1846#define WM5100_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
1847#define WM5100_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
1848#define WM5100_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
1849#define WM5100_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
1850
1851/*
1852 * R1042 (0x412) - DAC Volume Limit 1L
1853 */
1854#define WM5100_OUT1L_VOL_LIM_MASK 0x00FF /* OUT1L_VOL_LIM - [7:0] */
1855#define WM5100_OUT1L_VOL_LIM_SHIFT 0 /* OUT1L_VOL_LIM - [7:0] */
1856#define WM5100_OUT1L_VOL_LIM_WIDTH 8 /* OUT1L_VOL_LIM - [7:0] */
1857
1858/*
1859 * R1043 (0x413) - DAC Volume Limit 1R
1860 */
1861#define WM5100_OUT1R_VOL_LIM_MASK 0x00FF /* OUT1R_VOL_LIM - [7:0] */
1862#define WM5100_OUT1R_VOL_LIM_SHIFT 0 /* OUT1R_VOL_LIM - [7:0] */
1863#define WM5100_OUT1R_VOL_LIM_WIDTH 8 /* OUT1R_VOL_LIM - [7:0] */
1864
1865/*
1866 * R1044 (0x414) - Out Volume 2L
1867 */
1868#define WM5100_OUT2_OSR 0x2000 /* OUT2_OSR */
1869#define WM5100_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
1870#define WM5100_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
1871#define WM5100_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
1872#define WM5100_OUT2_MONO 0x1000 /* OUT2_MONO */
1873#define WM5100_OUT2_MONO_MASK 0x1000 /* OUT2_MONO */
1874#define WM5100_OUT2_MONO_SHIFT 12 /* OUT2_MONO */
1875#define WM5100_OUT2_MONO_WIDTH 1 /* OUT2_MONO */
1876#define WM5100_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
1877#define WM5100_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
1878#define WM5100_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
1879#define WM5100_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
1880#define WM5100_OUT2L_PGA_VOL_MASK 0x00FE /* OUT2L_PGA_VOL - [7:1] */
1881#define WM5100_OUT2L_PGA_VOL_SHIFT 1 /* OUT2L_PGA_VOL - [7:1] */
1882#define WM5100_OUT2L_PGA_VOL_WIDTH 7 /* OUT2L_PGA_VOL - [7:1] */
1883
1884/*
1885 * R1045 (0x415) - Out Volume 2R
1886 */
1887#define WM5100_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
1888#define WM5100_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
1889#define WM5100_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
1890#define WM5100_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
1891#define WM5100_OUT2R_PGA_VOL_MASK 0x00FE /* OUT2R_PGA_VOL - [7:1] */
1892#define WM5100_OUT2R_PGA_VOL_SHIFT 1 /* OUT2R_PGA_VOL - [7:1] */
1893#define WM5100_OUT2R_PGA_VOL_WIDTH 7 /* OUT2R_PGA_VOL - [7:1] */
1894
1895/*
1896 * R1046 (0x416) - DAC Volume Limit 2L
1897 */
1898#define WM5100_OUT2L_VOL_LIM_MASK 0x00FF /* OUT2L_VOL_LIM - [7:0] */
1899#define WM5100_OUT2L_VOL_LIM_SHIFT 0 /* OUT2L_VOL_LIM - [7:0] */
1900#define WM5100_OUT2L_VOL_LIM_WIDTH 8 /* OUT2L_VOL_LIM - [7:0] */
1901
1902/*
1903 * R1047 (0x417) - DAC Volume Limit 2R
1904 */
1905#define WM5100_OUT2R_VOL_LIM_MASK 0x00FF /* OUT2R_VOL_LIM - [7:0] */
1906#define WM5100_OUT2R_VOL_LIM_SHIFT 0 /* OUT2R_VOL_LIM - [7:0] */
1907#define WM5100_OUT2R_VOL_LIM_WIDTH 8 /* OUT2R_VOL_LIM - [7:0] */
1908
1909/*
1910 * R1048 (0x418) - Out Volume 3L
1911 */
1912#define WM5100_OUT3_OSR 0x2000 /* OUT3_OSR */
1913#define WM5100_OUT3_OSR_MASK 0x2000 /* OUT3_OSR */
1914#define WM5100_OUT3_OSR_SHIFT 13 /* OUT3_OSR */
1915#define WM5100_OUT3_OSR_WIDTH 1 /* OUT3_OSR */
1916#define WM5100_OUT3_MONO 0x1000 /* OUT3_MONO */
1917#define WM5100_OUT3_MONO_MASK 0x1000 /* OUT3_MONO */
1918#define WM5100_OUT3_MONO_SHIFT 12 /* OUT3_MONO */
1919#define WM5100_OUT3_MONO_WIDTH 1 /* OUT3_MONO */
1920#define WM5100_OUT3L_ANC_SRC 0x0800 /* OUT3L_ANC_SRC */
1921#define WM5100_OUT3L_ANC_SRC_MASK 0x0800 /* OUT3L_ANC_SRC */
1922#define WM5100_OUT3L_ANC_SRC_SHIFT 11 /* OUT3L_ANC_SRC */
1923#define WM5100_OUT3L_ANC_SRC_WIDTH 1 /* OUT3L_ANC_SRC */
1924#define WM5100_OUT3L_PGA_VOL_MASK 0x00FE /* OUT3L_PGA_VOL - [7:1] */
1925#define WM5100_OUT3L_PGA_VOL_SHIFT 1 /* OUT3L_PGA_VOL - [7:1] */
1926#define WM5100_OUT3L_PGA_VOL_WIDTH 7 /* OUT3L_PGA_VOL - [7:1] */
1927
1928/*
1929 * R1049 (0x419) - Out Volume 3R
1930 */
1931#define WM5100_OUT3R_ANC_SRC 0x0800 /* OUT3R_ANC_SRC */
1932#define WM5100_OUT3R_ANC_SRC_MASK 0x0800 /* OUT3R_ANC_SRC */
1933#define WM5100_OUT3R_ANC_SRC_SHIFT 11 /* OUT3R_ANC_SRC */
1934#define WM5100_OUT3R_ANC_SRC_WIDTH 1 /* OUT3R_ANC_SRC */
1935#define WM5100_OUT3R_PGA_VOL_MASK 0x00FE /* OUT3R_PGA_VOL - [7:1] */
1936#define WM5100_OUT3R_PGA_VOL_SHIFT 1 /* OUT3R_PGA_VOL - [7:1] */
1937#define WM5100_OUT3R_PGA_VOL_WIDTH 7 /* OUT3R_PGA_VOL - [7:1] */
1938
1939/*
1940 * R1050 (0x41A) - DAC Volume Limit 3L
1941 */
1942#define WM5100_OUT3L_VOL_LIM_MASK 0x00FF /* OUT3L_VOL_LIM - [7:0] */
1943#define WM5100_OUT3L_VOL_LIM_SHIFT 0 /* OUT3L_VOL_LIM - [7:0] */
1944#define WM5100_OUT3L_VOL_LIM_WIDTH 8 /* OUT3L_VOL_LIM - [7:0] */
1945
1946/*
1947 * R1051 (0x41B) - DAC Volume Limit 3R
1948 */
1949#define WM5100_OUT3R_VOL_LIM_MASK 0x00FF /* OUT3R_VOL_LIM - [7:0] */
1950#define WM5100_OUT3R_VOL_LIM_SHIFT 0 /* OUT3R_VOL_LIM - [7:0] */
1951#define WM5100_OUT3R_VOL_LIM_WIDTH 8 /* OUT3R_VOL_LIM - [7:0] */
1952
1953/*
1954 * R1052 (0x41C) - Out Volume 4L
1955 */
1956#define WM5100_OUT4_OSR 0x2000 /* OUT4_OSR */
1957#define WM5100_OUT4_OSR_MASK 0x2000 /* OUT4_OSR */
1958#define WM5100_OUT4_OSR_SHIFT 13 /* OUT4_OSR */
1959#define WM5100_OUT4_OSR_WIDTH 1 /* OUT4_OSR */
1960#define WM5100_OUT4L_ANC_SRC 0x0800 /* OUT4L_ANC_SRC */
1961#define WM5100_OUT4L_ANC_SRC_MASK 0x0800 /* OUT4L_ANC_SRC */
1962#define WM5100_OUT4L_ANC_SRC_SHIFT 11 /* OUT4L_ANC_SRC */
1963#define WM5100_OUT4L_ANC_SRC_WIDTH 1 /* OUT4L_ANC_SRC */
1964#define WM5100_OUT4L_VOL_LIM_MASK 0x00FF /* OUT4L_VOL_LIM - [7:0] */
1965#define WM5100_OUT4L_VOL_LIM_SHIFT 0 /* OUT4L_VOL_LIM - [7:0] */
1966#define WM5100_OUT4L_VOL_LIM_WIDTH 8 /* OUT4L_VOL_LIM - [7:0] */
1967
1968/*
1969 * R1053 (0x41D) - Out Volume 4R
1970 */
1971#define WM5100_OUT4R_ANC_SRC 0x0800 /* OUT4R_ANC_SRC */
1972#define WM5100_OUT4R_ANC_SRC_MASK 0x0800 /* OUT4R_ANC_SRC */
1973#define WM5100_OUT4R_ANC_SRC_SHIFT 11 /* OUT4R_ANC_SRC */
1974#define WM5100_OUT4R_ANC_SRC_WIDTH 1 /* OUT4R_ANC_SRC */
1975#define WM5100_OUT4R_VOL_LIM_MASK 0x00FF /* OUT4R_VOL_LIM - [7:0] */
1976#define WM5100_OUT4R_VOL_LIM_SHIFT 0 /* OUT4R_VOL_LIM - [7:0] */
1977#define WM5100_OUT4R_VOL_LIM_WIDTH 8 /* OUT4R_VOL_LIM - [7:0] */
1978
1979/*
1980 * R1054 (0x41E) - DAC Volume Limit 5L
1981 */
1982#define WM5100_OUT5_OSR 0x2000 /* OUT5_OSR */
1983#define WM5100_OUT5_OSR_MASK 0x2000 /* OUT5_OSR */
1984#define WM5100_OUT5_OSR_SHIFT 13 /* OUT5_OSR */
1985#define WM5100_OUT5_OSR_WIDTH 1 /* OUT5_OSR */
1986#define WM5100_OUT5L_ANC_SRC 0x0800 /* OUT5L_ANC_SRC */
1987#define WM5100_OUT5L_ANC_SRC_MASK 0x0800 /* OUT5L_ANC_SRC */
1988#define WM5100_OUT5L_ANC_SRC_SHIFT 11 /* OUT5L_ANC_SRC */
1989#define WM5100_OUT5L_ANC_SRC_WIDTH 1 /* OUT5L_ANC_SRC */
1990#define WM5100_OUT5L_VOL_LIM_MASK 0x00FF /* OUT5L_VOL_LIM - [7:0] */
1991#define WM5100_OUT5L_VOL_LIM_SHIFT 0 /* OUT5L_VOL_LIM - [7:0] */
1992#define WM5100_OUT5L_VOL_LIM_WIDTH 8 /* OUT5L_VOL_LIM - [7:0] */
1993
1994/*
1995 * R1055 (0x41F) - DAC Volume Limit 5R
1996 */
1997#define WM5100_OUT5R_ANC_SRC 0x0800 /* OUT5R_ANC_SRC */
1998#define WM5100_OUT5R_ANC_SRC_MASK 0x0800 /* OUT5R_ANC_SRC */
1999#define WM5100_OUT5R_ANC_SRC_SHIFT 11 /* OUT5R_ANC_SRC */
2000#define WM5100_OUT5R_ANC_SRC_WIDTH 1 /* OUT5R_ANC_SRC */
2001#define WM5100_OUT5R_VOL_LIM_MASK 0x00FF /* OUT5R_VOL_LIM - [7:0] */
2002#define WM5100_OUT5R_VOL_LIM_SHIFT 0 /* OUT5R_VOL_LIM - [7:0] */
2003#define WM5100_OUT5R_VOL_LIM_WIDTH 8 /* OUT5R_VOL_LIM - [7:0] */
2004
2005/*
2006 * R1056 (0x420) - DAC Volume Limit 6L
2007 */
2008#define WM5100_OUT6_OSR 0x2000 /* OUT6_OSR */
2009#define WM5100_OUT6_OSR_MASK 0x2000 /* OUT6_OSR */
2010#define WM5100_OUT6_OSR_SHIFT 13 /* OUT6_OSR */
2011#define WM5100_OUT6_OSR_WIDTH 1 /* OUT6_OSR */
2012#define WM5100_OUT6L_ANC_SRC 0x0800 /* OUT6L_ANC_SRC */
2013#define WM5100_OUT6L_ANC_SRC_MASK 0x0800 /* OUT6L_ANC_SRC */
2014#define WM5100_OUT6L_ANC_SRC_SHIFT 11 /* OUT6L_ANC_SRC */
2015#define WM5100_OUT6L_ANC_SRC_WIDTH 1 /* OUT6L_ANC_SRC */
2016#define WM5100_OUT6L_VOL_LIM_MASK 0x00FF /* OUT6L_VOL_LIM - [7:0] */
2017#define WM5100_OUT6L_VOL_LIM_SHIFT 0 /* OUT6L_VOL_LIM - [7:0] */
2018#define WM5100_OUT6L_VOL_LIM_WIDTH 8 /* OUT6L_VOL_LIM - [7:0] */
2019
2020/*
2021 * R1057 (0x421) - DAC Volume Limit 6R
2022 */
2023#define WM5100_OUT6R_ANC_SRC 0x0800 /* OUT6R_ANC_SRC */
2024#define WM5100_OUT6R_ANC_SRC_MASK 0x0800 /* OUT6R_ANC_SRC */
2025#define WM5100_OUT6R_ANC_SRC_SHIFT 11 /* OUT6R_ANC_SRC */
2026#define WM5100_OUT6R_ANC_SRC_WIDTH 1 /* OUT6R_ANC_SRC */
2027#define WM5100_OUT6R_VOL_LIM_MASK 0x00FF /* OUT6R_VOL_LIM - [7:0] */
2028#define WM5100_OUT6R_VOL_LIM_SHIFT 0 /* OUT6R_VOL_LIM - [7:0] */
2029#define WM5100_OUT6R_VOL_LIM_WIDTH 8 /* OUT6R_VOL_LIM - [7:0] */
2030
2031/*
2032 * R1088 (0x440) - DAC AEC Control 1
2033 */
2034#define WM5100_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */
2035#define WM5100_AEC_LOOPBACK_SRC_SHIFT 2 /* AEC_LOOPBACK_SRC - [5:2] */
2036#define WM5100_AEC_LOOPBACK_SRC_WIDTH 4 /* AEC_LOOPBACK_SRC - [5:2] */
2037#define WM5100_AEC_ENA_STS 0x0002 /* AEC_ENA_STS */
2038#define WM5100_AEC_ENA_STS_MASK 0x0002 /* AEC_ENA_STS */
2039#define WM5100_AEC_ENA_STS_SHIFT 1 /* AEC_ENA_STS */
2040#define WM5100_AEC_ENA_STS_WIDTH 1 /* AEC_ENA_STS */
2041#define WM5100_AEC_LOOPBACK_ENA 0x0001 /* AEC_LOOPBACK_ENA */
2042#define WM5100_AEC_LOOPBACK_ENA_MASK 0x0001 /* AEC_LOOPBACK_ENA */
2043#define WM5100_AEC_LOOPBACK_ENA_SHIFT 0 /* AEC_LOOPBACK_ENA */
2044#define WM5100_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
2045
2046/*
2047 * R1089 (0x441) - Output Volume Ramp
2048 */
2049#define WM5100_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
2050#define WM5100_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
2051#define WM5100_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
2052#define WM5100_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
2053#define WM5100_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
2054#define WM5100_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
2055
2056/*
2057 * R1152 (0x480) - DAC Digital Volume 1L
2058 */
2059#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2060#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2061#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2062#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2063#define WM5100_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
2064#define WM5100_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
2065#define WM5100_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
2066#define WM5100_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
2067#define WM5100_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
2068#define WM5100_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
2069#define WM5100_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
2070
2071/*
2072 * R1153 (0x481) - DAC Digital Volume 1R
2073 */
2074#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2075#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2076#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2077#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2078#define WM5100_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
2079#define WM5100_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
2080#define WM5100_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
2081#define WM5100_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
2082#define WM5100_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
2083#define WM5100_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
2084#define WM5100_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
2085
2086/*
2087 * R1154 (0x482) - DAC Digital Volume 2L
2088 */
2089#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2090#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2091#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2092#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2093#define WM5100_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
2094#define WM5100_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
2095#define WM5100_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
2096#define WM5100_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
2097#define WM5100_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
2098#define WM5100_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
2099#define WM5100_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
2100
2101/*
2102 * R1155 (0x483) - DAC Digital Volume 2R
2103 */
2104#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2105#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2106#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2107#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2108#define WM5100_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
2109#define WM5100_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
2110#define WM5100_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
2111#define WM5100_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
2112#define WM5100_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
2113#define WM5100_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
2114#define WM5100_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
2115
2116/*
2117 * R1156 (0x484) - DAC Digital Volume 3L
2118 */
2119#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2120#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2121#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2122#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2123#define WM5100_OUT3L_MUTE 0x0100 /* OUT3L_MUTE */
2124#define WM5100_OUT3L_MUTE_MASK 0x0100 /* OUT3L_MUTE */
2125#define WM5100_OUT3L_MUTE_SHIFT 8 /* OUT3L_MUTE */
2126#define WM5100_OUT3L_MUTE_WIDTH 1 /* OUT3L_MUTE */
2127#define WM5100_OUT3L_VOL_MASK 0x00FF /* OUT3L_VOL - [7:0] */
2128#define WM5100_OUT3L_VOL_SHIFT 0 /* OUT3L_VOL - [7:0] */
2129#define WM5100_OUT3L_VOL_WIDTH 8 /* OUT3L_VOL - [7:0] */
2130
2131/*
2132 * R1157 (0x485) - DAC Digital Volume 3R
2133 */
2134#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2135#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2136#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2137#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2138#define WM5100_OUT3R_MUTE 0x0100 /* OUT3R_MUTE */
2139#define WM5100_OUT3R_MUTE_MASK 0x0100 /* OUT3R_MUTE */
2140#define WM5100_OUT3R_MUTE_SHIFT 8 /* OUT3R_MUTE */
2141#define WM5100_OUT3R_MUTE_WIDTH 1 /* OUT3R_MUTE */
2142#define WM5100_OUT3R_VOL_MASK 0x00FF /* OUT3R_VOL - [7:0] */
2143#define WM5100_OUT3R_VOL_SHIFT 0 /* OUT3R_VOL - [7:0] */
2144#define WM5100_OUT3R_VOL_WIDTH 8 /* OUT3R_VOL - [7:0] */
2145
2146/*
2147 * R1158 (0x486) - DAC Digital Volume 4L
2148 */
2149#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2150#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2151#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2152#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2153#define WM5100_OUT4L_MUTE 0x0100 /* OUT4L_MUTE */
2154#define WM5100_OUT4L_MUTE_MASK 0x0100 /* OUT4L_MUTE */
2155#define WM5100_OUT4L_MUTE_SHIFT 8 /* OUT4L_MUTE */
2156#define WM5100_OUT4L_MUTE_WIDTH 1 /* OUT4L_MUTE */
2157#define WM5100_OUT4L_VOL_MASK 0x00FF /* OUT4L_VOL - [7:0] */
2158#define WM5100_OUT4L_VOL_SHIFT 0 /* OUT4L_VOL - [7:0] */
2159#define WM5100_OUT4L_VOL_WIDTH 8 /* OUT4L_VOL - [7:0] */
2160
2161/*
2162 * R1159 (0x487) - DAC Digital Volume 4R
2163 */
2164#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2165#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2166#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2167#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2168#define WM5100_OUT4R_MUTE 0x0100 /* OUT4R_MUTE */
2169#define WM5100_OUT4R_MUTE_MASK 0x0100 /* OUT4R_MUTE */
2170#define WM5100_OUT4R_MUTE_SHIFT 8 /* OUT4R_MUTE */
2171#define WM5100_OUT4R_MUTE_WIDTH 1 /* OUT4R_MUTE */
2172#define WM5100_OUT4R_VOL_MASK 0x00FF /* OUT4R_VOL - [7:0] */
2173#define WM5100_OUT4R_VOL_SHIFT 0 /* OUT4R_VOL - [7:0] */
2174#define WM5100_OUT4R_VOL_WIDTH 8 /* OUT4R_VOL - [7:0] */
2175
2176/*
2177 * R1160 (0x488) - DAC Digital Volume 5L
2178 */
2179#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2180#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2181#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2182#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2183#define WM5100_OUT5L_MUTE 0x0100 /* OUT5L_MUTE */
2184#define WM5100_OUT5L_MUTE_MASK 0x0100 /* OUT5L_MUTE */
2185#define WM5100_OUT5L_MUTE_SHIFT 8 /* OUT5L_MUTE */
2186#define WM5100_OUT5L_MUTE_WIDTH 1 /* OUT5L_MUTE */
2187#define WM5100_OUT5L_VOL_MASK 0x00FF /* OUT5L_VOL - [7:0] */
2188#define WM5100_OUT5L_VOL_SHIFT 0 /* OUT5L_VOL - [7:0] */
2189#define WM5100_OUT5L_VOL_WIDTH 8 /* OUT5L_VOL - [7:0] */
2190
2191/*
2192 * R1161 (0x489) - DAC Digital Volume 5R
2193 */
2194#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2195#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2196#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2197#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2198#define WM5100_OUT5R_MUTE 0x0100 /* OUT5R_MUTE */
2199#define WM5100_OUT5R_MUTE_MASK 0x0100 /* OUT5R_MUTE */
2200#define WM5100_OUT5R_MUTE_SHIFT 8 /* OUT5R_MUTE */
2201#define WM5100_OUT5R_MUTE_WIDTH 1 /* OUT5R_MUTE */
2202#define WM5100_OUT5R_VOL_MASK 0x00FF /* OUT5R_VOL - [7:0] */
2203#define WM5100_OUT5R_VOL_SHIFT 0 /* OUT5R_VOL - [7:0] */
2204#define WM5100_OUT5R_VOL_WIDTH 8 /* OUT5R_VOL - [7:0] */
2205
2206/*
2207 * R1162 (0x48A) - DAC Digital Volume 6L
2208 */
2209#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2210#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2211#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2212#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2213#define WM5100_OUT6L_MUTE 0x0100 /* OUT6L_MUTE */
2214#define WM5100_OUT6L_MUTE_MASK 0x0100 /* OUT6L_MUTE */
2215#define WM5100_OUT6L_MUTE_SHIFT 8 /* OUT6L_MUTE */
2216#define WM5100_OUT6L_MUTE_WIDTH 1 /* OUT6L_MUTE */
2217#define WM5100_OUT6L_VOL_MASK 0x00FF /* OUT6L_VOL - [7:0] */
2218#define WM5100_OUT6L_VOL_SHIFT 0 /* OUT6L_VOL - [7:0] */
2219#define WM5100_OUT6L_VOL_WIDTH 8 /* OUT6L_VOL - [7:0] */
2220
2221/*
2222 * R1163 (0x48B) - DAC Digital Volume 6R
2223 */
2224#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2225#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2226#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2227#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2228#define WM5100_OUT6R_MUTE 0x0100 /* OUT6R_MUTE */
2229#define WM5100_OUT6R_MUTE_MASK 0x0100 /* OUT6R_MUTE */
2230#define WM5100_OUT6R_MUTE_SHIFT 8 /* OUT6R_MUTE */
2231#define WM5100_OUT6R_MUTE_WIDTH 1 /* OUT6R_MUTE */
2232#define WM5100_OUT6R_VOL_MASK 0x00FF /* OUT6R_VOL - [7:0] */
2233#define WM5100_OUT6R_VOL_SHIFT 0 /* OUT6R_VOL - [7:0] */
2234#define WM5100_OUT6R_VOL_WIDTH 8 /* OUT6R_VOL - [7:0] */
2235
2236/*
2237 * R1216 (0x4C0) - PDM SPK1 CTRL 1
2238 */
2239#define WM5100_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
2240#define WM5100_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
2241#define WM5100_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
2242#define WM5100_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
2243#define WM5100_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
2244#define WM5100_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
2245#define WM5100_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
2246#define WM5100_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
2247#define WM5100_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
2248#define WM5100_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
2249#define WM5100_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
2250#define WM5100_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
2251#define WM5100_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
2252#define WM5100_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
2253#define WM5100_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
2254
2255/*
2256 * R1217 (0x4C1) - PDM SPK1 CTRL 2
2257 */
2258#define WM5100_SPK1_FMT 0x0001 /* SPK1_FMT */
2259#define WM5100_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
2260#define WM5100_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
2261#define WM5100_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
2262
2263/*
2264 * R1218 (0x4C2) - PDM SPK2 CTRL 1
2265 */
2266#define WM5100_SPK2R_MUTE 0x2000 /* SPK2R_MUTE */
2267#define WM5100_SPK2R_MUTE_MASK 0x2000 /* SPK2R_MUTE */
2268#define WM5100_SPK2R_MUTE_SHIFT 13 /* SPK2R_MUTE */
2269#define WM5100_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
2270#define WM5100_SPK2L_MUTE 0x1000 /* SPK2L_MUTE */
2271#define WM5100_SPK2L_MUTE_MASK 0x1000 /* SPK2L_MUTE */
2272#define WM5100_SPK2L_MUTE_SHIFT 12 /* SPK2L_MUTE */
2273#define WM5100_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
2274#define WM5100_SPK2_MUTE_ENDIAN 0x0100 /* SPK2_MUTE_ENDIAN */
2275#define WM5100_SPK2_MUTE_ENDIAN_MASK 0x0100 /* SPK2_MUTE_ENDIAN */
2276#define WM5100_SPK2_MUTE_ENDIAN_SHIFT 8 /* SPK2_MUTE_ENDIAN */
2277#define WM5100_SPK2_MUTE_ENDIAN_WIDTH 1 /* SPK2_MUTE_ENDIAN */
2278#define WM5100_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
2279#define WM5100_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
2280#define WM5100_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
2281
2282/*
2283 * R1219 (0x4C3) - PDM SPK2 CTRL 2
2284 */
2285#define WM5100_SPK2_FMT 0x0001 /* SPK2_FMT */
2286#define WM5100_SPK2_FMT_MASK 0x0001 /* SPK2_FMT */
2287#define WM5100_SPK2_FMT_SHIFT 0 /* SPK2_FMT */
2288#define WM5100_SPK2_FMT_WIDTH 1 /* SPK2_FMT */
2289
2290/*
2291 * R1280 (0x500) - Audio IF 1_1
2292 */
2293#define WM5100_AIF1_BCLK_INV 0x0080 /* AIF1_BCLK_INV */
2294#define WM5100_AIF1_BCLK_INV_MASK 0x0080 /* AIF1_BCLK_INV */
2295#define WM5100_AIF1_BCLK_INV_SHIFT 7 /* AIF1_BCLK_INV */
2296#define WM5100_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
2297#define WM5100_AIF1_BCLK_FRC 0x0040 /* AIF1_BCLK_FRC */
2298#define WM5100_AIF1_BCLK_FRC_MASK 0x0040 /* AIF1_BCLK_FRC */
2299#define WM5100_AIF1_BCLK_FRC_SHIFT 6 /* AIF1_BCLK_FRC */
2300#define WM5100_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
2301#define WM5100_AIF1_BCLK_MSTR 0x0020 /* AIF1_BCLK_MSTR */
2302#define WM5100_AIF1_BCLK_MSTR_MASK 0x0020 /* AIF1_BCLK_MSTR */
2303#define WM5100_AIF1_BCLK_MSTR_SHIFT 5 /* AIF1_BCLK_MSTR */
2304#define WM5100_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
2305#define WM5100_AIF1_BCLK_FREQ_MASK 0x001F /* AIF1_BCLK_FREQ - [4:0] */
2306#define WM5100_AIF1_BCLK_FREQ_SHIFT 0 /* AIF1_BCLK_FREQ - [4:0] */
2307#define WM5100_AIF1_BCLK_FREQ_WIDTH 5 /* AIF1_BCLK_FREQ - [4:0] */
2308
2309/*
2310 * R1281 (0x501) - Audio IF 1_2
2311 */
2312#define WM5100_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
2313#define WM5100_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
2314#define WM5100_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
2315#define WM5100_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
2316#define WM5100_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
2317#define WM5100_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
2318#define WM5100_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
2319#define WM5100_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
2320#define WM5100_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
2321#define WM5100_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
2322#define WM5100_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
2323#define WM5100_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
2324#define WM5100_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
2325#define WM5100_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
2326#define WM5100_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
2327#define WM5100_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
2328#define WM5100_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
2329#define WM5100_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
2330#define WM5100_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
2331#define WM5100_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
2332
2333/*
2334 * R1282 (0x502) - Audio IF 1_3
2335 */
2336#define WM5100_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
2337#define WM5100_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
2338#define WM5100_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
2339#define WM5100_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
2340#define WM5100_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
2341#define WM5100_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
2342#define WM5100_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
2343#define WM5100_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
2344#define WM5100_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
2345#define WM5100_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
2346#define WM5100_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
2347#define WM5100_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
2348
2349/*
2350 * R1283 (0x503) - Audio IF 1_4
2351 */
2352#define WM5100_AIF1_TRI 0x0040 /* AIF1_TRI */
2353#define WM5100_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
2354#define WM5100_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
2355#define WM5100_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
2356#define WM5100_AIF1_RATE_MASK 0x0003 /* AIF1_RATE - [1:0] */
2357#define WM5100_AIF1_RATE_SHIFT 0 /* AIF1_RATE - [1:0] */
2358#define WM5100_AIF1_RATE_WIDTH 2 /* AIF1_RATE - [1:0] */
2359
2360/*
2361 * R1284 (0x504) - Audio IF 1_5
2362 */
2363#define WM5100_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
2364#define WM5100_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
2365#define WM5100_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
2366
2367/*
2368 * R1285 (0x505) - Audio IF 1_6
2369 */
2370#define WM5100_AIF1TX_BCPF_MASK 0x1FFF /* AIF1TX_BCPF - [12:0] */
2371#define WM5100_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [12:0] */
2372#define WM5100_AIF1TX_BCPF_WIDTH 13 /* AIF1TX_BCPF - [12:0] */
2373
2374/*
2375 * R1286 (0x506) - Audio IF 1_7
2376 */
2377#define WM5100_AIF1RX_BCPF_MASK 0x1FFF /* AIF1RX_BCPF - [12:0] */
2378#define WM5100_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [12:0] */
2379#define WM5100_AIF1RX_BCPF_WIDTH 13 /* AIF1RX_BCPF - [12:0] */
2380
2381/*
2382 * R1287 (0x507) - Audio IF 1_8
2383 */
2384#define WM5100_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
2385#define WM5100_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
2386#define WM5100_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
2387#define WM5100_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
2388#define WM5100_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
2389#define WM5100_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
2390
2391/*
2392 * R1288 (0x508) - Audio IF 1_9
2393 */
2394#define WM5100_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
2395#define WM5100_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
2396#define WM5100_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
2397#define WM5100_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
2398#define WM5100_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
2399#define WM5100_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
2400
2401/*
2402 * R1289 (0x509) - Audio IF 1_10
2403 */
2404#define WM5100_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
2405#define WM5100_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
2406#define WM5100_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
2407
2408/*
2409 * R1290 (0x50A) - Audio IF 1_11
2410 */
2411#define WM5100_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
2412#define WM5100_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
2413#define WM5100_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
2414
2415/*
2416 * R1291 (0x50B) - Audio IF 1_12
2417 */
2418#define WM5100_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
2419#define WM5100_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
2420#define WM5100_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
2421
2422/*
2423 * R1292 (0x50C) - Audio IF 1_13
2424 */
2425#define WM5100_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
2426#define WM5100_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
2427#define WM5100_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
2428
2429/*
2430 * R1293 (0x50D) - Audio IF 1_14
2431 */
2432#define WM5100_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
2433#define WM5100_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
2434#define WM5100_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
2435
2436/*
2437 * R1294 (0x50E) - Audio IF 1_15
2438 */
2439#define WM5100_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
2440#define WM5100_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
2441#define WM5100_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
2442
2443/*
2444 * R1295 (0x50F) - Audio IF 1_16
2445 */
2446#define WM5100_AIF1TX7_SLOT_MASK 0x003F /* AIF1TX7_SLOT - [5:0] */
2447#define WM5100_AIF1TX7_SLOT_SHIFT 0 /* AIF1TX7_SLOT - [5:0] */
2448#define WM5100_AIF1TX7_SLOT_WIDTH 6 /* AIF1TX7_SLOT - [5:0] */
2449
2450/*
2451 * R1296 (0x510) - Audio IF 1_17
2452 */
2453#define WM5100_AIF1TX8_SLOT_MASK 0x003F /* AIF1TX8_SLOT - [5:0] */
2454#define WM5100_AIF1TX8_SLOT_SHIFT 0 /* AIF1TX8_SLOT - [5:0] */
2455#define WM5100_AIF1TX8_SLOT_WIDTH 6 /* AIF1TX8_SLOT - [5:0] */
2456
2457/*
2458 * R1297 (0x511) - Audio IF 1_18
2459 */
2460#define WM5100_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
2461#define WM5100_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
2462#define WM5100_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
2463
2464/*
2465 * R1298 (0x512) - Audio IF 1_19
2466 */
2467#define WM5100_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
2468#define WM5100_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
2469#define WM5100_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
2470
2471/*
2472 * R1299 (0x513) - Audio IF 1_20
2473 */
2474#define WM5100_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
2475#define WM5100_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
2476#define WM5100_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
2477
2478/*
2479 * R1300 (0x514) - Audio IF 1_21
2480 */
2481#define WM5100_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
2482#define WM5100_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
2483#define WM5100_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
2484
2485/*
2486 * R1301 (0x515) - Audio IF 1_22
2487 */
2488#define WM5100_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
2489#define WM5100_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
2490#define WM5100_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
2491
2492/*
2493 * R1302 (0x516) - Audio IF 1_23
2494 */
2495#define WM5100_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
2496#define WM5100_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
2497#define WM5100_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
2498
2499/*
2500 * R1303 (0x517) - Audio IF 1_24
2501 */
2502#define WM5100_AIF1RX7_SLOT_MASK 0x003F /* AIF1RX7_SLOT - [5:0] */
2503#define WM5100_AIF1RX7_SLOT_SHIFT 0 /* AIF1RX7_SLOT - [5:0] */
2504#define WM5100_AIF1RX7_SLOT_WIDTH 6 /* AIF1RX7_SLOT - [5:0] */
2505
2506/*
2507 * R1304 (0x518) - Audio IF 1_25
2508 */
2509#define WM5100_AIF1RX8_SLOT_MASK 0x003F /* AIF1RX8_SLOT - [5:0] */
2510#define WM5100_AIF1RX8_SLOT_SHIFT 0 /* AIF1RX8_SLOT - [5:0] */
2511#define WM5100_AIF1RX8_SLOT_WIDTH 6 /* AIF1RX8_SLOT - [5:0] */
2512
2513/*
2514 * R1305 (0x519) - Audio IF 1_26
2515 */
2516#define WM5100_AIF1TX8_ENA 0x0080 /* AIF1TX8_ENA */
2517#define WM5100_AIF1TX8_ENA_MASK 0x0080 /* AIF1TX8_ENA */
2518#define WM5100_AIF1TX8_ENA_SHIFT 7 /* AIF1TX8_ENA */
2519#define WM5100_AIF1TX8_ENA_WIDTH 1 /* AIF1TX8_ENA */
2520#define WM5100_AIF1TX7_ENA 0x0040 /* AIF1TX7_ENA */
2521#define WM5100_AIF1TX7_ENA_MASK 0x0040 /* AIF1TX7_ENA */
2522#define WM5100_AIF1TX7_ENA_SHIFT 6 /* AIF1TX7_ENA */
2523#define WM5100_AIF1TX7_ENA_WIDTH 1 /* AIF1TX7_ENA */
2524#define WM5100_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
2525#define WM5100_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
2526#define WM5100_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
2527#define WM5100_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
2528#define WM5100_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
2529#define WM5100_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
2530#define WM5100_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
2531#define WM5100_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
2532#define WM5100_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
2533#define WM5100_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
2534#define WM5100_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
2535#define WM5100_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
2536#define WM5100_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
2537#define WM5100_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
2538#define WM5100_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
2539#define WM5100_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
2540#define WM5100_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
2541#define WM5100_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
2542#define WM5100_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
2543#define WM5100_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
2544#define WM5100_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
2545#define WM5100_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
2546#define WM5100_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
2547#define WM5100_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
2548
2549/*
2550 * R1306 (0x51A) - Audio IF 1_27
2551 */
2552#define WM5100_AIF1RX8_ENA 0x0080 /* AIF1RX8_ENA */
2553#define WM5100_AIF1RX8_ENA_MASK 0x0080 /* AIF1RX8_ENA */
2554#define WM5100_AIF1RX8_ENA_SHIFT 7 /* AIF1RX8_ENA */
2555#define WM5100_AIF1RX8_ENA_WIDTH 1 /* AIF1RX8_ENA */
2556#define WM5100_AIF1RX7_ENA 0x0040 /* AIF1RX7_ENA */
2557#define WM5100_AIF1RX7_ENA_MASK 0x0040 /* AIF1RX7_ENA */
2558#define WM5100_AIF1RX7_ENA_SHIFT 6 /* AIF1RX7_ENA */
2559#define WM5100_AIF1RX7_ENA_WIDTH 1 /* AIF1RX7_ENA */
2560#define WM5100_AIF1RX6_ENA 0x0020 /* AIF1RX6_ENA */
2561#define WM5100_AIF1RX6_ENA_MASK 0x0020 /* AIF1RX6_ENA */
2562#define WM5100_AIF1RX6_ENA_SHIFT 5 /* AIF1RX6_ENA */
2563#define WM5100_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
2564#define WM5100_AIF1RX5_ENA 0x0010 /* AIF1RX5_ENA */
2565#define WM5100_AIF1RX5_ENA_MASK 0x0010 /* AIF1RX5_ENA */
2566#define WM5100_AIF1RX5_ENA_SHIFT 4 /* AIF1RX5_ENA */
2567#define WM5100_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
2568#define WM5100_AIF1RX4_ENA 0x0008 /* AIF1RX4_ENA */
2569#define WM5100_AIF1RX4_ENA_MASK 0x0008 /* AIF1RX4_ENA */
2570#define WM5100_AIF1RX4_ENA_SHIFT 3 /* AIF1RX4_ENA */
2571#define WM5100_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
2572#define WM5100_AIF1RX3_ENA 0x0004 /* AIF1RX3_ENA */
2573#define WM5100_AIF1RX3_ENA_MASK 0x0004 /* AIF1RX3_ENA */
2574#define WM5100_AIF1RX3_ENA_SHIFT 2 /* AIF1RX3_ENA */
2575#define WM5100_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
2576#define WM5100_AIF1RX2_ENA 0x0002 /* AIF1RX2_ENA */
2577#define WM5100_AIF1RX2_ENA_MASK 0x0002 /* AIF1RX2_ENA */
2578#define WM5100_AIF1RX2_ENA_SHIFT 1 /* AIF1RX2_ENA */
2579#define WM5100_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
2580#define WM5100_AIF1RX1_ENA 0x0001 /* AIF1RX1_ENA */
2581#define WM5100_AIF1RX1_ENA_MASK 0x0001 /* AIF1RX1_ENA */
2582#define WM5100_AIF1RX1_ENA_SHIFT 0 /* AIF1RX1_ENA */
2583#define WM5100_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
2584
2585/*
2586 * R1344 (0x540) - Audio IF 2_1
2587 */
2588#define WM5100_AIF2_BCLK_INV 0x0080 /* AIF2_BCLK_INV */
2589#define WM5100_AIF2_BCLK_INV_MASK 0x0080 /* AIF2_BCLK_INV */
2590#define WM5100_AIF2_BCLK_INV_SHIFT 7 /* AIF2_BCLK_INV */
2591#define WM5100_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2592#define WM5100_AIF2_BCLK_FRC 0x0040 /* AIF2_BCLK_FRC */
2593#define WM5100_AIF2_BCLK_FRC_MASK 0x0040 /* AIF2_BCLK_FRC */
2594#define WM5100_AIF2_BCLK_FRC_SHIFT 6 /* AIF2_BCLK_FRC */
2595#define WM5100_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2596#define WM5100_AIF2_BCLK_MSTR 0x0020 /* AIF2_BCLK_MSTR */
2597#define WM5100_AIF2_BCLK_MSTR_MASK 0x0020 /* AIF2_BCLK_MSTR */
2598#define WM5100_AIF2_BCLK_MSTR_SHIFT 5 /* AIF2_BCLK_MSTR */
2599#define WM5100_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2600#define WM5100_AIF2_BCLK_FREQ_MASK 0x001F /* AIF2_BCLK_FREQ - [4:0] */
2601#define WM5100_AIF2_BCLK_FREQ_SHIFT 0 /* AIF2_BCLK_FREQ - [4:0] */
2602#define WM5100_AIF2_BCLK_FREQ_WIDTH 5 /* AIF2_BCLK_FREQ - [4:0] */
2603
2604/*
2605 * R1345 (0x541) - Audio IF 2_2
2606 */
2607#define WM5100_AIF2TX_DAT_TRI 0x0020 /* AIF2TX_DAT_TRI */
2608#define WM5100_AIF2TX_DAT_TRI_MASK 0x0020 /* AIF2TX_DAT_TRI */
2609#define WM5100_AIF2TX_DAT_TRI_SHIFT 5 /* AIF2TX_DAT_TRI */
2610#define WM5100_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2611#define WM5100_AIF2TX_LRCLK_SRC 0x0008 /* AIF2TX_LRCLK_SRC */
2612#define WM5100_AIF2TX_LRCLK_SRC_MASK 0x0008 /* AIF2TX_LRCLK_SRC */
2613#define WM5100_AIF2TX_LRCLK_SRC_SHIFT 3 /* AIF2TX_LRCLK_SRC */
2614#define WM5100_AIF2TX_LRCLK_SRC_WIDTH 1 /* AIF2TX_LRCLK_SRC */
2615#define WM5100_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2616#define WM5100_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2617#define WM5100_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2618#define WM5100_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2619#define WM5100_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2620#define WM5100_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2621#define WM5100_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2622#define WM5100_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2623#define WM5100_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2624#define WM5100_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2625#define WM5100_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2626#define WM5100_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2627
2628/*
2629 * R1346 (0x542) - Audio IF 2_3
2630 */
2631#define WM5100_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2632#define WM5100_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2633#define WM5100_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2634#define WM5100_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2635#define WM5100_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2636#define WM5100_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2637#define WM5100_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2638#define WM5100_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2639#define WM5100_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2640#define WM5100_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2641#define WM5100_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2642#define WM5100_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2643
2644/*
2645 * R1347 (0x543) - Audio IF 2_4
2646 */
2647#define WM5100_AIF2_TRI 0x0040 /* AIF2_TRI */
2648#define WM5100_AIF2_TRI_MASK 0x0040 /* AIF2_TRI */
2649#define WM5100_AIF2_TRI_SHIFT 6 /* AIF2_TRI */
2650#define WM5100_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2651#define WM5100_AIF2_RATE_MASK 0x0003 /* AIF2_RATE - [1:0] */
2652#define WM5100_AIF2_RATE_SHIFT 0 /* AIF2_RATE - [1:0] */
2653#define WM5100_AIF2_RATE_WIDTH 2 /* AIF2_RATE - [1:0] */
2654
2655/*
2656 * R1348 (0x544) - Audio IF 2_5
2657 */
2658#define WM5100_AIF2_FMT_MASK 0x0007 /* AIF2_FMT - [2:0] */
2659#define WM5100_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [2:0] */
2660#define WM5100_AIF2_FMT_WIDTH 3 /* AIF2_FMT - [2:0] */
2661
2662/*
2663 * R1349 (0x545) - Audio IF 2_6
2664 */
2665#define WM5100_AIF2TX_BCPF_MASK 0x1FFF /* AIF2TX_BCPF - [12:0] */
2666#define WM5100_AIF2TX_BCPF_SHIFT 0 /* AIF2TX_BCPF - [12:0] */
2667#define WM5100_AIF2TX_BCPF_WIDTH 13 /* AIF2TX_BCPF - [12:0] */
2668
2669/*
2670 * R1350 (0x546) - Audio IF 2_7
2671 */
2672#define WM5100_AIF2RX_BCPF_MASK 0x1FFF /* AIF2RX_BCPF - [12:0] */
2673#define WM5100_AIF2RX_BCPF_SHIFT 0 /* AIF2RX_BCPF - [12:0] */
2674#define WM5100_AIF2RX_BCPF_WIDTH 13 /* AIF2RX_BCPF - [12:0] */
2675
2676/*
2677 * R1351 (0x547) - Audio IF 2_8
2678 */
2679#define WM5100_AIF2TX_WL_MASK 0x3F00 /* AIF2TX_WL - [13:8] */
2680#define WM5100_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [13:8] */
2681#define WM5100_AIF2TX_WL_WIDTH 6 /* AIF2TX_WL - [13:8] */
2682#define WM5100_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2683#define WM5100_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2684#define WM5100_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2685
2686/*
2687 * R1352 (0x548) - Audio IF 2_9
2688 */
2689#define WM5100_AIF2RX_WL_MASK 0x3F00 /* AIF2RX_WL - [13:8] */
2690#define WM5100_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [13:8] */
2691#define WM5100_AIF2RX_WL_WIDTH 6 /* AIF2RX_WL - [13:8] */
2692#define WM5100_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2693#define WM5100_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2694#define WM5100_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2695
2696/*
2697 * R1353 (0x549) - Audio IF 2_10
2698 */
2699#define WM5100_AIF2TX1_SLOT_MASK 0x003F /* AIF2TX1_SLOT - [5:0] */
2700#define WM5100_AIF2TX1_SLOT_SHIFT 0 /* AIF2TX1_SLOT - [5:0] */
2701#define WM5100_AIF2TX1_SLOT_WIDTH 6 /* AIF2TX1_SLOT - [5:0] */
2702
2703/*
2704 * R1354 (0x54A) - Audio IF 2_11
2705 */
2706#define WM5100_AIF2TX2_SLOT_MASK 0x003F /* AIF2TX2_SLOT - [5:0] */
2707#define WM5100_AIF2TX2_SLOT_SHIFT 0 /* AIF2TX2_SLOT - [5:0] */
2708#define WM5100_AIF2TX2_SLOT_WIDTH 6 /* AIF2TX2_SLOT - [5:0] */
2709
2710/*
2711 * R1361 (0x551) - Audio IF 2_18
2712 */
2713#define WM5100_AIF2RX1_SLOT_MASK 0x003F /* AIF2RX1_SLOT - [5:0] */
2714#define WM5100_AIF2RX1_SLOT_SHIFT 0 /* AIF2RX1_SLOT - [5:0] */
2715#define WM5100_AIF2RX1_SLOT_WIDTH 6 /* AIF2RX1_SLOT - [5:0] */
2716
2717/*
2718 * R1362 (0x552) - Audio IF 2_19
2719 */
2720#define WM5100_AIF2RX2_SLOT_MASK 0x003F /* AIF2RX2_SLOT - [5:0] */
2721#define WM5100_AIF2RX2_SLOT_SHIFT 0 /* AIF2RX2_SLOT - [5:0] */
2722#define WM5100_AIF2RX2_SLOT_WIDTH 6 /* AIF2RX2_SLOT - [5:0] */
2723
2724/*
2725 * R1369 (0x559) - Audio IF 2_26
2726 */
2727#define WM5100_AIF2TX2_ENA 0x0002 /* AIF2TX2_ENA */
2728#define WM5100_AIF2TX2_ENA_MASK 0x0002 /* AIF2TX2_ENA */
2729#define WM5100_AIF2TX2_ENA_SHIFT 1 /* AIF2TX2_ENA */
2730#define WM5100_AIF2TX2_ENA_WIDTH 1 /* AIF2TX2_ENA */
2731#define WM5100_AIF2TX1_ENA 0x0001 /* AIF2TX1_ENA */
2732#define WM5100_AIF2TX1_ENA_MASK 0x0001 /* AIF2TX1_ENA */
2733#define WM5100_AIF2TX1_ENA_SHIFT 0 /* AIF2TX1_ENA */
2734#define WM5100_AIF2TX1_ENA_WIDTH 1 /* AIF2TX1_ENA */
2735
2736/*
2737 * R1370 (0x55A) - Audio IF 2_27
2738 */
2739#define WM5100_AIF2RX2_ENA 0x0002 /* AIF2RX2_ENA */
2740#define WM5100_AIF2RX2_ENA_MASK 0x0002 /* AIF2RX2_ENA */
2741#define WM5100_AIF2RX2_ENA_SHIFT 1 /* AIF2RX2_ENA */
2742#define WM5100_AIF2RX2_ENA_WIDTH 1 /* AIF2RX2_ENA */
2743#define WM5100_AIF2RX1_ENA 0x0001 /* AIF2RX1_ENA */
2744#define WM5100_AIF2RX1_ENA_MASK 0x0001 /* AIF2RX1_ENA */
2745#define WM5100_AIF2RX1_ENA_SHIFT 0 /* AIF2RX1_ENA */
2746#define WM5100_AIF2RX1_ENA_WIDTH 1 /* AIF2RX1_ENA */
2747
2748/*
2749 * R1408 (0x580) - Audio IF 3_1
2750 */
2751#define WM5100_AIF3_BCLK_INV 0x0080 /* AIF3_BCLK_INV */
2752#define WM5100_AIF3_BCLK_INV_MASK 0x0080 /* AIF3_BCLK_INV */
2753#define WM5100_AIF3_BCLK_INV_SHIFT 7 /* AIF3_BCLK_INV */
2754#define WM5100_AIF3_BCLK_INV_WIDTH 1 /* AIF3_BCLK_INV */
2755#define WM5100_AIF3_BCLK_FRC 0x0040 /* AIF3_BCLK_FRC */
2756#define WM5100_AIF3_BCLK_FRC_MASK 0x0040 /* AIF3_BCLK_FRC */
2757#define WM5100_AIF3_BCLK_FRC_SHIFT 6 /* AIF3_BCLK_FRC */
2758#define WM5100_AIF3_BCLK_FRC_WIDTH 1 /* AIF3_BCLK_FRC */
2759#define WM5100_AIF3_BCLK_MSTR 0x0020 /* AIF3_BCLK_MSTR */
2760#define WM5100_AIF3_BCLK_MSTR_MASK 0x0020 /* AIF3_BCLK_MSTR */
2761#define WM5100_AIF3_BCLK_MSTR_SHIFT 5 /* AIF3_BCLK_MSTR */
2762#define WM5100_AIF3_BCLK_MSTR_WIDTH 1 /* AIF3_BCLK_MSTR */
2763#define WM5100_AIF3_BCLK_FREQ_MASK 0x001F /* AIF3_BCLK_FREQ - [4:0] */
2764#define WM5100_AIF3_BCLK_FREQ_SHIFT 0 /* AIF3_BCLK_FREQ - [4:0] */
2765#define WM5100_AIF3_BCLK_FREQ_WIDTH 5 /* AIF3_BCLK_FREQ - [4:0] */
2766
2767/*
2768 * R1409 (0x581) - Audio IF 3_2
2769 */
2770#define WM5100_AIF3TX_DAT_TRI 0x0020 /* AIF3TX_DAT_TRI */
2771#define WM5100_AIF3TX_DAT_TRI_MASK 0x0020 /* AIF3TX_DAT_TRI */
2772#define WM5100_AIF3TX_DAT_TRI_SHIFT 5 /* AIF3TX_DAT_TRI */
2773#define WM5100_AIF3TX_DAT_TRI_WIDTH 1 /* AIF3TX_DAT_TRI */
2774#define WM5100_AIF3TX_LRCLK_SRC 0x0008 /* AIF3TX_LRCLK_SRC */
2775#define WM5100_AIF3TX_LRCLK_SRC_MASK 0x0008 /* AIF3TX_LRCLK_SRC */
2776#define WM5100_AIF3TX_LRCLK_SRC_SHIFT 3 /* AIF3TX_LRCLK_SRC */
2777#define WM5100_AIF3TX_LRCLK_SRC_WIDTH 1 /* AIF3TX_LRCLK_SRC */
2778#define WM5100_AIF3TX_LRCLK_INV 0x0004 /* AIF3TX_LRCLK_INV */
2779#define WM5100_AIF3TX_LRCLK_INV_MASK 0x0004 /* AIF3TX_LRCLK_INV */
2780#define WM5100_AIF3TX_LRCLK_INV_SHIFT 2 /* AIF3TX_LRCLK_INV */
2781#define WM5100_AIF3TX_LRCLK_INV_WIDTH 1 /* AIF3TX_LRCLK_INV */
2782#define WM5100_AIF3TX_LRCLK_FRC 0x0002 /* AIF3TX_LRCLK_FRC */
2783#define WM5100_AIF3TX_LRCLK_FRC_MASK 0x0002 /* AIF3TX_LRCLK_FRC */
2784#define WM5100_AIF3TX_LRCLK_FRC_SHIFT 1 /* AIF3TX_LRCLK_FRC */
2785#define WM5100_AIF3TX_LRCLK_FRC_WIDTH 1 /* AIF3TX_LRCLK_FRC */
2786#define WM5100_AIF3TX_LRCLK_MSTR 0x0001 /* AIF3TX_LRCLK_MSTR */
2787#define WM5100_AIF3TX_LRCLK_MSTR_MASK 0x0001 /* AIF3TX_LRCLK_MSTR */
2788#define WM5100_AIF3TX_LRCLK_MSTR_SHIFT 0 /* AIF3TX_LRCLK_MSTR */
2789#define WM5100_AIF3TX_LRCLK_MSTR_WIDTH 1 /* AIF3TX_LRCLK_MSTR */
2790
2791/*
2792 * R1410 (0x582) - Audio IF 3_3
2793 */
2794#define WM5100_AIF3RX_LRCLK_INV 0x0004 /* AIF3RX_LRCLK_INV */
2795#define WM5100_AIF3RX_LRCLK_INV_MASK 0x0004 /* AIF3RX_LRCLK_INV */
2796#define WM5100_AIF3RX_LRCLK_INV_SHIFT 2 /* AIF3RX_LRCLK_INV */
2797#define WM5100_AIF3RX_LRCLK_INV_WIDTH 1 /* AIF3RX_LRCLK_INV */
2798#define WM5100_AIF3RX_LRCLK_FRC 0x0002 /* AIF3RX_LRCLK_FRC */
2799#define WM5100_AIF3RX_LRCLK_FRC_MASK 0x0002 /* AIF3RX_LRCLK_FRC */
2800#define WM5100_AIF3RX_LRCLK_FRC_SHIFT 1 /* AIF3RX_LRCLK_FRC */
2801#define WM5100_AIF3RX_LRCLK_FRC_WIDTH 1 /* AIF3RX_LRCLK_FRC */
2802#define WM5100_AIF3RX_LRCLK_MSTR 0x0001 /* AIF3RX_LRCLK_MSTR */
2803#define WM5100_AIF3RX_LRCLK_MSTR_MASK 0x0001 /* AIF3RX_LRCLK_MSTR */
2804#define WM5100_AIF3RX_LRCLK_MSTR_SHIFT 0 /* AIF3RX_LRCLK_MSTR */
2805#define WM5100_AIF3RX_LRCLK_MSTR_WIDTH 1 /* AIF3RX_LRCLK_MSTR */
2806
2807/*
2808 * R1411 (0x583) - Audio IF 3_4
2809 */
2810#define WM5100_AIF3_TRI 0x0040 /* AIF3_TRI */
2811#define WM5100_AIF3_TRI_MASK 0x0040 /* AIF3_TRI */
2812#define WM5100_AIF3_TRI_SHIFT 6 /* AIF3_TRI */
2813#define WM5100_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
2814#define WM5100_AIF3_RATE_MASK 0x0003 /* AIF3_RATE - [1:0] */
2815#define WM5100_AIF3_RATE_SHIFT 0 /* AIF3_RATE - [1:0] */
2816#define WM5100_AIF3_RATE_WIDTH 2 /* AIF3_RATE - [1:0] */
2817
2818/*
2819 * R1412 (0x584) - Audio IF 3_5
2820 */
2821#define WM5100_AIF3_FMT_MASK 0x0007 /* AIF3_FMT - [2:0] */
2822#define WM5100_AIF3_FMT_SHIFT 0 /* AIF3_FMT - [2:0] */
2823#define WM5100_AIF3_FMT_WIDTH 3 /* AIF3_FMT - [2:0] */
2824
2825/*
2826 * R1413 (0x585) - Audio IF 3_6
2827 */
2828#define WM5100_AIF3TX_BCPF_MASK 0x1FFF /* AIF3TX_BCPF - [12:0] */
2829#define WM5100_AIF3TX_BCPF_SHIFT 0 /* AIF3TX_BCPF - [12:0] */
2830#define WM5100_AIF3TX_BCPF_WIDTH 13 /* AIF3TX_BCPF - [12:0] */
2831
2832/*
2833 * R1414 (0x586) - Audio IF 3_7
2834 */
2835#define WM5100_AIF3RX_BCPF_MASK 0x1FFF /* AIF3RX_BCPF - [12:0] */
2836#define WM5100_AIF3RX_BCPF_SHIFT 0 /* AIF3RX_BCPF - [12:0] */
2837#define WM5100_AIF3RX_BCPF_WIDTH 13 /* AIF3RX_BCPF - [12:0] */
2838
2839/*
2840 * R1415 (0x587) - Audio IF 3_8
2841 */
2842#define WM5100_AIF3TX_WL_MASK 0x3F00 /* AIF3TX_WL - [13:8] */
2843#define WM5100_AIF3TX_WL_SHIFT 8 /* AIF3TX_WL - [13:8] */
2844#define WM5100_AIF3TX_WL_WIDTH 6 /* AIF3TX_WL - [13:8] */
2845#define WM5100_AIF3TX_SLOT_LEN_MASK 0x00FF /* AIF3TX_SLOT_LEN - [7:0] */
2846#define WM5100_AIF3TX_SLOT_LEN_SHIFT 0 /* AIF3TX_SLOT_LEN - [7:0] */
2847#define WM5100_AIF3TX_SLOT_LEN_WIDTH 8 /* AIF3TX_SLOT_LEN - [7:0] */
2848
2849/*
2850 * R1416 (0x588) - Audio IF 3_9
2851 */
2852#define WM5100_AIF3RX_WL_MASK 0x3F00 /* AIF3RX_WL - [13:8] */
2853#define WM5100_AIF3RX_WL_SHIFT 8 /* AIF3RX_WL - [13:8] */
2854#define WM5100_AIF3RX_WL_WIDTH 6 /* AIF3RX_WL - [13:8] */
2855#define WM5100_AIF3RX_SLOT_LEN_MASK 0x00FF /* AIF3RX_SLOT_LEN - [7:0] */
2856#define WM5100_AIF3RX_SLOT_LEN_SHIFT 0 /* AIF3RX_SLOT_LEN - [7:0] */
2857#define WM5100_AIF3RX_SLOT_LEN_WIDTH 8 /* AIF3RX_SLOT_LEN - [7:0] */
2858
2859/*
2860 * R1417 (0x589) - Audio IF 3_10
2861 */
2862#define WM5100_AIF3TX1_SLOT_MASK 0x003F /* AIF3TX1_SLOT - [5:0] */
2863#define WM5100_AIF3TX1_SLOT_SHIFT 0 /* AIF3TX1_SLOT - [5:0] */
2864#define WM5100_AIF3TX1_SLOT_WIDTH 6 /* AIF3TX1_SLOT - [5:0] */
2865
2866/*
2867 * R1418 (0x58A) - Audio IF 3_11
2868 */
2869#define WM5100_AIF3TX2_SLOT_MASK 0x003F /* AIF3TX2_SLOT - [5:0] */
2870#define WM5100_AIF3TX2_SLOT_SHIFT 0 /* AIF3TX2_SLOT - [5:0] */
2871#define WM5100_AIF3TX2_SLOT_WIDTH 6 /* AIF3TX2_SLOT - [5:0] */
2872
2873/*
2874 * R1425 (0x591) - Audio IF 3_18
2875 */
2876#define WM5100_AIF3RX1_SLOT_MASK 0x003F /* AIF3RX1_SLOT - [5:0] */
2877#define WM5100_AIF3RX1_SLOT_SHIFT 0 /* AIF3RX1_SLOT - [5:0] */
2878#define WM5100_AIF3RX1_SLOT_WIDTH 6 /* AIF3RX1_SLOT - [5:0] */
2879
2880/*
2881 * R1426 (0x592) - Audio IF 3_19
2882 */
2883#define WM5100_AIF3RX2_SLOT_MASK 0x003F /* AIF3RX2_SLOT - [5:0] */
2884#define WM5100_AIF3RX2_SLOT_SHIFT 0 /* AIF3RX2_SLOT - [5:0] */
2885#define WM5100_AIF3RX2_SLOT_WIDTH 6 /* AIF3RX2_SLOT - [5:0] */
2886
2887/*
2888 * R1433 (0x599) - Audio IF 3_26
2889 */
2890#define WM5100_AIF3TX2_ENA 0x0002 /* AIF3TX2_ENA */
2891#define WM5100_AIF3TX2_ENA_MASK 0x0002 /* AIF3TX2_ENA */
2892#define WM5100_AIF3TX2_ENA_SHIFT 1 /* AIF3TX2_ENA */
2893#define WM5100_AIF3TX2_ENA_WIDTH 1 /* AIF3TX2_ENA */
2894#define WM5100_AIF3TX1_ENA 0x0001 /* AIF3TX1_ENA */
2895#define WM5100_AIF3TX1_ENA_MASK 0x0001 /* AIF3TX1_ENA */
2896#define WM5100_AIF3TX1_ENA_SHIFT 0 /* AIF3TX1_ENA */
2897#define WM5100_AIF3TX1_ENA_WIDTH 1 /* AIF3TX1_ENA */
2898
2899/*
2900 * R1434 (0x59A) - Audio IF 3_27
2901 */
2902#define WM5100_AIF3RX2_ENA 0x0002 /* AIF3RX2_ENA */
2903#define WM5100_AIF3RX2_ENA_MASK 0x0002 /* AIF3RX2_ENA */
2904#define WM5100_AIF3RX2_ENA_SHIFT 1 /* AIF3RX2_ENA */
2905#define WM5100_AIF3RX2_ENA_WIDTH 1 /* AIF3RX2_ENA */
2906#define WM5100_AIF3RX1_ENA 0x0001 /* AIF3RX1_ENA */
2907#define WM5100_AIF3RX1_ENA_MASK 0x0001 /* AIF3RX1_ENA */
2908#define WM5100_AIF3RX1_ENA_SHIFT 0 /* AIF3RX1_ENA */
2909#define WM5100_AIF3RX1_ENA_WIDTH 1 /* AIF3RX1_ENA */
2910
2911#define WM5100_MIXER_VOL_MASK 0x00FE /* MIXER_VOL - [7:1] */
2912#define WM5100_MIXER_VOL_SHIFT 1 /* MIXER_VOL - [7:1] */
2913#define WM5100_MIXER_VOL_WIDTH 7 /* MIXER_VOL - [7:1] */
2914
2915/*
2916 * R3072 (0xC00) - GPIO CTRL 1
2917 */
2918#define WM5100_GP1_DIR 0x8000 /* GP1_DIR */
2919#define WM5100_GP1_DIR_MASK 0x8000 /* GP1_DIR */
2920#define WM5100_GP1_DIR_SHIFT 15 /* GP1_DIR */
2921#define WM5100_GP1_DIR_WIDTH 1 /* GP1_DIR */
2922#define WM5100_GP1_PU 0x4000 /* GP1_PU */
2923#define WM5100_GP1_PU_MASK 0x4000 /* GP1_PU */
2924#define WM5100_GP1_PU_SHIFT 14 /* GP1_PU */
2925#define WM5100_GP1_PU_WIDTH 1 /* GP1_PU */
2926#define WM5100_GP1_PD 0x2000 /* GP1_PD */
2927#define WM5100_GP1_PD_MASK 0x2000 /* GP1_PD */
2928#define WM5100_GP1_PD_SHIFT 13 /* GP1_PD */
2929#define WM5100_GP1_PD_WIDTH 1 /* GP1_PD */
2930#define WM5100_GP1_POL 0x0400 /* GP1_POL */
2931#define WM5100_GP1_POL_MASK 0x0400 /* GP1_POL */
2932#define WM5100_GP1_POL_SHIFT 10 /* GP1_POL */
2933#define WM5100_GP1_POL_WIDTH 1 /* GP1_POL */
2934#define WM5100_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
2935#define WM5100_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
2936#define WM5100_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
2937#define WM5100_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
2938#define WM5100_GP1_DB 0x0100 /* GP1_DB */
2939#define WM5100_GP1_DB_MASK 0x0100 /* GP1_DB */
2940#define WM5100_GP1_DB_SHIFT 8 /* GP1_DB */
2941#define WM5100_GP1_DB_WIDTH 1 /* GP1_DB */
2942#define WM5100_GP1_LVL 0x0040 /* GP1_LVL */
2943#define WM5100_GP1_LVL_MASK 0x0040 /* GP1_LVL */
2944#define WM5100_GP1_LVL_SHIFT 6 /* GP1_LVL */
2945#define WM5100_GP1_LVL_WIDTH 1 /* GP1_LVL */
2946#define WM5100_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
2947#define WM5100_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
2948#define WM5100_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
2949
2950/*
2951 * R3073 (0xC01) - GPIO CTRL 2
2952 */
2953#define WM5100_GP2_DIR 0x8000 /* GP2_DIR */
2954#define WM5100_GP2_DIR_MASK 0x8000 /* GP2_DIR */
2955#define WM5100_GP2_DIR_SHIFT 15 /* GP2_DIR */
2956#define WM5100_GP2_DIR_WIDTH 1 /* GP2_DIR */
2957#define WM5100_GP2_PU 0x4000 /* GP2_PU */
2958#define WM5100_GP2_PU_MASK 0x4000 /* GP2_PU */
2959#define WM5100_GP2_PU_SHIFT 14 /* GP2_PU */
2960#define WM5100_GP2_PU_WIDTH 1 /* GP2_PU */
2961#define WM5100_GP2_PD 0x2000 /* GP2_PD */
2962#define WM5100_GP2_PD_MASK 0x2000 /* GP2_PD */
2963#define WM5100_GP2_PD_SHIFT 13 /* GP2_PD */
2964#define WM5100_GP2_PD_WIDTH 1 /* GP2_PD */
2965#define WM5100_GP2_POL 0x0400 /* GP2_POL */
2966#define WM5100_GP2_POL_MASK 0x0400 /* GP2_POL */
2967#define WM5100_GP2_POL_SHIFT 10 /* GP2_POL */
2968#define WM5100_GP2_POL_WIDTH 1 /* GP2_POL */
2969#define WM5100_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
2970#define WM5100_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
2971#define WM5100_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
2972#define WM5100_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
2973#define WM5100_GP2_DB 0x0100 /* GP2_DB */
2974#define WM5100_GP2_DB_MASK 0x0100 /* GP2_DB */
2975#define WM5100_GP2_DB_SHIFT 8 /* GP2_DB */
2976#define WM5100_GP2_DB_WIDTH 1 /* GP2_DB */
2977#define WM5100_GP2_LVL 0x0040 /* GP2_LVL */
2978#define WM5100_GP2_LVL_MASK 0x0040 /* GP2_LVL */
2979#define WM5100_GP2_LVL_SHIFT 6 /* GP2_LVL */
2980#define WM5100_GP2_LVL_WIDTH 1 /* GP2_LVL */
2981#define WM5100_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
2982#define WM5100_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
2983#define WM5100_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
2984
2985/*
2986 * R3074 (0xC02) - GPIO CTRL 3
2987 */
2988#define WM5100_GP3_DIR 0x8000 /* GP3_DIR */
2989#define WM5100_GP3_DIR_MASK 0x8000 /* GP3_DIR */
2990#define WM5100_GP3_DIR_SHIFT 15 /* GP3_DIR */
2991#define WM5100_GP3_DIR_WIDTH 1 /* GP3_DIR */
2992#define WM5100_GP3_PU 0x4000 /* GP3_PU */
2993#define WM5100_GP3_PU_MASK 0x4000 /* GP3_PU */
2994#define WM5100_GP3_PU_SHIFT 14 /* GP3_PU */
2995#define WM5100_GP3_PU_WIDTH 1 /* GP3_PU */
2996#define WM5100_GP3_PD 0x2000 /* GP3_PD */
2997#define WM5100_GP3_PD_MASK 0x2000 /* GP3_PD */
2998#define WM5100_GP3_PD_SHIFT 13 /* GP3_PD */
2999#define WM5100_GP3_PD_WIDTH 1 /* GP3_PD */
3000#define WM5100_GP3_POL 0x0400 /* GP3_POL */
3001#define WM5100_GP3_POL_MASK 0x0400 /* GP3_POL */
3002#define WM5100_GP3_POL_SHIFT 10 /* GP3_POL */
3003#define WM5100_GP3_POL_WIDTH 1 /* GP3_POL */
3004#define WM5100_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3005#define WM5100_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3006#define WM5100_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3007#define WM5100_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3008#define WM5100_GP3_DB 0x0100 /* GP3_DB */
3009#define WM5100_GP3_DB_MASK 0x0100 /* GP3_DB */
3010#define WM5100_GP3_DB_SHIFT 8 /* GP3_DB */
3011#define WM5100_GP3_DB_WIDTH 1 /* GP3_DB */
3012#define WM5100_GP3_LVL 0x0040 /* GP3_LVL */
3013#define WM5100_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3014#define WM5100_GP3_LVL_SHIFT 6 /* GP3_LVL */
3015#define WM5100_GP3_LVL_WIDTH 1 /* GP3_LVL */
3016#define WM5100_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
3017#define WM5100_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
3018#define WM5100_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
3019
3020/*
3021 * R3075 (0xC03) - GPIO CTRL 4
3022 */
3023#define WM5100_GP4_DIR 0x8000 /* GP4_DIR */
3024#define WM5100_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3025#define WM5100_GP4_DIR_SHIFT 15 /* GP4_DIR */
3026#define WM5100_GP4_DIR_WIDTH 1 /* GP4_DIR */
3027#define WM5100_GP4_PU 0x4000 /* GP4_PU */
3028#define WM5100_GP4_PU_MASK 0x4000 /* GP4_PU */
3029#define WM5100_GP4_PU_SHIFT 14 /* GP4_PU */
3030#define WM5100_GP4_PU_WIDTH 1 /* GP4_PU */
3031#define WM5100_GP4_PD 0x2000 /* GP4_PD */
3032#define WM5100_GP4_PD_MASK 0x2000 /* GP4_PD */
3033#define WM5100_GP4_PD_SHIFT 13 /* GP4_PD */
3034#define WM5100_GP4_PD_WIDTH 1 /* GP4_PD */
3035#define WM5100_GP4_POL 0x0400 /* GP4_POL */
3036#define WM5100_GP4_POL_MASK 0x0400 /* GP4_POL */
3037#define WM5100_GP4_POL_SHIFT 10 /* GP4_POL */
3038#define WM5100_GP4_POL_WIDTH 1 /* GP4_POL */
3039#define WM5100_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3040#define WM5100_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3041#define WM5100_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3042#define WM5100_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3043#define WM5100_GP4_DB 0x0100 /* GP4_DB */
3044#define WM5100_GP4_DB_MASK 0x0100 /* GP4_DB */
3045#define WM5100_GP4_DB_SHIFT 8 /* GP4_DB */
3046#define WM5100_GP4_DB_WIDTH 1 /* GP4_DB */
3047#define WM5100_GP4_LVL 0x0040 /* GP4_LVL */
3048#define WM5100_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3049#define WM5100_GP4_LVL_SHIFT 6 /* GP4_LVL */
3050#define WM5100_GP4_LVL_WIDTH 1 /* GP4_LVL */
3051#define WM5100_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
3052#define WM5100_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
3053#define WM5100_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
3054
3055/*
3056 * R3076 (0xC04) - GPIO CTRL 5
3057 */
3058#define WM5100_GP5_DIR 0x8000 /* GP5_DIR */
3059#define WM5100_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3060#define WM5100_GP5_DIR_SHIFT 15 /* GP5_DIR */
3061#define WM5100_GP5_DIR_WIDTH 1 /* GP5_DIR */
3062#define WM5100_GP5_PU 0x4000 /* GP5_PU */
3063#define WM5100_GP5_PU_MASK 0x4000 /* GP5_PU */
3064#define WM5100_GP5_PU_SHIFT 14 /* GP5_PU */
3065#define WM5100_GP5_PU_WIDTH 1 /* GP5_PU */
3066#define WM5100_GP5_PD 0x2000 /* GP5_PD */
3067#define WM5100_GP5_PD_MASK 0x2000 /* GP5_PD */
3068#define WM5100_GP5_PD_SHIFT 13 /* GP5_PD */
3069#define WM5100_GP5_PD_WIDTH 1 /* GP5_PD */
3070#define WM5100_GP5_POL 0x0400 /* GP5_POL */
3071#define WM5100_GP5_POL_MASK 0x0400 /* GP5_POL */
3072#define WM5100_GP5_POL_SHIFT 10 /* GP5_POL */
3073#define WM5100_GP5_POL_WIDTH 1 /* GP5_POL */
3074#define WM5100_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3075#define WM5100_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3076#define WM5100_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3077#define WM5100_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3078#define WM5100_GP5_DB 0x0100 /* GP5_DB */
3079#define WM5100_GP5_DB_MASK 0x0100 /* GP5_DB */
3080#define WM5100_GP5_DB_SHIFT 8 /* GP5_DB */
3081#define WM5100_GP5_DB_WIDTH 1 /* GP5_DB */
3082#define WM5100_GP5_LVL 0x0040 /* GP5_LVL */
3083#define WM5100_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3084#define WM5100_GP5_LVL_SHIFT 6 /* GP5_LVL */
3085#define WM5100_GP5_LVL_WIDTH 1 /* GP5_LVL */
3086#define WM5100_GP5_FN_MASK 0x003F /* GP5_FN - [5:0] */
3087#define WM5100_GP5_FN_SHIFT 0 /* GP5_FN - [5:0] */
3088#define WM5100_GP5_FN_WIDTH 6 /* GP5_FN - [5:0] */
3089
3090/*
3091 * R3077 (0xC05) - GPIO CTRL 6
3092 */
3093#define WM5100_GP6_DIR 0x8000 /* GP6_DIR */
3094#define WM5100_GP6_DIR_MASK 0x8000 /* GP6_DIR */
3095#define WM5100_GP6_DIR_SHIFT 15 /* GP6_DIR */
3096#define WM5100_GP6_DIR_WIDTH 1 /* GP6_DIR */
3097#define WM5100_GP6_PU 0x4000 /* GP6_PU */
3098#define WM5100_GP6_PU_MASK 0x4000 /* GP6_PU */
3099#define WM5100_GP6_PU_SHIFT 14 /* GP6_PU */
3100#define WM5100_GP6_PU_WIDTH 1 /* GP6_PU */
3101#define WM5100_GP6_PD 0x2000 /* GP6_PD */
3102#define WM5100_GP6_PD_MASK 0x2000 /* GP6_PD */
3103#define WM5100_GP6_PD_SHIFT 13 /* GP6_PD */
3104#define WM5100_GP6_PD_WIDTH 1 /* GP6_PD */
3105#define WM5100_GP6_POL 0x0400 /* GP6_POL */
3106#define WM5100_GP6_POL_MASK 0x0400 /* GP6_POL */
3107#define WM5100_GP6_POL_SHIFT 10 /* GP6_POL */
3108#define WM5100_GP6_POL_WIDTH 1 /* GP6_POL */
3109#define WM5100_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
3110#define WM5100_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
3111#define WM5100_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
3112#define WM5100_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
3113#define WM5100_GP6_DB 0x0100 /* GP6_DB */
3114#define WM5100_GP6_DB_MASK 0x0100 /* GP6_DB */
3115#define WM5100_GP6_DB_SHIFT 8 /* GP6_DB */
3116#define WM5100_GP6_DB_WIDTH 1 /* GP6_DB */
3117#define WM5100_GP6_LVL 0x0040 /* GP6_LVL */
3118#define WM5100_GP6_LVL_MASK 0x0040 /* GP6_LVL */
3119#define WM5100_GP6_LVL_SHIFT 6 /* GP6_LVL */
3120#define WM5100_GP6_LVL_WIDTH 1 /* GP6_LVL */
3121#define WM5100_GP6_FN_MASK 0x003F /* GP6_FN - [5:0] */
3122#define WM5100_GP6_FN_SHIFT 0 /* GP6_FN - [5:0] */
3123#define WM5100_GP6_FN_WIDTH 6 /* GP6_FN - [5:0] */
3124
3125/*
3126 * R3107 (0xC23) - Misc Pad Ctrl 1
3127 */
3128#define WM5100_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
3129#define WM5100_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
3130#define WM5100_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
3131#define WM5100_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3132#define WM5100_MCLK2_PD 0x2000 /* MCLK2_PD */
3133#define WM5100_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
3134#define WM5100_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
3135#define WM5100_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3136#define WM5100_MCLK1_PD 0x1000 /* MCLK1_PD */
3137#define WM5100_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
3138#define WM5100_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
3139#define WM5100_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3140#define WM5100_RESET_PU 0x0002 /* RESET_PU */
3141#define WM5100_RESET_PU_MASK 0x0002 /* RESET_PU */
3142#define WM5100_RESET_PU_SHIFT 1 /* RESET_PU */
3143#define WM5100_RESET_PU_WIDTH 1 /* RESET_PU */
3144#define WM5100_ADDR_PD 0x0001 /* ADDR_PD */
3145#define WM5100_ADDR_PD_MASK 0x0001 /* ADDR_PD */
3146#define WM5100_ADDR_PD_SHIFT 0 /* ADDR_PD */
3147#define WM5100_ADDR_PD_WIDTH 1 /* ADDR_PD */
3148
3149/*
3150 * R3108 (0xC24) - Misc Pad Ctrl 2
3151 */
3152#define WM5100_DMICDAT4_PD 0x0008 /* DMICDAT4_PD */
3153#define WM5100_DMICDAT4_PD_MASK 0x0008 /* DMICDAT4_PD */
3154#define WM5100_DMICDAT4_PD_SHIFT 3 /* DMICDAT4_PD */
3155#define WM5100_DMICDAT4_PD_WIDTH 1 /* DMICDAT4_PD */
3156#define WM5100_DMICDAT3_PD 0x0004 /* DMICDAT3_PD */
3157#define WM5100_DMICDAT3_PD_MASK 0x0004 /* DMICDAT3_PD */
3158#define WM5100_DMICDAT3_PD_SHIFT 2 /* DMICDAT3_PD */
3159#define WM5100_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
3160#define WM5100_DMICDAT2_PD 0x0002 /* DMICDAT2_PD */
3161#define WM5100_DMICDAT2_PD_MASK 0x0002 /* DMICDAT2_PD */
3162#define WM5100_DMICDAT2_PD_SHIFT 1 /* DMICDAT2_PD */
3163#define WM5100_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3164#define WM5100_DMICDAT1_PD 0x0001 /* DMICDAT1_PD */
3165#define WM5100_DMICDAT1_PD_MASK 0x0001 /* DMICDAT1_PD */
3166#define WM5100_DMICDAT1_PD_SHIFT 0 /* DMICDAT1_PD */
3167#define WM5100_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3168
3169/*
3170 * R3109 (0xC25) - Misc Pad Ctrl 3
3171 */
3172#define WM5100_AIF1RXLRCLK_PU 0x0020 /* AIF1RXLRCLK_PU */
3173#define WM5100_AIF1RXLRCLK_PU_MASK 0x0020 /* AIF1RXLRCLK_PU */
3174#define WM5100_AIF1RXLRCLK_PU_SHIFT 5 /* AIF1RXLRCLK_PU */
3175#define WM5100_AIF1RXLRCLK_PU_WIDTH 1 /* AIF1RXLRCLK_PU */
3176#define WM5100_AIF1RXLRCLK_PD 0x0010 /* AIF1RXLRCLK_PD */
3177#define WM5100_AIF1RXLRCLK_PD_MASK 0x0010 /* AIF1RXLRCLK_PD */
3178#define WM5100_AIF1RXLRCLK_PD_SHIFT 4 /* AIF1RXLRCLK_PD */
3179#define WM5100_AIF1RXLRCLK_PD_WIDTH 1 /* AIF1RXLRCLK_PD */
3180#define WM5100_AIF1BCLK_PU 0x0008 /* AIF1BCLK_PU */
3181#define WM5100_AIF1BCLK_PU_MASK 0x0008 /* AIF1BCLK_PU */
3182#define WM5100_AIF1BCLK_PU_SHIFT 3 /* AIF1BCLK_PU */
3183#define WM5100_AIF1BCLK_PU_WIDTH 1 /* AIF1BCLK_PU */
3184#define WM5100_AIF1BCLK_PD 0x0004 /* AIF1BCLK_PD */
3185#define WM5100_AIF1BCLK_PD_MASK 0x0004 /* AIF1BCLK_PD */
3186#define WM5100_AIF1BCLK_PD_SHIFT 2 /* AIF1BCLK_PD */
3187#define WM5100_AIF1BCLK_PD_WIDTH 1 /* AIF1BCLK_PD */
3188#define WM5100_AIF1RXDAT_PU 0x0002 /* AIF1RXDAT_PU */
3189#define WM5100_AIF1RXDAT_PU_MASK 0x0002 /* AIF1RXDAT_PU */
3190#define WM5100_AIF1RXDAT_PU_SHIFT 1 /* AIF1RXDAT_PU */
3191#define WM5100_AIF1RXDAT_PU_WIDTH 1 /* AIF1RXDAT_PU */
3192#define WM5100_AIF1RXDAT_PD 0x0001 /* AIF1RXDAT_PD */
3193#define WM5100_AIF1RXDAT_PD_MASK 0x0001 /* AIF1RXDAT_PD */
3194#define WM5100_AIF1RXDAT_PD_SHIFT 0 /* AIF1RXDAT_PD */
3195#define WM5100_AIF1RXDAT_PD_WIDTH 1 /* AIF1RXDAT_PD */
3196
3197/*
3198 * R3110 (0xC26) - Misc Pad Ctrl 4
3199 */
3200#define WM5100_AIF2RXLRCLK_PU 0x0020 /* AIF2RXLRCLK_PU */
3201#define WM5100_AIF2RXLRCLK_PU_MASK 0x0020 /* AIF2RXLRCLK_PU */
3202#define WM5100_AIF2RXLRCLK_PU_SHIFT 5 /* AIF2RXLRCLK_PU */
3203#define WM5100_AIF2RXLRCLK_PU_WIDTH 1 /* AIF2RXLRCLK_PU */
3204#define WM5100_AIF2RXLRCLK_PD 0x0010 /* AIF2RXLRCLK_PD */
3205#define WM5100_AIF2RXLRCLK_PD_MASK 0x0010 /* AIF2RXLRCLK_PD */
3206#define WM5100_AIF2RXLRCLK_PD_SHIFT 4 /* AIF2RXLRCLK_PD */
3207#define WM5100_AIF2RXLRCLK_PD_WIDTH 1 /* AIF2RXLRCLK_PD */
3208#define WM5100_AIF2BCLK_PU 0x0008 /* AIF2BCLK_PU */
3209#define WM5100_AIF2BCLK_PU_MASK 0x0008 /* AIF2BCLK_PU */
3210#define WM5100_AIF2BCLK_PU_SHIFT 3 /* AIF2BCLK_PU */
3211#define WM5100_AIF2BCLK_PU_WIDTH 1 /* AIF2BCLK_PU */
3212#define WM5100_AIF2BCLK_PD 0x0004 /* AIF2BCLK_PD */
3213#define WM5100_AIF2BCLK_PD_MASK 0x0004 /* AIF2BCLK_PD */
3214#define WM5100_AIF2BCLK_PD_SHIFT 2 /* AIF2BCLK_PD */
3215#define WM5100_AIF2BCLK_PD_WIDTH 1 /* AIF2BCLK_PD */
3216#define WM5100_AIF2RXDAT_PU 0x0002 /* AIF2RXDAT_PU */
3217#define WM5100_AIF2RXDAT_PU_MASK 0x0002 /* AIF2RXDAT_PU */
3218#define WM5100_AIF2RXDAT_PU_SHIFT 1 /* AIF2RXDAT_PU */
3219#define WM5100_AIF2RXDAT_PU_WIDTH 1 /* AIF2RXDAT_PU */
3220#define WM5100_AIF2RXDAT_PD 0x0001 /* AIF2RXDAT_PD */
3221#define WM5100_AIF2RXDAT_PD_MASK 0x0001 /* AIF2RXDAT_PD */
3222#define WM5100_AIF2RXDAT_PD_SHIFT 0 /* AIF2RXDAT_PD */
3223#define WM5100_AIF2RXDAT_PD_WIDTH 1 /* AIF2RXDAT_PD */
3224
3225/*
3226 * R3111 (0xC27) - Misc Pad Ctrl 5
3227 */
3228#define WM5100_AIF3RXLRCLK_PU 0x0020 /* AIF3RXLRCLK_PU */
3229#define WM5100_AIF3RXLRCLK_PU_MASK 0x0020 /* AIF3RXLRCLK_PU */
3230#define WM5100_AIF3RXLRCLK_PU_SHIFT 5 /* AIF3RXLRCLK_PU */
3231#define WM5100_AIF3RXLRCLK_PU_WIDTH 1 /* AIF3RXLRCLK_PU */
3232#define WM5100_AIF3RXLRCLK_PD 0x0010 /* AIF3RXLRCLK_PD */
3233#define WM5100_AIF3RXLRCLK_PD_MASK 0x0010 /* AIF3RXLRCLK_PD */
3234#define WM5100_AIF3RXLRCLK_PD_SHIFT 4 /* AIF3RXLRCLK_PD */
3235#define WM5100_AIF3RXLRCLK_PD_WIDTH 1 /* AIF3RXLRCLK_PD */
3236#define WM5100_AIF3BCLK_PU 0x0008 /* AIF3BCLK_PU */
3237#define WM5100_AIF3BCLK_PU_MASK 0x0008 /* AIF3BCLK_PU */
3238#define WM5100_AIF3BCLK_PU_SHIFT 3 /* AIF3BCLK_PU */
3239#define WM5100_AIF3BCLK_PU_WIDTH 1 /* AIF3BCLK_PU */
3240#define WM5100_AIF3BCLK_PD 0x0004 /* AIF3BCLK_PD */
3241#define WM5100_AIF3BCLK_PD_MASK 0x0004 /* AIF3BCLK_PD */
3242#define WM5100_AIF3BCLK_PD_SHIFT 2 /* AIF3BCLK_PD */
3243#define WM5100_AIF3BCLK_PD_WIDTH 1 /* AIF3BCLK_PD */
3244#define WM5100_AIF3RXDAT_PU 0x0002 /* AIF3RXDAT_PU */
3245#define WM5100_AIF3RXDAT_PU_MASK 0x0002 /* AIF3RXDAT_PU */
3246#define WM5100_AIF3RXDAT_PU_SHIFT 1 /* AIF3RXDAT_PU */
3247#define WM5100_AIF3RXDAT_PU_WIDTH 1 /* AIF3RXDAT_PU */
3248#define WM5100_AIF3RXDAT_PD 0x0001 /* AIF3RXDAT_PD */
3249#define WM5100_AIF3RXDAT_PD_MASK 0x0001 /* AIF3RXDAT_PD */
3250#define WM5100_AIF3RXDAT_PD_SHIFT 0 /* AIF3RXDAT_PD */
3251#define WM5100_AIF3RXDAT_PD_WIDTH 1 /* AIF3RXDAT_PD */
3252
3253/*
3254 * R3112 (0xC28) - Misc GPIO 1
3255 */
3256#define WM5100_OPCLK_SEL_MASK 0x0003 /* OPCLK_SEL - [1:0] */
3257#define WM5100_OPCLK_SEL_SHIFT 0 /* OPCLK_SEL - [1:0] */
3258#define WM5100_OPCLK_SEL_WIDTH 2 /* OPCLK_SEL - [1:0] */
3259
3260/*
3261 * R3328 (0xD00) - Interrupt Status 1
3262 */
3263#define WM5100_GP6_EINT 0x0020 /* GP6_EINT */
3264#define WM5100_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3265#define WM5100_GP6_EINT_SHIFT 5 /* GP6_EINT */
3266#define WM5100_GP6_EINT_WIDTH 1 /* GP6_EINT */
3267#define WM5100_GP5_EINT 0x0010 /* GP5_EINT */
3268#define WM5100_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3269#define WM5100_GP5_EINT_SHIFT 4 /* GP5_EINT */
3270#define WM5100_GP5_EINT_WIDTH 1 /* GP5_EINT */
3271#define WM5100_GP4_EINT 0x0008 /* GP4_EINT */
3272#define WM5100_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3273#define WM5100_GP4_EINT_SHIFT 3 /* GP4_EINT */
3274#define WM5100_GP4_EINT_WIDTH 1 /* GP4_EINT */
3275#define WM5100_GP3_EINT 0x0004 /* GP3_EINT */
3276#define WM5100_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3277#define WM5100_GP3_EINT_SHIFT 2 /* GP3_EINT */
3278#define WM5100_GP3_EINT_WIDTH 1 /* GP3_EINT */
3279#define WM5100_GP2_EINT 0x0002 /* GP2_EINT */
3280#define WM5100_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3281#define WM5100_GP2_EINT_SHIFT 1 /* GP2_EINT */
3282#define WM5100_GP2_EINT_WIDTH 1 /* GP2_EINT */
3283#define WM5100_GP1_EINT 0x0001 /* GP1_EINT */
3284#define WM5100_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3285#define WM5100_GP1_EINT_SHIFT 0 /* GP1_EINT */
3286#define WM5100_GP1_EINT_WIDTH 1 /* GP1_EINT */
3287
3288/*
3289 * R3329 (0xD01) - Interrupt Status 2
3290 */
3291#define WM5100_DSP_IRQ6_EINT 0x0020 /* DSP_IRQ6_EINT */
3292#define WM5100_DSP_IRQ6_EINT_MASK 0x0020 /* DSP_IRQ6_EINT */
3293#define WM5100_DSP_IRQ6_EINT_SHIFT 5 /* DSP_IRQ6_EINT */
3294#define WM5100_DSP_IRQ6_EINT_WIDTH 1 /* DSP_IRQ6_EINT */
3295#define WM5100_DSP_IRQ5_EINT 0x0010 /* DSP_IRQ5_EINT */
3296#define WM5100_DSP_IRQ5_EINT_MASK 0x0010 /* DSP_IRQ5_EINT */
3297#define WM5100_DSP_IRQ5_EINT_SHIFT 4 /* DSP_IRQ5_EINT */
3298#define WM5100_DSP_IRQ5_EINT_WIDTH 1 /* DSP_IRQ5_EINT */
3299#define WM5100_DSP_IRQ4_EINT 0x0008 /* DSP_IRQ4_EINT */
3300#define WM5100_DSP_IRQ4_EINT_MASK 0x0008 /* DSP_IRQ4_EINT */
3301#define WM5100_DSP_IRQ4_EINT_SHIFT 3 /* DSP_IRQ4_EINT */
3302#define WM5100_DSP_IRQ4_EINT_WIDTH 1 /* DSP_IRQ4_EINT */
3303#define WM5100_DSP_IRQ3_EINT 0x0004 /* DSP_IRQ3_EINT */
3304#define WM5100_DSP_IRQ3_EINT_MASK 0x0004 /* DSP_IRQ3_EINT */
3305#define WM5100_DSP_IRQ3_EINT_SHIFT 2 /* DSP_IRQ3_EINT */
3306#define WM5100_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
3307#define WM5100_DSP_IRQ2_EINT 0x0002 /* DSP_IRQ2_EINT */
3308#define WM5100_DSP_IRQ2_EINT_MASK 0x0002 /* DSP_IRQ2_EINT */
3309#define WM5100_DSP_IRQ2_EINT_SHIFT 1 /* DSP_IRQ2_EINT */
3310#define WM5100_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
3311#define WM5100_DSP_IRQ1_EINT 0x0001 /* DSP_IRQ1_EINT */
3312#define WM5100_DSP_IRQ1_EINT_MASK 0x0001 /* DSP_IRQ1_EINT */
3313#define WM5100_DSP_IRQ1_EINT_SHIFT 0 /* DSP_IRQ1_EINT */
3314#define WM5100_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
3315
3316/*
3317 * R3330 (0xD02) - Interrupt Status 3
3318 */
3319#define WM5100_SPK_SHUTDOWN_WARN_EINT 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
3320#define WM5100_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
3321#define WM5100_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* SPK_SHUTDOWN_WARN_EINT */
3322#define WM5100_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* SPK_SHUTDOWN_WARN_EINT */
3323#define WM5100_SPK_SHUTDOWN_EINT 0x4000 /* SPK_SHUTDOWN_EINT */
3324#define WM5100_SPK_SHUTDOWN_EINT_MASK 0x4000 /* SPK_SHUTDOWN_EINT */
3325#define WM5100_SPK_SHUTDOWN_EINT_SHIFT 14 /* SPK_SHUTDOWN_EINT */
3326#define WM5100_SPK_SHUTDOWN_EINT_WIDTH 1 /* SPK_SHUTDOWN_EINT */
3327#define WM5100_HPDET_EINT 0x2000 /* HPDET_EINT */
3328#define WM5100_HPDET_EINT_MASK 0x2000 /* HPDET_EINT */
3329#define WM5100_HPDET_EINT_SHIFT 13 /* HPDET_EINT */
3330#define WM5100_HPDET_EINT_WIDTH 1 /* HPDET_EINT */
3331#define WM5100_ACCDET_EINT 0x1000 /* ACCDET_EINT */
3332#define WM5100_ACCDET_EINT_MASK 0x1000 /* ACCDET_EINT */
3333#define WM5100_ACCDET_EINT_SHIFT 12 /* ACCDET_EINT */
3334#define WM5100_ACCDET_EINT_WIDTH 1 /* ACCDET_EINT */
3335#define WM5100_DRC_SIG_DET_EINT 0x0200 /* DRC_SIG_DET_EINT */
3336#define WM5100_DRC_SIG_DET_EINT_MASK 0x0200 /* DRC_SIG_DET_EINT */
3337#define WM5100_DRC_SIG_DET_EINT_SHIFT 9 /* DRC_SIG_DET_EINT */
3338#define WM5100_DRC_SIG_DET_EINT_WIDTH 1 /* DRC_SIG_DET_EINT */
3339#define WM5100_ASRC2_LOCK_EINT 0x0100 /* ASRC2_LOCK_EINT */
3340#define WM5100_ASRC2_LOCK_EINT_MASK 0x0100 /* ASRC2_LOCK_EINT */
3341#define WM5100_ASRC2_LOCK_EINT_SHIFT 8 /* ASRC2_LOCK_EINT */
3342#define WM5100_ASRC2_LOCK_EINT_WIDTH 1 /* ASRC2_LOCK_EINT */
3343#define WM5100_ASRC1_LOCK_EINT 0x0080 /* ASRC1_LOCK_EINT */
3344#define WM5100_ASRC1_LOCK_EINT_MASK 0x0080 /* ASRC1_LOCK_EINT */
3345#define WM5100_ASRC1_LOCK_EINT_SHIFT 7 /* ASRC1_LOCK_EINT */
3346#define WM5100_ASRC1_LOCK_EINT_WIDTH 1 /* ASRC1_LOCK_EINT */
3347#define WM5100_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
3348#define WM5100_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
3349#define WM5100_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
3350#define WM5100_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
3351#define WM5100_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
3352#define WM5100_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
3353#define WM5100_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
3354#define WM5100_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
3355#define WM5100_CLKGEN_ERR_EINT 0x0002 /* CLKGEN_ERR_EINT */
3356#define WM5100_CLKGEN_ERR_EINT_MASK 0x0002 /* CLKGEN_ERR_EINT */
3357#define WM5100_CLKGEN_ERR_EINT_SHIFT 1 /* CLKGEN_ERR_EINT */
3358#define WM5100_CLKGEN_ERR_EINT_WIDTH 1 /* CLKGEN_ERR_EINT */
3359#define WM5100_CLKGEN_ERR_ASYNC_EINT 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
3360#define WM5100_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
3361#define WM5100_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* CLKGEN_ERR_ASYNC_EINT */
3362#define WM5100_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* CLKGEN_ERR_ASYNC_EINT */
3363
3364/*
3365 * R3331 (0xD03) - Interrupt Status 4
3366 */
3367#define WM5100_AIF3_ERR_EINT 0x2000 /* AIF3_ERR_EINT */
3368#define WM5100_AIF3_ERR_EINT_MASK 0x2000 /* AIF3_ERR_EINT */
3369#define WM5100_AIF3_ERR_EINT_SHIFT 13 /* AIF3_ERR_EINT */
3370#define WM5100_AIF3_ERR_EINT_WIDTH 1 /* AIF3_ERR_EINT */
3371#define WM5100_AIF2_ERR_EINT 0x1000 /* AIF2_ERR_EINT */
3372#define WM5100_AIF2_ERR_EINT_MASK 0x1000 /* AIF2_ERR_EINT */
3373#define WM5100_AIF2_ERR_EINT_SHIFT 12 /* AIF2_ERR_EINT */
3374#define WM5100_AIF2_ERR_EINT_WIDTH 1 /* AIF2_ERR_EINT */
3375#define WM5100_AIF1_ERR_EINT 0x0800 /* AIF1_ERR_EINT */
3376#define WM5100_AIF1_ERR_EINT_MASK 0x0800 /* AIF1_ERR_EINT */
3377#define WM5100_AIF1_ERR_EINT_SHIFT 11 /* AIF1_ERR_EINT */
3378#define WM5100_AIF1_ERR_EINT_WIDTH 1 /* AIF1_ERR_EINT */
3379#define WM5100_CTRLIF_ERR_EINT 0x0400 /* CTRLIF_ERR_EINT */
3380#define WM5100_CTRLIF_ERR_EINT_MASK 0x0400 /* CTRLIF_ERR_EINT */
3381#define WM5100_CTRLIF_ERR_EINT_SHIFT 10 /* CTRLIF_ERR_EINT */
3382#define WM5100_CTRLIF_ERR_EINT_WIDTH 1 /* CTRLIF_ERR_EINT */
3383#define WM5100_ISRC2_UNDERCLOCKED_EINT 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
3384#define WM5100_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
3385#define WM5100_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* ISRC2_UNDERCLOCKED_EINT */
3386#define WM5100_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC2_UNDERCLOCKED_EINT */
3387#define WM5100_ISRC1_UNDERCLOCKED_EINT 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
3388#define WM5100_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
3389#define WM5100_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* ISRC1_UNDERCLOCKED_EINT */
3390#define WM5100_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC1_UNDERCLOCKED_EINT */
3391#define WM5100_FX_UNDERCLOCKED_EINT 0x0080 /* FX_UNDERCLOCKED_EINT */
3392#define WM5100_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* FX_UNDERCLOCKED_EINT */
3393#define WM5100_FX_UNDERCLOCKED_EINT_SHIFT 7 /* FX_UNDERCLOCKED_EINT */
3394#define WM5100_FX_UNDERCLOCKED_EINT_WIDTH 1 /* FX_UNDERCLOCKED_EINT */
3395#define WM5100_AIF3_UNDERCLOCKED_EINT 0x0040 /* AIF3_UNDERCLOCKED_EINT */
3396#define WM5100_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* AIF3_UNDERCLOCKED_EINT */
3397#define WM5100_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* AIF3_UNDERCLOCKED_EINT */
3398#define WM5100_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* AIF3_UNDERCLOCKED_EINT */
3399#define WM5100_AIF2_UNDERCLOCKED_EINT 0x0020 /* AIF2_UNDERCLOCKED_EINT */
3400#define WM5100_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* AIF2_UNDERCLOCKED_EINT */
3401#define WM5100_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* AIF2_UNDERCLOCKED_EINT */
3402#define WM5100_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* AIF2_UNDERCLOCKED_EINT */
3403#define WM5100_AIF1_UNDERCLOCKED_EINT 0x0010 /* AIF1_UNDERCLOCKED_EINT */
3404#define WM5100_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* AIF1_UNDERCLOCKED_EINT */
3405#define WM5100_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* AIF1_UNDERCLOCKED_EINT */
3406#define WM5100_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* AIF1_UNDERCLOCKED_EINT */
3407#define WM5100_ASRC_UNDERCLOCKED_EINT 0x0008 /* ASRC_UNDERCLOCKED_EINT */
3408#define WM5100_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* ASRC_UNDERCLOCKED_EINT */
3409#define WM5100_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* ASRC_UNDERCLOCKED_EINT */
3410#define WM5100_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* ASRC_UNDERCLOCKED_EINT */
3411#define WM5100_DAC_UNDERCLOCKED_EINT 0x0004 /* DAC_UNDERCLOCKED_EINT */
3412#define WM5100_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* DAC_UNDERCLOCKED_EINT */
3413#define WM5100_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* DAC_UNDERCLOCKED_EINT */
3414#define WM5100_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* DAC_UNDERCLOCKED_EINT */
3415#define WM5100_ADC_UNDERCLOCKED_EINT 0x0002 /* ADC_UNDERCLOCKED_EINT */
3416#define WM5100_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* ADC_UNDERCLOCKED_EINT */
3417#define WM5100_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* ADC_UNDERCLOCKED_EINT */
3418#define WM5100_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* ADC_UNDERCLOCKED_EINT */
3419#define WM5100_MIXER_UNDERCLOCKED_EINT 0x0001 /* MIXER_UNDERCLOCKED_EINT */
3420#define WM5100_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* MIXER_UNDERCLOCKED_EINT */
3421#define WM5100_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* MIXER_UNDERCLOCKED_EINT */
3422#define WM5100_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* MIXER_UNDERCLOCKED_EINT */
3423
3424/*
3425 * R3332 (0xD04) - Interrupt Raw Status 2
3426 */
3427#define WM5100_DSP_IRQ6_STS 0x0020 /* DSP_IRQ6_STS */
3428#define WM5100_DSP_IRQ6_STS_MASK 0x0020 /* DSP_IRQ6_STS */
3429#define WM5100_DSP_IRQ6_STS_SHIFT 5 /* DSP_IRQ6_STS */
3430#define WM5100_DSP_IRQ6_STS_WIDTH 1 /* DSP_IRQ6_STS */
3431#define WM5100_DSP_IRQ5_STS 0x0010 /* DSP_IRQ5_STS */
3432#define WM5100_DSP_IRQ5_STS_MASK 0x0010 /* DSP_IRQ5_STS */
3433#define WM5100_DSP_IRQ5_STS_SHIFT 4 /* DSP_IRQ5_STS */
3434#define WM5100_DSP_IRQ5_STS_WIDTH 1 /* DSP_IRQ5_STS */
3435#define WM5100_DSP_IRQ4_STS 0x0008 /* DSP_IRQ4_STS */
3436#define WM5100_DSP_IRQ4_STS_MASK 0x0008 /* DSP_IRQ4_STS */
3437#define WM5100_DSP_IRQ4_STS_SHIFT 3 /* DSP_IRQ4_STS */
3438#define WM5100_DSP_IRQ4_STS_WIDTH 1 /* DSP_IRQ4_STS */
3439#define WM5100_DSP_IRQ3_STS 0x0004 /* DSP_IRQ3_STS */
3440#define WM5100_DSP_IRQ3_STS_MASK 0x0004 /* DSP_IRQ3_STS */
3441#define WM5100_DSP_IRQ3_STS_SHIFT 2 /* DSP_IRQ3_STS */
3442#define WM5100_DSP_IRQ3_STS_WIDTH 1 /* DSP_IRQ3_STS */
3443#define WM5100_DSP_IRQ2_STS 0x0002 /* DSP_IRQ2_STS */
3444#define WM5100_DSP_IRQ2_STS_MASK 0x0002 /* DSP_IRQ2_STS */
3445#define WM5100_DSP_IRQ2_STS_SHIFT 1 /* DSP_IRQ2_STS */
3446#define WM5100_DSP_IRQ2_STS_WIDTH 1 /* DSP_IRQ2_STS */
3447#define WM5100_DSP_IRQ1_STS 0x0001 /* DSP_IRQ1_STS */
3448#define WM5100_DSP_IRQ1_STS_MASK 0x0001 /* DSP_IRQ1_STS */
3449#define WM5100_DSP_IRQ1_STS_SHIFT 0 /* DSP_IRQ1_STS */
3450#define WM5100_DSP_IRQ1_STS_WIDTH 1 /* DSP_IRQ1_STS */
3451
3452/*
3453 * R3333 (0xD05) - Interrupt Raw Status 3
3454 */
3455#define WM5100_SPK_SHUTDOWN_WARN_STS 0x8000 /* SPK_SHUTDOWN_WARN_STS */
3456#define WM5100_SPK_SHUTDOWN_WARN_STS_MASK 0x8000 /* SPK_SHUTDOWN_WARN_STS */
3457#define WM5100_SPK_SHUTDOWN_WARN_STS_SHIFT 15 /* SPK_SHUTDOWN_WARN_STS */
3458#define WM5100_SPK_SHUTDOWN_WARN_STS_WIDTH 1 /* SPK_SHUTDOWN_WARN_STS */
3459#define WM5100_SPK_SHUTDOWN_STS 0x4000 /* SPK_SHUTDOWN_STS */
3460#define WM5100_SPK_SHUTDOWN_STS_MASK 0x4000 /* SPK_SHUTDOWN_STS */
3461#define WM5100_SPK_SHUTDOWN_STS_SHIFT 14 /* SPK_SHUTDOWN_STS */
3462#define WM5100_SPK_SHUTDOWN_STS_WIDTH 1 /* SPK_SHUTDOWN_STS */
3463#define WM5100_HPDET_STS 0x2000 /* HPDET_STS */
3464#define WM5100_HPDET_STS_MASK 0x2000 /* HPDET_STS */
3465#define WM5100_HPDET_STS_SHIFT 13 /* HPDET_STS */
3466#define WM5100_HPDET_STS_WIDTH 1 /* HPDET_STS */
3467#define WM5100_DRC_SID_DET_STS 0x0200 /* DRC_SID_DET_STS */
3468#define WM5100_DRC_SID_DET_STS_MASK 0x0200 /* DRC_SID_DET_STS */
3469#define WM5100_DRC_SID_DET_STS_SHIFT 9 /* DRC_SID_DET_STS */
3470#define WM5100_DRC_SID_DET_STS_WIDTH 1 /* DRC_SID_DET_STS */
3471#define WM5100_ASRC2_LOCK_STS 0x0100 /* ASRC2_LOCK_STS */
3472#define WM5100_ASRC2_LOCK_STS_MASK 0x0100 /* ASRC2_LOCK_STS */
3473#define WM5100_ASRC2_LOCK_STS_SHIFT 8 /* ASRC2_LOCK_STS */
3474#define WM5100_ASRC2_LOCK_STS_WIDTH 1 /* ASRC2_LOCK_STS */
3475#define WM5100_ASRC1_LOCK_STS 0x0080 /* ASRC1_LOCK_STS */
3476#define WM5100_ASRC1_LOCK_STS_MASK 0x0080 /* ASRC1_LOCK_STS */
3477#define WM5100_ASRC1_LOCK_STS_SHIFT 7 /* ASRC1_LOCK_STS */
3478#define WM5100_ASRC1_LOCK_STS_WIDTH 1 /* ASRC1_LOCK_STS */
3479#define WM5100_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
3480#define WM5100_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
3481#define WM5100_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
3482#define WM5100_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
3483#define WM5100_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
3484#define WM5100_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
3485#define WM5100_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
3486#define WM5100_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
3487#define WM5100_CLKGEN_ERR_STS 0x0002 /* CLKGEN_ERR_STS */
3488#define WM5100_CLKGEN_ERR_STS_MASK 0x0002 /* CLKGEN_ERR_STS */
3489#define WM5100_CLKGEN_ERR_STS_SHIFT 1 /* CLKGEN_ERR_STS */
3490#define WM5100_CLKGEN_ERR_STS_WIDTH 1 /* CLKGEN_ERR_STS */
3491#define WM5100_CLKGEN_ERR_ASYNC_STS 0x0001 /* CLKGEN_ERR_ASYNC_STS */
3492#define WM5100_CLKGEN_ERR_ASYNC_STS_MASK 0x0001 /* CLKGEN_ERR_ASYNC_STS */
3493#define WM5100_CLKGEN_ERR_ASYNC_STS_SHIFT 0 /* CLKGEN_ERR_ASYNC_STS */
3494#define WM5100_CLKGEN_ERR_ASYNC_STS_WIDTH 1 /* CLKGEN_ERR_ASYNC_STS */
3495
3496/*
3497 * R3334 (0xD06) - Interrupt Raw Status 4
3498 */
3499#define WM5100_AIF3_ERR_STS 0x2000 /* AIF3_ERR_STS */
3500#define WM5100_AIF3_ERR_STS_MASK 0x2000 /* AIF3_ERR_STS */
3501#define WM5100_AIF3_ERR_STS_SHIFT 13 /* AIF3_ERR_STS */
3502#define WM5100_AIF3_ERR_STS_WIDTH 1 /* AIF3_ERR_STS */
3503#define WM5100_AIF2_ERR_STS 0x1000 /* AIF2_ERR_STS */
3504#define WM5100_AIF2_ERR_STS_MASK 0x1000 /* AIF2_ERR_STS */
3505#define WM5100_AIF2_ERR_STS_SHIFT 12 /* AIF2_ERR_STS */
3506#define WM5100_AIF2_ERR_STS_WIDTH 1 /* AIF2_ERR_STS */
3507#define WM5100_AIF1_ERR_STS 0x0800 /* AIF1_ERR_STS */
3508#define WM5100_AIF1_ERR_STS_MASK 0x0800 /* AIF1_ERR_STS */
3509#define WM5100_AIF1_ERR_STS_SHIFT 11 /* AIF1_ERR_STS */
3510#define WM5100_AIF1_ERR_STS_WIDTH 1 /* AIF1_ERR_STS */
3511#define WM5100_CTRLIF_ERR_STS 0x0400 /* CTRLIF_ERR_STS */
3512#define WM5100_CTRLIF_ERR_STS_MASK 0x0400 /* CTRLIF_ERR_STS */
3513#define WM5100_CTRLIF_ERR_STS_SHIFT 10 /* CTRLIF_ERR_STS */
3514#define WM5100_CTRLIF_ERR_STS_WIDTH 1 /* CTRLIF_ERR_STS */
3515#define WM5100_ISRC2_UNDERCLOCKED_STS 0x0200 /* ISRC2_UNDERCLOCKED_STS */
3516#define WM5100_ISRC2_UNDERCLOCKED_STS_MASK 0x0200 /* ISRC2_UNDERCLOCKED_STS */
3517#define WM5100_ISRC2_UNDERCLOCKED_STS_SHIFT 9 /* ISRC2_UNDERCLOCKED_STS */
3518#define WM5100_ISRC2_UNDERCLOCKED_STS_WIDTH 1 /* ISRC2_UNDERCLOCKED_STS */
3519#define WM5100_ISRC1_UNDERCLOCKED_STS 0x0100 /* ISRC1_UNDERCLOCKED_STS */
3520#define WM5100_ISRC1_UNDERCLOCKED_STS_MASK 0x0100 /* ISRC1_UNDERCLOCKED_STS */
3521#define WM5100_ISRC1_UNDERCLOCKED_STS_SHIFT 8 /* ISRC1_UNDERCLOCKED_STS */
3522#define WM5100_ISRC1_UNDERCLOCKED_STS_WIDTH 1 /* ISRC1_UNDERCLOCKED_STS */
3523#define WM5100_FX_UNDERCLOCKED_STS 0x0080 /* FX_UNDERCLOCKED_STS */
3524#define WM5100_FX_UNDERCLOCKED_STS_MASK 0x0080 /* FX_UNDERCLOCKED_STS */
3525#define WM5100_FX_UNDERCLOCKED_STS_SHIFT 7 /* FX_UNDERCLOCKED_STS */
3526#define WM5100_FX_UNDERCLOCKED_STS_WIDTH 1 /* FX_UNDERCLOCKED_STS */
3527#define WM5100_AIF3_UNDERCLOCKED_STS 0x0040 /* AIF3_UNDERCLOCKED_STS */
3528#define WM5100_AIF3_UNDERCLOCKED_STS_MASK 0x0040 /* AIF3_UNDERCLOCKED_STS */
3529#define WM5100_AIF3_UNDERCLOCKED_STS_SHIFT 6 /* AIF3_UNDERCLOCKED_STS */
3530#define WM5100_AIF3_UNDERCLOCKED_STS_WIDTH 1 /* AIF3_UNDERCLOCKED_STS */
3531#define WM5100_AIF2_UNDERCLOCKED_STS 0x0020 /* AIF2_UNDERCLOCKED_STS */
3532#define WM5100_AIF2_UNDERCLOCKED_STS_MASK 0x0020 /* AIF2_UNDERCLOCKED_STS */
3533#define WM5100_AIF2_UNDERCLOCKED_STS_SHIFT 5 /* AIF2_UNDERCLOCKED_STS */
3534#define WM5100_AIF2_UNDERCLOCKED_STS_WIDTH 1 /* AIF2_UNDERCLOCKED_STS */
3535#define WM5100_AIF1_UNDERCLOCKED_STS 0x0010 /* AIF1_UNDERCLOCKED_STS */
3536#define WM5100_AIF1_UNDERCLOCKED_STS_MASK 0x0010 /* AIF1_UNDERCLOCKED_STS */
3537#define WM5100_AIF1_UNDERCLOCKED_STS_SHIFT 4 /* AIF1_UNDERCLOCKED_STS */
3538#define WM5100_AIF1_UNDERCLOCKED_STS_WIDTH 1 /* AIF1_UNDERCLOCKED_STS */
3539#define WM5100_ASRC_UNDERCLOCKED_STS 0x0008 /* ASRC_UNDERCLOCKED_STS */
3540#define WM5100_ASRC_UNDERCLOCKED_STS_MASK 0x0008 /* ASRC_UNDERCLOCKED_STS */
3541#define WM5100_ASRC_UNDERCLOCKED_STS_SHIFT 3 /* ASRC_UNDERCLOCKED_STS */
3542#define WM5100_ASRC_UNDERCLOCKED_STS_WIDTH 1 /* ASRC_UNDERCLOCKED_STS */
3543#define WM5100_DAC_UNDERCLOCKED_STS 0x0004 /* DAC_UNDERCLOCKED_STS */
3544#define WM5100_DAC_UNDERCLOCKED_STS_MASK 0x0004 /* DAC_UNDERCLOCKED_STS */
3545#define WM5100_DAC_UNDERCLOCKED_STS_SHIFT 2 /* DAC_UNDERCLOCKED_STS */
3546#define WM5100_DAC_UNDERCLOCKED_STS_WIDTH 1 /* DAC_UNDERCLOCKED_STS */
3547#define WM5100_ADC_UNDERCLOCKED_STS 0x0002 /* ADC_UNDERCLOCKED_STS */
3548#define WM5100_ADC_UNDERCLOCKED_STS_MASK 0x0002 /* ADC_UNDERCLOCKED_STS */
3549#define WM5100_ADC_UNDERCLOCKED_STS_SHIFT 1 /* ADC_UNDERCLOCKED_STS */
3550#define WM5100_ADC_UNDERCLOCKED_STS_WIDTH 1 /* ADC_UNDERCLOCKED_STS */
3551#define WM5100_MIXER_UNDERCLOCKED_STS 0x0001 /* MIXER_UNDERCLOCKED_STS */
3552#define WM5100_MIXER_UNDERCLOCKED_STS_MASK 0x0001 /* MIXER_UNDERCLOCKED_STS */
3553#define WM5100_MIXER_UNDERCLOCKED_STS_SHIFT 0 /* MIXER_UNDERCLOCKED_STS */
3554#define WM5100_MIXER_UNDERCLOCKED_STS_WIDTH 1 /* MIXER_UNDERCLOCKED_STS */
3555
3556/*
3557 * R3335 (0xD07) - Interrupt Status 1 Mask
3558 */
3559#define WM5100_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
3560#define WM5100_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
3561#define WM5100_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
3562#define WM5100_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
3563#define WM5100_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3564#define WM5100_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3565#define WM5100_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3566#define WM5100_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3567#define WM5100_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3568#define WM5100_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3569#define WM5100_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3570#define WM5100_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3571#define WM5100_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3572#define WM5100_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3573#define WM5100_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3574#define WM5100_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3575#define WM5100_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3576#define WM5100_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3577#define WM5100_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3578#define WM5100_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3579#define WM5100_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3580#define WM5100_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3581#define WM5100_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3582#define WM5100_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3583
3584/*
3585 * R3336 (0xD08) - Interrupt Status 2 Mask
3586 */
3587#define WM5100_IM_DSP_IRQ6_EINT 0x0020 /* IM_DSP_IRQ6_EINT */
3588#define WM5100_IM_DSP_IRQ6_EINT_MASK 0x0020 /* IM_DSP_IRQ6_EINT */
3589#define WM5100_IM_DSP_IRQ6_EINT_SHIFT 5 /* IM_DSP_IRQ6_EINT */
3590#define WM5100_IM_DSP_IRQ6_EINT_WIDTH 1 /* IM_DSP_IRQ6_EINT */
3591#define WM5100_IM_DSP_IRQ5_EINT 0x0010 /* IM_DSP_IRQ5_EINT */
3592#define WM5100_IM_DSP_IRQ5_EINT_MASK 0x0010 /* IM_DSP_IRQ5_EINT */
3593#define WM5100_IM_DSP_IRQ5_EINT_SHIFT 4 /* IM_DSP_IRQ5_EINT */
3594#define WM5100_IM_DSP_IRQ5_EINT_WIDTH 1 /* IM_DSP_IRQ5_EINT */
3595#define WM5100_IM_DSP_IRQ4_EINT 0x0008 /* IM_DSP_IRQ4_EINT */
3596#define WM5100_IM_DSP_IRQ4_EINT_MASK 0x0008 /* IM_DSP_IRQ4_EINT */
3597#define WM5100_IM_DSP_IRQ4_EINT_SHIFT 3 /* IM_DSP_IRQ4_EINT */
3598#define WM5100_IM_DSP_IRQ4_EINT_WIDTH 1 /* IM_DSP_IRQ4_EINT */
3599#define WM5100_IM_DSP_IRQ3_EINT 0x0004 /* IM_DSP_IRQ3_EINT */
3600#define WM5100_IM_DSP_IRQ3_EINT_MASK 0x0004 /* IM_DSP_IRQ3_EINT */
3601#define WM5100_IM_DSP_IRQ3_EINT_SHIFT 2 /* IM_DSP_IRQ3_EINT */
3602#define WM5100_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
3603#define WM5100_IM_DSP_IRQ2_EINT 0x0002 /* IM_DSP_IRQ2_EINT */
3604#define WM5100_IM_DSP_IRQ2_EINT_MASK 0x0002 /* IM_DSP_IRQ2_EINT */
3605#define WM5100_IM_DSP_IRQ2_EINT_SHIFT 1 /* IM_DSP_IRQ2_EINT */
3606#define WM5100_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
3607#define WM5100_IM_DSP_IRQ1_EINT 0x0001 /* IM_DSP_IRQ1_EINT */
3608#define WM5100_IM_DSP_IRQ1_EINT_MASK 0x0001 /* IM_DSP_IRQ1_EINT */
3609#define WM5100_IM_DSP_IRQ1_EINT_SHIFT 0 /* IM_DSP_IRQ1_EINT */
3610#define WM5100_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
3611
3612/*
3613 * R3337 (0xD09) - Interrupt Status 3 Mask
3614 */
3615#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
3616#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
3617#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* IM_SPK_SHUTDOWN_WARN_EINT */
3618#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_WARN_EINT */
3619#define WM5100_IM_SPK_SHUTDOWN_EINT 0x4000 /* IM_SPK_SHUTDOWN_EINT */
3620#define WM5100_IM_SPK_SHUTDOWN_EINT_MASK 0x4000 /* IM_SPK_SHUTDOWN_EINT */
3621#define WM5100_IM_SPK_SHUTDOWN_EINT_SHIFT 14 /* IM_SPK_SHUTDOWN_EINT */
3622#define WM5100_IM_SPK_SHUTDOWN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_EINT */
3623#define WM5100_IM_HPDET_EINT 0x2000 /* IM_HPDET_EINT */
3624#define WM5100_IM_HPDET_EINT_MASK 0x2000 /* IM_HPDET_EINT */
3625#define WM5100_IM_HPDET_EINT_SHIFT 13 /* IM_HPDET_EINT */
3626#define WM5100_IM_HPDET_EINT_WIDTH 1 /* IM_HPDET_EINT */
3627#define WM5100_IM_ACCDET_EINT 0x1000 /* IM_ACCDET_EINT */
3628#define WM5100_IM_ACCDET_EINT_MASK 0x1000 /* IM_ACCDET_EINT */
3629#define WM5100_IM_ACCDET_EINT_SHIFT 12 /* IM_ACCDET_EINT */
3630#define WM5100_IM_ACCDET_EINT_WIDTH 1 /* IM_ACCDET_EINT */
3631#define WM5100_IM_DRC_SIG_DET_EINT 0x0200 /* IM_DRC_SIG_DET_EINT */
3632#define WM5100_IM_DRC_SIG_DET_EINT_MASK 0x0200 /* IM_DRC_SIG_DET_EINT */
3633#define WM5100_IM_DRC_SIG_DET_EINT_SHIFT 9 /* IM_DRC_SIG_DET_EINT */
3634#define WM5100_IM_DRC_SIG_DET_EINT_WIDTH 1 /* IM_DRC_SIG_DET_EINT */
3635#define WM5100_IM_ASRC2_LOCK_EINT 0x0100 /* IM_ASRC2_LOCK_EINT */
3636#define WM5100_IM_ASRC2_LOCK_EINT_MASK 0x0100 /* IM_ASRC2_LOCK_EINT */
3637#define WM5100_IM_ASRC2_LOCK_EINT_SHIFT 8 /* IM_ASRC2_LOCK_EINT */
3638#define WM5100_IM_ASRC2_LOCK_EINT_WIDTH 1 /* IM_ASRC2_LOCK_EINT */
3639#define WM5100_IM_ASRC1_LOCK_EINT 0x0080 /* IM_ASRC1_LOCK_EINT */
3640#define WM5100_IM_ASRC1_LOCK_EINT_MASK 0x0080 /* IM_ASRC1_LOCK_EINT */
3641#define WM5100_IM_ASRC1_LOCK_EINT_SHIFT 7 /* IM_ASRC1_LOCK_EINT */
3642#define WM5100_IM_ASRC1_LOCK_EINT_WIDTH 1 /* IM_ASRC1_LOCK_EINT */
3643#define WM5100_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
3644#define WM5100_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
3645#define WM5100_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
3646#define WM5100_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
3647#define WM5100_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
3648#define WM5100_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
3649#define WM5100_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
3650#define WM5100_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
3651#define WM5100_IM_CLKGEN_ERR_EINT 0x0002 /* IM_CLKGEN_ERR_EINT */
3652#define WM5100_IM_CLKGEN_ERR_EINT_MASK 0x0002 /* IM_CLKGEN_ERR_EINT */
3653#define WM5100_IM_CLKGEN_ERR_EINT_SHIFT 1 /* IM_CLKGEN_ERR_EINT */
3654#define WM5100_IM_CLKGEN_ERR_EINT_WIDTH 1 /* IM_CLKGEN_ERR_EINT */
3655#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
3656#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
3657#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* IM_CLKGEN_ERR_ASYNC_EINT */
3658#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* IM_CLKGEN_ERR_ASYNC_EINT */
3659
3660/*
3661 * R3338 (0xD0A) - Interrupt Status 4 Mask
3662 */
3663#define WM5100_IM_AIF3_ERR_EINT 0x2000 /* IM_AIF3_ERR_EINT */
3664#define WM5100_IM_AIF3_ERR_EINT_MASK 0x2000 /* IM_AIF3_ERR_EINT */
3665#define WM5100_IM_AIF3_ERR_EINT_SHIFT 13 /* IM_AIF3_ERR_EINT */
3666#define WM5100_IM_AIF3_ERR_EINT_WIDTH 1 /* IM_AIF3_ERR_EINT */
3667#define WM5100_IM_AIF2_ERR_EINT 0x1000 /* IM_AIF2_ERR_EINT */
3668#define WM5100_IM_AIF2_ERR_EINT_MASK 0x1000 /* IM_AIF2_ERR_EINT */
3669#define WM5100_IM_AIF2_ERR_EINT_SHIFT 12 /* IM_AIF2_ERR_EINT */
3670#define WM5100_IM_AIF2_ERR_EINT_WIDTH 1 /* IM_AIF2_ERR_EINT */
3671#define WM5100_IM_AIF1_ERR_EINT 0x0800 /* IM_AIF1_ERR_EINT */
3672#define WM5100_IM_AIF1_ERR_EINT_MASK 0x0800 /* IM_AIF1_ERR_EINT */
3673#define WM5100_IM_AIF1_ERR_EINT_SHIFT 11 /* IM_AIF1_ERR_EINT */
3674#define WM5100_IM_AIF1_ERR_EINT_WIDTH 1 /* IM_AIF1_ERR_EINT */
3675#define WM5100_IM_CTRLIF_ERR_EINT 0x0400 /* IM_CTRLIF_ERR_EINT */
3676#define WM5100_IM_CTRLIF_ERR_EINT_MASK 0x0400 /* IM_CTRLIF_ERR_EINT */
3677#define WM5100_IM_CTRLIF_ERR_EINT_SHIFT 10 /* IM_CTRLIF_ERR_EINT */
3678#define WM5100_IM_CTRLIF_ERR_EINT_WIDTH 1 /* IM_CTRLIF_ERR_EINT */
3679#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
3680#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
3681#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* IM_ISRC2_UNDERCLOCKED_EINT */
3682#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC2_UNDERCLOCKED_EINT */
3683#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
3684#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
3685#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* IM_ISRC1_UNDERCLOCKED_EINT */
3686#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC1_UNDERCLOCKED_EINT */
3687#define WM5100_IM_FX_UNDERCLOCKED_EINT 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
3688#define WM5100_IM_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
3689#define WM5100_IM_FX_UNDERCLOCKED_EINT_SHIFT 7 /* IM_FX_UNDERCLOCKED_EINT */
3690#define WM5100_IM_FX_UNDERCLOCKED_EINT_WIDTH 1 /* IM_FX_UNDERCLOCKED_EINT */
3691#define WM5100_IM_AIF3_UNDERCLOCKED_EINT 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
3692#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
3693#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* IM_AIF3_UNDERCLOCKED_EINT */
3694#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF3_UNDERCLOCKED_EINT */
3695#define WM5100_IM_AIF2_UNDERCLOCKED_EINT 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
3696#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
3697#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* IM_AIF2_UNDERCLOCKED_EINT */
3698#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF2_UNDERCLOCKED_EINT */
3699#define WM5100_IM_AIF1_UNDERCLOCKED_EINT 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
3700#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
3701#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* IM_AIF1_UNDERCLOCKED_EINT */
3702#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF1_UNDERCLOCKED_EINT */
3703#define WM5100_IM_ASRC_UNDERCLOCKED_EINT 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
3704#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
3705#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* IM_ASRC_UNDERCLOCKED_EINT */
3706#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ASRC_UNDERCLOCKED_EINT */
3707#define WM5100_IM_DAC_UNDERCLOCKED_EINT 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
3708#define WM5100_IM_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
3709#define WM5100_IM_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* IM_DAC_UNDERCLOCKED_EINT */
3710#define WM5100_IM_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_DAC_UNDERCLOCKED_EINT */
3711#define WM5100_IM_ADC_UNDERCLOCKED_EINT 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
3712#define WM5100_IM_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
3713#define WM5100_IM_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* IM_ADC_UNDERCLOCKED_EINT */
3714#define WM5100_IM_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ADC_UNDERCLOCKED_EINT */
3715#define WM5100_IM_MIXER_UNDERCLOCKED_EINT 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
3716#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
3717#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* IM_MIXER_UNDERCLOCKED_EINT */
3718#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* IM_MIXER_UNDERCLOCKED_EINT */
3719
3720/*
3721 * R3359 (0xD1F) - Interrupt Control
3722 */
3723#define WM5100_IM_IRQ 0x0001 /* IM_IRQ */
3724#define WM5100_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3725#define WM5100_IM_IRQ_SHIFT 0 /* IM_IRQ */
3726#define WM5100_IM_IRQ_WIDTH 1 /* IM_IRQ */
3727
3728/*
3729 * R3360 (0xD20) - IRQ Debounce 1
3730 */
3731#define WM5100_SPK_SHUTDOWN_WARN_DB 0x0200 /* SPK_SHUTDOWN_WARN_DB */
3732#define WM5100_SPK_SHUTDOWN_WARN_DB_MASK 0x0200 /* SPK_SHUTDOWN_WARN_DB */
3733#define WM5100_SPK_SHUTDOWN_WARN_DB_SHIFT 9 /* SPK_SHUTDOWN_WARN_DB */
3734#define WM5100_SPK_SHUTDOWN_WARN_DB_WIDTH 1 /* SPK_SHUTDOWN_WARN_DB */
3735#define WM5100_SPK_SHUTDOWN_DB 0x0100 /* SPK_SHUTDOWN_DB */
3736#define WM5100_SPK_SHUTDOWN_DB_MASK 0x0100 /* SPK_SHUTDOWN_DB */
3737#define WM5100_SPK_SHUTDOWN_DB_SHIFT 8 /* SPK_SHUTDOWN_DB */
3738#define WM5100_SPK_SHUTDOWN_DB_WIDTH 1 /* SPK_SHUTDOWN_DB */
3739#define WM5100_FLL1_LOCK_IRQ_DB 0x0008 /* FLL1_LOCK_IRQ_DB */
3740#define WM5100_FLL1_LOCK_IRQ_DB_MASK 0x0008 /* FLL1_LOCK_IRQ_DB */
3741#define WM5100_FLL1_LOCK_IRQ_DB_SHIFT 3 /* FLL1_LOCK_IRQ_DB */
3742#define WM5100_FLL1_LOCK_IRQ_DB_WIDTH 1 /* FLL1_LOCK_IRQ_DB */
3743#define WM5100_FLL2_LOCK_IRQ_DB 0x0004 /* FLL2_LOCK_IRQ_DB */
3744#define WM5100_FLL2_LOCK_IRQ_DB_MASK 0x0004 /* FLL2_LOCK_IRQ_DB */
3745#define WM5100_FLL2_LOCK_IRQ_DB_SHIFT 2 /* FLL2_LOCK_IRQ_DB */
3746#define WM5100_FLL2_LOCK_IRQ_DB_WIDTH 1 /* FLL2_LOCK_IRQ_DB */
3747#define WM5100_CLKGEN_ERR_IRQ_DB 0x0002 /* CLKGEN_ERR_IRQ_DB */
3748#define WM5100_CLKGEN_ERR_IRQ_DB_MASK 0x0002 /* CLKGEN_ERR_IRQ_DB */
3749#define WM5100_CLKGEN_ERR_IRQ_DB_SHIFT 1 /* CLKGEN_ERR_IRQ_DB */
3750#define WM5100_CLKGEN_ERR_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_IRQ_DB */
3751#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3752#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_MASK 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3753#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_SHIFT 0 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3754#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3755
3756/*
3757 * R3361 (0xD21) - IRQ Debounce 2
3758 */
3759#define WM5100_AIF_ERR_DB 0x0001 /* AIF_ERR_DB */
3760#define WM5100_AIF_ERR_DB_MASK 0x0001 /* AIF_ERR_DB */
3761#define WM5100_AIF_ERR_DB_SHIFT 0 /* AIF_ERR_DB */
3762#define WM5100_AIF_ERR_DB_WIDTH 1 /* AIF_ERR_DB */
3763
3764/*
3765 * R3584 (0xE00) - FX_Ctrl
3766 */
3767#define WM5100_FX_STS_MASK 0xFFC0 /* FX_STS - [15:6] */
3768#define WM5100_FX_STS_SHIFT 6 /* FX_STS - [15:6] */
3769#define WM5100_FX_STS_WIDTH 10 /* FX_STS - [15:6] */
3770#define WM5100_FX_RATE_MASK 0x0003 /* FX_RATE - [1:0] */
3771#define WM5100_FX_RATE_SHIFT 0 /* FX_RATE - [1:0] */
3772#define WM5100_FX_RATE_WIDTH 2 /* FX_RATE - [1:0] */
3773
3774/*
3775 * R3600 (0xE10) - EQ1_1
3776 */
3777#define WM5100_EQ1_B1_GAIN_MASK 0xF800 /* EQ1_B1_GAIN - [15:11] */
3778#define WM5100_EQ1_B1_GAIN_SHIFT 11 /* EQ1_B1_GAIN - [15:11] */
3779#define WM5100_EQ1_B1_GAIN_WIDTH 5 /* EQ1_B1_GAIN - [15:11] */
3780#define WM5100_EQ1_B2_GAIN_MASK 0x07C0 /* EQ1_B2_GAIN - [10:6] */
3781#define WM5100_EQ1_B2_GAIN_SHIFT 6 /* EQ1_B2_GAIN - [10:6] */
3782#define WM5100_EQ1_B2_GAIN_WIDTH 5 /* EQ1_B2_GAIN - [10:6] */
3783#define WM5100_EQ1_B3_GAIN_MASK 0x003E /* EQ1_B3_GAIN - [5:1] */
3784#define WM5100_EQ1_B3_GAIN_SHIFT 1 /* EQ1_B3_GAIN - [5:1] */
3785#define WM5100_EQ1_B3_GAIN_WIDTH 5 /* EQ1_B3_GAIN - [5:1] */
3786#define WM5100_EQ1_ENA 0x0001 /* EQ1_ENA */
3787#define WM5100_EQ1_ENA_MASK 0x0001 /* EQ1_ENA */
3788#define WM5100_EQ1_ENA_SHIFT 0 /* EQ1_ENA */
3789#define WM5100_EQ1_ENA_WIDTH 1 /* EQ1_ENA */
3790
3791/*
3792 * R3601 (0xE11) - EQ1_2
3793 */
3794#define WM5100_EQ1_B4_GAIN_MASK 0xF800 /* EQ1_B4_GAIN - [15:11] */
3795#define WM5100_EQ1_B4_GAIN_SHIFT 11 /* EQ1_B4_GAIN - [15:11] */
3796#define WM5100_EQ1_B4_GAIN_WIDTH 5 /* EQ1_B4_GAIN - [15:11] */
3797#define WM5100_EQ1_B5_GAIN_MASK 0x07C0 /* EQ1_B5_GAIN - [10:6] */
3798#define WM5100_EQ1_B5_GAIN_SHIFT 6 /* EQ1_B5_GAIN - [10:6] */
3799#define WM5100_EQ1_B5_GAIN_WIDTH 5 /* EQ1_B5_GAIN - [10:6] */
3800
3801/*
3802 * R3602 (0xE12) - EQ1_3
3803 */
3804#define WM5100_EQ1_B1_A_MASK 0xFFFF /* EQ1_B1_A - [15:0] */
3805#define WM5100_EQ1_B1_A_SHIFT 0 /* EQ1_B1_A - [15:0] */
3806#define WM5100_EQ1_B1_A_WIDTH 16 /* EQ1_B1_A - [15:0] */
3807
3808/*
3809 * R3603 (0xE13) - EQ1_4
3810 */
3811#define WM5100_EQ1_B1_B_MASK 0xFFFF /* EQ1_B1_B - [15:0] */
3812#define WM5100_EQ1_B1_B_SHIFT 0 /* EQ1_B1_B - [15:0] */
3813#define WM5100_EQ1_B1_B_WIDTH 16 /* EQ1_B1_B - [15:0] */
3814
3815/*
3816 * R3604 (0xE14) - EQ1_5
3817 */
3818#define WM5100_EQ1_B1_PG_MASK 0xFFFF /* EQ1_B1_PG - [15:0] */
3819#define WM5100_EQ1_B1_PG_SHIFT 0 /* EQ1_B1_PG - [15:0] */
3820#define WM5100_EQ1_B1_PG_WIDTH 16 /* EQ1_B1_PG - [15:0] */
3821
3822/*
3823 * R3605 (0xE15) - EQ1_6
3824 */
3825#define WM5100_EQ1_B2_A_MASK 0xFFFF /* EQ1_B2_A - [15:0] */
3826#define WM5100_EQ1_B2_A_SHIFT 0 /* EQ1_B2_A - [15:0] */
3827#define WM5100_EQ1_B2_A_WIDTH 16 /* EQ1_B2_A - [15:0] */
3828
3829/*
3830 * R3606 (0xE16) - EQ1_7
3831 */
3832#define WM5100_EQ1_B2_B_MASK 0xFFFF /* EQ1_B2_B - [15:0] */
3833#define WM5100_EQ1_B2_B_SHIFT 0 /* EQ1_B2_B - [15:0] */
3834#define WM5100_EQ1_B2_B_WIDTH 16 /* EQ1_B2_B - [15:0] */
3835
3836/*
3837 * R3607 (0xE17) - EQ1_8
3838 */
3839#define WM5100_EQ1_B2_C_MASK 0xFFFF /* EQ1_B2_C - [15:0] */
3840#define WM5100_EQ1_B2_C_SHIFT 0 /* EQ1_B2_C - [15:0] */
3841#define WM5100_EQ1_B2_C_WIDTH 16 /* EQ1_B2_C - [15:0] */
3842
3843/*
3844 * R3608 (0xE18) - EQ1_9
3845 */
3846#define WM5100_EQ1_B2_PG_MASK 0xFFFF /* EQ1_B2_PG - [15:0] */
3847#define WM5100_EQ1_B2_PG_SHIFT 0 /* EQ1_B2_PG - [15:0] */
3848#define WM5100_EQ1_B2_PG_WIDTH 16 /* EQ1_B2_PG - [15:0] */
3849
3850/*
3851 * R3609 (0xE19) - EQ1_10
3852 */
3853#define WM5100_EQ1_B3_A_MASK 0xFFFF /* EQ1_B3_A - [15:0] */
3854#define WM5100_EQ1_B3_A_SHIFT 0 /* EQ1_B3_A - [15:0] */
3855#define WM5100_EQ1_B3_A_WIDTH 16 /* EQ1_B3_A - [15:0] */
3856
3857/*
3858 * R3610 (0xE1A) - EQ1_11
3859 */
3860#define WM5100_EQ1_B3_B_MASK 0xFFFF /* EQ1_B3_B - [15:0] */
3861#define WM5100_EQ1_B3_B_SHIFT 0 /* EQ1_B3_B - [15:0] */
3862#define WM5100_EQ1_B3_B_WIDTH 16 /* EQ1_B3_B - [15:0] */
3863
3864/*
3865 * R3611 (0xE1B) - EQ1_12
3866 */
3867#define WM5100_EQ1_B3_C_MASK 0xFFFF /* EQ1_B3_C - [15:0] */
3868#define WM5100_EQ1_B3_C_SHIFT 0 /* EQ1_B3_C - [15:0] */
3869#define WM5100_EQ1_B3_C_WIDTH 16 /* EQ1_B3_C - [15:0] */
3870
3871/*
3872 * R3612 (0xE1C) - EQ1_13
3873 */
3874#define WM5100_EQ1_B3_PG_MASK 0xFFFF /* EQ1_B3_PG - [15:0] */
3875#define WM5100_EQ1_B3_PG_SHIFT 0 /* EQ1_B3_PG - [15:0] */
3876#define WM5100_EQ1_B3_PG_WIDTH 16 /* EQ1_B3_PG - [15:0] */
3877
3878/*
3879 * R3613 (0xE1D) - EQ1_14
3880 */
3881#define WM5100_EQ1_B4_A_MASK 0xFFFF /* EQ1_B4_A - [15:0] */
3882#define WM5100_EQ1_B4_A_SHIFT 0 /* EQ1_B4_A - [15:0] */
3883#define WM5100_EQ1_B4_A_WIDTH 16 /* EQ1_B4_A - [15:0] */
3884
3885/*
3886 * R3614 (0xE1E) - EQ1_15
3887 */
3888#define WM5100_EQ1_B4_B_MASK 0xFFFF /* EQ1_B4_B - [15:0] */
3889#define WM5100_EQ1_B4_B_SHIFT 0 /* EQ1_B4_B - [15:0] */
3890#define WM5100_EQ1_B4_B_WIDTH 16 /* EQ1_B4_B - [15:0] */
3891
3892/*
3893 * R3615 (0xE1F) - EQ1_16
3894 */
3895#define WM5100_EQ1_B4_C_MASK 0xFFFF /* EQ1_B4_C - [15:0] */
3896#define WM5100_EQ1_B4_C_SHIFT 0 /* EQ1_B4_C - [15:0] */
3897#define WM5100_EQ1_B4_C_WIDTH 16 /* EQ1_B4_C - [15:0] */
3898
3899/*
3900 * R3616 (0xE20) - EQ1_17
3901 */
3902#define WM5100_EQ1_B4_PG_MASK 0xFFFF /* EQ1_B4_PG - [15:0] */
3903#define WM5100_EQ1_B4_PG_SHIFT 0 /* EQ1_B4_PG - [15:0] */
3904#define WM5100_EQ1_B4_PG_WIDTH 16 /* EQ1_B4_PG - [15:0] */
3905
3906/*
3907 * R3617 (0xE21) - EQ1_18
3908 */
3909#define WM5100_EQ1_B5_A_MASK 0xFFFF /* EQ1_B5_A - [15:0] */
3910#define WM5100_EQ1_B5_A_SHIFT 0 /* EQ1_B5_A - [15:0] */
3911#define WM5100_EQ1_B5_A_WIDTH 16 /* EQ1_B5_A - [15:0] */
3912
3913/*
3914 * R3618 (0xE22) - EQ1_19
3915 */
3916#define WM5100_EQ1_B5_B_MASK 0xFFFF /* EQ1_B5_B - [15:0] */
3917#define WM5100_EQ1_B5_B_SHIFT 0 /* EQ1_B5_B - [15:0] */
3918#define WM5100_EQ1_B5_B_WIDTH 16 /* EQ1_B5_B - [15:0] */
3919
3920/*
3921 * R3619 (0xE23) - EQ1_20
3922 */
3923#define WM5100_EQ1_B5_PG_MASK 0xFFFF /* EQ1_B5_PG - [15:0] */
3924#define WM5100_EQ1_B5_PG_SHIFT 0 /* EQ1_B5_PG - [15:0] */
3925#define WM5100_EQ1_B5_PG_WIDTH 16 /* EQ1_B5_PG - [15:0] */
3926
3927/*
3928 * R3622 (0xE26) - EQ2_1
3929 */
3930#define WM5100_EQ2_B1_GAIN_MASK 0xF800 /* EQ2_B1_GAIN - [15:11] */
3931#define WM5100_EQ2_B1_GAIN_SHIFT 11 /* EQ2_B1_GAIN - [15:11] */
3932#define WM5100_EQ2_B1_GAIN_WIDTH 5 /* EQ2_B1_GAIN - [15:11] */
3933#define WM5100_EQ2_B2_GAIN_MASK 0x07C0 /* EQ2_B2_GAIN - [10:6] */
3934#define WM5100_EQ2_B2_GAIN_SHIFT 6 /* EQ2_B2_GAIN - [10:6] */
3935#define WM5100_EQ2_B2_GAIN_WIDTH 5 /* EQ2_B2_GAIN - [10:6] */
3936#define WM5100_EQ2_B3_GAIN_MASK 0x003E /* EQ2_B3_GAIN - [5:1] */
3937#define WM5100_EQ2_B3_GAIN_SHIFT 1 /* EQ2_B3_GAIN - [5:1] */
3938#define WM5100_EQ2_B3_GAIN_WIDTH 5 /* EQ2_B3_GAIN - [5:1] */
3939#define WM5100_EQ2_ENA 0x0001 /* EQ2_ENA */
3940#define WM5100_EQ2_ENA_MASK 0x0001 /* EQ2_ENA */
3941#define WM5100_EQ2_ENA_SHIFT 0 /* EQ2_ENA */
3942#define WM5100_EQ2_ENA_WIDTH 1 /* EQ2_ENA */
3943
3944/*
3945 * R3623 (0xE27) - EQ2_2
3946 */
3947#define WM5100_EQ2_B4_GAIN_MASK 0xF800 /* EQ2_B4_GAIN - [15:11] */
3948#define WM5100_EQ2_B4_GAIN_SHIFT 11 /* EQ2_B4_GAIN - [15:11] */
3949#define WM5100_EQ2_B4_GAIN_WIDTH 5 /* EQ2_B4_GAIN - [15:11] */
3950#define WM5100_EQ2_B5_GAIN_MASK 0x07C0 /* EQ2_B5_GAIN - [10:6] */
3951#define WM5100_EQ2_B5_GAIN_SHIFT 6 /* EQ2_B5_GAIN - [10:6] */
3952#define WM5100_EQ2_B5_GAIN_WIDTH 5 /* EQ2_B5_GAIN - [10:6] */
3953
3954/*
3955 * R3624 (0xE28) - EQ2_3
3956 */
3957#define WM5100_EQ2_B1_A_MASK 0xFFFF /* EQ2_B1_A - [15:0] */
3958#define WM5100_EQ2_B1_A_SHIFT 0 /* EQ2_B1_A - [15:0] */
3959#define WM5100_EQ2_B1_A_WIDTH 16 /* EQ2_B1_A - [15:0] */
3960
3961/*
3962 * R3625 (0xE29) - EQ2_4
3963 */
3964#define WM5100_EQ2_B1_B_MASK 0xFFFF /* EQ2_B1_B - [15:0] */
3965#define WM5100_EQ2_B1_B_SHIFT 0 /* EQ2_B1_B - [15:0] */
3966#define WM5100_EQ2_B1_B_WIDTH 16 /* EQ2_B1_B - [15:0] */
3967
3968/*
3969 * R3626 (0xE2A) - EQ2_5
3970 */
3971#define WM5100_EQ2_B1_PG_MASK 0xFFFF /* EQ2_B1_PG - [15:0] */
3972#define WM5100_EQ2_B1_PG_SHIFT 0 /* EQ2_B1_PG - [15:0] */
3973#define WM5100_EQ2_B1_PG_WIDTH 16 /* EQ2_B1_PG - [15:0] */
3974
3975/*
3976 * R3627 (0xE2B) - EQ2_6
3977 */
3978#define WM5100_EQ2_B2_A_MASK 0xFFFF /* EQ2_B2_A - [15:0] */
3979#define WM5100_EQ2_B2_A_SHIFT 0 /* EQ2_B2_A - [15:0] */
3980#define WM5100_EQ2_B2_A_WIDTH 16 /* EQ2_B2_A - [15:0] */
3981
3982/*
3983 * R3628 (0xE2C) - EQ2_7
3984 */
3985#define WM5100_EQ2_B2_B_MASK 0xFFFF /* EQ2_B2_B - [15:0] */
3986#define WM5100_EQ2_B2_B_SHIFT 0 /* EQ2_B2_B - [15:0] */
3987#define WM5100_EQ2_B2_B_WIDTH 16 /* EQ2_B2_B - [15:0] */
3988
3989/*
3990 * R3629 (0xE2D) - EQ2_8
3991 */
3992#define WM5100_EQ2_B2_C_MASK 0xFFFF /* EQ2_B2_C - [15:0] */
3993#define WM5100_EQ2_B2_C_SHIFT 0 /* EQ2_B2_C - [15:0] */
3994#define WM5100_EQ2_B2_C_WIDTH 16 /* EQ2_B2_C - [15:0] */
3995
3996/*
3997 * R3630 (0xE2E) - EQ2_9
3998 */
3999#define WM5100_EQ2_B2_PG_MASK 0xFFFF /* EQ2_B2_PG - [15:0] */
4000#define WM5100_EQ2_B2_PG_SHIFT 0 /* EQ2_B2_PG - [15:0] */
4001#define WM5100_EQ2_B2_PG_WIDTH 16 /* EQ2_B2_PG - [15:0] */
4002
4003/*
4004 * R3631 (0xE2F) - EQ2_10
4005 */
4006#define WM5100_EQ2_B3_A_MASK 0xFFFF /* EQ2_B3_A - [15:0] */
4007#define WM5100_EQ2_B3_A_SHIFT 0 /* EQ2_B3_A - [15:0] */
4008#define WM5100_EQ2_B3_A_WIDTH 16 /* EQ2_B3_A - [15:0] */
4009
4010/*
4011 * R3632 (0xE30) - EQ2_11
4012 */
4013#define WM5100_EQ2_B3_B_MASK 0xFFFF /* EQ2_B3_B - [15:0] */
4014#define WM5100_EQ2_B3_B_SHIFT 0 /* EQ2_B3_B - [15:0] */
4015#define WM5100_EQ2_B3_B_WIDTH 16 /* EQ2_B3_B - [15:0] */
4016
4017/*
4018 * R3633 (0xE31) - EQ2_12
4019 */
4020#define WM5100_EQ2_B3_C_MASK 0xFFFF /* EQ2_B3_C - [15:0] */
4021#define WM5100_EQ2_B3_C_SHIFT 0 /* EQ2_B3_C - [15:0] */
4022#define WM5100_EQ2_B3_C_WIDTH 16 /* EQ2_B3_C - [15:0] */
4023
4024/*
4025 * R3634 (0xE32) - EQ2_13
4026 */
4027#define WM5100_EQ2_B3_PG_MASK 0xFFFF /* EQ2_B3_PG - [15:0] */
4028#define WM5100_EQ2_B3_PG_SHIFT 0 /* EQ2_B3_PG - [15:0] */
4029#define WM5100_EQ2_B3_PG_WIDTH 16 /* EQ2_B3_PG - [15:0] */
4030
4031/*
4032 * R3635 (0xE33) - EQ2_14
4033 */
4034#define WM5100_EQ2_B4_A_MASK 0xFFFF /* EQ2_B4_A - [15:0] */
4035#define WM5100_EQ2_B4_A_SHIFT 0 /* EQ2_B4_A - [15:0] */
4036#define WM5100_EQ2_B4_A_WIDTH 16 /* EQ2_B4_A - [15:0] */
4037
4038/*
4039 * R3636 (0xE34) - EQ2_15
4040 */
4041#define WM5100_EQ2_B4_B_MASK 0xFFFF /* EQ2_B4_B - [15:0] */
4042#define WM5100_EQ2_B4_B_SHIFT 0 /* EQ2_B4_B - [15:0] */
4043#define WM5100_EQ2_B4_B_WIDTH 16 /* EQ2_B4_B - [15:0] */
4044
4045/*
4046 * R3637 (0xE35) - EQ2_16
4047 */
4048#define WM5100_EQ2_B4_C_MASK 0xFFFF /* EQ2_B4_C - [15:0] */
4049#define WM5100_EQ2_B4_C_SHIFT 0 /* EQ2_B4_C - [15:0] */
4050#define WM5100_EQ2_B4_C_WIDTH 16 /* EQ2_B4_C - [15:0] */
4051
4052/*
4053 * R3638 (0xE36) - EQ2_17
4054 */
4055#define WM5100_EQ2_B4_PG_MASK 0xFFFF /* EQ2_B4_PG - [15:0] */
4056#define WM5100_EQ2_B4_PG_SHIFT 0 /* EQ2_B4_PG - [15:0] */
4057#define WM5100_EQ2_B4_PG_WIDTH 16 /* EQ2_B4_PG - [15:0] */
4058
4059/*
4060 * R3639 (0xE37) - EQ2_18
4061 */
4062#define WM5100_EQ2_B5_A_MASK 0xFFFF /* EQ2_B5_A - [15:0] */
4063#define WM5100_EQ2_B5_A_SHIFT 0 /* EQ2_B5_A - [15:0] */
4064#define WM5100_EQ2_B5_A_WIDTH 16 /* EQ2_B5_A - [15:0] */
4065
4066/*
4067 * R3640 (0xE38) - EQ2_19
4068 */
4069#define WM5100_EQ2_B5_B_MASK 0xFFFF /* EQ2_B5_B - [15:0] */
4070#define WM5100_EQ2_B5_B_SHIFT 0 /* EQ2_B5_B - [15:0] */
4071#define WM5100_EQ2_B5_B_WIDTH 16 /* EQ2_B5_B - [15:0] */
4072
4073/*
4074 * R3641 (0xE39) - EQ2_20
4075 */
4076#define WM5100_EQ2_B5_PG_MASK 0xFFFF /* EQ2_B5_PG - [15:0] */
4077#define WM5100_EQ2_B5_PG_SHIFT 0 /* EQ2_B5_PG - [15:0] */
4078#define WM5100_EQ2_B5_PG_WIDTH 16 /* EQ2_B5_PG - [15:0] */
4079
4080/*
4081 * R3644 (0xE3C) - EQ3_1
4082 */
4083#define WM5100_EQ3_B1_GAIN_MASK 0xF800 /* EQ3_B1_GAIN - [15:11] */
4084#define WM5100_EQ3_B1_GAIN_SHIFT 11 /* EQ3_B1_GAIN - [15:11] */
4085#define WM5100_EQ3_B1_GAIN_WIDTH 5 /* EQ3_B1_GAIN - [15:11] */
4086#define WM5100_EQ3_B2_GAIN_MASK 0x07C0 /* EQ3_B2_GAIN - [10:6] */
4087#define WM5100_EQ3_B2_GAIN_SHIFT 6 /* EQ3_B2_GAIN - [10:6] */
4088#define WM5100_EQ3_B2_GAIN_WIDTH 5 /* EQ3_B2_GAIN - [10:6] */
4089#define WM5100_EQ3_B3_GAIN_MASK 0x003E /* EQ3_B3_GAIN - [5:1] */
4090#define WM5100_EQ3_B3_GAIN_SHIFT 1 /* EQ3_B3_GAIN - [5:1] */
4091#define WM5100_EQ3_B3_GAIN_WIDTH 5 /* EQ3_B3_GAIN - [5:1] */
4092#define WM5100_EQ3_ENA 0x0001 /* EQ3_ENA */
4093#define WM5100_EQ3_ENA_MASK 0x0001 /* EQ3_ENA */
4094#define WM5100_EQ3_ENA_SHIFT 0 /* EQ3_ENA */
4095#define WM5100_EQ3_ENA_WIDTH 1 /* EQ3_ENA */
4096
4097/*
4098 * R3645 (0xE3D) - EQ3_2
4099 */
4100#define WM5100_EQ3_B4_GAIN_MASK 0xF800 /* EQ3_B4_GAIN - [15:11] */
4101#define WM5100_EQ3_B4_GAIN_SHIFT 11 /* EQ3_B4_GAIN - [15:11] */
4102#define WM5100_EQ3_B4_GAIN_WIDTH 5 /* EQ3_B4_GAIN - [15:11] */
4103#define WM5100_EQ3_B5_GAIN_MASK 0x07C0 /* EQ3_B5_GAIN - [10:6] */
4104#define WM5100_EQ3_B5_GAIN_SHIFT 6 /* EQ3_B5_GAIN - [10:6] */
4105#define WM5100_EQ3_B5_GAIN_WIDTH 5 /* EQ3_B5_GAIN - [10:6] */
4106
4107/*
4108 * R3646 (0xE3E) - EQ3_3
4109 */
4110#define WM5100_EQ3_B1_A_MASK 0xFFFF /* EQ3_B1_A - [15:0] */
4111#define WM5100_EQ3_B1_A_SHIFT 0 /* EQ3_B1_A - [15:0] */
4112#define WM5100_EQ3_B1_A_WIDTH 16 /* EQ3_B1_A - [15:0] */
4113
4114/*
4115 * R3647 (0xE3F) - EQ3_4
4116 */
4117#define WM5100_EQ3_B1_B_MASK 0xFFFF /* EQ3_B1_B - [15:0] */
4118#define WM5100_EQ3_B1_B_SHIFT 0 /* EQ3_B1_B - [15:0] */
4119#define WM5100_EQ3_B1_B_WIDTH 16 /* EQ3_B1_B - [15:0] */
4120
4121/*
4122 * R3648 (0xE40) - EQ3_5
4123 */
4124#define WM5100_EQ3_B1_PG_MASK 0xFFFF /* EQ3_B1_PG - [15:0] */
4125#define WM5100_EQ3_B1_PG_SHIFT 0 /* EQ3_B1_PG - [15:0] */
4126#define WM5100_EQ3_B1_PG_WIDTH 16 /* EQ3_B1_PG - [15:0] */
4127
4128/*
4129 * R3649 (0xE41) - EQ3_6
4130 */
4131#define WM5100_EQ3_B2_A_MASK 0xFFFF /* EQ3_B2_A - [15:0] */
4132#define WM5100_EQ3_B2_A_SHIFT 0 /* EQ3_B2_A - [15:0] */
4133#define WM5100_EQ3_B2_A_WIDTH 16 /* EQ3_B2_A - [15:0] */
4134
4135/*
4136 * R3650 (0xE42) - EQ3_7
4137 */
4138#define WM5100_EQ3_B2_B_MASK 0xFFFF /* EQ3_B2_B - [15:0] */
4139#define WM5100_EQ3_B2_B_SHIFT 0 /* EQ3_B2_B - [15:0] */
4140#define WM5100_EQ3_B2_B_WIDTH 16 /* EQ3_B2_B - [15:0] */
4141
4142/*
4143 * R3651 (0xE43) - EQ3_8
4144 */
4145#define WM5100_EQ3_B2_C_MASK 0xFFFF /* EQ3_B2_C - [15:0] */
4146#define WM5100_EQ3_B2_C_SHIFT 0 /* EQ3_B2_C - [15:0] */
4147#define WM5100_EQ3_B2_C_WIDTH 16 /* EQ3_B2_C - [15:0] */
4148
4149/*
4150 * R3652 (0xE44) - EQ3_9
4151 */
4152#define WM5100_EQ3_B2_PG_MASK 0xFFFF /* EQ3_B2_PG - [15:0] */
4153#define WM5100_EQ3_B2_PG_SHIFT 0 /* EQ3_B2_PG - [15:0] */
4154#define WM5100_EQ3_B2_PG_WIDTH 16 /* EQ3_B2_PG - [15:0] */
4155
4156/*
4157 * R3653 (0xE45) - EQ3_10
4158 */
4159#define WM5100_EQ3_B3_A_MASK 0xFFFF /* EQ3_B3_A - [15:0] */
4160#define WM5100_EQ3_B3_A_SHIFT 0 /* EQ3_B3_A - [15:0] */
4161#define WM5100_EQ3_B3_A_WIDTH 16 /* EQ3_B3_A - [15:0] */
4162
4163/*
4164 * R3654 (0xE46) - EQ3_11
4165 */
4166#define WM5100_EQ3_B3_B_MASK 0xFFFF /* EQ3_B3_B - [15:0] */
4167#define WM5100_EQ3_B3_B_SHIFT 0 /* EQ3_B3_B - [15:0] */
4168#define WM5100_EQ3_B3_B_WIDTH 16 /* EQ3_B3_B - [15:0] */
4169
4170/*
4171 * R3655 (0xE47) - EQ3_12
4172 */
4173#define WM5100_EQ3_B3_C_MASK 0xFFFF /* EQ3_B3_C - [15:0] */
4174#define WM5100_EQ3_B3_C_SHIFT 0 /* EQ3_B3_C - [15:0] */
4175#define WM5100_EQ3_B3_C_WIDTH 16 /* EQ3_B3_C - [15:0] */
4176
4177/*
4178 * R3656 (0xE48) - EQ3_13
4179 */
4180#define WM5100_EQ3_B3_PG_MASK 0xFFFF /* EQ3_B3_PG - [15:0] */
4181#define WM5100_EQ3_B3_PG_SHIFT 0 /* EQ3_B3_PG - [15:0] */
4182#define WM5100_EQ3_B3_PG_WIDTH 16 /* EQ3_B3_PG - [15:0] */
4183
4184/*
4185 * R3657 (0xE49) - EQ3_14
4186 */
4187#define WM5100_EQ3_B4_A_MASK 0xFFFF /* EQ3_B4_A - [15:0] */
4188#define WM5100_EQ3_B4_A_SHIFT 0 /* EQ3_B4_A - [15:0] */
4189#define WM5100_EQ3_B4_A_WIDTH 16 /* EQ3_B4_A - [15:0] */
4190
4191/*
4192 * R3658 (0xE4A) - EQ3_15
4193 */
4194#define WM5100_EQ3_B4_B_MASK 0xFFFF /* EQ3_B4_B - [15:0] */
4195#define WM5100_EQ3_B4_B_SHIFT 0 /* EQ3_B4_B - [15:0] */
4196#define WM5100_EQ3_B4_B_WIDTH 16 /* EQ3_B4_B - [15:0] */
4197
4198/*
4199 * R3659 (0xE4B) - EQ3_16
4200 */
4201#define WM5100_EQ3_B4_C_MASK 0xFFFF /* EQ3_B4_C - [15:0] */
4202#define WM5100_EQ3_B4_C_SHIFT 0 /* EQ3_B4_C - [15:0] */
4203#define WM5100_EQ3_B4_C_WIDTH 16 /* EQ3_B4_C - [15:0] */
4204
4205/*
4206 * R3660 (0xE4C) - EQ3_17
4207 */
4208#define WM5100_EQ3_B4_PG_MASK 0xFFFF /* EQ3_B4_PG - [15:0] */
4209#define WM5100_EQ3_B4_PG_SHIFT 0 /* EQ3_B4_PG - [15:0] */
4210#define WM5100_EQ3_B4_PG_WIDTH 16 /* EQ3_B4_PG - [15:0] */
4211
4212/*
4213 * R3661 (0xE4D) - EQ3_18
4214 */
4215#define WM5100_EQ3_B5_A_MASK 0xFFFF /* EQ3_B5_A - [15:0] */
4216#define WM5100_EQ3_B5_A_SHIFT 0 /* EQ3_B5_A - [15:0] */
4217#define WM5100_EQ3_B5_A_WIDTH 16 /* EQ3_B5_A - [15:0] */
4218
4219/*
4220 * R3662 (0xE4E) - EQ3_19
4221 */
4222#define WM5100_EQ3_B5_B_MASK 0xFFFF /* EQ3_B5_B - [15:0] */
4223#define WM5100_EQ3_B5_B_SHIFT 0 /* EQ3_B5_B - [15:0] */
4224#define WM5100_EQ3_B5_B_WIDTH 16 /* EQ3_B5_B - [15:0] */
4225
4226/*
4227 * R3663 (0xE4F) - EQ3_20
4228 */
4229#define WM5100_EQ3_B5_PG_MASK 0xFFFF /* EQ3_B5_PG - [15:0] */
4230#define WM5100_EQ3_B5_PG_SHIFT 0 /* EQ3_B5_PG - [15:0] */
4231#define WM5100_EQ3_B5_PG_WIDTH 16 /* EQ3_B5_PG - [15:0] */
4232
4233/*
4234 * R3666 (0xE52) - EQ4_1
4235 */
4236#define WM5100_EQ4_B1_GAIN_MASK 0xF800 /* EQ4_B1_GAIN - [15:11] */
4237#define WM5100_EQ4_B1_GAIN_SHIFT 11 /* EQ4_B1_GAIN - [15:11] */
4238#define WM5100_EQ4_B1_GAIN_WIDTH 5 /* EQ4_B1_GAIN - [15:11] */
4239#define WM5100_EQ4_B2_GAIN_MASK 0x07C0 /* EQ4_B2_GAIN - [10:6] */
4240#define WM5100_EQ4_B2_GAIN_SHIFT 6 /* EQ4_B2_GAIN - [10:6] */
4241#define WM5100_EQ4_B2_GAIN_WIDTH 5 /* EQ4_B2_GAIN - [10:6] */
4242#define WM5100_EQ4_B3_GAIN_MASK 0x003E /* EQ4_B3_GAIN - [5:1] */
4243#define WM5100_EQ4_B3_GAIN_SHIFT 1 /* EQ4_B3_GAIN - [5:1] */
4244#define WM5100_EQ4_B3_GAIN_WIDTH 5 /* EQ4_B3_GAIN - [5:1] */
4245#define WM5100_EQ4_ENA 0x0001 /* EQ4_ENA */
4246#define WM5100_EQ4_ENA_MASK 0x0001 /* EQ4_ENA */
4247#define WM5100_EQ4_ENA_SHIFT 0 /* EQ4_ENA */
4248#define WM5100_EQ4_ENA_WIDTH 1 /* EQ4_ENA */
4249
4250/*
4251 * R3667 (0xE53) - EQ4_2
4252 */
4253#define WM5100_EQ4_B4_GAIN_MASK 0xF800 /* EQ4_B4_GAIN - [15:11] */
4254#define WM5100_EQ4_B4_GAIN_SHIFT 11 /* EQ4_B4_GAIN - [15:11] */
4255#define WM5100_EQ4_B4_GAIN_WIDTH 5 /* EQ4_B4_GAIN - [15:11] */
4256#define WM5100_EQ4_B5_GAIN_MASK 0x07C0 /* EQ4_B5_GAIN - [10:6] */
4257#define WM5100_EQ4_B5_GAIN_SHIFT 6 /* EQ4_B5_GAIN - [10:6] */
4258#define WM5100_EQ4_B5_GAIN_WIDTH 5 /* EQ4_B5_GAIN - [10:6] */
4259
4260/*
4261 * R3668 (0xE54) - EQ4_3
4262 */
4263#define WM5100_EQ4_B1_A_MASK 0xFFFF /* EQ4_B1_A - [15:0] */
4264#define WM5100_EQ4_B1_A_SHIFT 0 /* EQ4_B1_A - [15:0] */
4265#define WM5100_EQ4_B1_A_WIDTH 16 /* EQ4_B1_A - [15:0] */
4266
4267/*
4268 * R3669 (0xE55) - EQ4_4
4269 */
4270#define WM5100_EQ4_B1_B_MASK 0xFFFF /* EQ4_B1_B - [15:0] */
4271#define WM5100_EQ4_B1_B_SHIFT 0 /* EQ4_B1_B - [15:0] */
4272#define WM5100_EQ4_B1_B_WIDTH 16 /* EQ4_B1_B - [15:0] */
4273
4274/*
4275 * R3670 (0xE56) - EQ4_5
4276 */
4277#define WM5100_EQ4_B1_PG_MASK 0xFFFF /* EQ4_B1_PG - [15:0] */
4278#define WM5100_EQ4_B1_PG_SHIFT 0 /* EQ4_B1_PG - [15:0] */
4279#define WM5100_EQ4_B1_PG_WIDTH 16 /* EQ4_B1_PG - [15:0] */
4280
4281/*
4282 * R3671 (0xE57) - EQ4_6
4283 */
4284#define WM5100_EQ4_B2_A_MASK 0xFFFF /* EQ4_B2_A - [15:0] */
4285#define WM5100_EQ4_B2_A_SHIFT 0 /* EQ4_B2_A - [15:0] */
4286#define WM5100_EQ4_B2_A_WIDTH 16 /* EQ4_B2_A - [15:0] */
4287
4288/*
4289 * R3672 (0xE58) - EQ4_7
4290 */
4291#define WM5100_EQ4_B2_B_MASK 0xFFFF /* EQ4_B2_B - [15:0] */
4292#define WM5100_EQ4_B2_B_SHIFT 0 /* EQ4_B2_B - [15:0] */
4293#define WM5100_EQ4_B2_B_WIDTH 16 /* EQ4_B2_B - [15:0] */
4294
4295/*
4296 * R3673 (0xE59) - EQ4_8
4297 */
4298#define WM5100_EQ4_B2_C_MASK 0xFFFF /* EQ4_B2_C - [15:0] */
4299#define WM5100_EQ4_B2_C_SHIFT 0 /* EQ4_B2_C - [15:0] */
4300#define WM5100_EQ4_B2_C_WIDTH 16 /* EQ4_B2_C - [15:0] */
4301
4302/*
4303 * R3674 (0xE5A) - EQ4_9
4304 */
4305#define WM5100_EQ4_B2_PG_MASK 0xFFFF /* EQ4_B2_PG - [15:0] */
4306#define WM5100_EQ4_B2_PG_SHIFT 0 /* EQ4_B2_PG - [15:0] */
4307#define WM5100_EQ4_B2_PG_WIDTH 16 /* EQ4_B2_PG - [15:0] */
4308
4309/*
4310 * R3675 (0xE5B) - EQ4_10
4311 */
4312#define WM5100_EQ4_B3_A_MASK 0xFFFF /* EQ4_B3_A - [15:0] */
4313#define WM5100_EQ4_B3_A_SHIFT 0 /* EQ4_B3_A - [15:0] */
4314#define WM5100_EQ4_B3_A_WIDTH 16 /* EQ4_B3_A - [15:0] */
4315
4316/*
4317 * R3676 (0xE5C) - EQ4_11
4318 */
4319#define WM5100_EQ4_B3_B_MASK 0xFFFF /* EQ4_B3_B - [15:0] */
4320#define WM5100_EQ4_B3_B_SHIFT 0 /* EQ4_B3_B - [15:0] */
4321#define WM5100_EQ4_B3_B_WIDTH 16 /* EQ4_B3_B - [15:0] */
4322
4323/*
4324 * R3677 (0xE5D) - EQ4_12
4325 */
4326#define WM5100_EQ4_B3_C_MASK 0xFFFF /* EQ4_B3_C - [15:0] */
4327#define WM5100_EQ4_B3_C_SHIFT 0 /* EQ4_B3_C - [15:0] */
4328#define WM5100_EQ4_B3_C_WIDTH 16 /* EQ4_B3_C - [15:0] */
4329
4330/*
4331 * R3678 (0xE5E) - EQ4_13
4332 */
4333#define WM5100_EQ4_B3_PG_MASK 0xFFFF /* EQ4_B3_PG - [15:0] */
4334#define WM5100_EQ4_B3_PG_SHIFT 0 /* EQ4_B3_PG - [15:0] */
4335#define WM5100_EQ4_B3_PG_WIDTH 16 /* EQ4_B3_PG - [15:0] */
4336
4337/*
4338 * R3679 (0xE5F) - EQ4_14
4339 */
4340#define WM5100_EQ4_B4_A_MASK 0xFFFF /* EQ4_B4_A - [15:0] */
4341#define WM5100_EQ4_B4_A_SHIFT 0 /* EQ4_B4_A - [15:0] */
4342#define WM5100_EQ4_B4_A_WIDTH 16 /* EQ4_B4_A - [15:0] */
4343
4344/*
4345 * R3680 (0xE60) - EQ4_15
4346 */
4347#define WM5100_EQ4_B4_B_MASK 0xFFFF /* EQ4_B4_B - [15:0] */
4348#define WM5100_EQ4_B4_B_SHIFT 0 /* EQ4_B4_B - [15:0] */
4349#define WM5100_EQ4_B4_B_WIDTH 16 /* EQ4_B4_B - [15:0] */
4350
4351/*
4352 * R3681 (0xE61) - EQ4_16
4353 */
4354#define WM5100_EQ4_B4_C_MASK 0xFFFF /* EQ4_B4_C - [15:0] */
4355#define WM5100_EQ4_B4_C_SHIFT 0 /* EQ4_B4_C - [15:0] */
4356#define WM5100_EQ4_B4_C_WIDTH 16 /* EQ4_B4_C - [15:0] */
4357
4358/*
4359 * R3682 (0xE62) - EQ4_17
4360 */
4361#define WM5100_EQ4_B4_PG_MASK 0xFFFF /* EQ4_B4_PG - [15:0] */
4362#define WM5100_EQ4_B4_PG_SHIFT 0 /* EQ4_B4_PG - [15:0] */
4363#define WM5100_EQ4_B4_PG_WIDTH 16 /* EQ4_B4_PG - [15:0] */
4364
4365/*
4366 * R3683 (0xE63) - EQ4_18
4367 */
4368#define WM5100_EQ4_B5_A_MASK 0xFFFF /* EQ4_B5_A - [15:0] */
4369#define WM5100_EQ4_B5_A_SHIFT 0 /* EQ4_B5_A - [15:0] */
4370#define WM5100_EQ4_B5_A_WIDTH 16 /* EQ4_B5_A - [15:0] */
4371
4372/*
4373 * R3684 (0xE64) - EQ4_19
4374 */
4375#define WM5100_EQ4_B5_B_MASK 0xFFFF /* EQ4_B5_B - [15:0] */
4376#define WM5100_EQ4_B5_B_SHIFT 0 /* EQ4_B5_B - [15:0] */
4377#define WM5100_EQ4_B5_B_WIDTH 16 /* EQ4_B5_B - [15:0] */
4378
4379/*
4380 * R3685 (0xE65) - EQ4_20
4381 */
4382#define WM5100_EQ4_B5_PG_MASK 0xFFFF /* EQ4_B5_PG - [15:0] */
4383#define WM5100_EQ4_B5_PG_SHIFT 0 /* EQ4_B5_PG - [15:0] */
4384#define WM5100_EQ4_B5_PG_WIDTH 16 /* EQ4_B5_PG - [15:0] */
4385
4386/*
4387 * R3712 (0xE80) - DRC1 ctrl1
4388 */
4389#define WM5100_DRC_SIG_DET_RMS_MASK 0xF800 /* DRC_SIG_DET_RMS - [15:11] */
4390#define WM5100_DRC_SIG_DET_RMS_SHIFT 11 /* DRC_SIG_DET_RMS - [15:11] */
4391#define WM5100_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [15:11] */
4392#define WM5100_DRC_SIG_DET_PK_MASK 0x0600 /* DRC_SIG_DET_PK - [10:9] */
4393#define WM5100_DRC_SIG_DET_PK_SHIFT 9 /* DRC_SIG_DET_PK - [10:9] */
4394#define WM5100_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [10:9] */
4395#define WM5100_DRC_NG_ENA 0x0100 /* DRC_NG_ENA */
4396#define WM5100_DRC_NG_ENA_MASK 0x0100 /* DRC_NG_ENA */
4397#define WM5100_DRC_NG_ENA_SHIFT 8 /* DRC_NG_ENA */
4398#define WM5100_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */
4399#define WM5100_DRC_SIG_DET_MODE 0x0080 /* DRC_SIG_DET_MODE */
4400#define WM5100_DRC_SIG_DET_MODE_MASK 0x0080 /* DRC_SIG_DET_MODE */
4401#define WM5100_DRC_SIG_DET_MODE_SHIFT 7 /* DRC_SIG_DET_MODE */
4402#define WM5100_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */
4403#define WM5100_DRC_SIG_DET 0x0040 /* DRC_SIG_DET */
4404#define WM5100_DRC_SIG_DET_MASK 0x0040 /* DRC_SIG_DET */
4405#define WM5100_DRC_SIG_DET_SHIFT 6 /* DRC_SIG_DET */
4406#define WM5100_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */
4407#define WM5100_DRC_KNEE2_OP_ENA 0x0020 /* DRC_KNEE2_OP_ENA */
4408#define WM5100_DRC_KNEE2_OP_ENA_MASK 0x0020 /* DRC_KNEE2_OP_ENA */
4409#define WM5100_DRC_KNEE2_OP_ENA_SHIFT 5 /* DRC_KNEE2_OP_ENA */
4410#define WM5100_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */
4411#define WM5100_DRC_QR 0x0010 /* DRC_QR */
4412#define WM5100_DRC_QR_MASK 0x0010 /* DRC_QR */
4413#define WM5100_DRC_QR_SHIFT 4 /* DRC_QR */
4414#define WM5100_DRC_QR_WIDTH 1 /* DRC_QR */
4415#define WM5100_DRC_ANTICLIP 0x0008 /* DRC_ANTICLIP */
4416#define WM5100_DRC_ANTICLIP_MASK 0x0008 /* DRC_ANTICLIP */
4417#define WM5100_DRC_ANTICLIP_SHIFT 3 /* DRC_ANTICLIP */
4418#define WM5100_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
4419#define WM5100_DRCL_ENA 0x0002 /* DRCL_ENA */
4420#define WM5100_DRCL_ENA_MASK 0x0002 /* DRCL_ENA */
4421#define WM5100_DRCL_ENA_SHIFT 1 /* DRCL_ENA */
4422#define WM5100_DRCL_ENA_WIDTH 1 /* DRCL_ENA */
4423#define WM5100_DRCR_ENA 0x0001 /* DRCR_ENA */
4424#define WM5100_DRCR_ENA_MASK 0x0001 /* DRCR_ENA */
4425#define WM5100_DRCR_ENA_SHIFT 0 /* DRCR_ENA */
4426#define WM5100_DRCR_ENA_WIDTH 1 /* DRCR_ENA */
4427
4428/*
4429 * R3713 (0xE81) - DRC1 ctrl2
4430 */
4431#define WM5100_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */
4432#define WM5100_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */
4433#define WM5100_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */
4434#define WM5100_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */
4435#define WM5100_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */
4436#define WM5100_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */
4437#define WM5100_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */
4438#define WM5100_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */
4439#define WM5100_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */
4440#define WM5100_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
4441#define WM5100_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
4442#define WM5100_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
4443
4444/*
4445 * R3714 (0xE82) - DRC1 ctrl3
4446 */
4447#define WM5100_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */
4448#define WM5100_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */
4449#define WM5100_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */
4450#define WM5100_DRC_NG_EXP_MASK 0x0C00 /* DRC_NG_EXP - [11:10] */
4451#define WM5100_DRC_NG_EXP_SHIFT 10 /* DRC_NG_EXP - [11:10] */
4452#define WM5100_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [11:10] */
4453#define WM5100_DRC_QR_THR_MASK 0x0300 /* DRC_QR_THR - [9:8] */
4454#define WM5100_DRC_QR_THR_SHIFT 8 /* DRC_QR_THR - [9:8] */
4455#define WM5100_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [9:8] */
4456#define WM5100_DRC_QR_DCY_MASK 0x00C0 /* DRC_QR_DCY - [7:6] */
4457#define WM5100_DRC_QR_DCY_SHIFT 6 /* DRC_QR_DCY - [7:6] */
4458#define WM5100_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [7:6] */
4459#define WM5100_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
4460#define WM5100_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
4461#define WM5100_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
4462#define WM5100_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
4463#define WM5100_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
4464#define WM5100_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
4465
4466/*
4467 * R3715 (0xE83) - DRC1 ctrl4
4468 */
4469#define WM5100_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
4470#define WM5100_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
4471#define WM5100_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
4472#define WM5100_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
4473#define WM5100_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
4474#define WM5100_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
4475
4476/*
4477 * R3716 (0xE84) - DRC1 ctrl5
4478 */
4479#define WM5100_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */
4480#define WM5100_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */
4481#define WM5100_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */
4482#define WM5100_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */
4483#define WM5100_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */
4484#define WM5100_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */
4485
4486/*
4487 * R3776 (0xEC0) - HPLPF1_1
4488 */
4489#define WM5100_LHPF1_MODE 0x0002 /* LHPF1_MODE */
4490#define WM5100_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
4491#define WM5100_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
4492#define WM5100_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
4493#define WM5100_LHPF1_ENA 0x0001 /* LHPF1_ENA */
4494#define WM5100_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
4495#define WM5100_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
4496#define WM5100_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
4497
4498/*
4499 * R3777 (0xEC1) - HPLPF1_2
4500 */
4501#define WM5100_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
4502#define WM5100_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
4503#define WM5100_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
4504
4505/*
4506 * R3780 (0xEC4) - HPLPF2_1
4507 */
4508#define WM5100_LHPF2_MODE 0x0002 /* LHPF2_MODE */
4509#define WM5100_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
4510#define WM5100_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
4511#define WM5100_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
4512#define WM5100_LHPF2_ENA 0x0001 /* LHPF2_ENA */
4513#define WM5100_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
4514#define WM5100_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
4515#define WM5100_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
4516
4517/*
4518 * R3781 (0xEC5) - HPLPF2_2
4519 */
4520#define WM5100_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
4521#define WM5100_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
4522#define WM5100_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
4523
4524/*
4525 * R3784 (0xEC8) - HPLPF3_1
4526 */
4527#define WM5100_LHPF3_MODE 0x0002 /* LHPF3_MODE */
4528#define WM5100_LHPF3_MODE_MASK 0x0002 /* LHPF3_MODE */
4529#define WM5100_LHPF3_MODE_SHIFT 1 /* LHPF3_MODE */
4530#define WM5100_LHPF3_MODE_WIDTH 1 /* LHPF3_MODE */
4531#define WM5100_LHPF3_ENA 0x0001 /* LHPF3_ENA */
4532#define WM5100_LHPF3_ENA_MASK 0x0001 /* LHPF3_ENA */
4533#define WM5100_LHPF3_ENA_SHIFT 0 /* LHPF3_ENA */
4534#define WM5100_LHPF3_ENA_WIDTH 1 /* LHPF3_ENA */
4535
4536/*
4537 * R3785 (0xEC9) - HPLPF3_2
4538 */
4539#define WM5100_LHPF3_COEFF_MASK 0xFFFF /* LHPF3_COEFF - [15:0] */
4540#define WM5100_LHPF3_COEFF_SHIFT 0 /* LHPF3_COEFF - [15:0] */
4541#define WM5100_LHPF3_COEFF_WIDTH 16 /* LHPF3_COEFF - [15:0] */
4542
4543/*
4544 * R3788 (0xECC) - HPLPF4_1
4545 */
4546#define WM5100_LHPF4_MODE 0x0002 /* LHPF4_MODE */
4547#define WM5100_LHPF4_MODE_MASK 0x0002 /* LHPF4_MODE */
4548#define WM5100_LHPF4_MODE_SHIFT 1 /* LHPF4_MODE */
4549#define WM5100_LHPF4_MODE_WIDTH 1 /* LHPF4_MODE */
4550#define WM5100_LHPF4_ENA 0x0001 /* LHPF4_ENA */
4551#define WM5100_LHPF4_ENA_MASK 0x0001 /* LHPF4_ENA */
4552#define WM5100_LHPF4_ENA_SHIFT 0 /* LHPF4_ENA */
4553#define WM5100_LHPF4_ENA_WIDTH 1 /* LHPF4_ENA */
4554
4555/*
4556 * R3789 (0xECD) - HPLPF4_2
4557 */
4558#define WM5100_LHPF4_COEFF_MASK 0xFFFF /* LHPF4_COEFF - [15:0] */
4559#define WM5100_LHPF4_COEFF_SHIFT 0 /* LHPF4_COEFF - [15:0] */
4560#define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */
4561
4562/*
4563 * R16384 (0x4000) - DSP1 DM 0
4564 */
4565#define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */
4566#define WM5100_DSP1_DM_START_1_SHIFT 0 /* DSP1_DM_START - [7:0] */
4567#define WM5100_DSP1_DM_START_1_WIDTH 8 /* DSP1_DM_START - [7:0] */
4568
4569/*
4570 * R16385 (0x4001) - DSP1 DM 1
4571 */
4572#define WM5100_DSP1_DM_START_MASK 0xFFFF /* DSP1_DM_START - [15:0] */
4573#define WM5100_DSP1_DM_START_SHIFT 0 /* DSP1_DM_START - [15:0] */
4574#define WM5100_DSP1_DM_START_WIDTH 16 /* DSP1_DM_START - [15:0] */
4575
4576/*
4577 * R16386 (0x4002) - DSP1 DM 2
4578 */
4579#define WM5100_DSP1_DM_1_1_MASK 0x00FF /* DSP1_DM_1 - [7:0] */
4580#define WM5100_DSP1_DM_1_1_SHIFT 0 /* DSP1_DM_1 - [7:0] */
4581#define WM5100_DSP1_DM_1_1_WIDTH 8 /* DSP1_DM_1 - [7:0] */
4582
4583/*
4584 * R16387 (0x4003) - DSP1 DM 3
4585 */
4586#define WM5100_DSP1_DM_1_MASK 0xFFFF /* DSP1_DM_1 - [15:0] */
4587#define WM5100_DSP1_DM_1_SHIFT 0 /* DSP1_DM_1 - [15:0] */
4588#define WM5100_DSP1_DM_1_WIDTH 16 /* DSP1_DM_1 - [15:0] */
4589
4590/*
4591 * R16892 (0x41FC) - DSP1 DM 508
4592 */
4593#define WM5100_DSP1_DM_254_1_MASK 0x00FF /* DSP1_DM_254 - [7:0] */
4594#define WM5100_DSP1_DM_254_1_SHIFT 0 /* DSP1_DM_254 - [7:0] */
4595#define WM5100_DSP1_DM_254_1_WIDTH 8 /* DSP1_DM_254 - [7:0] */
4596
4597/*
4598 * R16893 (0x41FD) - DSP1 DM 509
4599 */
4600#define WM5100_DSP1_DM_254_MASK 0xFFFF /* DSP1_DM_254 - [15:0] */
4601#define WM5100_DSP1_DM_254_SHIFT 0 /* DSP1_DM_254 - [15:0] */
4602#define WM5100_DSP1_DM_254_WIDTH 16 /* DSP1_DM_254 - [15:0] */
4603
4604/*
4605 * R16894 (0x41FE) - DSP1 DM 510
4606 */
4607#define WM5100_DSP1_DM_END_1_MASK 0x00FF /* DSP1_DM_END - [7:0] */
4608#define WM5100_DSP1_DM_END_1_SHIFT 0 /* DSP1_DM_END - [7:0] */
4609#define WM5100_DSP1_DM_END_1_WIDTH 8 /* DSP1_DM_END - [7:0] */
4610
4611/*
4612 * R16895 (0x41FF) - DSP1 DM 511
4613 */
4614#define WM5100_DSP1_DM_END_MASK 0xFFFF /* DSP1_DM_END - [15:0] */
4615#define WM5100_DSP1_DM_END_SHIFT 0 /* DSP1_DM_END - [15:0] */
4616#define WM5100_DSP1_DM_END_WIDTH 16 /* DSP1_DM_END - [15:0] */
4617
4618/*
4619 * R18432 (0x4800) - DSP1 PM 0
4620 */
4621#define WM5100_DSP1_PM_START_2_MASK 0x00FF /* DSP1_PM_START - [7:0] */
4622#define WM5100_DSP1_PM_START_2_SHIFT 0 /* DSP1_PM_START - [7:0] */
4623#define WM5100_DSP1_PM_START_2_WIDTH 8 /* DSP1_PM_START - [7:0] */
4624
4625/*
4626 * R18433 (0x4801) - DSP1 PM 1
4627 */
4628#define WM5100_DSP1_PM_START_1_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
4629#define WM5100_DSP1_PM_START_1_SHIFT 0 /* DSP1_PM_START - [15:0] */
4630#define WM5100_DSP1_PM_START_1_WIDTH 16 /* DSP1_PM_START - [15:0] */
4631
4632/*
4633 * R18434 (0x4802) - DSP1 PM 2
4634 */
4635#define WM5100_DSP1_PM_START_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
4636#define WM5100_DSP1_PM_START_SHIFT 0 /* DSP1_PM_START - [15:0] */
4637#define WM5100_DSP1_PM_START_WIDTH 16 /* DSP1_PM_START - [15:0] */
4638
4639/*
4640 * R18435 (0x4803) - DSP1 PM 3
4641 */
4642#define WM5100_DSP1_PM_1_2_MASK 0x00FF /* DSP1_PM_1 - [7:0] */
4643#define WM5100_DSP1_PM_1_2_SHIFT 0 /* DSP1_PM_1 - [7:0] */
4644#define WM5100_DSP1_PM_1_2_WIDTH 8 /* DSP1_PM_1 - [7:0] */
4645
4646/*
4647 * R18436 (0x4804) - DSP1 PM 4
4648 */
4649#define WM5100_DSP1_PM_1_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
4650#define WM5100_DSP1_PM_1_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
4651#define WM5100_DSP1_PM_1_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
4652
4653/*
4654 * R18437 (0x4805) - DSP1 PM 5
4655 */
4656#define WM5100_DSP1_PM_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
4657#define WM5100_DSP1_PM_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
4658#define WM5100_DSP1_PM_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
4659
4660/*
4661 * R19962 (0x4DFA) - DSP1 PM 1530
4662 */
4663#define WM5100_DSP1_PM_510_2_MASK 0x00FF /* DSP1_PM_510 - [7:0] */
4664#define WM5100_DSP1_PM_510_2_SHIFT 0 /* DSP1_PM_510 - [7:0] */
4665#define WM5100_DSP1_PM_510_2_WIDTH 8 /* DSP1_PM_510 - [7:0] */
4666
4667/*
4668 * R19963 (0x4DFB) - DSP1 PM 1531
4669 */
4670#define WM5100_DSP1_PM_510_1_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
4671#define WM5100_DSP1_PM_510_1_SHIFT 0 /* DSP1_PM_510 - [15:0] */
4672#define WM5100_DSP1_PM_510_1_WIDTH 16 /* DSP1_PM_510 - [15:0] */
4673
4674/*
4675 * R19964 (0x4DFC) - DSP1 PM 1532
4676 */
4677#define WM5100_DSP1_PM_510_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
4678#define WM5100_DSP1_PM_510_SHIFT 0 /* DSP1_PM_510 - [15:0] */
4679#define WM5100_DSP1_PM_510_WIDTH 16 /* DSP1_PM_510 - [15:0] */
4680
4681/*
4682 * R19965 (0x4DFD) - DSP1 PM 1533
4683 */
4684#define WM5100_DSP1_PM_END_2_MASK 0x00FF /* DSP1_PM_END - [7:0] */
4685#define WM5100_DSP1_PM_END_2_SHIFT 0 /* DSP1_PM_END - [7:0] */
4686#define WM5100_DSP1_PM_END_2_WIDTH 8 /* DSP1_PM_END - [7:0] */
4687
4688/*
4689 * R19966 (0x4DFE) - DSP1 PM 1534
4690 */
4691#define WM5100_DSP1_PM_END_1_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
4692#define WM5100_DSP1_PM_END_1_SHIFT 0 /* DSP1_PM_END - [15:0] */
4693#define WM5100_DSP1_PM_END_1_WIDTH 16 /* DSP1_PM_END - [15:0] */
4694
4695/*
4696 * R19967 (0x4DFF) - DSP1 PM 1535
4697 */
4698#define WM5100_DSP1_PM_END_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
4699#define WM5100_DSP1_PM_END_SHIFT 0 /* DSP1_PM_END - [15:0] */
4700#define WM5100_DSP1_PM_END_WIDTH 16 /* DSP1_PM_END - [15:0] */
4701
4702/*
4703 * R20480 (0x5000) - DSP1 ZM 0
4704 */
4705#define WM5100_DSP1_ZM_START_1_MASK 0x00FF /* DSP1_ZM_START - [7:0] */
4706#define WM5100_DSP1_ZM_START_1_SHIFT 0 /* DSP1_ZM_START - [7:0] */
4707#define WM5100_DSP1_ZM_START_1_WIDTH 8 /* DSP1_ZM_START - [7:0] */
4708
4709/*
4710 * R20481 (0x5001) - DSP1 ZM 1
4711 */
4712#define WM5100_DSP1_ZM_START_MASK 0xFFFF /* DSP1_ZM_START - [15:0] */
4713#define WM5100_DSP1_ZM_START_SHIFT 0 /* DSP1_ZM_START - [15:0] */
4714#define WM5100_DSP1_ZM_START_WIDTH 16 /* DSP1_ZM_START - [15:0] */
4715
4716/*
4717 * R20482 (0x5002) - DSP1 ZM 2
4718 */
4719#define WM5100_DSP1_ZM_1_1_MASK 0x00FF /* DSP1_ZM_1 - [7:0] */
4720#define WM5100_DSP1_ZM_1_1_SHIFT 0 /* DSP1_ZM_1 - [7:0] */
4721#define WM5100_DSP1_ZM_1_1_WIDTH 8 /* DSP1_ZM_1 - [7:0] */
4722
4723/*
4724 * R20483 (0x5003) - DSP1 ZM 3
4725 */
4726#define WM5100_DSP1_ZM_1_MASK 0xFFFF /* DSP1_ZM_1 - [15:0] */
4727#define WM5100_DSP1_ZM_1_SHIFT 0 /* DSP1_ZM_1 - [15:0] */
4728#define WM5100_DSP1_ZM_1_WIDTH 16 /* DSP1_ZM_1 - [15:0] */
4729
4730/*
4731 * R22524 (0x57FC) - DSP1 ZM 2044
4732 */
4733#define WM5100_DSP1_ZM_1022_1_MASK 0x00FF /* DSP1_ZM_1022 - [7:0] */
4734#define WM5100_DSP1_ZM_1022_1_SHIFT 0 /* DSP1_ZM_1022 - [7:0] */
4735#define WM5100_DSP1_ZM_1022_1_WIDTH 8 /* DSP1_ZM_1022 - [7:0] */
4736
4737/*
4738 * R22525 (0x57FD) - DSP1 ZM 2045
4739 */
4740#define WM5100_DSP1_ZM_1022_MASK 0xFFFF /* DSP1_ZM_1022 - [15:0] */
4741#define WM5100_DSP1_ZM_1022_SHIFT 0 /* DSP1_ZM_1022 - [15:0] */
4742#define WM5100_DSP1_ZM_1022_WIDTH 16 /* DSP1_ZM_1022 - [15:0] */
4743
4744/*
4745 * R22526 (0x57FE) - DSP1 ZM 2046
4746 */
4747#define WM5100_DSP1_ZM_END_1_MASK 0x00FF /* DSP1_ZM_END - [7:0] */
4748#define WM5100_DSP1_ZM_END_1_SHIFT 0 /* DSP1_ZM_END - [7:0] */
4749#define WM5100_DSP1_ZM_END_1_WIDTH 8 /* DSP1_ZM_END - [7:0] */
4750
4751/*
4752 * R22527 (0x57FF) - DSP1 ZM 2047
4753 */
4754#define WM5100_DSP1_ZM_END_MASK 0xFFFF /* DSP1_ZM_END - [15:0] */
4755#define WM5100_DSP1_ZM_END_SHIFT 0 /* DSP1_ZM_END - [15:0] */
4756#define WM5100_DSP1_ZM_END_WIDTH 16 /* DSP1_ZM_END - [15:0] */
4757
4758/*
4759 * R24576 (0x6000) - DSP2 DM 0
4760 */
4761#define WM5100_DSP2_DM_START_1_MASK 0x00FF /* DSP2_DM_START - [7:0] */
4762#define WM5100_DSP2_DM_START_1_SHIFT 0 /* DSP2_DM_START - [7:0] */
4763#define WM5100_DSP2_DM_START_1_WIDTH 8 /* DSP2_DM_START - [7:0] */
4764
4765/*
4766 * R24577 (0x6001) - DSP2 DM 1
4767 */
4768#define WM5100_DSP2_DM_START_MASK 0xFFFF /* DSP2_DM_START - [15:0] */
4769#define WM5100_DSP2_DM_START_SHIFT 0 /* DSP2_DM_START - [15:0] */
4770#define WM5100_DSP2_DM_START_WIDTH 16 /* DSP2_DM_START - [15:0] */
4771
4772/*
4773 * R24578 (0x6002) - DSP2 DM 2
4774 */
4775#define WM5100_DSP2_DM_1_1_MASK 0x00FF /* DSP2_DM_1 - [7:0] */
4776#define WM5100_DSP2_DM_1_1_SHIFT 0 /* DSP2_DM_1 - [7:0] */
4777#define WM5100_DSP2_DM_1_1_WIDTH 8 /* DSP2_DM_1 - [7:0] */
4778
4779/*
4780 * R24579 (0x6003) - DSP2 DM 3
4781 */
4782#define WM5100_DSP2_DM_1_MASK 0xFFFF /* DSP2_DM_1 - [15:0] */
4783#define WM5100_DSP2_DM_1_SHIFT 0 /* DSP2_DM_1 - [15:0] */
4784#define WM5100_DSP2_DM_1_WIDTH 16 /* DSP2_DM_1 - [15:0] */
4785
4786/*
4787 * R25084 (0x61FC) - DSP2 DM 508
4788 */
4789#define WM5100_DSP2_DM_254_1_MASK 0x00FF /* DSP2_DM_254 - [7:0] */
4790#define WM5100_DSP2_DM_254_1_SHIFT 0 /* DSP2_DM_254 - [7:0] */
4791#define WM5100_DSP2_DM_254_1_WIDTH 8 /* DSP2_DM_254 - [7:0] */
4792
4793/*
4794 * R25085 (0x61FD) - DSP2 DM 509
4795 */
4796#define WM5100_DSP2_DM_254_MASK 0xFFFF /* DSP2_DM_254 - [15:0] */
4797#define WM5100_DSP2_DM_254_SHIFT 0 /* DSP2_DM_254 - [15:0] */
4798#define WM5100_DSP2_DM_254_WIDTH 16 /* DSP2_DM_254 - [15:0] */
4799
4800/*
4801 * R25086 (0x61FE) - DSP2 DM 510
4802 */
4803#define WM5100_DSP2_DM_END_1_MASK 0x00FF /* DSP2_DM_END - [7:0] */
4804#define WM5100_DSP2_DM_END_1_SHIFT 0 /* DSP2_DM_END - [7:0] */
4805#define WM5100_DSP2_DM_END_1_WIDTH 8 /* DSP2_DM_END - [7:0] */
4806
4807/*
4808 * R25087 (0x61FF) - DSP2 DM 511
4809 */
4810#define WM5100_DSP2_DM_END_MASK 0xFFFF /* DSP2_DM_END - [15:0] */
4811#define WM5100_DSP2_DM_END_SHIFT 0 /* DSP2_DM_END - [15:0] */
4812#define WM5100_DSP2_DM_END_WIDTH 16 /* DSP2_DM_END - [15:0] */
4813
4814/*
4815 * R26624 (0x6800) - DSP2 PM 0
4816 */
4817#define WM5100_DSP2_PM_START_2_MASK 0x00FF /* DSP2_PM_START - [7:0] */
4818#define WM5100_DSP2_PM_START_2_SHIFT 0 /* DSP2_PM_START - [7:0] */
4819#define WM5100_DSP2_PM_START_2_WIDTH 8 /* DSP2_PM_START - [7:0] */
4820
4821/*
4822 * R26625 (0x6801) - DSP2 PM 1
4823 */
4824#define WM5100_DSP2_PM_START_1_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
4825#define WM5100_DSP2_PM_START_1_SHIFT 0 /* DSP2_PM_START - [15:0] */
4826#define WM5100_DSP2_PM_START_1_WIDTH 16 /* DSP2_PM_START - [15:0] */
4827
4828/*
4829 * R26626 (0x6802) - DSP2 PM 2
4830 */
4831#define WM5100_DSP2_PM_START_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
4832#define WM5100_DSP2_PM_START_SHIFT 0 /* DSP2_PM_START - [15:0] */
4833#define WM5100_DSP2_PM_START_WIDTH 16 /* DSP2_PM_START - [15:0] */
4834
4835/*
4836 * R26627 (0x6803) - DSP2 PM 3
4837 */
4838#define WM5100_DSP2_PM_1_2_MASK 0x00FF /* DSP2_PM_1 - [7:0] */
4839#define WM5100_DSP2_PM_1_2_SHIFT 0 /* DSP2_PM_1 - [7:0] */
4840#define WM5100_DSP2_PM_1_2_WIDTH 8 /* DSP2_PM_1 - [7:0] */
4841
4842/*
4843 * R26628 (0x6804) - DSP2 PM 4
4844 */
4845#define WM5100_DSP2_PM_1_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
4846#define WM5100_DSP2_PM_1_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
4847#define WM5100_DSP2_PM_1_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
4848
4849/*
4850 * R26629 (0x6805) - DSP2 PM 5
4851 */
4852#define WM5100_DSP2_PM_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
4853#define WM5100_DSP2_PM_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
4854#define WM5100_DSP2_PM_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
4855
4856/*
4857 * R28154 (0x6DFA) - DSP2 PM 1530
4858 */
4859#define WM5100_DSP2_PM_510_2_MASK 0x00FF /* DSP2_PM_510 - [7:0] */
4860#define WM5100_DSP2_PM_510_2_SHIFT 0 /* DSP2_PM_510 - [7:0] */
4861#define WM5100_DSP2_PM_510_2_WIDTH 8 /* DSP2_PM_510 - [7:0] */
4862
4863/*
4864 * R28155 (0x6DFB) - DSP2 PM 1531
4865 */
4866#define WM5100_DSP2_PM_510_1_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
4867#define WM5100_DSP2_PM_510_1_SHIFT 0 /* DSP2_PM_510 - [15:0] */
4868#define WM5100_DSP2_PM_510_1_WIDTH 16 /* DSP2_PM_510 - [15:0] */
4869
4870/*
4871 * R28156 (0x6DFC) - DSP2 PM 1532
4872 */
4873#define WM5100_DSP2_PM_510_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
4874#define WM5100_DSP2_PM_510_SHIFT 0 /* DSP2_PM_510 - [15:0] */
4875#define WM5100_DSP2_PM_510_WIDTH 16 /* DSP2_PM_510 - [15:0] */
4876
4877/*
4878 * R28157 (0x6DFD) - DSP2 PM 1533
4879 */
4880#define WM5100_DSP2_PM_END_2_MASK 0x00FF /* DSP2_PM_END - [7:0] */
4881#define WM5100_DSP2_PM_END_2_SHIFT 0 /* DSP2_PM_END - [7:0] */
4882#define WM5100_DSP2_PM_END_2_WIDTH 8 /* DSP2_PM_END - [7:0] */
4883
4884/*
4885 * R28158 (0x6DFE) - DSP2 PM 1534
4886 */
4887#define WM5100_DSP2_PM_END_1_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
4888#define WM5100_DSP2_PM_END_1_SHIFT 0 /* DSP2_PM_END - [15:0] */
4889#define WM5100_DSP2_PM_END_1_WIDTH 16 /* DSP2_PM_END - [15:0] */
4890
4891/*
4892 * R28159 (0x6DFF) - DSP2 PM 1535
4893 */
4894#define WM5100_DSP2_PM_END_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
4895#define WM5100_DSP2_PM_END_SHIFT 0 /* DSP2_PM_END - [15:0] */
4896#define WM5100_DSP2_PM_END_WIDTH 16 /* DSP2_PM_END - [15:0] */
4897
4898/*
4899 * R28672 (0x7000) - DSP2 ZM 0
4900 */
4901#define WM5100_DSP2_ZM_START_1_MASK 0x00FF /* DSP2_ZM_START - [7:0] */
4902#define WM5100_DSP2_ZM_START_1_SHIFT 0 /* DSP2_ZM_START - [7:0] */
4903#define WM5100_DSP2_ZM_START_1_WIDTH 8 /* DSP2_ZM_START - [7:0] */
4904
4905/*
4906 * R28673 (0x7001) - DSP2 ZM 1
4907 */
4908#define WM5100_DSP2_ZM_START_MASK 0xFFFF /* DSP2_ZM_START - [15:0] */
4909#define WM5100_DSP2_ZM_START_SHIFT 0 /* DSP2_ZM_START - [15:0] */
4910#define WM5100_DSP2_ZM_START_WIDTH 16 /* DSP2_ZM_START - [15:0] */
4911
4912/*
4913 * R28674 (0x7002) - DSP2 ZM 2
4914 */
4915#define WM5100_DSP2_ZM_1_1_MASK 0x00FF /* DSP2_ZM_1 - [7:0] */
4916#define WM5100_DSP2_ZM_1_1_SHIFT 0 /* DSP2_ZM_1 - [7:0] */
4917#define WM5100_DSP2_ZM_1_1_WIDTH 8 /* DSP2_ZM_1 - [7:0] */
4918
4919/*
4920 * R28675 (0x7003) - DSP2 ZM 3
4921 */
4922#define WM5100_DSP2_ZM_1_MASK 0xFFFF /* DSP2_ZM_1 - [15:0] */
4923#define WM5100_DSP2_ZM_1_SHIFT 0 /* DSP2_ZM_1 - [15:0] */
4924#define WM5100_DSP2_ZM_1_WIDTH 16 /* DSP2_ZM_1 - [15:0] */
4925
4926/*
4927 * R30716 (0x77FC) - DSP2 ZM 2044
4928 */
4929#define WM5100_DSP2_ZM_1022_1_MASK 0x00FF /* DSP2_ZM_1022 - [7:0] */
4930#define WM5100_DSP2_ZM_1022_1_SHIFT 0 /* DSP2_ZM_1022 - [7:0] */
4931#define WM5100_DSP2_ZM_1022_1_WIDTH 8 /* DSP2_ZM_1022 - [7:0] */
4932
4933/*
4934 * R30717 (0x77FD) - DSP2 ZM 2045
4935 */
4936#define WM5100_DSP2_ZM_1022_MASK 0xFFFF /* DSP2_ZM_1022 - [15:0] */
4937#define WM5100_DSP2_ZM_1022_SHIFT 0 /* DSP2_ZM_1022 - [15:0] */
4938#define WM5100_DSP2_ZM_1022_WIDTH 16 /* DSP2_ZM_1022 - [15:0] */
4939
4940/*
4941 * R30718 (0x77FE) - DSP2 ZM 2046
4942 */
4943#define WM5100_DSP2_ZM_END_1_MASK 0x00FF /* DSP2_ZM_END - [7:0] */
4944#define WM5100_DSP2_ZM_END_1_SHIFT 0 /* DSP2_ZM_END - [7:0] */
4945#define WM5100_DSP2_ZM_END_1_WIDTH 8 /* DSP2_ZM_END - [7:0] */
4946
4947/*
4948 * R30719 (0x77FF) - DSP2 ZM 2047
4949 */
4950#define WM5100_DSP2_ZM_END_MASK 0xFFFF /* DSP2_ZM_END - [15:0] */
4951#define WM5100_DSP2_ZM_END_SHIFT 0 /* DSP2_ZM_END - [15:0] */
4952#define WM5100_DSP2_ZM_END_WIDTH 16 /* DSP2_ZM_END - [15:0] */
4953
4954/*
4955 * R32768 (0x8000) - DSP3 DM 0
4956 */
4957#define WM5100_DSP3_DM_START_1_MASK 0x00FF /* DSP3_DM_START - [7:0] */
4958#define WM5100_DSP3_DM_START_1_SHIFT 0 /* DSP3_DM_START - [7:0] */
4959#define WM5100_DSP3_DM_START_1_WIDTH 8 /* DSP3_DM_START - [7:0] */
4960
4961/*
4962 * R32769 (0x8001) - DSP3 DM 1
4963 */
4964#define WM5100_DSP3_DM_START_MASK 0xFFFF /* DSP3_DM_START - [15:0] */
4965#define WM5100_DSP3_DM_START_SHIFT 0 /* DSP3_DM_START - [15:0] */
4966#define WM5100_DSP3_DM_START_WIDTH 16 /* DSP3_DM_START - [15:0] */
4967
4968/*
4969 * R32770 (0x8002) - DSP3 DM 2
4970 */
4971#define WM5100_DSP3_DM_1_1_MASK 0x00FF /* DSP3_DM_1 - [7:0] */
4972#define WM5100_DSP3_DM_1_1_SHIFT 0 /* DSP3_DM_1 - [7:0] */
4973#define WM5100_DSP3_DM_1_1_WIDTH 8 /* DSP3_DM_1 - [7:0] */
4974
4975/*
4976 * R32771 (0x8003) - DSP3 DM 3
4977 */
4978#define WM5100_DSP3_DM_1_MASK 0xFFFF /* DSP3_DM_1 - [15:0] */
4979#define WM5100_DSP3_DM_1_SHIFT 0 /* DSP3_DM_1 - [15:0] */
4980#define WM5100_DSP3_DM_1_WIDTH 16 /* DSP3_DM_1 - [15:0] */
4981
4982/*
4983 * R33276 (0x81FC) - DSP3 DM 508
4984 */
4985#define WM5100_DSP3_DM_254_1_MASK 0x00FF /* DSP3_DM_254 - [7:0] */
4986#define WM5100_DSP3_DM_254_1_SHIFT 0 /* DSP3_DM_254 - [7:0] */
4987#define WM5100_DSP3_DM_254_1_WIDTH 8 /* DSP3_DM_254 - [7:0] */
4988
4989/*
4990 * R33277 (0x81FD) - DSP3 DM 509
4991 */
4992#define WM5100_DSP3_DM_254_MASK 0xFFFF /* DSP3_DM_254 - [15:0] */
4993#define WM5100_DSP3_DM_254_SHIFT 0 /* DSP3_DM_254 - [15:0] */
4994#define WM5100_DSP3_DM_254_WIDTH 16 /* DSP3_DM_254 - [15:0] */
4995
4996/*
4997 * R33278 (0x81FE) - DSP3 DM 510
4998 */
4999#define WM5100_DSP3_DM_END_1_MASK 0x00FF /* DSP3_DM_END - [7:0] */
5000#define WM5100_DSP3_DM_END_1_SHIFT 0 /* DSP3_DM_END - [7:0] */
5001#define WM5100_DSP3_DM_END_1_WIDTH 8 /* DSP3_DM_END - [7:0] */
5002
5003/*
5004 * R33279 (0x81FF) - DSP3 DM 511
5005 */
5006#define WM5100_DSP3_DM_END_MASK 0xFFFF /* DSP3_DM_END - [15:0] */
5007#define WM5100_DSP3_DM_END_SHIFT 0 /* DSP3_DM_END - [15:0] */
5008#define WM5100_DSP3_DM_END_WIDTH 16 /* DSP3_DM_END - [15:0] */
5009
5010/*
5011 * R34816 (0x8800) - DSP3 PM 0
5012 */
5013#define WM5100_DSP3_PM_START_2_MASK 0x00FF /* DSP3_PM_START - [7:0] */
5014#define WM5100_DSP3_PM_START_2_SHIFT 0 /* DSP3_PM_START - [7:0] */
5015#define WM5100_DSP3_PM_START_2_WIDTH 8 /* DSP3_PM_START - [7:0] */
5016
5017/*
5018 * R34817 (0x8801) - DSP3 PM 1
5019 */
5020#define WM5100_DSP3_PM_START_1_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
5021#define WM5100_DSP3_PM_START_1_SHIFT 0 /* DSP3_PM_START - [15:0] */
5022#define WM5100_DSP3_PM_START_1_WIDTH 16 /* DSP3_PM_START - [15:0] */
5023
5024/*
5025 * R34818 (0x8802) - DSP3 PM 2
5026 */
5027#define WM5100_DSP3_PM_START_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
5028#define WM5100_DSP3_PM_START_SHIFT 0 /* DSP3_PM_START - [15:0] */
5029#define WM5100_DSP3_PM_START_WIDTH 16 /* DSP3_PM_START - [15:0] */
5030
5031/*
5032 * R34819 (0x8803) - DSP3 PM 3
5033 */
5034#define WM5100_DSP3_PM_1_2_MASK 0x00FF /* DSP3_PM_1 - [7:0] */
5035#define WM5100_DSP3_PM_1_2_SHIFT 0 /* DSP3_PM_1 - [7:0] */
5036#define WM5100_DSP3_PM_1_2_WIDTH 8 /* DSP3_PM_1 - [7:0] */
5037
5038/*
5039 * R34820 (0x8804) - DSP3 PM 4
5040 */
5041#define WM5100_DSP3_PM_1_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
5042#define WM5100_DSP3_PM_1_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
5043#define WM5100_DSP3_PM_1_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
5044
5045/*
5046 * R34821 (0x8805) - DSP3 PM 5
5047 */
5048#define WM5100_DSP3_PM_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
5049#define WM5100_DSP3_PM_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
5050#define WM5100_DSP3_PM_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
5051
5052/*
5053 * R36346 (0x8DFA) - DSP3 PM 1530
5054 */
5055#define WM5100_DSP3_PM_510_2_MASK 0x00FF /* DSP3_PM_510 - [7:0] */
5056#define WM5100_DSP3_PM_510_2_SHIFT 0 /* DSP3_PM_510 - [7:0] */
5057#define WM5100_DSP3_PM_510_2_WIDTH 8 /* DSP3_PM_510 - [7:0] */
5058
5059/*
5060 * R36347 (0x8DFB) - DSP3 PM 1531
5061 */
5062#define WM5100_DSP3_PM_510_1_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
5063#define WM5100_DSP3_PM_510_1_SHIFT 0 /* DSP3_PM_510 - [15:0] */
5064#define WM5100_DSP3_PM_510_1_WIDTH 16 /* DSP3_PM_510 - [15:0] */
5065
5066/*
5067 * R36348 (0x8DFC) - DSP3 PM 1532
5068 */
5069#define WM5100_DSP3_PM_510_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
5070#define WM5100_DSP3_PM_510_SHIFT 0 /* DSP3_PM_510 - [15:0] */
5071#define WM5100_DSP3_PM_510_WIDTH 16 /* DSP3_PM_510 - [15:0] */
5072
5073/*
5074 * R36349 (0x8DFD) - DSP3 PM 1533
5075 */
5076#define WM5100_DSP3_PM_END_2_MASK 0x00FF /* DSP3_PM_END - [7:0] */
5077#define WM5100_DSP3_PM_END_2_SHIFT 0 /* DSP3_PM_END - [7:0] */
5078#define WM5100_DSP3_PM_END_2_WIDTH 8 /* DSP3_PM_END - [7:0] */
5079
5080/*
5081 * R36350 (0x8DFE) - DSP3 PM 1534
5082 */
5083#define WM5100_DSP3_PM_END_1_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
5084#define WM5100_DSP3_PM_END_1_SHIFT 0 /* DSP3_PM_END - [15:0] */
5085#define WM5100_DSP3_PM_END_1_WIDTH 16 /* DSP3_PM_END - [15:0] */
5086
5087/*
5088 * R36351 (0x8DFF) - DSP3 PM 1535
5089 */
5090#define WM5100_DSP3_PM_END_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
5091#define WM5100_DSP3_PM_END_SHIFT 0 /* DSP3_PM_END - [15:0] */
5092#define WM5100_DSP3_PM_END_WIDTH 16 /* DSP3_PM_END - [15:0] */
5093
5094/*
5095 * R36864 (0x9000) - DSP3 ZM 0
5096 */
5097#define WM5100_DSP3_ZM_START_1_MASK 0x00FF /* DSP3_ZM_START - [7:0] */
5098#define WM5100_DSP3_ZM_START_1_SHIFT 0 /* DSP3_ZM_START - [7:0] */
5099#define WM5100_DSP3_ZM_START_1_WIDTH 8 /* DSP3_ZM_START - [7:0] */
5100
5101/*
5102 * R36865 (0x9001) - DSP3 ZM 1
5103 */
5104#define WM5100_DSP3_ZM_START_MASK 0xFFFF /* DSP3_ZM_START - [15:0] */
5105#define WM5100_DSP3_ZM_START_SHIFT 0 /* DSP3_ZM_START - [15:0] */
5106#define WM5100_DSP3_ZM_START_WIDTH 16 /* DSP3_ZM_START - [15:0] */
5107
5108/*
5109 * R36866 (0x9002) - DSP3 ZM 2
5110 */
5111#define WM5100_DSP3_ZM_1_1_MASK 0x00FF /* DSP3_ZM_1 - [7:0] */
5112#define WM5100_DSP3_ZM_1_1_SHIFT 0 /* DSP3_ZM_1 - [7:0] */
5113#define WM5100_DSP3_ZM_1_1_WIDTH 8 /* DSP3_ZM_1 - [7:0] */
5114
5115/*
5116 * R36867 (0x9003) - DSP3 ZM 3
5117 */
5118#define WM5100_DSP3_ZM_1_MASK 0xFFFF /* DSP3_ZM_1 - [15:0] */
5119#define WM5100_DSP3_ZM_1_SHIFT 0 /* DSP3_ZM_1 - [15:0] */
5120#define WM5100_DSP3_ZM_1_WIDTH 16 /* DSP3_ZM_1 - [15:0] */
5121
5122/*
5123 * R38908 (0x97FC) - DSP3 ZM 2044
5124 */
5125#define WM5100_DSP3_ZM_1022_1_MASK 0x00FF /* DSP3_ZM_1022 - [7:0] */
5126#define WM5100_DSP3_ZM_1022_1_SHIFT 0 /* DSP3_ZM_1022 - [7:0] */
5127#define WM5100_DSP3_ZM_1022_1_WIDTH 8 /* DSP3_ZM_1022 - [7:0] */
5128
5129/*
5130 * R38909 (0x97FD) - DSP3 ZM 2045
5131 */
5132#define WM5100_DSP3_ZM_1022_MASK 0xFFFF /* DSP3_ZM_1022 - [15:0] */
5133#define WM5100_DSP3_ZM_1022_SHIFT 0 /* DSP3_ZM_1022 - [15:0] */
5134#define WM5100_DSP3_ZM_1022_WIDTH 16 /* DSP3_ZM_1022 - [15:0] */
5135
5136/*
5137 * R38910 (0x97FE) - DSP3 ZM 2046
5138 */
5139#define WM5100_DSP3_ZM_END_1_MASK 0x00FF /* DSP3_ZM_END - [7:0] */
5140#define WM5100_DSP3_ZM_END_1_SHIFT 0 /* DSP3_ZM_END - [7:0] */
5141#define WM5100_DSP3_ZM_END_1_WIDTH 8 /* DSP3_ZM_END - [7:0] */
5142
5143/*
5144 * R38911 (0x97FF) - DSP3 ZM 2047
5145 */
5146#define WM5100_DSP3_ZM_END_MASK 0xFFFF /* DSP3_ZM_END - [15:0] */
5147#define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */
5148#define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */
5149
5150int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg);
5151int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg);
5152
5153extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1];
5154
5155#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 6d6dc9efe914..35f3ad83dfb6 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -355,7 +355,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
355 return 1; 355 return 1;
356 } 356 }
357 357
358 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 358 ret = snd_soc_put_volsw(kcontrol, ucontrol);
359 if (ret < 0) 359 if (ret < 0)
360 return ret; 360 return ret;
361 361
@@ -392,23 +392,9 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
392 break; 392 break;
393 } 393 }
394 394
395 return snd_soc_get_volsw_2r(kcontrol, ucontrol); 395 return snd_soc_get_volsw(kcontrol, ucontrol);
396} 396}
397 397
398/* double control with volume update */
399#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
400 xinvert, tlv_array) \
401{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
402 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
403 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
404 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
405 .tlv.p = (tlv_array), \
406 .info = snd_soc_info_volsw_2r, \
407 .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
408 .private_value = (unsigned long)&(struct soc_mixer_control) \
409 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
410 .rshift = xshift, .max = xmax, .invert = xinvert}, }
411
412static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 398static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
413static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; 399static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
414static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; 400static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
@@ -443,26 +429,29 @@ static const unsigned int capture_sd_tlv[] = {
443static const struct snd_kcontrol_new wm8350_snd_controls[] = { 429static const struct snd_kcontrol_new wm8350_snd_controls[] = {
444 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]), 430 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
445 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]), 431 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
446 SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume", 432 SOC_DOUBLE_R_EXT_TLV("Playback PCM Volume",
447 WM8350_DAC_DIGITAL_VOLUME_L, 433 WM8350_DAC_DIGITAL_VOLUME_L,
448 WM8350_DAC_DIGITAL_VOLUME_R, 434 WM8350_DAC_DIGITAL_VOLUME_R,
449 0, 255, 0, dac_pcm_tlv), 435 0, 255, 0, wm8350_get_volsw_2r,
436 wm8350_put_volsw_2r_vu, dac_pcm_tlv),
450 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), 437 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
451 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), 438 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
452 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]), 439 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
453 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]), 440 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
454 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]), 441 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
455 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume", 442 SOC_DOUBLE_R_EXT_TLV("Capture PCM Volume",
456 WM8350_ADC_DIGITAL_VOLUME_L, 443 WM8350_ADC_DIGITAL_VOLUME_L,
457 WM8350_ADC_DIGITAL_VOLUME_R, 444 WM8350_ADC_DIGITAL_VOLUME_R,
458 0, 255, 0, adc_pcm_tlv), 445 0, 255, 0, wm8350_get_volsw_2r,
446 wm8350_put_volsw_2r_vu, adc_pcm_tlv),
459 SOC_DOUBLE_TLV("Capture Sidetone Volume", 447 SOC_DOUBLE_TLV("Capture Sidetone Volume",
460 WM8350_ADC_DIVIDER, 448 WM8350_ADC_DIVIDER,
461 8, 4, 15, 1, capture_sd_tlv), 449 8, 4, 15, 1, capture_sd_tlv),
462 SOC_WM8350_DOUBLE_R_TLV("Capture Volume", 450 SOC_DOUBLE_R_EXT_TLV("Capture Volume",
463 WM8350_LEFT_INPUT_VOLUME, 451 WM8350_LEFT_INPUT_VOLUME,
464 WM8350_RIGHT_INPUT_VOLUME, 452 WM8350_RIGHT_INPUT_VOLUME,
465 2, 63, 0, pre_amp_tlv), 453 2, 63, 0, wm8350_get_volsw_2r,
454 wm8350_put_volsw_2r_vu, pre_amp_tlv),
466 SOC_DOUBLE_R("Capture ZC Switch", 455 SOC_DOUBLE_R("Capture ZC Switch",
467 WM8350_LEFT_INPUT_VOLUME, 456 WM8350_LEFT_INPUT_VOLUME,
468 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0), 457 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
@@ -490,17 +479,19 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = {
490 SOC_SINGLE_TLV("Out4 Capture Volume", 479 SOC_SINGLE_TLV("Out4 Capture Volume",
491 WM8350_INPUT_MIXER_VOLUME, 480 WM8350_INPUT_MIXER_VOLUME,
492 1, 7, 0, out_mix_tlv), 481 1, 7, 0, out_mix_tlv),
493 SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume", 482 SOC_DOUBLE_R_EXT_TLV("Out1 Playback Volume",
494 WM8350_LOUT1_VOLUME, 483 WM8350_LOUT1_VOLUME,
495 WM8350_ROUT1_VOLUME, 484 WM8350_ROUT1_VOLUME,
496 2, 63, 0, out_pga_tlv), 485 2, 63, 0, wm8350_get_volsw_2r,
486 wm8350_put_volsw_2r_vu, out_pga_tlv),
497 SOC_DOUBLE_R("Out1 Playback ZC Switch", 487 SOC_DOUBLE_R("Out1 Playback ZC Switch",
498 WM8350_LOUT1_VOLUME, 488 WM8350_LOUT1_VOLUME,
499 WM8350_ROUT1_VOLUME, 13, 1, 0), 489 WM8350_ROUT1_VOLUME, 13, 1, 0),
500 SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume", 490 SOC_DOUBLE_R_EXT_TLV("Out2 Playback Volume",
501 WM8350_LOUT2_VOLUME, 491 WM8350_LOUT2_VOLUME,
502 WM8350_ROUT2_VOLUME, 492 WM8350_ROUT2_VOLUME,
503 2, 63, 0, out_pga_tlv), 493 2, 63, 0, wm8350_get_volsw_2r,
494 wm8350_put_volsw_2r_vu, out_pga_tlv),
504 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME, 495 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
505 WM8350_ROUT2_VOLUME, 13, 1, 0), 496 WM8350_ROUT2_VOLUME, 13, 1, 0),
506 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0), 497 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index fbee556cbf35..dc13be2a09c5 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -383,7 +383,7 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
383 (1 << WM8400_AINRMUX_PWR))) { 383 (1 << WM8400_AINRMUX_PWR))) {
384 reg |= WM8400_AINR_ENA; 384 reg |= WM8400_AINR_ENA;
385 } else { 385 } else {
386 reg &= ~WM8400_AINL_ENA; 386 reg &= ~WM8400_AINR_ENA;
387 } 387 }
388 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); 388 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
389 389
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index db0dced74843..07c9cc759e97 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -479,6 +480,8 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; 480 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
480 481
481 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 482 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
483 snd_soc_cache_sync(codec);
484
482 /* Initial cap charge at VMID 5k */ 485 /* Initial cap charge at VMID 5k */
483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); 486 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
484 mdelay(100); 487 mdelay(100);
@@ -540,18 +543,7 @@ static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
540 543
541static int wm8510_resume(struct snd_soc_codec *codec) 544static int wm8510_resume(struct snd_soc_codec *codec)
542{ 545{
543 int i;
544 u8 data[2];
545 u16 *cache = codec->reg_cache;
546
547 /* Sync reg_cache with the hardware */
548 for (i = 0; i < ARRAY_SIZE(wm8510_reg); i++) {
549 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
550 data[1] = cache[i] & 0x00ff;
551 codec->hw_write(codec->control_data, data, 2);
552 }
553 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 546 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
554
555 return 0; 547 return 0;
556} 548}
557 549
@@ -598,6 +590,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
598 .reg_cache_default =wm8510_reg, 590 .reg_cache_default =wm8510_reg,
599}; 591};
600 592
593static const struct of_device_id wm8510_of_match[] = {
594 { .compatible = "wlf,wm8510" },
595 { },
596};
597
601#if defined(CONFIG_SPI_MASTER) 598#if defined(CONFIG_SPI_MASTER)
602static int __devinit wm8510_spi_probe(struct spi_device *spi) 599static int __devinit wm8510_spi_probe(struct spi_device *spi)
603{ 600{
@@ -628,6 +625,7 @@ static struct spi_driver wm8510_spi_driver = {
628 .driver = { 625 .driver = {
629 .name = "wm8510", 626 .name = "wm8510",
630 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
628 .of_match_table = wm8510_of_match,
631 }, 629 },
632 .probe = wm8510_spi_probe, 630 .probe = wm8510_spi_probe,
633 .remove = __devexit_p(wm8510_spi_remove), 631 .remove = __devexit_p(wm8510_spi_remove),
@@ -671,6 +669,7 @@ static struct i2c_driver wm8510_i2c_driver = {
671 .driver = { 669 .driver = {
672 .name = "wm8510-codec", 670 .name = "wm8510-codec",
673 .owner = THIS_MODULE, 671 .owner = THIS_MODULE,
672 .of_match_table = wm8510_of_match,
674 }, 673 },
675 .probe = wm8510_i2c_probe, 674 .probe = wm8510_i2c_probe,
676 .remove = __devexit_p(wm8510_i2c_remove), 675 .remove = __devexit_p(wm8510_i2c_remove),
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 4fd4d8dca0fc..db7a6819499f 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -84,7 +85,7 @@ static const char *wm8523_zd_count_text[] = {
84static const struct soc_enum wm8523_zc_count = 85static const struct soc_enum wm8523_zc_count =
85 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); 86 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
86 87
87static const struct snd_kcontrol_new wm8523_snd_controls[] = { 88static const struct snd_kcontrol_new wm8523_controls[] = {
88SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, 89SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
89 0, 448, 0, dac_tlv), 90 0, 448, 0, dac_tlv),
90SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), 91SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
@@ -101,22 +102,11 @@ SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
101SND_SOC_DAPM_OUTPUT("LINEVOUTR"), 102SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
102}; 103};
103 104
104static const struct snd_soc_dapm_route intercon[] = { 105static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
105 { "LINEVOUTL", NULL, "DAC" }, 106 { "LINEVOUTL", NULL, "DAC" },
106 { "LINEVOUTR", NULL, "DAC" }, 107 { "LINEVOUTR", NULL, "DAC" },
107}; 108};
108 109
109static int wm8523_add_widgets(struct snd_soc_codec *codec)
110{
111 struct snd_soc_dapm_context *dapm = &codec->dapm;
112
113 snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
114 ARRAY_SIZE(wm8523_dapm_widgets));
115 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
116
117 return 0;
118}
119
120static struct { 110static struct {
121 int value; 111 int value;
122 int ratio; 112 int ratio;
@@ -416,7 +406,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 406 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
417 int ret, i; 407 int ret, i;
418 408
419 codec->hw_write = (hw_write_t)i2c_master_send;
420 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; 409 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
421 wm8523->rate_constraint.count = 410 wm8523->rate_constraint.count =
422 ARRAY_SIZE(wm8523->rate_constraint_list); 411 ARRAY_SIZE(wm8523->rate_constraint_list);
@@ -479,10 +468,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
479 /* Bias level configuration will have done an extra enable */ 468 /* Bias level configuration will have done an extra enable */
480 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 469 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
481 470
482 snd_soc_add_controls(codec, wm8523_snd_controls,
483 ARRAY_SIZE(wm8523_snd_controls));
484 wm8523_add_widgets(codec);
485
486 return 0; 471 return 0;
487 472
488err_enable: 473err_enable:
@@ -512,6 +497,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
512 .reg_word_size = sizeof(u16), 497 .reg_word_size = sizeof(u16),
513 .reg_cache_default = wm8523_reg, 498 .reg_cache_default = wm8523_reg,
514 .volatile_register = wm8523_volatile_register, 499 .volatile_register = wm8523_volatile_register,
500
501 .controls = wm8523_controls,
502 .num_controls = ARRAY_SIZE(wm8523_controls),
503 .dapm_widgets = wm8523_dapm_widgets,
504 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
505 .dapm_routes = wm8523_dapm_routes,
506 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
507};
508
509static const struct of_device_id wm8523_of_match[] = {
510 { .compatible = "wlf,wm8523" },
511 { },
515}; 512};
516 513
517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 514#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -551,8 +548,9 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
551 548
552static struct i2c_driver wm8523_i2c_driver = { 549static struct i2c_driver wm8523_i2c_driver = {
553 .driver = { 550 .driver = {
554 .name = "wm8523-codec", 551 .name = "wm8523",
555 .owner = THIS_MODULE, 552 .owner = THIS_MODULE,
553 .of_match_table = wm8523_of_match,
556 }, 554 },
557 .probe = wm8523_i2c_probe, 555 .probe = wm8523_i2c_probe,
558 .remove = __devexit_p(wm8523_i2c_remove), 556 .remove = __devexit_p(wm8523_i2c_remove),
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 4bbc0a79f01e..8212b3c8bfdd 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/of_device.h>
29 30
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -212,7 +213,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
212 reg_cache[reg] = 0; 213 reg_cache[reg] = 0;
213 reg_cache[reg2] = 0; 214 reg_cache[reg2] = 0;
214 215
215 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 216 ret = snd_soc_put_volsw(kcontrol, ucontrol);
216 if (ret < 0) 217 if (ret < 0)
217 return ret; 218 return ret;
218 219
@@ -223,31 +224,19 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
223 return 0; 224 return 0;
224} 225}
225 226
226#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
227 xinvert, tlv_array) \
228{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
229 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
230 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
231 .tlv.p = (tlv_array), \
232 .info = snd_soc_info_volsw_2r, \
233 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
234 .private_value = (unsigned long)&(struct soc_mixer_control) \
235 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
236 .max = xmax, .invert = xinvert} }
237
238static const struct snd_kcontrol_new wm8580_snd_controls[] = { 227static const struct snd_kcontrol_new wm8580_snd_controls[] = {
239SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume", 228SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume",
240 WM8580_DIGITAL_ATTENUATION_DACL1, 229 WM8580_DIGITAL_ATTENUATION_DACL1,
241 WM8580_DIGITAL_ATTENUATION_DACR1, 230 WM8580_DIGITAL_ATTENUATION_DACR1,
242 0, 0xff, 0, dac_tlv), 231 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
243SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume", 232SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume",
244 WM8580_DIGITAL_ATTENUATION_DACL2, 233 WM8580_DIGITAL_ATTENUATION_DACL2,
245 WM8580_DIGITAL_ATTENUATION_DACR2, 234 WM8580_DIGITAL_ATTENUATION_DACR2,
246 0, 0xff, 0, dac_tlv), 235 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
247SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume", 236SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume",
248 WM8580_DIGITAL_ATTENUATION_DACL3, 237 WM8580_DIGITAL_ATTENUATION_DACL3,
249 WM8580_DIGITAL_ATTENUATION_DACR3, 238 WM8580_DIGITAL_ATTENUATION_DACR3,
250 0, 0xff, 0, dac_tlv), 239 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
251 240
252SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0), 241SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
253SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0), 242SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
@@ -441,8 +430,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
441 /* Always disable the PLL - it is not safe to leave it running 430 /* Always disable the PLL - it is not safe to leave it running
442 * while reprogramming it. 431 * while reprogramming it.
443 */ 432 */
444 reg = snd_soc_read(codec, WM8580_PWRDN2); 433 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
445 snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
446 434
447 if (!freq_in || !freq_out) 435 if (!freq_in || !freq_out)
448 return 0; 436 return 0;
@@ -460,8 +448,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
460 snd_soc_write(codec, WM8580_PLLA4 + offset, reg); 448 snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
461 449
462 /* All done, turn it on */ 450 /* All done, turn it on */
463 reg = snd_soc_read(codec, WM8580_PWRDN2); 451 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
464 snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
465 452
466 return 0; 453 return 0;
467} 454}
@@ -759,7 +746,6 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
759static int wm8580_set_bias_level(struct snd_soc_codec *codec, 746static int wm8580_set_bias_level(struct snd_soc_codec *codec,
760 enum snd_soc_bias_level level) 747 enum snd_soc_bias_level level)
761{ 748{
762 u16 reg;
763 switch (level) { 749 switch (level) {
764 case SND_SOC_BIAS_ON: 750 case SND_SOC_BIAS_ON:
765 case SND_SOC_BIAS_PREPARE: 751 case SND_SOC_BIAS_PREPARE:
@@ -768,20 +754,19 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
768 case SND_SOC_BIAS_STANDBY: 754 case SND_SOC_BIAS_STANDBY:
769 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 755 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
770 /* Power up and get individual control of the DACs */ 756 /* Power up and get individual control of the DACs */
771 reg = snd_soc_read(codec, WM8580_PWRDN1); 757 snd_soc_update_bits(codec, WM8580_PWRDN1,
772 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 758 WM8580_PWRDN1_PWDN |
773 snd_soc_write(codec, WM8580_PWRDN1, reg); 759 WM8580_PWRDN1_ALLDACPD, 0);
774 760
775 /* Make VMID high impedance */ 761 /* Make VMID high impedance */
776 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); 762 snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
777 reg &= ~0x100; 763 0x100, 0);
778 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
779 } 764 }
780 break; 765 break;
781 766
782 case SND_SOC_BIAS_OFF: 767 case SND_SOC_BIAS_OFF:
783 reg = snd_soc_read(codec, WM8580_PWRDN1); 768 snd_soc_update_bits(codec, WM8580_PWRDN1,
784 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 769 WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
785 break; 770 break;
786 } 771 }
787 codec->dapm.bias_level = level; 772 codec->dapm.bias_level = level;
@@ -907,6 +892,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
907 .reg_cache_default = wm8580_reg, 892 .reg_cache_default = wm8580_reg,
908}; 893};
909 894
895static const struct of_device_id wm8580_of_match[] = {
896 { .compatible = "wlf,wm8580" },
897 { },
898};
899
910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 900#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
911static int wm8580_i2c_probe(struct i2c_client *i2c, 901static int wm8580_i2c_probe(struct i2c_client *i2c,
912 const struct i2c_device_id *id) 902 const struct i2c_device_id *id)
@@ -943,8 +933,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
943 933
944static struct i2c_driver wm8580_i2c_driver = { 934static struct i2c_driver wm8580_i2c_driver = {
945 .driver = { 935 .driver = {
946 .name = "wm8580-codec", 936 .name = "wm8580",
947 .owner = THIS_MODULE, 937 .owner = THIS_MODULE,
938 .of_match_table = wm8580_of_match,
948 }, 939 },
949 .probe = wm8580_i2c_probe, 940 .probe = wm8580_i2c_probe,
950 .remove = wm8580_i2c_remove, 941 .remove = wm8580_i2c_remove,
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index a537e4af6ae7..8d0347cf0e9a 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics 4 * Copyright 2006 Wolfson Microelectronics
5 * 5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com> 6 * Author: Mike Arthur <Mike.Arthur@wolfsonmicro.com>
7 * 7 *
8 * Based on wm8731.c by Richard Purdie 8 * Based on wm8731.c by Richard Purdie
9 * 9 *
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -286,7 +287,6 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
286 return 0; 287 return 0;
287} 288}
288 289
289
290static int wm8711_set_bias_level(struct snd_soc_codec *codec, 290static int wm8711_set_bias_level(struct snd_soc_codec *codec,
291 enum snd_soc_bias_level level) 291 enum snd_soc_bias_level level)
292{ 292{
@@ -299,6 +299,9 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
299 case SND_SOC_BIAS_PREPARE: 299 case SND_SOC_BIAS_PREPARE:
300 break; 300 break;
301 case SND_SOC_BIAS_STANDBY: 301 case SND_SOC_BIAS_STANDBY:
302 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
303 snd_soc_cache_sync(codec);
304
302 snd_soc_write(codec, WM8711_PWR, reg | 0x0040); 305 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
303 break; 306 break;
304 case SND_SOC_BIAS_OFF: 307 case SND_SOC_BIAS_OFF:
@@ -345,25 +348,14 @@ static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
345 348
346static int wm8711_resume(struct snd_soc_codec *codec) 349static int wm8711_resume(struct snd_soc_codec *codec)
347{ 350{
348 int i;
349 u8 data[2];
350 u16 *cache = codec->reg_cache;
351
352 /* Sync reg_cache with the hardware */
353 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
354 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
355 data[1] = cache[i] & 0x00ff;
356 codec->hw_write(codec->control_data, data, 2);
357 }
358 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 351 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
359
360 return 0; 352 return 0;
361} 353}
362 354
363static int wm8711_probe(struct snd_soc_codec *codec) 355static int wm8711_probe(struct snd_soc_codec *codec)
364{ 356{
365 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 357 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
366 int ret, reg; 358 int ret;
367 359
368 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type); 360 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
369 if (ret < 0) { 361 if (ret < 0) {
@@ -380,10 +372,8 @@ static int wm8711_probe(struct snd_soc_codec *codec)
380 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 372 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
381 373
382 /* Latch the update bits */ 374 /* Latch the update bits */
383 reg = snd_soc_read(codec, WM8711_LOUT1V); 375 snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
384 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100); 376 snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
385 reg = snd_soc_read(codec, WM8711_ROUT1V);
386 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
387 377
388 snd_soc_add_controls(codec, wm8711_snd_controls, 378 snd_soc_add_controls(codec, wm8711_snd_controls,
389 ARRAY_SIZE(wm8711_snd_controls)); 379 ARRAY_SIZE(wm8711_snd_controls));
@@ -414,6 +404,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), 404 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
415}; 405};
416 406
407static const struct of_device_id wm8711_of_match[] = {
408 { .compatible = "wlf,wm8711", },
409 { }
410};
411MODULE_DEVICE_TABLE(of, wm8711_of_match);
412
417#if defined(CONFIG_SPI_MASTER) 413#if defined(CONFIG_SPI_MASTER)
418static int __devinit wm8711_spi_probe(struct spi_device *spi) 414static int __devinit wm8711_spi_probe(struct spi_device *spi)
419{ 415{
@@ -443,8 +439,9 @@ static int __devexit wm8711_spi_remove(struct spi_device *spi)
443 439
444static struct spi_driver wm8711_spi_driver = { 440static struct spi_driver wm8711_spi_driver = {
445 .driver = { 441 .driver = {
446 .name = "wm8711-codec", 442 .name = "wm8711",
447 .owner = THIS_MODULE, 443 .owner = THIS_MODULE,
444 .of_match_table = wm8711_of_match,
448 }, 445 },
449 .probe = wm8711_spi_probe, 446 .probe = wm8711_spi_probe,
450 .remove = __devexit_p(wm8711_spi_remove), 447 .remove = __devexit_p(wm8711_spi_remove),
@@ -487,8 +484,9 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
487 484
488static struct i2c_driver wm8711_i2c_driver = { 485static struct i2c_driver wm8711_i2c_driver = {
489 .driver = { 486 .driver = {
490 .name = "wm8711-codec", 487 .name = "wm8711",
491 .owner = THIS_MODULE, 488 .owner = THIS_MODULE,
489 .of_match_table = wm8711_of_match,
492 }, 490 },
493 .probe = wm8711_i2c_probe, 491 .probe = wm8711_i2c_probe,
494 .remove = __devexit_p(wm8711_i2c_remove), 492 .remove = __devexit_p(wm8711_i2c_remove),
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 86d4718d3a76..04b027efd5c0 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of_device.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -269,6 +270,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), 270 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
270}; 271};
271 272
273static const struct of_device_id wm8728_of_match[] = {
274 { .compatible = "wlf,wm8728", },
275 { }
276};
277MODULE_DEVICE_TABLE(of, wm8728_of_match);
278
272#if defined(CONFIG_SPI_MASTER) 279#if defined(CONFIG_SPI_MASTER)
273static int __devinit wm8728_spi_probe(struct spi_device *spi) 280static int __devinit wm8728_spi_probe(struct spi_device *spi)
274{ 281{
@@ -298,8 +305,9 @@ static int __devexit wm8728_spi_remove(struct spi_device *spi)
298 305
299static struct spi_driver wm8728_spi_driver = { 306static struct spi_driver wm8728_spi_driver = {
300 .driver = { 307 .driver = {
301 .name = "wm8728-codec", 308 .name = "wm8728",
302 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
310 .of_match_table = wm8728_of_match,
303 }, 311 },
304 .probe = wm8728_spi_probe, 312 .probe = wm8728_spi_probe,
305 .remove = __devexit_p(wm8728_spi_remove), 313 .remove = __devexit_p(wm8728_spi_remove),
@@ -342,8 +350,9 @@ MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
342 350
343static struct i2c_driver wm8728_i2c_driver = { 351static struct i2c_driver wm8728_i2c_driver = {
344 .driver = { 352 .driver = {
345 .name = "wm8728-codec", 353 .name = "wm8728",
346 .owner = THIS_MODULE, 354 .owner = THIS_MODULE,
355 .of_match_table = wm8728_of_match,
347 }, 356 },
348 .probe = wm8728_i2c_probe, 357 .probe = wm8728_i2c_probe,
349 .remove = __devexit_p(wm8728_i2c_remove), 358 .remove = __devexit_p(wm8728_i2c_remove),
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 76b4361e9b80..7e5ec03f6f8d 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25#include <linux/of_device.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -426,9 +427,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
426 enum snd_soc_bias_level level) 427 enum snd_soc_bias_level level)
427{ 428{
428 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 429 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
429 int i, ret; 430 int ret;
430 u8 data[2];
431 u16 *cache = codec->reg_cache;
432 u16 reg; 431 u16 reg;
433 432
434 switch (level) { 433 switch (level) {
@@ -443,16 +442,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
443 if (ret != 0) 442 if (ret != 0)
444 return ret; 443 return ret;
445 444
446 /* Sync reg_cache with the hardware */ 445 snd_soc_cache_sync(codec);
447 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
448 if (cache[i] == wm8731_reg[i])
449 continue;
450
451 data[0] = (i << 1) | ((cache[i] >> 8)
452 & 0x0001);
453 data[1] = cache[i] & 0x00ff;
454 codec->hw_write(codec->control_data, data, 2);
455 }
456 } 446 }
457 447
458 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 448 /* Clear PWROFF, gate CLKOUT, everything else as-is */
@@ -607,6 +597,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
607 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 597 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
608}; 598};
609 599
600static const struct of_device_id wm8731_of_match[] = {
601 { .compatible = "wlf,wm8731", },
602 { }
603};
604
605MODULE_DEVICE_TABLE(of, wm8731_of_match);
606
610#if defined(CONFIG_SPI_MASTER) 607#if defined(CONFIG_SPI_MASTER)
611static int __devinit wm8731_spi_probe(struct spi_device *spi) 608static int __devinit wm8731_spi_probe(struct spi_device *spi)
612{ 609{
@@ -638,6 +635,7 @@ static struct spi_driver wm8731_spi_driver = {
638 .driver = { 635 .driver = {
639 .name = "wm8731", 636 .name = "wm8731",
640 .owner = THIS_MODULE, 637 .owner = THIS_MODULE,
638 .of_match_table = wm8731_of_match,
641 }, 639 },
642 .probe = wm8731_spi_probe, 640 .probe = wm8731_spi_probe,
643 .remove = __devexit_p(wm8731_spi_remove), 641 .remove = __devexit_p(wm8731_spi_remove),
@@ -682,6 +680,7 @@ static struct i2c_driver wm8731_i2c_driver = {
682 .driver = { 680 .driver = {
683 .name = "wm8731", 681 .name = "wm8731",
684 .owner = THIS_MODULE, 682 .owner = THIS_MODULE,
683 .of_match_table = wm8731_of_match,
685 }, 684 },
686 .probe = wm8731_i2c_probe, 685 .probe = wm8731_i2c_probe,
687 .remove = __devexit_p(wm8731_i2c_remove), 686 .remove = __devexit_p(wm8731_i2c_remove),
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 30c67d06a904..f6aef58845c2 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -634,6 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
634 .reg_cache_default = wm8737_reg, 635 .reg_cache_default = wm8737_reg,
635}; 636};
636 637
638static const struct of_device_id wm8737_of_match[] = {
639 { .compatible = "wlf,wm8737", },
640 { }
641};
642
643MODULE_DEVICE_TABLE(of, wm8737_of_match);
644
637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 645#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, 646static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id) 647 const struct i2c_device_id *id)
@@ -673,6 +681,7 @@ static struct i2c_driver wm8737_i2c_driver = {
673 .driver = { 681 .driver = {
674 .name = "wm8737", 682 .name = "wm8737",
675 .owner = THIS_MODULE, 683 .owner = THIS_MODULE,
684 .of_match_table = wm8737_of_match,
676 }, 685 },
677 .probe = wm8737_i2c_probe, 686 .probe = wm8737_i2c_probe,
678 .remove = __devexit_p(wm8737_i2c_remove), 687 .remove = __devexit_p(wm8737_i2c_remove),
@@ -711,6 +720,7 @@ static struct spi_driver wm8737_spi_driver = {
711 .driver = { 720 .driver = {
712 .name = "wm8737", 721 .name = "wm8737",
713 .owner = THIS_MODULE, 722 .owner = THIS_MODULE,
723 .of_match_table = wm8737_of_match,
714 }, 724 },
715 .probe = wm8737_spi_probe, 725 .probe = wm8737_spi_probe,
716 .remove = __devexit_p(wm8737_spi_remove), 726 .remove = __devexit_p(wm8737_spi_remove),
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 25af901fe813..57ad22aacc51 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -17,9 +17,11 @@
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/spi/spi.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
23#include <sound/core.h> 25#include <sound/core.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
25#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -337,10 +339,10 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
337 iface |= 0x0004; 339 iface |= 0x0004;
338 break; 340 break;
339 case SND_SOC_DAIFMT_DSP_A: 341 case SND_SOC_DAIFMT_DSP_A:
340 iface |= 0x0003; 342 iface |= 0x000C;
341 break; 343 break;
342 case SND_SOC_DAIFMT_DSP_B: 344 case SND_SOC_DAIFMT_DSP_B:
343 iface |= 0x0013; 345 iface |= 0x001C;
344 break; 346 break;
345 default: 347 default:
346 return -EINVAL; 348 return -EINVAL;
@@ -402,15 +404,7 @@ static struct snd_soc_dai_driver wm8741_dai = {
402#ifdef CONFIG_PM 404#ifdef CONFIG_PM
403static int wm8741_resume(struct snd_soc_codec *codec) 405static int wm8741_resume(struct snd_soc_codec *codec)
404{ 406{
405 u16 *cache = codec->reg_cache; 407 snd_soc_cache_sync(codec);
406 int i;
407
408 /* RESTORE REG Cache */
409 for (i = 0; i < WM8741_REGISTER_COUNT; i++) {
410 if (cache[i] == wm8741_reg_defaults[i] || WM8741_RESET == i)
411 continue;
412 snd_soc_write(codec, i, cache[i]);
413 }
414 return 0; 408 return 0;
415} 409}
416#else 410#else
@@ -422,17 +416,35 @@ static int wm8741_probe(struct snd_soc_codec *codec)
422{ 416{
423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 417 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
424 int ret = 0; 418 int ret = 0;
419 int i;
420
421 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
422 wm8741->supplies[i].supply = wm8741_supply_names[i];
423
424 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
425 wm8741->supplies);
426 if (ret != 0) {
427 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
428 goto err;
429 }
430
431 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
432 wm8741->supplies);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
435 goto err_get;
436 }
425 437
426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); 438 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
427 if (ret != 0) { 439 if (ret != 0) {
428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 440 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
429 return ret; 441 goto err_enable;
430 } 442 }
431 443
432 ret = wm8741_reset(codec); 444 ret = wm8741_reset(codec);
433 if (ret < 0) { 445 if (ret < 0) {
434 dev_err(codec->dev, "Failed to issue reset\n"); 446 dev_err(codec->dev, "Failed to issue reset\n");
435 return ret; 447 goto err_enable;
436 } 448 }
437 449
438 /* Change some default settings - latch VU */ 450 /* Change some default settings - latch VU */
@@ -442,7 +454,7 @@ static int wm8741_probe(struct snd_soc_codec *codec)
442 WM8741_UPDATELM, WM8741_UPDATELM); 454 WM8741_UPDATELM, WM8741_UPDATELM);
443 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, 455 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
444 WM8741_UPDATERL, WM8741_UPDATERL); 456 WM8741_UPDATERL, WM8741_UPDATERL);
445 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, 457 snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
446 WM8741_UPDATERM, WM8741_UPDATERM); 458 WM8741_UPDATERM, WM8741_UPDATERM);
447 459
448 snd_soc_add_controls(codec, wm8741_snd_controls, 460 snd_soc_add_controls(codec, wm8741_snd_controls,
@@ -451,58 +463,61 @@ static int wm8741_probe(struct snd_soc_codec *codec)
451 463
452 dev_dbg(codec->dev, "Successful registration\n"); 464 dev_dbg(codec->dev, "Successful registration\n");
453 return ret; 465 return ret;
466
467err_enable:
468 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
469err_get:
470 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
471err:
472 return ret;
473}
474
475static int wm8741_remove(struct snd_soc_codec *codec)
476{
477 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
478
479 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
480 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
481
482 return 0;
454} 483}
455 484
456static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { 485static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
457 .probe = wm8741_probe, 486 .probe = wm8741_probe,
487 .remove = wm8741_remove,
458 .resume = wm8741_resume, 488 .resume = wm8741_resume,
459 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), 489 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
460 .reg_word_size = sizeof(u16), 490 .reg_word_size = sizeof(u16),
461 .reg_cache_default = wm8741_reg_defaults, 491 .reg_cache_default = wm8741_reg_defaults,
462}; 492};
463 493
494static const struct of_device_id wm8741_of_match[] = {
495 { .compatible = "wlf,wm8741", },
496 { }
497};
498MODULE_DEVICE_TABLE(of, wm8741_of_match);
499
464#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 500#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
465static int wm8741_i2c_probe(struct i2c_client *i2c, 501static int wm8741_i2c_probe(struct i2c_client *i2c,
466 const struct i2c_device_id *id) 502 const struct i2c_device_id *id)
467{ 503{
468 struct wm8741_priv *wm8741; 504 struct wm8741_priv *wm8741;
469 int ret, i; 505 int ret;
470 506
471 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); 507 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
472 if (wm8741 == NULL) 508 if (wm8741 == NULL)
473 return -ENOMEM; 509 return -ENOMEM;
474 510
475 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
476 wm8741->supplies[i].supply = wm8741_supply_names[i];
477
478 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
479 wm8741->supplies);
480 if (ret != 0) {
481 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
482 goto err;
483 }
484
485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
486 wm8741->supplies);
487 if (ret != 0) {
488 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
489 goto err_get;
490 }
491
492 i2c_set_clientdata(i2c, wm8741); 511 i2c_set_clientdata(i2c, wm8741);
493 wm8741->control_type = SND_SOC_I2C; 512 wm8741->control_type = SND_SOC_I2C;
494 513
495 ret = snd_soc_register_codec(&i2c->dev, 514 ret = snd_soc_register_codec(&i2c->dev,
496 &soc_codec_dev_wm8741, &wm8741_dai, 1); 515 &soc_codec_dev_wm8741, &wm8741_dai, 1);
497 if (ret < 0) 516 if (ret != 0)
498 goto err_enable; 517 goto err;
499 return ret;
500 518
501err_enable: 519 return ret;
502 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
503 520
504err_get:
505 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
506err: 521err:
507 kfree(wm8741); 522 kfree(wm8741);
508 return ret; 523 return ret;
@@ -510,10 +525,7 @@ err:
510 525
511static int wm8741_i2c_remove(struct i2c_client *client) 526static int wm8741_i2c_remove(struct i2c_client *client)
512{ 527{
513 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
514
515 snd_soc_unregister_codec(&client->dev); 528 snd_soc_unregister_codec(&client->dev);
516 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
517 kfree(i2c_get_clientdata(client)); 529 kfree(i2c_get_clientdata(client));
518 return 0; 530 return 0;
519} 531}
@@ -526,8 +538,9 @@ MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
526 538
527static struct i2c_driver wm8741_i2c_driver = { 539static struct i2c_driver wm8741_i2c_driver = {
528 .driver = { 540 .driver = {
529 .name = "wm8741-codec", 541 .name = "wm8741",
530 .owner = THIS_MODULE, 542 .owner = THIS_MODULE,
543 .of_match_table = wm8741_of_match,
531 }, 544 },
532 .probe = wm8741_i2c_probe, 545 .probe = wm8741_i2c_probe,
533 .remove = wm8741_i2c_remove, 546 .remove = wm8741_i2c_remove,
@@ -535,6 +548,44 @@ static struct i2c_driver wm8741_i2c_driver = {
535}; 548};
536#endif 549#endif
537 550
551#if defined(CONFIG_SPI_MASTER)
552static int __devinit wm8741_spi_probe(struct spi_device *spi)
553{
554 struct wm8741_priv *wm8741;
555 int ret;
556
557 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
558 if (wm8741 == NULL)
559 return -ENOMEM;
560
561 wm8741->control_type = SND_SOC_SPI;
562 spi_set_drvdata(spi, wm8741);
563
564 ret = snd_soc_register_codec(&spi->dev,
565 &soc_codec_dev_wm8741, &wm8741_dai, 1);
566 if (ret < 0)
567 kfree(wm8741);
568 return ret;
569}
570
571static int __devexit wm8741_spi_remove(struct spi_device *spi)
572{
573 snd_soc_unregister_codec(&spi->dev);
574 kfree(spi_get_drvdata(spi));
575 return 0;
576}
577
578static struct spi_driver wm8741_spi_driver = {
579 .driver = {
580 .name = "wm8741",
581 .owner = THIS_MODULE,
582 .of_match_table = wm8741_of_match,
583 },
584 .probe = wm8741_spi_probe,
585 .remove = __devexit_p(wm8741_spi_remove),
586};
587#endif /* CONFIG_SPI_MASTER */
588
538static int __init wm8741_modinit(void) 589static int __init wm8741_modinit(void)
539{ 590{
540 int ret = 0; 591 int ret = 0;
@@ -544,6 +595,13 @@ static int __init wm8741_modinit(void)
544 if (ret != 0) 595 if (ret != 0)
545 pr_err("Failed to register WM8741 I2C driver: %d\n", ret); 596 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
546#endif 597#endif
598#if defined(CONFIG_SPI_MASTER)
599 ret = spi_register_driver(&wm8741_spi_driver);
600 if (ret != 0) {
601 printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
602 ret);
603 }
604#endif
547 605
548 return ret; 606 return ret;
549} 607}
@@ -551,6 +609,9 @@ module_init(wm8741_modinit);
551 609
552static void __exit wm8741_exit(void) 610static void __exit wm8741_exit(void)
553{ 611{
612#if defined(CONFIG_SPI_MASTER)
613 spi_unregister_driver(&wm8741_spi_driver);
614#endif
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 615#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555 i2c_del_driver(&wm8741_i2c_driver); 616 i2c_del_driver(&wm8741_i2c_driver);
556#endif 617#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index d0003cc3bcd6..ca75a8180708 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -615,6 +616,8 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
615 break; 616 break;
616 case SND_SOC_BIAS_STANDBY: 617 case SND_SOC_BIAS_STANDBY:
617 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 618 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
619 snd_soc_cache_sync(codec);
620
618 /* Set VMID to 5k */ 621 /* Set VMID to 5k */
619 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
620 623
@@ -672,28 +675,14 @@ static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
672 675
673static int wm8750_resume(struct snd_soc_codec *codec) 676static int wm8750_resume(struct snd_soc_codec *codec)
674{ 677{
675 int i;
676 u8 data[2];
677 u16 *cache = codec->reg_cache;
678
679 /* Sync reg_cache with the hardware */
680 for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) {
681 if (i == WM8750_RESET)
682 continue;
683 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
684 data[1] = cache[i] & 0x00ff;
685 codec->hw_write(codec->control_data, data, 2);
686 }
687
688 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 678 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
689
690 return 0; 679 return 0;
691} 680}
692 681
693static int wm8750_probe(struct snd_soc_codec *codec) 682static int wm8750_probe(struct snd_soc_codec *codec)
694{ 683{
695 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 684 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
696 int reg, ret; 685 int ret;
697 686
698 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); 687 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
699 if (ret < 0) { 688 if (ret < 0) {
@@ -711,22 +700,14 @@ static int wm8750_probe(struct snd_soc_codec *codec)
711 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 700 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
712 701
713 /* set the update bits */ 702 /* set the update bits */
714 reg = snd_soc_read(codec, WM8750_LDAC); 703 snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
715 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); 704 snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
716 reg = snd_soc_read(codec, WM8750_RDAC); 705 snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
717 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); 706 snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
718 reg = snd_soc_read(codec, WM8750_LOUT1V); 707 snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
719 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); 708 snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
720 reg = snd_soc_read(codec, WM8750_ROUT1V); 709 snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
721 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); 710 snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
722 reg = snd_soc_read(codec, WM8750_LOUT2V);
723 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
724 reg = snd_soc_read(codec, WM8750_ROUT2V);
725 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
726 reg = snd_soc_read(codec, WM8750_LINVOL);
727 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
728 reg = snd_soc_read(codec, WM8750_RINVOL);
729 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
730 711
731 snd_soc_add_controls(codec, wm8750_snd_controls, 712 snd_soc_add_controls(codec, wm8750_snd_controls,
732 ARRAY_SIZE(wm8750_snd_controls)); 713 ARRAY_SIZE(wm8750_snd_controls));
@@ -751,6 +732,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
751 .reg_cache_default = wm8750_reg, 732 .reg_cache_default = wm8750_reg,
752}; 733};
753 734
735static const struct of_device_id wm8750_of_match[] = {
736 { .compatible = "wlf,wm8750", },
737 { .compatible = "wlf,wm8987", },
738 { }
739};
740MODULE_DEVICE_TABLE(of, wm8750_of_match);
741
754#if defined(CONFIG_SPI_MASTER) 742#if defined(CONFIG_SPI_MASTER)
755static int __devinit wm8750_spi_probe(struct spi_device *spi) 743static int __devinit wm8750_spi_probe(struct spi_device *spi)
756{ 744{
@@ -787,8 +775,9 @@ MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
787 775
788static struct spi_driver wm8750_spi_driver = { 776static struct spi_driver wm8750_spi_driver = {
789 .driver = { 777 .driver = {
790 .name = "wm8750-codec", 778 .name = "wm8750",
791 .owner = THIS_MODULE, 779 .owner = THIS_MODULE,
780 .of_match_table = wm8750_of_match,
792 }, 781 },
793 .id_table = wm8750_spi_ids, 782 .id_table = wm8750_spi_ids,
794 .probe = wm8750_spi_probe, 783 .probe = wm8750_spi_probe,
@@ -833,8 +822,9 @@ MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
833 822
834static struct i2c_driver wm8750_i2c_driver = { 823static struct i2c_driver wm8750_i2c_driver = {
835 .driver = { 824 .driver = {
836 .name = "wm8750-codec", 825 .name = "wm8750",
837 .owner = THIS_MODULE, 826 .owner = THIS_MODULE,
827 .of_match_table = wm8750_of_match,
838 }, 828 },
839 .probe = wm8750_i2c_probe, 829 .probe = wm8750_i2c_probe,
840 .remove = __devexit_p(wm8750_i2c_remove), 830 .remove = __devexit_p(wm8750_i2c_remove),
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index aa091a0d8187..a9504710bb69 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
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/platform_device.h> 42#include <linux/platform_device.h>
42#include <linux/spi/spi.h> 43#include <linux/spi/spi.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
@@ -1490,6 +1491,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1490 .reg_cache_default = wm8753_reg, 1491 .reg_cache_default = wm8753_reg,
1491}; 1492};
1492 1493
1494static const struct of_device_id wm8753_of_match[] = {
1495 { .compatible = "wlf,wm8753", },
1496 { }
1497};
1498MODULE_DEVICE_TABLE(of, wm8753_of_match);
1499
1493#if defined(CONFIG_SPI_MASTER) 1500#if defined(CONFIG_SPI_MASTER)
1494static int __devinit wm8753_spi_probe(struct spi_device *spi) 1501static int __devinit wm8753_spi_probe(struct spi_device *spi)
1495{ 1502{
@@ -1519,8 +1526,9 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1519 1526
1520static struct spi_driver wm8753_spi_driver = { 1527static struct spi_driver wm8753_spi_driver = {
1521 .driver = { 1528 .driver = {
1522 .name = "wm8753-codec", 1529 .name = "wm8753",
1523 .owner = THIS_MODULE, 1530 .owner = THIS_MODULE,
1531 .of_match_table = wm8753_of_match,
1524 }, 1532 },
1525 .probe = wm8753_spi_probe, 1533 .probe = wm8753_spi_probe,
1526 .remove = __devexit_p(wm8753_spi_remove), 1534 .remove = __devexit_p(wm8753_spi_remove),
@@ -1563,8 +1571,9 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1563 1571
1564static struct i2c_driver wm8753_i2c_driver = { 1572static struct i2c_driver wm8753_i2c_driver = {
1565 .driver = { 1573 .driver = {
1566 .name = "wm8753-codec", 1574 .name = "wm8753",
1567 .owner = THIS_MODULE, 1575 .owner = THIS_MODULE,
1576 .of_match_table = wm8753_of_match,
1568 }, 1577 },
1569 .probe = wm8753_i2c_probe, 1578 .probe = wm8753_i2c_probe,
1570 .remove = __devexit_p(wm8753_i2c_remove), 1579 .remove = __devexit_p(wm8753_i2c_remove),
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19b92baa9e8c..aa05e6507f84 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -14,6 +14,7 @@
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/of_device.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
@@ -684,6 +685,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
684 .reg_cache_default = wm8770_reg_defs 685 .reg_cache_default = wm8770_reg_defs
685}; 686};
686 687
688static const struct of_device_id wm8770_of_match[] = {
689 { .compatible = "wlf,wm8770", },
690 { }
691};
692MODULE_DEVICE_TABLE(of, wm8770_of_match);
693
687#if defined(CONFIG_SPI_MASTER) 694#if defined(CONFIG_SPI_MASTER)
688static int __devinit wm8770_spi_probe(struct spi_device *spi) 695static int __devinit wm8770_spi_probe(struct spi_device *spi)
689{ 696{
@@ -715,6 +722,7 @@ static struct spi_driver wm8770_spi_driver = {
715 .driver = { 722 .driver = {
716 .name = "wm8770", 723 .name = "wm8770",
717 .owner = THIS_MODULE, 724 .owner = THIS_MODULE,
725 .of_match_table = wm8770_of_match,
718 }, 726 },
719 .probe = wm8770_spi_probe, 727 .probe = wm8770_spi_probe,
720 .remove = __devexit_p(wm8770_spi_remove) 728 .remove = __devexit_p(wm8770_spi_remove)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 8e7953b1b790..bfdc52370ad0 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.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/of_device.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -215,8 +216,6 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
215 int ratio_shift, master; 216 int ratio_shift, master;
216 int i; 217 int i;
217 218
218 iface = 0;
219
220 switch (dai->driver->id) { 219 switch (dai->driver->id) {
221 case WM8776_DAI_DAC: 220 case WM8776_DAI_DAC:
222 iface_reg = WM8776_DACIFCTRL; 221 iface_reg = WM8776_DACIFCTRL;
@@ -232,20 +231,23 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
232 return -EINVAL; 231 return -EINVAL;
233 } 232 }
234 233
235
236 /* Set word length */ 234 /* Set word length */
237 switch (params_format(params)) { 235 switch (snd_pcm_format_width(params_format(params))) {
238 case SNDRV_PCM_FORMAT_S16_LE: 236 case 16:
239 break; 237 iface = 0;
240 case SNDRV_PCM_FORMAT_S20_3LE: 238 case 20:
241 iface |= 0x10; 239 iface = 0x10;
242 break; 240 break;
243 case SNDRV_PCM_FORMAT_S24_LE: 241 case 24:
244 iface |= 0x20; 242 iface = 0x20;
245 break; 243 break;
246 case SNDRV_PCM_FORMAT_S32_LE: 244 case 32:
247 iface |= 0x30; 245 iface = 0x30;
248 break; 246 break;
247 default:
248 dev_err(codec->dev, "Unsupported sample size: %i\n",
249 snd_pcm_format_width(params_format(params)));
250 return -EINVAL;
249 } 251 }
250 252
251 /* Only need to set MCLK/LRCLK ratio if we're master */ 253 /* Only need to set MCLK/LRCLK ratio if we're master */
@@ -306,6 +308,8 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
306 break; 308 break;
307 case SND_SOC_BIAS_STANDBY: 309 case SND_SOC_BIAS_STANDBY:
308 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 310 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
311 snd_soc_cache_sync(codec);
312
309 /* Disable the global powerdown; DAPM does the rest */ 313 /* Disable the global powerdown; DAPM does the rest */
310 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); 314 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
311 } 315 }
@@ -320,11 +324,6 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
320 return 0; 324 return 0;
321} 325}
322 326
323#define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
324 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
325 SNDRV_PCM_RATE_96000)
326
327
328#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 327#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
329 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 328 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
330 329
@@ -349,7 +348,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
349 .stream_name = "Playback", 348 .stream_name = "Playback",
350 .channels_min = 2, 349 .channels_min = 2,
351 .channels_max = 2, 350 .channels_max = 2,
352 .rates = WM8776_RATES, 351 .rates = SNDRV_PCM_RATE_CONTINUOUS,
352 .rate_min = 32000,
353 .rate_max = 192000,
353 .formats = WM8776_FORMATS, 354 .formats = WM8776_FORMATS,
354 }, 355 },
355 .ops = &wm8776_dac_ops, 356 .ops = &wm8776_dac_ops,
@@ -361,7 +362,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
361 .stream_name = "Capture", 362 .stream_name = "Capture",
362 .channels_min = 2, 363 .channels_min = 2,
363 .channels_max = 2, 364 .channels_max = 2,
364 .rates = WM8776_RATES, 365 .rates = SNDRV_PCM_RATE_CONTINUOUS,
366 .rate_min = 32000,
367 .rate_max = 96000,
365 .formats = WM8776_FORMATS, 368 .formats = WM8776_FORMATS,
366 }, 369 },
367 .ops = &wm8776_adc_ops, 370 .ops = &wm8776_adc_ops,
@@ -378,21 +381,7 @@ static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
378 381
379static int wm8776_resume(struct snd_soc_codec *codec) 382static int wm8776_resume(struct snd_soc_codec *codec)
380{ 383{
381 int i;
382 u8 data[2];
383 u16 *cache = codec->reg_cache;
384
385 /* Sync reg_cache with the hardware */
386 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
387 if (cache[i] == wm8776_reg[i])
388 continue;
389 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
390 data[1] = cache[i] & 0x00ff;
391 codec->hw_write(codec->control_data, data, 2);
392 }
393
394 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 384 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
395
396 return 0; 385 return 0;
397} 386}
398#else 387#else
@@ -452,6 +441,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
452 .reg_cache_default = wm8776_reg, 441 .reg_cache_default = wm8776_reg,
453}; 442};
454 443
444static const struct of_device_id wm8776_of_match[] = {
445 { .compatible = "wlf,wm8776", },
446 { }
447};
448MODULE_DEVICE_TABLE(of, wm8776_of_match);
449
455#if defined(CONFIG_SPI_MASTER) 450#if defined(CONFIG_SPI_MASTER)
456static int __devinit wm8776_spi_probe(struct spi_device *spi) 451static int __devinit wm8776_spi_probe(struct spi_device *spi)
457{ 452{
@@ -481,8 +476,9 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
481 476
482static struct spi_driver wm8776_spi_driver = { 477static struct spi_driver wm8776_spi_driver = {
483 .driver = { 478 .driver = {
484 .name = "wm8776-codec", 479 .name = "wm8776",
485 .owner = THIS_MODULE, 480 .owner = THIS_MODULE,
481 .of_match_table = wm8776_of_match,
486 }, 482 },
487 .probe = wm8776_spi_probe, 483 .probe = wm8776_spi_probe,
488 .remove = __devexit_p(wm8776_spi_remove), 484 .remove = __devexit_p(wm8776_spi_remove),
@@ -525,8 +521,9 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
525 521
526static struct i2c_driver wm8776_i2c_driver = { 522static struct i2c_driver wm8776_i2c_driver = {
527 .driver = { 523 .driver = {
528 .name = "wm8776-codec", 524 .name = "wm8776",
529 .owner = THIS_MODULE, 525 .owner = THIS_MODULE,
526 .of_match_table = wm8776_of_match,
530 }, 527 },
531 .probe = wm8776_i2c_probe, 528 .probe = wm8776_i2c_probe,
532 .remove = __devexit_p(wm8776_i2c_remove), 529 .remove = __devexit_p(wm8776_i2c_remove),
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index a2a09f85ea99..f2ced71328b0 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -60,7 +60,7 @@ static struct platform_driver wm8782_codec_driver = {
60 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
61 }, 61 },
62 .probe = wm8782_probe, 62 .probe = wm8782_probe,
63 .remove = wm8782_remove, 63 .remove = __devexit_p(wm8782_remove),
64}; 64};
65 65
66static int __init wm8782_init(void) 66static int __init wm8782_init(void)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 9a5e67c5a6bd..9ee072b85975 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.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/of_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -717,6 +718,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
717 .volatile_register = wm8804_volatile 718 .volatile_register = wm8804_volatile
718}; 719};
719 720
721static const struct of_device_id wm8804_of_match[] = {
722 { .compatible = "wlf,wm8804", },
723 { }
724};
725MODULE_DEVICE_TABLE(of, wm8804_of_match);
726
720#if defined(CONFIG_SPI_MASTER) 727#if defined(CONFIG_SPI_MASTER)
721static int __devinit wm8804_spi_probe(struct spi_device *spi) 728static int __devinit wm8804_spi_probe(struct spi_device *spi)
722{ 729{
@@ -748,6 +755,7 @@ static struct spi_driver wm8804_spi_driver = {
748 .driver = { 755 .driver = {
749 .name = "wm8804", 756 .name = "wm8804",
750 .owner = THIS_MODULE, 757 .owner = THIS_MODULE,
758 .of_match_table = wm8804_of_match,
751 }, 759 },
752 .probe = wm8804_spi_probe, 760 .probe = wm8804_spi_probe,
753 .remove = __devexit_p(wm8804_spi_remove) 761 .remove = __devexit_p(wm8804_spi_remove)
@@ -792,6 +800,7 @@ static struct i2c_driver wm8804_i2c_driver = {
792 .driver = { 800 .driver = {
793 .name = "wm8804", 801 .name = "wm8804",
794 .owner = THIS_MODULE, 802 .owner = THIS_MODULE,
803 .of_match_table = wm8804_of_match,
795 }, 804 },
796 .probe = wm8804_i2c_probe, 805 .probe = wm8804_i2c_probe,
797 .remove = __devexit_p(wm8804_i2c_remove), 806 .remove = __devexit_p(wm8804_i2c_remove),
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 082040eda8a2..3d0dc1591ecc 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -110,8 +110,8 @@
110 110
111#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 111#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
112#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 112#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
113#define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e) 113#define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e
114#define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000) 114#define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000
115 115
116#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 116#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
117#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c 117#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
@@ -135,7 +135,7 @@
135#define WM8900_REG_HPCTL1_HP_SHORT 0x08 135#define WM8900_REG_HPCTL1_HP_SHORT 0x08
136#define WM8900_REG_HPCTL1_HP_SHORT2 0x04 136#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
137 137
138#define WM8900_LRC_MASK 0xfc00 138#define WM8900_LRC_MASK 0x03ff
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 enum snd_soc_control_type control_type; 141 enum snd_soc_control_type control_type;
@@ -742,26 +742,20 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
742{ 742{
743 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 743 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
744 struct _fll_div fll_div; 744 struct _fll_div fll_div;
745 unsigned int reg;
746 745
747 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) 746 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
748 return 0; 747 return 0;
749 748
750 /* The digital side should be disabled during any change. */ 749 /* The digital side should be disabled during any change. */
751 reg = snd_soc_read(codec, WM8900_REG_POWER1); 750 snd_soc_update_bits(codec, WM8900_REG_POWER1,
752 snd_soc_write(codec, WM8900_REG_POWER1, 751 WM8900_REG_POWER1_FLL_ENA, 0);
753 reg & (~WM8900_REG_POWER1_FLL_ENA));
754 752
755 /* Disable the FLL? */ 753 /* Disable the FLL? */
756 if (!freq_in || !freq_out) { 754 if (!freq_in || !freq_out) {
757 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 755 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
758 snd_soc_write(codec, WM8900_REG_CLOCKING1, 756 WM8900_REG_CLOCKING1_MCLK_SRC, 0);
759 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); 757 snd_soc_update_bits(codec, WM8900_REG_FLLCTL1,
760 758 WM8900_REG_FLLCTL1_OSC_ENA, 0);
761 reg = snd_soc_read(codec, WM8900_REG_FLLCTL1);
762 snd_soc_write(codec, WM8900_REG_FLLCTL1,
763 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
764
765 wm8900->fll_in = freq_in; 759 wm8900->fll_in = freq_in;
766 wm8900->fll_out = freq_out; 760 wm8900->fll_out = freq_out;
767 761
@@ -796,15 +790,14 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
796 else 790 else
797 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); 791 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
798 792
799 reg = snd_soc_read(codec, WM8900_REG_POWER1); 793 snd_soc_update_bits(codec, WM8900_REG_POWER1,
800 snd_soc_write(codec, WM8900_REG_POWER1, 794 WM8900_REG_POWER1_FLL_ENA,
801 reg | WM8900_REG_POWER1_FLL_ENA); 795 WM8900_REG_POWER1_FLL_ENA);
802 796
803reenable: 797reenable:
804 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 798 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
805 snd_soc_write(codec, WM8900_REG_CLOCKING1, 799 WM8900_REG_CLOCKING1_MCLK_SRC,
806 reg | WM8900_REG_CLOCKING1_MCLK_SRC); 800 WM8900_REG_CLOCKING1_MCLK_SRC);
807
808 return 0; 801 return 0;
809} 802}
810 803
@@ -818,43 +811,35 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
818 int div_id, int div) 811 int div_id, int div)
819{ 812{
820 struct snd_soc_codec *codec = codec_dai->codec; 813 struct snd_soc_codec *codec = codec_dai->codec;
821 unsigned int reg;
822 814
823 switch (div_id) { 815 switch (div_id) {
824 case WM8900_BCLK_DIV: 816 case WM8900_BCLK_DIV:
825 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 817 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
826 snd_soc_write(codec, WM8900_REG_CLOCKING1, 818 WM8900_REG_CLOCKING1_BCLK_MASK, div);
827 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
828 break; 819 break;
829 case WM8900_OPCLK_DIV: 820 case WM8900_OPCLK_DIV:
830 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 821 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
831 snd_soc_write(codec, WM8900_REG_CLOCKING1, 822 WM8900_REG_CLOCKING1_OPCLK_MASK, div);
832 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
833 break; 823 break;
834 case WM8900_DAC_LRCLK: 824 case WM8900_DAC_LRCLK:
835 reg = snd_soc_read(codec, WM8900_REG_AUDIO4); 825 snd_soc_update_bits(codec, WM8900_REG_AUDIO4,
836 snd_soc_write(codec, WM8900_REG_AUDIO4, 826 WM8900_LRC_MASK, div);
837 div | (reg & WM8900_LRC_MASK));
838 break; 827 break;
839 case WM8900_ADC_LRCLK: 828 case WM8900_ADC_LRCLK:
840 reg = snd_soc_read(codec, WM8900_REG_AUDIO3); 829 snd_soc_update_bits(codec, WM8900_REG_AUDIO3,
841 snd_soc_write(codec, WM8900_REG_AUDIO3, 830 WM8900_LRC_MASK, div);
842 div | (reg & WM8900_LRC_MASK));
843 break; 831 break;
844 case WM8900_DAC_CLKDIV: 832 case WM8900_DAC_CLKDIV:
845 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); 833 snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
846 snd_soc_write(codec, WM8900_REG_CLOCKING2, 834 WM8900_REG_CLOCKING2_DAC_CLKDIV, div);
847 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
848 break; 835 break;
849 case WM8900_ADC_CLKDIV: 836 case WM8900_ADC_CLKDIV:
850 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); 837 snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
851 snd_soc_write(codec, WM8900_REG_CLOCKING2, 838 WM8900_REG_CLOCKING2_ADC_CLKDIV, div);
852 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
853 break; 839 break;
854 case WM8900_LRCLK_MODE: 840 case WM8900_LRCLK_MODE:
855 reg = snd_soc_read(codec, WM8900_REG_DACCTRL); 841 snd_soc_update_bits(codec, WM8900_REG_DACCTRL,
856 snd_soc_write(codec, WM8900_REG_DACCTRL, 842 WM8900_REG_DACCTRL_AIF_LRCLKRATE, div);
857 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
858 break; 843 break;
859 default: 844 default:
860 return -EINVAL; 845 return -EINVAL;
@@ -1037,12 +1022,12 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1037 switch (level) { 1022 switch (level) {
1038 case SND_SOC_BIAS_ON: 1023 case SND_SOC_BIAS_ON:
1039 /* Enable thermal shutdown */ 1024 /* Enable thermal shutdown */
1040 reg = snd_soc_read(codec, WM8900_REG_GPIO); 1025 snd_soc_update_bits(codec, WM8900_REG_GPIO,
1041 snd_soc_write(codec, WM8900_REG_GPIO, 1026 WM8900_REG_GPIO_TEMP_ENA,
1042 reg | WM8900_REG_GPIO_TEMP_ENA); 1027 WM8900_REG_GPIO_TEMP_ENA);
1043 reg = snd_soc_read(codec, WM8900_REG_ADDCTL); 1028 snd_soc_update_bits(codec, WM8900_REG_ADDCTL,
1044 snd_soc_write(codec, WM8900_REG_ADDCTL, 1029 WM8900_REG_ADDCTL_TEMP_SD,
1045 reg | WM8900_REG_ADDCTL_TEMP_SD); 1030 WM8900_REG_ADDCTL_TEMP_SD);
1046 break; 1031 break;
1047 1032
1048 case SND_SOC_BIAS_PREPARE: 1033 case SND_SOC_BIAS_PREPARE:
@@ -1205,26 +1190,16 @@ static int wm8900_probe(struct snd_soc_codec *codec)
1205 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1190 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1206 1191
1207 /* Latch the volume update bits */ 1192 /* Latch the volume update bits */
1208 snd_soc_write(codec, WM8900_REG_LINVOL, 1193 snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100);
1209 snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100); 1194 snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100);
1210 snd_soc_write(codec, WM8900_REG_RINVOL, 1195 snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100);
1211 snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100); 1196 snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100);
1212 snd_soc_write(codec, WM8900_REG_LOUT1CTL, 1197 snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100);
1213 snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100); 1198 snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100);
1214 snd_soc_write(codec, WM8900_REG_ROUT1CTL, 1199 snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100);
1215 snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100); 1200 snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100);
1216 snd_soc_write(codec, WM8900_REG_LOUT2CTL, 1201 snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100);
1217 snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100); 1202 snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100);
1218 snd_soc_write(codec, WM8900_REG_ROUT2CTL,
1219 snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1220 snd_soc_write(codec, WM8900_REG_LDAC_DV,
1221 snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1222 snd_soc_write(codec, WM8900_REG_RDAC_DV,
1223 snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1224 snd_soc_write(codec, WM8900_REG_LADC_DV,
1225 snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100);
1226 snd_soc_write(codec, WM8900_REG_RADC_DV,
1227 snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100);
1228 1203
1229 /* Set the DAC and mixer output bias */ 1204 /* Set the DAC and mixer output bias */
1230 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1205 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index b085575d4aa5..9fc8f4c0a9a9 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -50,7 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
50struct wm8904_priv { 50struct wm8904_priv {
51 51
52 enum wm8904_type devtype; 52 enum wm8904_type devtype;
53 void *control_data;
54 53
55 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 54 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
56 55
@@ -2540,7 +2539,6 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2540 2539
2541 wm8904->devtype = id->driver_data; 2540 wm8904->devtype = id->driver_data;
2542 i2c_set_clientdata(i2c, wm8904); 2541 i2c_set_clientdata(i2c, wm8904);
2543 wm8904->control_data = i2c;
2544 wm8904->pdata = i2c->dev.platform_data; 2542 wm8904->pdata = i2c->dev.platform_data;
2545 2543
2546 ret = snd_soc_register_codec(&i2c->dev, 2544 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 056daa0010f9..dc5cb3150857 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -43,9 +43,19 @@
43struct wm8940_priv { 43struct wm8940_priv {
44 unsigned int sysclk; 44 unsigned int sysclk;
45 enum snd_soc_control_type control_type; 45 enum snd_soc_control_type control_type;
46 void *control_data;
47}; 46};
48 47
48static int wm8940_volatile_register(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 switch (reg) {
52 case WM8940_SOFTRESET:
53 return 1;
54 default:
55 return 0;
56 }
57}
58
49static u16 wm8940_reg_defaults[] = { 59static u16 wm8940_reg_defaults[] = {
50 0x8940, /* Soft Reset */ 60 0x8940, /* Soft Reset */
51 0x0000, /* Power 1 */ 61 0x0000, /* Power 1 */
@@ -460,6 +470,14 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
460 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1); 470 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
461 break; 471 break;
462 case SND_SOC_BIAS_STANDBY: 472 case SND_SOC_BIAS_STANDBY:
473 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
474 ret = snd_soc_cache_sync(codec);
475 if (ret < 0) {
476 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
477 return ret;
478 }
479 }
480
463 /* ensure bufioen and biasen */ 481 /* ensure bufioen and biasen */
464 pwr_reg |= (1 << 2) | (1 << 3); 482 pwr_reg |= (1 << 2) | (1 << 3);
465 /* set vmid to 300k for standby */ 483 /* set vmid to 300k for standby */
@@ -470,6 +488,8 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
470 break; 488 break;
471 } 489 }
472 490
491 codec->dapm.bias_level = level;
492
473 return ret; 493 return ret;
474} 494}
475 495
@@ -660,30 +680,8 @@ static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
660 680
661static int wm8940_resume(struct snd_soc_codec *codec) 681static int wm8940_resume(struct snd_soc_codec *codec)
662{ 682{
663 int i; 683 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
664 int ret; 684 return 0;
665 u8 data[3];
666 u16 *cache = codec->reg_cache;
667
668 /* Sync reg_cache with the hardware
669 * Could use auto incremented writes to speed this up
670 */
671 for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) {
672 data[0] = i;
673 data[1] = (cache[i] & 0xFF00) >> 8;
674 data[2] = cache[i] & 0x00FF;
675 ret = codec->hw_write(codec->control_data, data, 3);
676 if (ret < 0)
677 goto error_ret;
678 else if (ret != 3) {
679 ret = -EIO;
680 goto error_ret;
681 }
682 }
683 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
684
685error_ret:
686 return ret;
687} 685}
688 686
689static int wm8940_probe(struct snd_soc_codec *codec) 687static int wm8940_probe(struct snd_soc_codec *codec)
@@ -693,7 +691,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
693 int ret; 691 int ret;
694 u16 reg; 692 u16 reg;
695 693
696 codec->control_data = wm8940->control_data;
697 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type); 694 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
698 if (ret < 0) { 695 if (ret < 0) {
699 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 696 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -744,6 +741,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
744 .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults), 741 .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
745 .reg_word_size = sizeof(u16), 742 .reg_word_size = sizeof(u16),
746 .reg_cache_default = wm8940_reg_defaults, 743 .reg_cache_default = wm8940_reg_defaults,
744 .volatile_register = wm8940_volatile_register,
747}; 745};
748 746
749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 747#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -758,7 +756,6 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
758 return -ENOMEM; 756 return -ENOMEM;
759 757
760 i2c_set_clientdata(i2c, wm8940); 758 i2c_set_clientdata(i2c, wm8940);
761 wm8940->control_data = i2c;
762 wm8940->control_type = SND_SOC_I2C; 759 wm8940->control_type = SND_SOC_I2C;
763 760
764 ret = snd_soc_register_codec(&i2c->dev, 761 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 4393394b7bc1..2df253c18568 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -72,7 +72,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
72 72
73struct wm8960_priv { 73struct wm8960_priv {
74 enum snd_soc_control_type control_type; 74 enum snd_soc_control_type control_type;
75 void *control_data;
76 int (*set_bias_level)(struct snd_soc_codec *, 75 int (*set_bias_level)(struct snd_soc_codec *,
77 enum snd_soc_bias_level level); 76 enum snd_soc_bias_level level);
78 struct snd_soc_dapm_widget *lout1; 77 struct snd_soc_dapm_widget *lout1;
@@ -575,6 +574,8 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
575 574
576 case SND_SOC_BIAS_STANDBY: 575 case SND_SOC_BIAS_STANDBY:
577 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 576 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
577 snd_soc_cache_sync(codec);
578
578 /* Enable anti-pop features */ 579 /* Enable anti-pop features */
579 snd_soc_write(codec, WM8960_APOP1, 580 snd_soc_write(codec, WM8960_APOP1,
580 WM8960_POBCTRL | WM8960_SOFT_ST | 581 WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -677,6 +678,9 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
677 WM8960_VREF | WM8960_VMID_MASK, 0); 678 WM8960_VREF | WM8960_VMID_MASK, 0);
678 break; 679 break;
679 680
681 case SND_SOC_BIAS_OFF:
682 snd_soc_cache_sync(codec);
683 break;
680 default: 684 default:
681 break; 685 break;
682 } 686 }
@@ -902,16 +906,6 @@ static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
902static int wm8960_resume(struct snd_soc_codec *codec) 906static int wm8960_resume(struct snd_soc_codec *codec)
903{ 907{
904 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 908 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
905 int i;
906 u8 data[2];
907 u16 *cache = codec->reg_cache;
908
909 /* Sync reg_cache with the hardware */
910 for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
911 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
912 data[1] = cache[i] & 0x00ff;
913 codec->hw_write(codec->control_data, data, 2);
914 }
915 909
916 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); 910 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
917 return 0; 911 return 0;
@@ -925,7 +919,6 @@ static int wm8960_probe(struct snd_soc_codec *codec)
925 u16 reg; 919 u16 reg;
926 920
927 wm8960->set_bias_level = wm8960_set_bias_level_out3; 921 wm8960->set_bias_level = wm8960_set_bias_level_out3;
928 codec->control_data = wm8960->control_data;
929 922
930 if (!pdata) { 923 if (!pdata) {
931 dev_warn(codec->dev, "No platform data supplied\n"); 924 dev_warn(codec->dev, "No platform data supplied\n");
@@ -1015,7 +1008,6 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
1015 1008
1016 i2c_set_clientdata(i2c, wm8960); 1009 i2c_set_clientdata(i2c, wm8960);
1017 wm8960->control_type = SND_SOC_I2C; 1010 wm8960->control_type = SND_SOC_I2C;
1018 wm8960->control_data = i2c;
1019 1011
1020 ret = snd_soc_register_codec(&i2c->dev, 1012 ret = snd_soc_register_codec(&i2c->dev,
1021 &soc_codec_dev_wm8960, &wm8960_dai, 1); 1013 &soc_codec_dev_wm8960, &wm8960_dai, 1);
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index cdee8103d09b..9568c8a49f96 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -974,7 +974,9 @@ static int wm8961_probe(struct snd_soc_codec *codec)
974 } 974 }
975 975
976 /* This isn't volatile - readback doesn't correspond to write */ 976 /* This isn't volatile - readback doesn't correspond to write */
977 reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME); 977 codec->cache_bypass = 1;
978 reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
979 codec->cache_bypass = 0;
978 dev_info(codec->dev, "WM8961 family %d revision %c\n", 980 dev_info(codec->dev, "WM8961 family %d revision %c\n",
979 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, 981 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
980 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) 982 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index d2c315fa1b9b..f60dfa16545e 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -63,6 +63,8 @@ struct wm8962_priv {
63 int fll_fref; 63 int fll_fref;
64 int fll_fout; 64 int fll_fout;
65 65
66 u16 dsp2_ena;
67
66 struct delayed_work mic_work; 68 struct delayed_work mic_work;
67 struct snd_soc_jack *jack; 69 struct snd_soc_jack *jack;
68 70
@@ -837,7 +839,7 @@ static const struct wm8962_reg_access {
837 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ 839 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
838 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ 840 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
839 841
840 [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */ 842 [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */
841 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ 843 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
842 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ 844 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
843 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ 845 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
@@ -965,7 +967,7 @@ static const struct wm8962_reg_access {
965 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ 967 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
966 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ 968 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
967 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ 969 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
968 [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */ 970 [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */
969 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ 971 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
970 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ 972 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
971 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ 973 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
@@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = {
1986}; 1988};
1987static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 1989static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1988 1990
1991static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1992{
1993 return 0;
1994}
1995
1996static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
1997{
1998 u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
1999 u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
2000 u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
2001
2002 /* Mute the ADCs and DACs */
2003 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
2004 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
2005 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2006 WM8962_DAC_MUTE, WM8962_DAC_MUTE);
2007
2008 snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
2009
2010 /* Restore the ADCs and DACs */
2011 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
2012 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
2013 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2014 WM8962_DAC_MUTE, dac);
2015
2016 return 0;
2017}
2018
2019static int wm8962_dsp2_start(struct snd_soc_codec *codec)
2020{
2021 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2022
2023 wm8962_dsp2_write_config(codec);
2024
2025 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
2026
2027 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2028
2029 return 0;
2030}
2031
2032static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
2033{
2034 wm8962_dsp2_set_enable(codec, 0);
2035
2036 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
2037
2038 return 0;
2039}
2040
2041#define WM8962_DSP2_ENABLE(xname, xshift) \
2042{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2043 .info = wm8962_dsp2_ena_info, \
2044 .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
2045 .private_value = xshift }
2046
2047static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
2048 struct snd_ctl_elem_info *uinfo)
2049{
2050 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2051
2052 uinfo->count = 1;
2053 uinfo->value.integer.min = 0;
2054 uinfo->value.integer.max = 1;
2055
2056 return 0;
2057}
2058
2059static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 int shift = kcontrol->private_value;
2063 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2064 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2065
2066 ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
2067
2068 return 0;
2069}
2070
2071static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
2072 struct snd_ctl_elem_value *ucontrol)
2073{
2074 int shift = kcontrol->private_value;
2075 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2077 int old = wm8962->dsp2_ena;
2078 int ret = 0;
2079 int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
2080 WM8962_DSP2_ENA;
2081
2082 mutex_lock(&codec->mutex);
2083
2084 if (ucontrol->value.integer.value[0])
2085 wm8962->dsp2_ena |= 1 << shift;
2086 else
2087 wm8962->dsp2_ena &= ~(1 << shift);
2088
2089 if (wm8962->dsp2_ena == old)
2090 goto out;
2091
2092 ret = 1;
2093
2094 if (dsp2_running) {
2095 if (wm8962->dsp2_ena)
2096 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2097 else
2098 wm8962_dsp2_stop(codec);
2099 }
2100
2101out:
2102 mutex_unlock(&codec->mutex);
2103
2104 return ret;
2105}
2106
1989/* The VU bits for the headphones are in a different register to the mute 2107/* The VU bits for the headphones are in a different register to the mute
1990 * bits and only take effect on the PGA if it is actually powered. 2108 * bits and only take effect on the PGA if it is actually powered.
1991 */ 2109 */
@@ -2021,7 +2139,6 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2021 struct snd_ctl_elem_value *ucontrol) 2139 struct snd_ctl_elem_value *ucontrol)
2022{ 2140{
2023 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2024 u16 *reg_cache = codec->reg_cache;
2025 int ret; 2142 int ret;
2026 2143
2027 /* Apply the update (if any) */ 2144 /* Apply the update (if any) */
@@ -2030,16 +2147,19 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2030 return 0; 2147 return 0;
2031 2148
2032 /* If the left PGA is enabled hit that VU bit... */ 2149 /* If the left PGA is enabled hit that VU bit... */
2033 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA) 2150 ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
2034 return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME, 2151 if (ret & WM8962_SPKOUTL_PGA_ENA) {
2035 reg_cache[WM8962_SPKOUTL_VOLUME]); 2152 snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
2153 snd_soc_read(codec, WM8962_SPKOUTL_VOLUME));
2154 return 1;
2155 }
2036 2156
2037 /* ...otherwise the right. The VU is stereo. */ 2157 /* ...otherwise the right. The VU is stereo. */
2038 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA) 2158 if (ret & WM8962_SPKOUTR_PGA_ENA)
2039 return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME, 2159 snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
2040 reg_cache[WM8962_SPKOUTR_VOLUME]); 2160 snd_soc_read(codec, WM8962_SPKOUTR_VOLUME));
2041 2161
2042 return 0; 2162 return 1;
2043} 2163}
2044 2164
2045static const char *cap_hpf_mode_text[] = { 2165static const char *cap_hpf_mode_text[] = {
@@ -2049,6 +2169,14 @@ static const char *cap_hpf_mode_text[] = {
2049static const struct soc_enum cap_hpf_mode = 2169static const struct soc_enum cap_hpf_mode =
2050 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); 2170 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2051 2171
2172
2173static const char *cap_lhpf_mode_text[] = {
2174 "LPF", "HPF"
2175};
2176
2177static const struct soc_enum cap_lhpf_mode =
2178 SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
2179
2052static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2180static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2053SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2181SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2054 2182
@@ -2077,6 +2205,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2077SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), 2205SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2078SOC_ENUM("Capture HPF Mode", cap_hpf_mode), 2206SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2079SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), 2207SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2208SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
2209SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
2080 2210
2081SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2211SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2082 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2212 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2134,6 +2264,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
2134 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), 2264 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
2135SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 2265SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
2136 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 2266 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
2267
2268WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
2269WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
2270WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
2271WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
2137}; 2272};
2138 2273
2139static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 2274static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2365,7 +2500,6 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2365 struct snd_kcontrol *kcontrol, int event) 2500 struct snd_kcontrol *kcontrol, int event)
2366{ 2501{
2367 struct snd_soc_codec *codec = w->codec; 2502 struct snd_soc_codec *codec = w->codec;
2368 u16 *reg_cache = codec->reg_cache;
2369 int reg; 2503 int reg;
2370 2504
2371 switch (w->shift) { 2505 switch (w->shift) {
@@ -2388,11 +2522,36 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2388 2522
2389 switch (event) { 2523 switch (event) {
2390 case SND_SOC_DAPM_POST_PMU: 2524 case SND_SOC_DAPM_POST_PMU:
2391 return snd_soc_write(codec, reg, reg_cache[reg]); 2525 return snd_soc_write(codec, reg, snd_soc_read(codec, reg));
2526 default:
2527 BUG();
2528 return -EINVAL;
2529 }
2530}
2531
2532static int dsp2_event(struct snd_soc_dapm_widget *w,
2533 struct snd_kcontrol *kcontrol, int event)
2534{
2535 struct snd_soc_codec *codec = w->codec;
2536 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2537
2538 switch (event) {
2539 case SND_SOC_DAPM_POST_PMU:
2540 if (wm8962->dsp2_ena)
2541 wm8962_dsp2_start(codec);
2542 break;
2543
2544 case SND_SOC_DAPM_PRE_PMD:
2545 if (wm8962->dsp2_ena)
2546 wm8962_dsp2_stop(codec);
2547 break;
2548
2392 default: 2549 default:
2393 BUG(); 2550 BUG();
2394 return -EINVAL; 2551 return -EINVAL;
2395 } 2552 }
2553
2554 return 0;
2396} 2555}
2397 2556
2398static const char *st_text[] = { "None", "Right", "Left" }; 2557static const char *st_text[] = { "None", "Right", "Left" };
@@ -2509,7 +2668,7 @@ SND_SOC_DAPM_INPUT("IN4R"),
2509SND_SOC_DAPM_INPUT("Beep"), 2668SND_SOC_DAPM_INPUT("Beep"),
2510SND_SOC_DAPM_INPUT("DMICDAT"), 2669SND_SOC_DAPM_INPUT("DMICDAT"),
2511 2670
2512SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), 2671SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2513 2672
2514SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2673SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2515SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2674SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
@@ -2517,6 +2676,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
2517SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2676SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2518 SND_SOC_DAPM_POST_PMU), 2677 SND_SOC_DAPM_POST_PMU),
2519SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2678SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
2679SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
2680 WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
2681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2520 2682
2521SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, 2683SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
2522 inpgal, ARRAY_SIZE(inpgal)), 2684 inpgal, ARRAY_SIZE(inpgal)),
@@ -2527,7 +2689,7 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2527SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, 2689SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2528 mixinr, ARRAY_SIZE(mixinr)), 2690 mixinr, ARRAY_SIZE(mixinr)),
2529 2691
2530SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0), 2692SND_SOC_DAPM_AIF_IN("DMIC_ENA", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2531 2693
2532SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), 2694SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2533SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), 2695SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
@@ -2606,17 +2768,19 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2606 2768
2607 { "MICBIAS", NULL, "SYSCLK" }, 2769 { "MICBIAS", NULL, "SYSCLK" },
2608 2770
2609 { "DMIC", NULL, "DMICDAT" }, 2771 { "DMIC_ENA", NULL, "DMICDAT" },
2610 2772
2611 { "ADCL", NULL, "SYSCLK" }, 2773 { "ADCL", NULL, "SYSCLK" },
2612 { "ADCL", NULL, "TOCLK" }, 2774 { "ADCL", NULL, "TOCLK" },
2613 { "ADCL", NULL, "MIXINL" }, 2775 { "ADCL", NULL, "MIXINL" },
2614 { "ADCL", NULL, "DMIC" }, 2776 { "ADCL", NULL, "DMIC_ENA" },
2777 { "ADCL", NULL, "DSP2" },
2615 2778
2616 { "ADCR", NULL, "SYSCLK" }, 2779 { "ADCR", NULL, "SYSCLK" },
2617 { "ADCR", NULL, "TOCLK" }, 2780 { "ADCR", NULL, "TOCLK" },
2618 { "ADCR", NULL, "MIXINR" }, 2781 { "ADCR", NULL, "MIXINR" },
2619 { "ADCR", NULL, "DMIC" }, 2782 { "ADCR", NULL, "DMIC_ENA" },
2783 { "ADCR", NULL, "DSP2" },
2620 2784
2621 { "STL", "Left", "ADCL" }, 2785 { "STL", "Left", "ADCL" },
2622 { "STL", "Right", "ADCR" }, 2786 { "STL", "Right", "ADCR" },
@@ -2628,11 +2792,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2628 { "DACL", NULL, "TOCLK" }, 2792 { "DACL", NULL, "TOCLK" },
2629 { "DACL", NULL, "Beep" }, 2793 { "DACL", NULL, "Beep" },
2630 { "DACL", NULL, "STL" }, 2794 { "DACL", NULL, "STL" },
2795 { "DACL", NULL, "DSP2" },
2631 2796
2632 { "DACR", NULL, "SYSCLK" }, 2797 { "DACR", NULL, "SYSCLK" },
2633 { "DACR", NULL, "TOCLK" }, 2798 { "DACR", NULL, "TOCLK" },
2634 { "DACR", NULL, "Beep" }, 2799 { "DACR", NULL, "Beep" },
2635 { "DACR", NULL, "STR" }, 2800 { "DACR", NULL, "STR" },
2801 { "DACR", NULL, "DSP2" },
2636 2802
2637 { "HPMIXL", "IN4L Switch", "IN4L" }, 2803 { "HPMIXL", "IN4L Switch", "IN4L" },
2638 { "HPMIXL", "IN4R Switch", "IN4R" }, 2804 { "HPMIXL", "IN4R Switch", "IN4R" },
@@ -3058,9 +3224,9 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3058 int aif0 = 0; 3224 int aif0 = 0;
3059 3225
3060 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 3226 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3061 case SND_SOC_DAIFMT_DSP_A:
3062 aif0 |= WM8962_LRCLK_INV;
3063 case SND_SOC_DAIFMT_DSP_B: 3227 case SND_SOC_DAIFMT_DSP_B:
3228 aif0 |= WM8962_LRCLK_INV | 3;
3229 case SND_SOC_DAIFMT_DSP_A:
3064 aif0 |= 3; 3230 aif0 |= 3;
3065 3231
3066 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 3232 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -3403,12 +3569,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3403 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3569 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3404 int mask; 3570 int mask;
3405 int active; 3571 int active;
3572 int reg;
3406 3573
3407 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 3574 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
3408 3575
3409 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3576 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3410 active &= ~mask; 3577 active &= ~mask;
3411 3578
3579 if (!active)
3580 return IRQ_NONE;
3581
3412 /* Acknowledge the interrupts */ 3582 /* Acknowledge the interrupts */
3413 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 3583 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
3414 3584
@@ -3420,9 +3590,21 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3420 if (active & WM8962_FIFOS_ERR_EINT) 3590 if (active & WM8962_FIFOS_ERR_EINT)
3421 dev_err(codec->dev, "FIFO error\n"); 3591 dev_err(codec->dev, "FIFO error\n");
3422 3592
3423 if (active & WM8962_TEMP_SHUT_EINT) 3593 if (active & WM8962_TEMP_SHUT_EINT) {
3424 dev_crit(codec->dev, "Thermal shutdown\n"); 3594 dev_crit(codec->dev, "Thermal shutdown\n");
3425 3595
3596 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS);
3597
3598 if (reg & WM8962_TEMP_ERR_HP)
3599 dev_crit(codec->dev, "Headphone thermal error\n");
3600 if (reg & WM8962_TEMP_WARN_HP)
3601 dev_crit(codec->dev, "Headphone thermal warning\n");
3602 if (reg & WM8962_TEMP_ERR_SPK)
3603 dev_crit(codec->dev, "Speaker thermal error\n");
3604 if (reg & WM8962_TEMP_WARN_SPK)
3605 dev_crit(codec->dev, "Speaker thermal warning\n");
3606 }
3607
3426 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3608 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3427 dev_dbg(codec->dev, "Microphone event detected\n"); 3609 dev_dbg(codec->dev, "Microphone event detected\n");
3428 3610
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 572bb80627a4..b444b297d0b2 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -546,6 +546,9 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
546 case SND_SOC_BIAS_PREPARE: 546 case SND_SOC_BIAS_PREPARE:
547 break; 547 break;
548 case SND_SOC_BIAS_STANDBY: 548 case SND_SOC_BIAS_STANDBY:
549 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
550 snd_soc_cache_sync(codec);
551
549 /* mute dac and set vmid to 500k, enable VREF */ 552 /* mute dac and set vmid to 500k, enable VREF */
550 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140); 553 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
551 break; 554 break;
@@ -605,20 +608,8 @@ static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
605 608
606static int wm8971_resume(struct snd_soc_codec *codec) 609static int wm8971_resume(struct snd_soc_codec *codec)
607{ 610{
608 int i;
609 u8 data[2];
610 u16 *cache = codec->reg_cache;
611 u16 reg; 611 u16 reg;
612 612
613 /* Sync reg_cache with the hardware */
614 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
615 if (i + 1 == WM8971_RESET)
616 continue;
617 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
618 data[1] = cache[i] & 0x00ff;
619 codec->hw_write(codec->control_data, data, 2);
620 }
621
622 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 613 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
623 614
624 /* charge wm8971 caps */ 615 /* charge wm8971 caps */
@@ -660,25 +651,14 @@ static int wm8971_probe(struct snd_soc_codec *codec)
660 msecs_to_jiffies(1000)); 651 msecs_to_jiffies(1000));
661 652
662 /* set the update bits */ 653 /* set the update bits */
663 reg = snd_soc_read(codec, WM8971_LDAC); 654 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
664 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100); 655 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
665 reg = snd_soc_read(codec, WM8971_RDAC); 656 snd_soc_update_bits(codec, WM8971_LOUT1V, 0x0100, 0x0100);
666 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100); 657 snd_soc_update_bits(codec, WM8971_ROUT1V, 0x0100, 0x0100);
667 658 snd_soc_update_bits(codec, WM8971_LOUT2V, 0x0100, 0x0100);
668 reg = snd_soc_read(codec, WM8971_LOUT1V); 659 snd_soc_update_bits(codec, WM8971_ROUT2V, 0x0100, 0x0100);
669 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100); 660 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
670 reg = snd_soc_read(codec, WM8971_ROUT1V); 661 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
671 snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100);
672
673 reg = snd_soc_read(codec, WM8971_LOUT2V);
674 snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100);
675 reg = snd_soc_read(codec, WM8971_ROUT2V);
676 snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100);
677
678 reg = snd_soc_read(codec, WM8971_LINVOL);
679 snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100);
680 reg = snd_soc_read(codec, WM8971_RINVOL);
681 snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100);
682 662
683 snd_soc_add_controls(codec, wm8971_snd_controls, 663 snd_soc_add_controls(codec, wm8971_snd_controls,
684 ARRAY_SIZE(wm8971_snd_controls)); 664 ARRAY_SIZE(wm8971_snd_controls));
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index ca646a822444..9352f1e088d2 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006-2009 Wolfson Microelectronics PLC. 4 * Copyright 2006-2009 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <linux@wolfsonmicro.com> 6 * Author: Liam Girdwood <Liam.Girdwood@wolfsonmicro.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
@@ -530,6 +530,8 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; 530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
531 531
532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
533 snd_soc_cache_sync(codec);
534
533 /* Initial cap charge at VMID 5k */ 535 /* Initial cap charge at VMID 5k */
534 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); 536 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
535 mdelay(100); 537 mdelay(100);
@@ -589,18 +591,7 @@ static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
589 591
590static int wm8974_resume(struct snd_soc_codec *codec) 592static int wm8974_resume(struct snd_soc_codec *codec)
591{ 593{
592 int i;
593 u8 data[2];
594 u16 *cache = codec->reg_cache;
595
596 /* Sync reg_cache with the hardware */
597 for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) {
598 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
599 data[1] = cache[i] & 0x00ff;
600 codec->hw_write(codec->control_data, data, 2);
601 }
602 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 594 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
603
604 return 0; 595 return 0;
605} 596}
606 597
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 85e3e630e763..41ca4d9ac20c 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -52,7 +52,6 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
52/* codec private data */ 52/* codec private data */
53struct wm8978_priv { 53struct wm8978_priv {
54 enum snd_soc_control_type control_type; 54 enum snd_soc_control_type control_type;
55 void *control_data;
56 unsigned int f_pllout; 55 unsigned int f_pllout;
57 unsigned int f_mclk; 56 unsigned int f_mclk;
58 unsigned int f_256fs; 57 unsigned int f_256fs;
@@ -955,7 +954,6 @@ static int wm8978_probe(struct snd_soc_codec *codec)
955 * default hardware setting 954 * default hardware setting
956 */ 955 */
957 wm8978->sysclk = WM8978_PLL; 956 wm8978->sysclk = WM8978_PLL;
958 codec->control_data = wm8978->control_data;
959 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); 957 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
960 if (ret < 0) { 958 if (ret < 0) {
961 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 959 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -1016,7 +1014,6 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1016 return -ENOMEM; 1014 return -ENOMEM;
1017 1015
1018 i2c_set_clientdata(i2c, wm8978); 1016 i2c_set_clientdata(i2c, wm8978);
1019 wm8978->control_data = i2c;
1020 1017
1021 ret = snd_soc_register_codec(&i2c->dev, 1018 ret = snd_soc_register_codec(&i2c->dev,
1022 &soc_codec_dev_wm8978, &wm8978_dai, 1); 1019 &soc_codec_dev_wm8978, &wm8978_dai, 1);
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 17f04ec2b940..93ee28439be5 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -1007,7 +1007,7 @@ static int wm8983_probe(struct snd_soc_codec *codec)
1007 return ret; 1007 return ret;
1008 } 1008 }
1009 1009
1010 ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0x8983); 1010 ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
1011 if (ret < 0) { 1011 if (ret < 0) {
1012 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1012 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1013 return ret; 1013 return ret;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index d7170f1381aa..2e9eba717d1a 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -55,7 +55,6 @@ struct wm8988_priv {
55 struct snd_pcm_hw_constraint_list *sysclk_constraints; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
56}; 56};
57 57
58
59#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) 58#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
60 59
61/* 60/*
@@ -676,6 +675,8 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
676 675
677 case SND_SOC_BIAS_STANDBY: 676 case SND_SOC_BIAS_STANDBY:
678 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 677 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
678 snd_soc_cache_sync(codec);
679
679 /* VREF, VMID=2x5k */ 680 /* VREF, VMID=2x5k */
680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 681 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
681 682
@@ -736,21 +737,7 @@ static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
736 737
737static int wm8988_resume(struct snd_soc_codec *codec) 738static int wm8988_resume(struct snd_soc_codec *codec)
738{ 739{
739 int i;
740 u8 data[2];
741 u16 *cache = codec->reg_cache;
742
743 /* Sync reg_cache with the hardware */
744 for (i = 0; i < WM8988_NUM_REG; i++) {
745 if (i == WM8988_RESET)
746 continue;
747 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
748 data[1] = cache[i] & 0x00ff;
749 codec->hw_write(codec->control_data, data, 2);
750 }
751
752 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 740 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
753
754 return 0; 741 return 0;
755} 742}
756 743
@@ -759,7 +746,6 @@ static int wm8988_probe(struct snd_soc_codec *codec)
759 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 746 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
760 struct snd_soc_dapm_context *dapm = &codec->dapm; 747 struct snd_soc_dapm_context *dapm = &codec->dapm;
761 int ret = 0; 748 int ret = 0;
762 u16 reg;
763 749
764 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); 750 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
765 if (ret < 0) { 751 if (ret < 0) {
@@ -774,16 +760,11 @@ static int wm8988_probe(struct snd_soc_codec *codec)
774 } 760 }
775 761
776 /* set the update bits (we always update left then right) */ 762 /* set the update bits (we always update left then right) */
777 reg = snd_soc_read(codec, WM8988_RADC); 763 snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100);
778 snd_soc_write(codec, WM8988_RADC, reg | 0x100); 764 snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100);
779 reg = snd_soc_read(codec, WM8988_RDAC); 765 snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100);
780 snd_soc_write(codec, WM8988_RDAC, reg | 0x0100); 766 snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100);
781 reg = snd_soc_read(codec, WM8988_ROUT1V); 767 snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100);
782 snd_soc_write(codec, WM8988_ROUT1V, reg | 0x0100);
783 reg = snd_soc_read(codec, WM8988_ROUT2V);
784 snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
785 reg = snd_soc_read(codec, WM8988_RINVOL);
786 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
787 768
788 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 769 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
789 770
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 100aeee5ba96..d29a9622964c 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -36,10 +36,17 @@ struct wm8990_priv {
36 unsigned int pcmclk; 36 unsigned int pcmclk;
37}; 37};
38 38
39/* 39static int wm8990_volatile_register(struct snd_soc_codec *codec,
40 * wm8990 register cache. Note that register 0 is not included in the 40 unsigned int reg)
41 * cache. 41{
42 */ 42 switch (reg) {
43 case WM8990_RESET:
44 return 1;
45 default:
46 return 0;
47 }
48}
49
43static const u16 wm8990_reg[] = { 50static const u16 wm8990_reg[] = {
44 0x8990, /* R0 - Reset */ 51 0x8990, /* R0 - Reset */
45 0x0000, /* R1 - Power Management (1) */ 52 0x0000, /* R1 - Power Management (1) */
@@ -394,7 +401,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
394 (1 << WM8990_AINRMUX_PWR_BIT))) { 401 (1 << WM8990_AINRMUX_PWR_BIT))) {
395 reg |= WM8990_AINR_ENA; 402 reg |= WM8990_AINR_ENA;
396 } else { 403 } else {
397 reg &= ~WM8990_AINL_ENA; 404 reg &= ~WM8990_AINR_ENA;
398 } 405 }
399 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); 406 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
400 407
@@ -974,7 +981,6 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
974static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 981static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
975 int source, unsigned int freq_in, unsigned int freq_out) 982 int source, unsigned int freq_in, unsigned int freq_out)
976{ 983{
977 u16 reg;
978 struct snd_soc_codec *codec = codec_dai->codec; 984 struct snd_soc_codec *codec = codec_dai->codec;
979 struct _pll_div pll_div; 985 struct _pll_div pll_div;
980 986
@@ -982,13 +988,12 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
982 pll_factors(&pll_div, freq_out * 4, freq_in); 988 pll_factors(&pll_div, freq_out * 4, freq_in);
983 989
984 /* Turn on PLL */ 990 /* Turn on PLL */
985 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 991 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
986 reg |= WM8990_PLL_ENA; 992 WM8990_PLL_ENA, WM8990_PLL_ENA);
987 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
988 993
989 /* sysclk comes from PLL */ 994 /* sysclk comes from PLL */
990 reg = snd_soc_read(codec, WM8990_CLOCKING_2); 995 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
991 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 996 WM8990_SYSCLK_SRC, WM8990_SYSCLK_SRC);
992 997
993 /* set up N , fractional mode and pre-divisor if necessary */ 998 /* set up N , fractional mode and pre-divisor if necessary */
994 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 999 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
@@ -996,10 +1001,9 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
996 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 1001 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
997 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); 1002 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
998 } else { 1003 } else {
999 /* Turn on PLL */ 1004 /* Turn off PLL */
1000 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 1005 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
1001 reg &= ~WM8990_PLL_ENA; 1006 WM8990_PLL_ENA, 0);
1002 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1003 } 1007 }
1004 return 0; 1008 return 0;
1005} 1009}
@@ -1077,28 +1081,23 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1077 int div_id, int div) 1081 int div_id, int div)
1078{ 1082{
1079 struct snd_soc_codec *codec = codec_dai->codec; 1083 struct snd_soc_codec *codec = codec_dai->codec;
1080 u16 reg;
1081 1084
1082 switch (div_id) { 1085 switch (div_id) {
1083 case WM8990_MCLK_DIV: 1086 case WM8990_MCLK_DIV:
1084 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1087 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1085 ~WM8990_MCLK_DIV_MASK; 1088 WM8990_MCLK_DIV_MASK, div);
1086 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1087 break; 1089 break;
1088 case WM8990_DACCLK_DIV: 1090 case WM8990_DACCLK_DIV:
1089 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1091 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1090 ~WM8990_DAC_CLKDIV_MASK; 1092 WM8990_DAC_CLKDIV_MASK, div);
1091 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1092 break; 1093 break;
1093 case WM8990_ADCCLK_DIV: 1094 case WM8990_ADCCLK_DIV:
1094 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1095 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1095 ~WM8990_ADC_CLKDIV_MASK; 1096 WM8990_ADC_CLKDIV_MASK, div);
1096 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1097 break; 1097 break;
1098 case WM8990_BCLK_DIV: 1098 case WM8990_BCLK_DIV:
1099 reg = snd_soc_read(codec, WM8990_CLOCKING_1) & 1099 snd_soc_update_bits(codec, WM8990_CLOCKING_1,
1100 ~WM8990_BCLK_DIV_MASK; 1100 WM8990_BCLK_DIV_MASK, div);
1101 snd_soc_write(codec, WM8990_CLOCKING_1, reg | div);
1102 break; 1101 break;
1103 default: 1102 default:
1104 return -EINVAL; 1103 return -EINVAL;
@@ -1156,7 +1155,7 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
1156static int wm8990_set_bias_level(struct snd_soc_codec *codec, 1155static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1157 enum snd_soc_bias_level level) 1156 enum snd_soc_bias_level level)
1158{ 1157{
1159 u16 val; 1158 int ret;
1160 1159
1161 switch (level) { 1160 switch (level) {
1162 case SND_SOC_BIAS_ON: 1161 case SND_SOC_BIAS_ON:
@@ -1164,13 +1163,18 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1164 1163
1165 case SND_SOC_BIAS_PREPARE: 1164 case SND_SOC_BIAS_PREPARE:
1166 /* VMID=2*50k */ 1165 /* VMID=2*50k */
1167 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & 1166 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
1168 ~WM8990_VMID_MODE_MASK; 1167 WM8990_VMID_MODE_MASK, 0x2);
1169 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1170 break; 1168 break;
1171 1169
1172 case SND_SOC_BIAS_STANDBY: 1170 case SND_SOC_BIAS_STANDBY:
1173 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1171 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1172 ret = snd_soc_cache_sync(codec);
1173 if (ret < 0) {
1174 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1175 return ret;
1176 }
1177
1174 /* Enable all output discharge bits */ 1178 /* Enable all output discharge bits */
1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1179 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1180 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1225,9 +1229,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1225 } 1229 }
1226 1230
1227 /* VMID=2*250k */ 1231 /* VMID=2*250k */
1228 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & 1232 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
1229 ~WM8990_VMID_MODE_MASK; 1233 WM8990_VMID_MODE_MASK, 0x4);
1230 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1231 break; 1234 break;
1232 1235
1233 case SND_SOC_BIAS_OFF: 1236 case SND_SOC_BIAS_OFF:
@@ -1241,8 +1244,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1241 WM8990_BUFIOEN); 1244 WM8990_BUFIOEN);
1242 1245
1243 /* mute DAC */ 1246 /* mute DAC */
1244 val = snd_soc_read(codec, WM8990_DAC_CTRL); 1247 snd_soc_update_bits(codec, WM8990_DAC_CTRL,
1245 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1248 WM8990_DAC_MUTE, WM8990_DAC_MUTE);
1246 1249
1247 /* Enable any disabled outputs */ 1250 /* Enable any disabled outputs */
1248 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
@@ -1319,19 +1322,6 @@ static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state)
1319 1322
1320static int wm8990_resume(struct snd_soc_codec *codec) 1323static int wm8990_resume(struct snd_soc_codec *codec)
1321{ 1324{
1322 int i;
1323 u8 data[2];
1324 u16 *cache = codec->reg_cache;
1325
1326 /* Sync reg_cache with the hardware */
1327 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1328 if (i + 1 == WM8990_RESET)
1329 continue;
1330 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
1331 data[1] = cache[i] & 0x00ff;
1332 codec->hw_write(codec->control_data, data, 2);
1333 }
1334
1335 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1325 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1336 return 0; 1326 return 0;
1337} 1327}
@@ -1343,7 +1333,6 @@ static int wm8990_resume(struct snd_soc_codec *codec)
1343static int wm8990_probe(struct snd_soc_codec *codec) 1333static int wm8990_probe(struct snd_soc_codec *codec)
1344{ 1334{
1345 int ret; 1335 int ret;
1346 u16 reg;
1347 1336
1348 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1337 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1349 if (ret < 0) { 1338 if (ret < 0) {
@@ -1356,15 +1345,14 @@ static int wm8990_probe(struct snd_soc_codec *codec)
1356 /* charge output caps */ 1345 /* charge output caps */
1357 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1346 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1358 1347
1359 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4); 1348 snd_soc_update_bits(codec, WM8990_AUDIO_INTERFACE_4,
1360 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1); 1349 WM8990_ALRCGPIO1, WM8990_ALRCGPIO1);
1361 1350
1362 reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) & 1351 snd_soc_update_bits(codec, WM8990_GPIO1_GPIO2,
1363 ~WM8990_GPIO1_SEL_MASK; 1352 WM8990_GPIO1_SEL_MASK, 1);
1364 snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
1365 1353
1366 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 1354 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
1367 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA); 1355 WM8990_OPCLK_ENA, WM8990_OPCLK_ENA);
1368 1356
1369 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1357 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1370 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1358 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
@@ -1392,6 +1380,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
1392 .reg_cache_size = ARRAY_SIZE(wm8990_reg), 1380 .reg_cache_size = ARRAY_SIZE(wm8990_reg),
1393 .reg_word_size = sizeof(u16), 1381 .reg_word_size = sizeof(u16),
1394 .reg_cache_default = wm8990_reg, 1382 .reg_cache_default = wm8990_reg,
1383 .volatile_register = wm8990_volatile_register,
1395}; 1384};
1396 1385
1397#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1386#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 6af23d06870f..c9ab3ba9bced 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2007-2010 Wolfson Microelectronics PLC. 4 * Copyright 2007-2010 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 5 * Author: Graeme Gregory
6 * linux@wolfsonmicro.com 6 * Graeme.Gregory@wolfsonmicro.com
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -393,7 +393,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
393 (1 << WM8991_AINRMUX_PWR_BIT))) 393 (1 << WM8991_AINRMUX_PWR_BIT)))
394 reg |= WM8991_AINR_ENA; 394 reg |= WM8991_AINR_ENA;
395 else 395 else
396 reg &= ~WM8991_AINL_ENA; 396 reg &= ~WM8991_AINR_ENA;
397 397
398 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg); 398 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
399 return 0; 399 return 0;
@@ -1264,7 +1264,6 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1264{ 1264{
1265 struct wm8991_priv *wm8991; 1265 struct wm8991_priv *wm8991;
1266 int ret; 1266 int ret;
1267 unsigned int reg;
1268 1267
1269 wm8991 = snd_soc_codec_get_drvdata(codec); 1268 wm8991 = snd_soc_codec_get_drvdata(codec);
1270 1269
@@ -1282,19 +1281,18 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1282 1281
1283 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1282 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1284 1283
1285 reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4); 1284 snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4,
1286 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1); 1285 WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
1287 1286
1288 reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) & 1287 snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2,
1289 ~WM8991_GPIO1_SEL_MASK; 1288 WM8991_GPIO1_SEL_MASK, 1);
1290 snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1);
1291 1289
1292 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1); 1290 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1,
1293 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA| 1291 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
1294 WM8991_VMID_MODE_MASK); 1292 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
1295 1293
1296 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2); 1294 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2,
1297 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA); 1295 WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
1298 1296
1299 snd_soc_write(codec, WM8991_DAC_CTRL, 0); 1297 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1300 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1298 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 6e85b8869af7..eec8e1435116 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -847,6 +847,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0), 848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0), 849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
850SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0),
850 851
851SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0), 852SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
852SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0), 853SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
@@ -880,6 +881,9 @@ SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
880}; 881};
881 882
882static const struct snd_soc_dapm_route routes[] = { 883static const struct snd_soc_dapm_route routes[] = {
884 { "MICBIAS1", NULL, "VMID" },
885 { "MICBIAS2", NULL, "VMID" },
886
883 { "ADCL", NULL, "CLK_SYS" }, 887 { "ADCL", NULL, "CLK_SYS" },
884 { "ADCL", NULL, "CLK_DSP" }, 888 { "ADCL", NULL, "CLK_DSP" },
885 { "ADCR", NULL, "CLK_SYS" }, 889 { "ADCR", NULL, "CLK_SYS" },
@@ -1433,7 +1437,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1433 int ret, i, val; 1437 int ret, i, val;
1434 1438
1435 wm8993->hubs_data.hp_startup_mode = 1; 1439 wm8993->hubs_data.hp_startup_mode = 1;
1436 wm8993->hubs_data.dcs_codes = -2; 1440 wm8993->hubs_data.dcs_codes_l = -2;
1441 wm8993->hubs_data.dcs_codes_r = -2;
1437 wm8993->hubs_data.series_startup = 1; 1442 wm8993->hubs_data.series_startup = 1;
1438 1443
1439 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1444 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index a87adbd05ee1..df5a8b9a250f 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -1073,8 +1073,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1073 { 0x0000, 0x0000 }, /* R1069 */ 1073 { 0x0000, 0x0000 }, /* R1069 */
1074 { 0x0000, 0x0000 }, /* R1070 */ 1074 { 0x0000, 0x0000 }, /* R1070 */
1075 { 0x0000, 0x0000 }, /* R1071 */ 1075 { 0x0000, 0x0000 }, /* R1071 */
1076 { 0x0000, 0x0000 }, /* R1072 */ 1076 { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */
1077 { 0x0000, 0x0000 }, /* R1073 */ 1077 { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */
1078 { 0x0000, 0x0000 }, /* R1074 */ 1078 { 0x0000, 0x0000 }, /* R1074 */
1079 { 0x0000, 0x0000 }, /* R1075 */ 1079 { 0x0000, 0x0000 }, /* R1075 */
1080 { 0x0000, 0x0000 }, /* R1076 */ 1080 { 0x0000, 0x0000 }, /* R1076 */
@@ -1329,7 +1329,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1329 { 0x0000, 0x0000 }, /* R1325 */ 1329 { 0x0000, 0x0000 }, /* R1325 */
1330 { 0x0000, 0x0000 }, /* R1326 */ 1330 { 0x0000, 0x0000 }, /* R1326 */
1331 { 0x0000, 0x0000 }, /* R1327 */ 1331 { 0x0000, 0x0000 }, /* R1327 */
1332 { 0x0000, 0x0000 }, /* R1328 */ 1332 { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */
1333 { 0x0000, 0x0000 }, /* R1329 */ 1333 { 0x0000, 0x0000 }, /* R1329 */
1334 { 0x0000, 0x0000 }, /* R1330 */ 1334 { 0x0000, 0x0000 }, /* R1330 */
1335 { 0x0000, 0x0000 }, /* R1331 */ 1335 { 0x0000, 0x0000 }, /* R1331 */
@@ -1635,8 +1635,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1635 0x0000, /* R58 - MICBIAS */ 1635 0x0000, /* R58 - MICBIAS */
1636 0x000D, /* R59 - LDO 1 */ 1636 0x000D, /* R59 - LDO 1 */
1637 0x0003, /* R60 - LDO 2 */ 1637 0x0003, /* R60 - LDO 2 */
1638 0x0000, /* R61 */ 1638 0x0039, /* R61 - MICBIAS1 */
1639 0x0000, /* R62 */ 1639 0x0039, /* R62 - MICBIAS2 */
1640 0x0000, /* R63 */ 1640 0x0000, /* R63 */
1641 0x0000, /* R64 */ 1641 0x0000, /* R64 */
1642 0x0000, /* R65 */ 1642 0x0000, /* R65 */
@@ -2646,8 +2646,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2646 0x0000, /* R1069 */ 2646 0x0000, /* R1069 */
2647 0x0000, /* R1070 */ 2647 0x0000, /* R1070 */
2648 0x0000, /* R1071 */ 2648 0x0000, /* R1071 */
2649 0x0000, /* R1072 */ 2649 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */
2650 0x0000, /* R1073 */ 2650 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */
2651 0x0000, /* R1074 */ 2651 0x0000, /* R1074 */
2652 0x0000, /* R1075 */ 2652 0x0000, /* R1075 */
2653 0x0000, /* R1076 */ 2653 0x0000, /* R1076 */
@@ -2902,7 +2902,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2902 0x0000, /* R1325 */ 2902 0x0000, /* R1325 */
2903 0x0000, /* R1326 */ 2903 0x0000, /* R1326 */
2904 0x0000, /* R1327 */ 2904 0x0000, /* R1327 */
2905 0x0000, /* R1328 */ 2905 0x0068, /* R1328 - AIF2 DAC Noise Gate */
2906 0x0000, /* R1329 */ 2906 0x0000, /* R1329 */
2907 0x0000, /* R1330 */ 2907 0x0000, /* R1330 */
2908 0x0000, /* R1331 */ 2908 0x0000, /* R1331 */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b393f9fac97a..6b73efd26991 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -107,6 +107,7 @@ static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
107 case WM8994_LDO_2: 107 case WM8994_LDO_2:
108 case WM8958_DSP2_EXECCONTROL: 108 case WM8958_DSP2_EXECCONTROL:
109 case WM8958_MIC_DETECT_3: 109 case WM8958_MIC_DETECT_3:
110 case WM8994_DC_SERVO_4E:
110 return 1; 111 return 1;
111 default: 112 default:
112 return 0; 113 return 0;
@@ -207,7 +208,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
207static int configure_clock(struct snd_soc_codec *codec) 208static int configure_clock(struct snd_soc_codec *codec)
208{ 209{
209 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 210 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
210 int old, new; 211 int change, new;
211 212
212 /* Bring up the AIF clocks first */ 213 /* Bring up the AIF clocks first */
213 configure_aif_clock(codec, 0); 214 configure_aif_clock(codec, 0);
@@ -228,14 +229,11 @@ static int configure_clock(struct snd_soc_codec *codec)
228 else 229 else
229 new = 0; 230 new = 0;
230 231
231 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC; 232 change = snd_soc_update_bits(codec, WM8994_CLOCKING_1,
232 233 WM8994_SYSCLK_SRC, new);
233 /* If there's no change then we're done. */ 234 if (!change)
234 if (old == new)
235 return 0; 235 return 0;
236 236
237 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
238
239 snd_soc_dapm_sync(&codec->dapm); 237 snd_soc_dapm_sync(&codec->dapm);
240 238
241 return 0; 239 return 0;
@@ -281,6 +279,8 @@ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
281static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); 279static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
282static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); 280static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
283static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 281static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
282static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
283static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
284 284
285#define WM8994_DRC_SWITCH(xname, reg, shift) \ 285#define WM8994_DRC_SWITCH(xname, reg, shift) \
286{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 286{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -660,8 +660,52 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
660 eq_tlv), 660 eq_tlv),
661}; 661};
662 662
663static const char *wm8958_ng_text[] = {
664 "30ms", "125ms", "250ms", "500ms",
665};
666
667static const struct soc_enum wm8958_aif1dac1_ng_hold =
668 SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
669 WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
670
671static const struct soc_enum wm8958_aif1dac2_ng_hold =
672 SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
673 WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
674
675static const struct soc_enum wm8958_aif2dac_ng_hold =
676 SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
677 WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
678
663static const struct snd_kcontrol_new wm8958_snd_controls[] = { 679static const struct snd_kcontrol_new wm8958_snd_controls[] = {
664SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 680SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
681
682SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE,
683 WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0),
684SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold),
685SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume",
686 WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT,
687 7, 1, ng_tlv),
688
689SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE,
690 WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0),
691SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold),
692SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume",
693 WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT,
694 7, 1, ng_tlv),
695
696SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE,
697 WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0),
698SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold),
699SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
700 WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT,
701 7, 1, ng_tlv),
702};
703
704static const struct snd_kcontrol_new wm1811_snd_controls[] = {
705SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0,
706 mixin_boost_tlv),
707SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
708 mixin_boost_tlv),
665}; 709};
666 710
667static int clk_sys_event(struct snd_soc_dapm_widget *w, 711static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -681,6 +725,97 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
681 return 0; 725 return 0;
682} 726}
683 727
728static void vmid_reference(struct snd_soc_codec *codec)
729{
730 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
731
732 wm8994->vmid_refcount++;
733
734 dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
735 wm8994->vmid_refcount);
736
737 if (wm8994->vmid_refcount == 1) {
738 /* Startup bias, VMID ramp & buffer */
739 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
740 WM8994_STARTUP_BIAS_ENA |
741 WM8994_VMID_BUF_ENA |
742 WM8994_VMID_RAMP_MASK,
743 WM8994_STARTUP_BIAS_ENA |
744 WM8994_VMID_BUF_ENA |
745 (0x11 << WM8994_VMID_RAMP_SHIFT));
746
747 /* Main bias enable, VMID=2x40k */
748 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
749 WM8994_BIAS_ENA |
750 WM8994_VMID_SEL_MASK,
751 WM8994_BIAS_ENA | 0x2);
752
753 msleep(20);
754 }
755}
756
757static void vmid_dereference(struct snd_soc_codec *codec)
758{
759 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
760
761 wm8994->vmid_refcount--;
762
763 dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
764 wm8994->vmid_refcount);
765
766 if (wm8994->vmid_refcount == 0) {
767 /* Switch over to startup biases */
768 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
769 WM8994_BIAS_SRC |
770 WM8994_STARTUP_BIAS_ENA |
771 WM8994_VMID_BUF_ENA |
772 WM8994_VMID_RAMP_MASK,
773 WM8994_BIAS_SRC |
774 WM8994_STARTUP_BIAS_ENA |
775 WM8994_VMID_BUF_ENA |
776 (1 << WM8994_VMID_RAMP_SHIFT));
777
778 /* Disable main biases */
779 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
780 WM8994_BIAS_ENA |
781 WM8994_VMID_SEL_MASK, 0);
782
783 /* Discharge line */
784 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
785 WM8994_LINEOUT1_DISCH |
786 WM8994_LINEOUT2_DISCH,
787 WM8994_LINEOUT1_DISCH |
788 WM8994_LINEOUT2_DISCH);
789
790 msleep(5);
791
792 /* Switch off startup biases */
793 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
794 WM8994_BIAS_SRC |
795 WM8994_STARTUP_BIAS_ENA |
796 WM8994_VMID_BUF_ENA |
797 WM8994_VMID_RAMP_MASK, 0);
798 }
799}
800
801static int vmid_event(struct snd_soc_dapm_widget *w,
802 struct snd_kcontrol *kcontrol, int event)
803{
804 struct snd_soc_codec *codec = w->codec;
805
806 switch (event) {
807 case SND_SOC_DAPM_PRE_PMU:
808 vmid_reference(codec);
809 break;
810
811 case SND_SOC_DAPM_POST_PMD:
812 vmid_dereference(codec);
813 break;
814 }
815
816 return 0;
817}
818
684static void wm8994_update_class_w(struct snd_soc_codec *codec) 819static void wm8994_update_class_w(struct snd_soc_codec *codec)
685{ 820{
686 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 821 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1208,6 +1343,8 @@ SND_SOC_DAPM_INPUT("Clock"),
1208 1343
1209SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, 1344SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1210 SND_SOC_DAPM_PRE_PMU), 1345 SND_SOC_DAPM_PRE_PMU),
1346SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
1347 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1211 1348
1212SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1349SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1213 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1350 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1282,7 +1419,7 @@ SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1282SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1419SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1283 1420
1284SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1421SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
1285SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1422SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
1286 1423
1287SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1424SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1288 1425
@@ -1525,6 +1662,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1525static const struct snd_soc_dapm_route wm8994_intercon[] = { 1662static const struct snd_soc_dapm_route wm8994_intercon[] = {
1526 { "AIF2DACL", NULL, "AIF2DAC Mux" }, 1663 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1527 { "AIF2DACR", NULL, "AIF2DAC Mux" }, 1664 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1665 { "MICBIAS1", NULL, "VMID" },
1666 { "MICBIAS2", NULL, "VMID" },
1528}; 1667};
1529 1668
1530static const struct snd_soc_dapm_route wm8958_intercon[] = { 1669static const struct snd_soc_dapm_route wm8958_intercon[] = {
@@ -1629,10 +1768,12 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1629 unsigned int freq_in, unsigned int freq_out) 1768 unsigned int freq_in, unsigned int freq_out)
1630{ 1769{
1631 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1770 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1771 struct wm8994 *control = codec->control_data;
1632 int reg_offset, ret; 1772 int reg_offset, ret;
1633 struct fll_div fll; 1773 struct fll_div fll;
1634 u16 reg, aif1, aif2; 1774 u16 reg, aif1, aif2;
1635 unsigned long timeout; 1775 unsigned long timeout;
1776 bool was_enabled;
1636 1777
1637 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) 1778 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1638 & WM8994_AIF1CLK_ENA; 1779 & WM8994_AIF1CLK_ENA;
@@ -1653,6 +1794,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1653 return -EINVAL; 1794 return -EINVAL;
1654 } 1795 }
1655 1796
1797 reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
1798 was_enabled = reg & WM8994_FLL1_ENA;
1799
1656 switch (src) { 1800 switch (src) {
1657 case 0: 1801 case 0:
1658 /* Allow no source specification when stopping */ 1802 /* Allow no source specification when stopping */
@@ -1719,6 +1863,21 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1719 1863
1720 /* Enable (with fractional mode if required) */ 1864 /* Enable (with fractional mode if required) */
1721 if (freq_out) { 1865 if (freq_out) {
1866 /* Enable VMID if we need it */
1867 if (!was_enabled) {
1868 switch (control->type) {
1869 case WM8994:
1870 vmid_reference(codec);
1871 break;
1872 case WM8958:
1873 if (wm8994->revision < 1)
1874 vmid_reference(codec);
1875 break;
1876 default:
1877 break;
1878 }
1879 }
1880
1722 if (fll.k) 1881 if (fll.k)
1723 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; 1882 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
1724 else 1883 else
@@ -1736,6 +1895,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1736 } else { 1895 } else {
1737 msleep(5); 1896 msleep(5);
1738 } 1897 }
1898 } else {
1899 if (was_enabled) {
1900 switch (control->type) {
1901 case WM8994:
1902 vmid_dereference(codec);
1903 break;
1904 case WM8958:
1905 if (wm8994->revision < 1)
1906 vmid_dereference(codec);
1907 break;
1908 default:
1909 break;
1910 }
1911 }
1739 } 1912 }
1740 1913
1741 wm8994->fll[id].in = freq_in; 1914 wm8994->fll[id].in = freq_in;
@@ -1852,9 +2025,6 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1852 break; 2025 break;
1853 2026
1854 case SND_SOC_BIAS_PREPARE: 2027 case SND_SOC_BIAS_PREPARE:
1855 /* VMID=2x40k */
1856 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1857 WM8994_VMID_SEL_MASK, 0x2);
1858 break; 2028 break;
1859 2029
1860 case SND_SOC_BIAS_STANDBY: 2030 case SND_SOC_BIAS_STANDBY:
@@ -1888,6 +2058,15 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1888 WM8958_CP_DISCH); 2058 WM8958_CP_DISCH);
1889 } 2059 }
1890 break; 2060 break;
2061
2062 case WM1811:
2063 if (wm8994->revision < 2) {
2064 snd_soc_write(codec, 0x102, 0x3);
2065 snd_soc_write(codec, 0x5d, 0x7e);
2066 snd_soc_write(codec, 0x5e, 0x0);
2067 snd_soc_write(codec, 0x102, 0x0);
2068 }
2069 break;
1891 } 2070 }
1892 2071
1893 /* Discharge LINEOUT1 & 2 */ 2072 /* Discharge LINEOUT1 & 2 */
@@ -1896,65 +2075,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1896 WM8994_LINEOUT2_DISCH, 2075 WM8994_LINEOUT2_DISCH,
1897 WM8994_LINEOUT1_DISCH | 2076 WM8994_LINEOUT1_DISCH |
1898 WM8994_LINEOUT2_DISCH); 2077 WM8994_LINEOUT2_DISCH);
1899
1900 /* Startup bias, VMID ramp & buffer */
1901 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1902 WM8994_STARTUP_BIAS_ENA |
1903 WM8994_VMID_BUF_ENA |
1904 WM8994_VMID_RAMP_MASK,
1905 WM8994_STARTUP_BIAS_ENA |
1906 WM8994_VMID_BUF_ENA |
1907 (0x11 << WM8994_VMID_RAMP_SHIFT));
1908
1909 /* Main bias enable, VMID=2x40k */
1910 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1911 WM8994_BIAS_ENA |
1912 WM8994_VMID_SEL_MASK,
1913 WM8994_BIAS_ENA | 0x2);
1914
1915 msleep(20);
1916 } 2078 }
1917 2079
1918 /* VMID=2x500k */
1919 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1920 WM8994_VMID_SEL_MASK, 0x4);
1921 2080
1922 break; 2081 break;
1923 2082
1924 case SND_SOC_BIAS_OFF: 2083 case SND_SOC_BIAS_OFF:
1925 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { 2084 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1926 /* Switch over to startup biases */
1927 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1928 WM8994_BIAS_SRC |
1929 WM8994_STARTUP_BIAS_ENA |
1930 WM8994_VMID_BUF_ENA |
1931 WM8994_VMID_RAMP_MASK,
1932 WM8994_BIAS_SRC |
1933 WM8994_STARTUP_BIAS_ENA |
1934 WM8994_VMID_BUF_ENA |
1935 (1 << WM8994_VMID_RAMP_SHIFT));
1936
1937 /* Disable main biases */
1938 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1939 WM8994_BIAS_ENA |
1940 WM8994_VMID_SEL_MASK, 0);
1941
1942 /* Discharge line */
1943 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
1944 WM8994_LINEOUT1_DISCH |
1945 WM8994_LINEOUT2_DISCH,
1946 WM8994_LINEOUT1_DISCH |
1947 WM8994_LINEOUT2_DISCH);
1948
1949 msleep(5);
1950
1951 /* Switch off startup biases */
1952 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1953 WM8994_BIAS_SRC |
1954 WM8994_STARTUP_BIAS_ENA |
1955 WM8994_VMID_BUF_ENA |
1956 WM8994_VMID_RAMP_MASK, 0);
1957
1958 wm8994->cur_fw = NULL; 2085 wm8994->cur_fw = NULL;
1959 2086
1960 pm_runtime_put(codec->dev); 2087 pm_runtime_put(codec->dev);
@@ -2055,10 +2182,18 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2055 2182
2056 /* The AIF2 format configuration needs to be mirrored to AIF3 2183 /* The AIF2 format configuration needs to be mirrored to AIF3
2057 * on WM8958 if it's in use so just do it all the time. */ 2184 * on WM8958 if it's in use so just do it all the time. */
2058 if (control->type == WM8958 && dai->id == 2) 2185 switch (control->type) {
2059 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, 2186 case WM1811:
2060 WM8994_AIF1_LRCLK_INV | 2187 case WM8958:
2061 WM8958_AIF3_FMT_MASK, aif1); 2188 if (dai->id == 2)
2189 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
2190 WM8994_AIF1_LRCLK_INV |
2191 WM8958_AIF3_FMT_MASK, aif1);
2192 break;
2193
2194 default:
2195 break;
2196 }
2062 2197
2063 snd_soc_update_bits(codec, aif1_reg, 2198 snd_soc_update_bits(codec, aif1_reg,
2064 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 2199 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
@@ -2100,7 +2235,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2100 struct snd_soc_dai *dai) 2235 struct snd_soc_dai *dai)
2101{ 2236{
2102 struct snd_soc_codec *codec = dai->codec; 2237 struct snd_soc_codec *codec = dai->codec;
2103 struct wm8994 *control = codec->control_data;
2104 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2105 int aif1_reg; 2239 int aif1_reg;
2106 int aif2_reg; 2240 int aif2_reg;
@@ -2143,14 +2277,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2143 dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); 2277 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
2144 } 2278 }
2145 break; 2279 break;
2146 case 3:
2147 switch (control->type) {
2148 case WM8958:
2149 aif1_reg = WM8958_AIF3_CONTROL_1;
2150 break;
2151 default:
2152 return 0;
2153 }
2154 default: 2280 default:
2155 return -EINVAL; 2281 return -EINVAL;
2156 } 2282 }
@@ -2271,6 +2397,7 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2271 switch (dai->id) { 2397 switch (dai->id) {
2272 case 3: 2398 case 3:
2273 switch (control->type) { 2399 switch (control->type) {
2400 case WM1811:
2274 case WM8958: 2401 case WM8958:
2275 aif1_reg = WM8958_AIF3_CONTROL_1; 2402 aif1_reg = WM8958_AIF3_CONTROL_1;
2276 break; 2403 break;
@@ -2311,7 +2438,7 @@ static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2311 rate_reg = WM8994_AIF1_RATE; 2438 rate_reg = WM8994_AIF1_RATE;
2312 break; 2439 break;
2313 case 2: 2440 case 2:
2314 rate_reg = WM8994_AIF1_RATE; 2441 rate_reg = WM8994_AIF2_RATE;
2315 break; 2442 break;
2316 default: 2443 default:
2317 break; 2444 break;
@@ -2384,6 +2511,21 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
2384 return snd_soc_update_bits(codec, reg, mask, val); 2511 return snd_soc_update_bits(codec, reg, mask, val);
2385} 2512}
2386 2513
2514static int wm8994_aif2_probe(struct snd_soc_dai *dai)
2515{
2516 struct snd_soc_codec *codec = dai->codec;
2517
2518 /* Disable the pulls on the AIF if we're using it to save power. */
2519 snd_soc_update_bits(codec, WM8994_GPIO_3,
2520 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2521 snd_soc_update_bits(codec, WM8994_GPIO_4,
2522 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2523 snd_soc_update_bits(codec, WM8994_GPIO_5,
2524 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2525
2526 return 0;
2527}
2528
2387#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 2529#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
2388 2530
2389#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2531#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -2451,6 +2593,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2451 .rates = WM8994_RATES, 2593 .rates = WM8994_RATES,
2452 .formats = WM8994_FORMATS, 2594 .formats = WM8994_FORMATS,
2453 }, 2595 },
2596 .probe = wm8994_aif2_probe,
2454 .ops = &wm8994_aif2_dai_ops, 2597 .ops = &wm8994_aif2_dai_ops,
2455 }, 2598 },
2456 { 2599 {
@@ -2485,6 +2628,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2485 case WM8994: 2628 case WM8994:
2486 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); 2629 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2487 break; 2630 break;
2631 case WM1811:
2488 case WM8958: 2632 case WM8958:
2489 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2633 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2490 WM8958_MICD_ENA, 0); 2634 WM8958_MICD_ENA, 0);
@@ -2553,6 +2697,7 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2553 snd_soc_update_bits(codec, WM8994_MICBIAS, 2697 snd_soc_update_bits(codec, WM8994_MICBIAS,
2554 WM8994_MICD_ENA, WM8994_MICD_ENA); 2698 WM8994_MICD_ENA, WM8994_MICD_ENA);
2555 break; 2699 break;
2700 case WM1811:
2556 case WM8958: 2701 case WM8958:
2557 if (wm8994->jack_cb) 2702 if (wm8994->jack_cb)
2558 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2703 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -2851,8 +2996,13 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2851 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2996 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2852 struct wm8994 *control = codec->control_data; 2997 struct wm8994 *control = codec->control_data;
2853 2998
2854 if (control->type != WM8958) 2999 switch (control->type) {
3000 case WM1811:
3001 case WM8958:
3002 break;
3003 default:
2855 return -EINVAL; 3004 return -EINVAL;
3005 }
2856 3006
2857 if (jack) { 3007 if (jack) {
2858 if (!cb) { 3008 if (!cb) {
@@ -2916,6 +3066,24 @@ static irqreturn_t wm8994_fifo_error(int irq, void *data)
2916 return IRQ_HANDLED; 3066 return IRQ_HANDLED;
2917} 3067}
2918 3068
3069static irqreturn_t wm8994_temp_warn(int irq, void *data)
3070{
3071 struct snd_soc_codec *codec = data;
3072
3073 dev_err(codec->dev, "Thermal warning\n");
3074
3075 return IRQ_HANDLED;
3076}
3077
3078static irqreturn_t wm8994_temp_shut(int irq, void *data)
3079{
3080 struct snd_soc_codec *codec = data;
3081
3082 dev_crit(codec->dev, "Thermal shutdown\n");
3083
3084 return IRQ_HANDLED;
3085}
3086
2919static int wm8994_codec_probe(struct snd_soc_codec *codec) 3087static int wm8994_codec_probe(struct snd_soc_codec *codec)
2920{ 3088{
2921 struct wm8994 *control; 3089 struct wm8994 *control;
@@ -2972,13 +3140,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2972 switch (wm8994->revision) { 3140 switch (wm8994->revision) {
2973 case 2: 3141 case 2:
2974 case 3: 3142 case 3:
2975 wm8994->hubs.dcs_codes = -5; 3143 wm8994->hubs.dcs_codes_l = -5;
3144 wm8994->hubs.dcs_codes_r = -5;
2976 wm8994->hubs.hp_startup_mode = 1; 3145 wm8994->hubs.hp_startup_mode = 1;
2977 wm8994->hubs.dcs_readback_mode = 1; 3146 wm8994->hubs.dcs_readback_mode = 1;
2978 wm8994->hubs.series_startup = 1; 3147 wm8994->hubs.series_startup = 1;
2979 break; 3148 break;
2980 default: 3149 default:
2981 wm8994->hubs.dcs_readback_mode = 1; 3150 wm8994->hubs.dcs_readback_mode = 2;
2982 break; 3151 break;
2983 } 3152 }
2984 break; 3153 break;
@@ -2987,12 +3156,34 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2987 wm8994->hubs.dcs_readback_mode = 1; 3156 wm8994->hubs.dcs_readback_mode = 1;
2988 break; 3157 break;
2989 3158
3159 case WM1811:
3160 wm8994->hubs.dcs_readback_mode = 2;
3161 wm8994->hubs.no_series_update = 1;
3162
3163 switch (wm8994->revision) {
3164 case 0:
3165 case 1:
3166 wm8994->hubs.dcs_codes_l = -9;
3167 wm8994->hubs.dcs_codes_r = -5;
3168 break;
3169 default:
3170 break;
3171 }
3172
3173 snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
3174 WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
3175 break;
3176
2990 default: 3177 default:
2991 break; 3178 break;
2992 } 3179 }
2993 3180
2994 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, 3181 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
2995 wm8994_fifo_error, "FIFO error", codec); 3182 wm8994_fifo_error, "FIFO error", codec);
3183 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
3184 wm8994_temp_warn, "Thermal warning", codec);
3185 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
3186 wm8994_temp_shut, "Thermal shutdown", codec);
2996 3187
2997 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3188 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
2998 wm_hubs_dcs_done, "DC servo done", 3189 wm_hubs_dcs_done, "DC servo done",
@@ -3043,6 +3234,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3043 break; 3234 break;
3044 3235
3045 case WM8958: 3236 case WM8958:
3237 case WM1811:
3046 if (wm8994->micdet_irq) { 3238 if (wm8994->micdet_irq) {
3047 ret = request_threaded_irq(wm8994->micdet_irq, NULL, 3239 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3048 wm8958_mic_irq, 3240 wm8958_mic_irq,
@@ -3205,6 +3397,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3205 ARRAY_SIZE(wm8994_dac_widgets)); 3397 ARRAY_SIZE(wm8994_dac_widgets));
3206 } 3398 }
3207 break; 3399 break;
3400
3401 case WM1811:
3402 snd_soc_add_controls(codec, wm8958_snd_controls,
3403 ARRAY_SIZE(wm8958_snd_controls));
3404 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3405 ARRAY_SIZE(wm8958_dapm_widgets));
3406 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3407 ARRAY_SIZE(wm8994_lateclk_widgets));
3408 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3409 ARRAY_SIZE(wm8994_adc_widgets));
3410 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3411 ARRAY_SIZE(wm8994_dac_widgets));
3412 break;
3208 } 3413 }
3209 3414
3210 3415
@@ -3241,6 +3446,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3241 3446
3242 wm8958_dsp2_init(codec); 3447 wm8958_dsp2_init(codec);
3243 break; 3448 break;
3449 case WM1811:
3450 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3451 ARRAY_SIZE(wm8994_lateclk_intercon));
3452 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3453 ARRAY_SIZE(wm8958_intercon));
3454 break;
3244 } 3455 }
3245 3456
3246 return 0; 3457 return 0;
@@ -3257,6 +3468,8 @@ err_irq:
3257 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3468 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3258 &wm8994->hubs); 3469 &wm8994->hubs);
3259 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3470 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3471 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3472 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3260err: 3473err:
3261 kfree(wm8994); 3474 kfree(wm8994);
3262 return ret; 3475 return ret;
@@ -3279,6 +3492,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3279 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3492 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3280 &wm8994->hubs); 3493 &wm8994->hubs);
3281 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3494 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3495 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3496 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3282 3497
3283 switch (control->type) { 3498 switch (control->type) {
3284 case WM8994: 3499 case WM8994:
@@ -3292,6 +3507,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3292 wm8994); 3507 wm8994);
3293 break; 3508 break;
3294 3509
3510 case WM1811:
3295 case WM8958: 3511 case WM8958:
3296 if (wm8994->micdet_irq) 3512 if (wm8994->micdet_irq)
3297 free_irq(wm8994->micdet_irq, wm8994); 3513 free_irq(wm8994->micdet_irq, wm8994);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 1ab2266039f7..f4f1355efc82 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -83,6 +83,8 @@ struct wm8994_priv {
83 struct completion fll_locked[2]; 83 struct completion fll_locked[2];
84 bool fll_locked_irq; 84 bool fll_locked_irq;
85 85
86 int vmid_refcount;
87
86 int dac_rates[2]; 88 int dac_rates[2];
87 int lrclk_shared[2]; 89 int lrclk_shared[2];
88 90
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 5ad873fda814..78eeb21e6696 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -485,7 +485,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
485static int configure_clock(struct snd_soc_codec *codec) 485static int configure_clock(struct snd_soc_codec *codec)
486{ 486{
487 struct wm8995_priv *wm8995; 487 struct wm8995_priv *wm8995;
488 int old, new; 488 int change, new;
489 489
490 wm8995 = snd_soc_codec_get_drvdata(codec); 490 wm8995 = snd_soc_codec_get_drvdata(codec);
491 491
@@ -509,15 +509,11 @@ static int configure_clock(struct snd_soc_codec *codec)
509 else 509 else
510 new = 0; 510 new = 0;
511 511
512 old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC; 512 change = snd_soc_update_bits(codec, WM8995_CLOCKING_1,
513 513 WM8995_SYSCLK_SRC_MASK, new);
514 /* If there's no change then we're done. */ 514 if (!change)
515 if (old == new)
516 return 0; 515 return 0;
517 516
518 snd_soc_update_bits(codec, WM8995_CLOCKING_1,
519 WM8995_SYSCLK_SRC_MASK, new);
520
521 snd_soc_dapm_sync(&codec->dapm); 517 snd_soc_dapm_sync(&codec->dapm);
522 518
523 return 0; 519 return 0;
@@ -1573,11 +1569,16 @@ static int wm8995_resume(struct snd_soc_codec *codec)
1573static int wm8995_remove(struct snd_soc_codec *codec) 1569static int wm8995_remove(struct snd_soc_codec *codec)
1574{ 1570{
1575 struct wm8995_priv *wm8995; 1571 struct wm8995_priv *wm8995;
1576 struct i2c_client *i2c; 1572 int i;
1577 1573
1578 i2c = container_of(codec->dev, struct i2c_client, dev);
1579 wm8995 = snd_soc_codec_get_drvdata(codec); 1574 wm8995 = snd_soc_codec_get_drvdata(codec);
1580 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); 1575 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1576
1577 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i)
1578 regulator_unregister_notifier(wm8995->supplies[i].consumer,
1579 &wm8995->disable_nb[i]);
1580
1581 regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1581 return 0; 1582 return 0;
1582} 1583}
1583 1584
@@ -1642,6 +1643,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1642 1643
1643 if (ret != 0x8995) { 1644 if (ret != 0x8995) {
1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret); 1645 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1646 ret = -EINVAL;
1645 goto err_reg_enable; 1647 goto err_reg_enable;
1646 } 1648 }
1647 1649
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 0cdb9d105671..645c980d6b80 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -41,12 +41,11 @@
41#define HPOUT2L 4 41#define HPOUT2L 4
42#define HPOUT2R 8 42#define HPOUT2R 8
43 43
44#define WM8996_NUM_SUPPLIES 4 44#define WM8996_NUM_SUPPLIES 3
45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { 45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
46 "DBVDD", 46 "DBVDD",
47 "AVDD1", 47 "AVDD1",
48 "AVDD2", 48 "AVDD2",
49 "CPVDD",
50}; 49};
51 50
52struct wm8996_priv { 51struct wm8996_priv {
@@ -71,6 +70,8 @@ struct wm8996_priv {
71 70
72 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 71 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
73 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 72 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
73 struct regulator *cpvdd;
74 int bg_ena;
74 75
75 struct wm8996_pdata pdata; 76 struct wm8996_pdata pdata;
76 77
@@ -112,7 +113,6 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
112WM8996_REGULATOR_EVENT(0) 113WM8996_REGULATOR_EVENT(0)
113WM8996_REGULATOR_EVENT(1) 114WM8996_REGULATOR_EVENT(1)
114WM8996_REGULATOR_EVENT(2) 115WM8996_REGULATOR_EVENT(2)
115WM8996_REGULATOR_EVENT(3)
116 116
117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { 117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
118 [WM8996_SOFTWARE_RESET] = 0x8996, 118 [WM8996_SOFTWARE_RESET] = 0x8996,
@@ -414,6 +414,7 @@ static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); 414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); 415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
417static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);
417 418
418static const char *sidetone_hpf_text[] = { 419static const char *sidetone_hpf_text[] = {
419 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" 420 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
@@ -608,6 +609,14 @@ SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
608SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), 609SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
609SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), 610SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
610 611
612SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),
613SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),
614
615SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,
616 0, threedstereo_tlv),
617SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,
618 0, threedstereo_tlv),
619
611SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, 620SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
612 8, 0, out_digital_tlv), 621 8, 0, out_digital_tlv),
613SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, 622SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
@@ -632,6 +641,14 @@ SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,
632 641
633SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), 642SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
634SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), 643SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
644
645SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
646SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
647SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
648
649SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
650SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
651SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
635}; 652};
636 653
637static const struct snd_kcontrol_new wm8996_eq_controls[] = { 654static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -658,19 +675,75 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
658 eq_tlv), 675 eq_tlv),
659}; 676};
660 677
678static void wm8996_bg_enable(struct snd_soc_codec *codec)
679{
680 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
681
682 wm8996->bg_ena++;
683 if (wm8996->bg_ena == 1) {
684 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
685 WM8996_BG_ENA, WM8996_BG_ENA);
686 msleep(2);
687 }
688}
689
690static void wm8996_bg_disable(struct snd_soc_codec *codec)
691{
692 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
693
694 wm8996->bg_ena--;
695 if (!wm8996->bg_ena)
696 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
697 WM8996_BG_ENA, 0);
698}
699
700static int bg_event(struct snd_soc_dapm_widget *w,
701 struct snd_kcontrol *kcontrol, int event)
702{
703 struct snd_soc_codec *codec = w->codec;
704 int ret = 0;
705
706 switch (event) {
707 case SND_SOC_DAPM_PRE_PMU:
708 wm8996_bg_enable(codec);
709 break;
710 case SND_SOC_DAPM_POST_PMD:
711 wm8996_bg_disable(codec);
712 break;
713 default:
714 BUG();
715 ret = -EINVAL;
716 }
717
718 return ret;
719}
720
661static int cp_event(struct snd_soc_dapm_widget *w, 721static int cp_event(struct snd_soc_dapm_widget *w,
662 struct snd_kcontrol *kcontrol, int event) 722 struct snd_kcontrol *kcontrol, int event)
663{ 723{
724 struct snd_soc_codec *codec = w->codec;
725 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
726 int ret = 0;
727
664 switch (event) { 728 switch (event) {
729 case SND_SOC_DAPM_PRE_PMU:
730 ret = regulator_enable(wm8996->cpvdd);
731 if (ret != 0)
732 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
733 ret);
734 break;
665 case SND_SOC_DAPM_POST_PMU: 735 case SND_SOC_DAPM_POST_PMU:
666 msleep(5); 736 msleep(5);
667 break; 737 break;
738 case SND_SOC_DAPM_POST_PMD:
739 regulator_disable_deferred(wm8996->cpvdd, 20);
740 break;
668 default: 741 default:
669 BUG(); 742 BUG();
670 return -EINVAL; 743 ret = -EINVAL;
671 } 744 }
672 745
673 return 0; 746 return ret;
674} 747}
675 748
676static int rmv_short_event(struct snd_soc_dapm_widget *w, 749static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -698,7 +771,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
698{ 771{
699 struct i2c_client *i2c = to_i2c_client(codec->dev); 772 struct i2c_client *i2c = to_i2c_client(codec->dev);
700 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 773 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
701 int i, ret; 774 int ret;
702 unsigned long timeout = 200; 775 unsigned long timeout = 200;
703 776
704 snd_soc_write(codec, WM8996_DC_SERVO_2, mask); 777 snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
@@ -713,15 +786,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
713 786
714 } else { 787 } else {
715 msleep(1); 788 msleep(1);
716 if (--i) { 789 timeout--;
717 timeout = 0;
718 break;
719 }
720 } 790 }
721 791
722 ret = snd_soc_read(codec, WM8996_DC_SERVO_2); 792 ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
723 dev_dbg(codec->dev, "DC servo state: %x\n", ret); 793 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
724 } while (ret & mask); 794 } while (timeout && ret & mask);
725 795
726 if (timeout == 0) 796 if (timeout == 0)
727 dev_err(codec->dev, "DC servo timed out for %x\n", mask); 797 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
@@ -979,9 +1049,12 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
979SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1049SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
980SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1050SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
981SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1051SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
982 SND_SOC_DAPM_POST_PMU), 1052 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
983 1053SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
984SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1055SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
1056SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
1057SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
985SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), 1058SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
986SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), 1059SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
987 1060
@@ -1035,14 +1108,14 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1035SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1108SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1036SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1109SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1037 1110
1038SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, 1111SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
1039 WM8996_POWER_MANAGEMENT_4, 9, 0), 1112 WM8996_POWER_MANAGEMENT_4, 9, 0),
1040SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, 1113SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1,
1041 WM8996_POWER_MANAGEMENT_4, 8, 0), 1114 WM8996_POWER_MANAGEMENT_4, 8, 0),
1042 1115
1043SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, 1116SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1044 WM8996_POWER_MANAGEMENT_6, 9, 0), 1117 WM8996_POWER_MANAGEMENT_6, 9, 0),
1045SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, 1118SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1,
1046 WM8996_POWER_MANAGEMENT_6, 8, 0), 1119 WM8996_POWER_MANAGEMENT_6, 8, 0),
1047 1120
1048SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1121SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
@@ -1137,17 +1210,23 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1137 { "Charge Pump", NULL, "SYSCLK" }, 1210 { "Charge Pump", NULL, "SYSCLK" },
1138 1211
1139 { "MICB1", NULL, "LDO2" }, 1212 { "MICB1", NULL, "LDO2" },
1213 { "MICB1", NULL, "MICB1 Audio" },
1214 { "MICB1", NULL, "Bandgap" },
1140 { "MICB2", NULL, "LDO2" }, 1215 { "MICB2", NULL, "LDO2" },
1216 { "MICB2", NULL, "MICB2 Audio" },
1217 { "MICB2", NULL, "Bandgap" },
1141 1218
1142 { "IN1L PGA", NULL, "IN2LN" }, 1219 { "IN1L PGA", NULL, "IN2LN" },
1143 { "IN1L PGA", NULL, "IN2LP" }, 1220 { "IN1L PGA", NULL, "IN2LP" },
1144 { "IN1L PGA", NULL, "IN1LN" }, 1221 { "IN1L PGA", NULL, "IN1LN" },
1145 { "IN1L PGA", NULL, "IN1LP" }, 1222 { "IN1L PGA", NULL, "IN1LP" },
1223 { "IN1L PGA", NULL, "Bandgap" },
1146 1224
1147 { "IN1R PGA", NULL, "IN2RN" }, 1225 { "IN1R PGA", NULL, "IN2RN" },
1148 { "IN1R PGA", NULL, "IN2RP" }, 1226 { "IN1R PGA", NULL, "IN2RP" },
1149 { "IN1R PGA", NULL, "IN1RN" }, 1227 { "IN1R PGA", NULL, "IN1RN" },
1150 { "IN1R PGA", NULL, "IN1RP" }, 1228 { "IN1R PGA", NULL, "IN1RP" },
1229 { "IN1R PGA", NULL, "Bandgap" },
1151 1230
1152 { "ADCL", NULL, "IN1L PGA" }, 1231 { "ADCL", NULL, "IN1L PGA" },
1153 1232
@@ -1281,6 +1360,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1281 { "DAC2R", NULL, "DAC2R Mixer" }, 1360 { "DAC2R", NULL, "DAC2R Mixer" },
1282 1361
1283 { "HPOUT2L PGA", NULL, "Charge Pump" }, 1362 { "HPOUT2L PGA", NULL, "Charge Pump" },
1363 { "HPOUT2L PGA", NULL, "Bandgap" },
1284 { "HPOUT2L PGA", NULL, "DAC2L" }, 1364 { "HPOUT2L PGA", NULL, "DAC2L" },
1285 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1365 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1286 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1366 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
@@ -1288,6 +1368,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1288 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, 1368 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1289 1369
1290 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1370 { "HPOUT2R PGA", NULL, "Charge Pump" },
1371 { "HPOUT2R PGA", NULL, "Bandgap" },
1291 { "HPOUT2R PGA", NULL, "DAC2R" }, 1372 { "HPOUT2R PGA", NULL, "DAC2R" },
1292 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1373 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1293 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1374 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
@@ -1295,6 +1376,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1295 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, 1376 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1296 1377
1297 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1378 { "HPOUT1L PGA", NULL, "Charge Pump" },
1379 { "HPOUT1L PGA", NULL, "Bandgap" },
1298 { "HPOUT1L PGA", NULL, "DAC1L" }, 1380 { "HPOUT1L PGA", NULL, "DAC1L" },
1299 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1381 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1300 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1382 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
@@ -1302,6 +1384,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1302 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, 1384 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1303 1385
1304 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1386 { "HPOUT1R PGA", NULL, "Charge Pump" },
1387 { "HPOUT1R PGA", NULL, "Bandgap" },
1305 { "HPOUT1R PGA", NULL, "DAC1R" }, 1388 { "HPOUT1R PGA", NULL, "DAC1R" },
1306 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1389 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1307 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1390 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
@@ -1620,14 +1703,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1620 1703
1621 switch (level) { 1704 switch (level) {
1622 case SND_SOC_BIAS_ON: 1705 case SND_SOC_BIAS_ON:
1623 break;
1624
1625 case SND_SOC_BIAS_PREPARE: 1706 case SND_SOC_BIAS_PREPARE:
1626 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1627 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1628 WM8996_BG_ENA, WM8996_BG_ENA);
1629 msleep(2);
1630 }
1631 break; 1707 break;
1632 1708
1633 case SND_SOC_BIAS_STANDBY: 1709 case SND_SOC_BIAS_STANDBY:
@@ -1650,9 +1726,6 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1650 codec->cache_only = false; 1726 codec->cache_only = false;
1651 snd_soc_cache_sync(codec); 1727 snd_soc_cache_sync(codec);
1652 } 1728 }
1653
1654 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1655 WM8996_BG_ENA, 0);
1656 break; 1729 break;
1657 1730
1658 case SND_SOC_BIAS_OFF: 1731 case SND_SOC_BIAS_OFF:
@@ -1847,7 +1920,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
1847 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, 1920 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
1848 lrclk); 1921 lrclk);
1849 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, 1922 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
1850 WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp); 1923 WM8996_DSP1_DIV_MASK << dsp_shift, dsp);
1851 1924
1852 return 0; 1925 return 0;
1853} 1926}
@@ -2041,7 +2114,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2041 struct i2c_client *i2c = to_i2c_client(codec->dev); 2114 struct i2c_client *i2c = to_i2c_client(codec->dev);
2042 struct _fll_div fll_div; 2115 struct _fll_div fll_div;
2043 unsigned long timeout; 2116 unsigned long timeout;
2044 int ret, reg; 2117 int ret, reg, retry;
2045 2118
2046 /* Any change? */ 2119 /* Any change? */
2047 if (source == wm8996->fll_src && Fref == wm8996->fll_fref && 2120 if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
@@ -2057,6 +2130,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2057 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, 2130 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
2058 WM8996_FLL_ENA, 0); 2131 WM8996_FLL_ENA, 0);
2059 2132
2133 wm8996_bg_disable(codec);
2134
2060 return 0; 2135 return 0;
2061 } 2136 }
2062 2137
@@ -2111,6 +2186,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2111 2186
2112 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); 2187 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
2113 2188
2189 /* Enable the bandgap if it's not already enabled */
2190 ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
2191 if (!(ret & WM8996_FLL_ENA))
2192 wm8996_bg_enable(codec);
2193
2114 /* Clear any pending completions (eg, from failed startups) */ 2194 /* Clear any pending completions (eg, from failed startups) */
2115 try_wait_for_completion(&wm8996->fll_lock); 2195 try_wait_for_completion(&wm8996->fll_lock);
2116 2196
@@ -2128,17 +2208,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2128 else 2208 else
2129 timeout = msecs_to_jiffies(2); 2209 timeout = msecs_to_jiffies(2);
2130 2210
2131 /* Allow substantially longer if we've actually got the IRQ */ 2211 /* Allow substantially longer if we've actually got the IRQ, poll
2212 * at a slightly higher rate if we don't.
2213 */
2132 if (i2c->irq) 2214 if (i2c->irq)
2133 timeout *= 1000; 2215 timeout *= 10;
2216 else
2217 timeout /= 2;
2134 2218
2135 ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); 2219 for (retry = 0; retry < 10; retry++) {
2220 ret = wait_for_completion_timeout(&wm8996->fll_lock,
2221 timeout);
2222 if (ret != 0) {
2223 WARN_ON(!i2c->irq);
2224 break;
2225 }
2136 2226
2137 if (ret == 0 && i2c->irq) { 2227 ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
2228 if (ret & WM8996_FLL_LOCK_STS)
2229 break;
2230 }
2231 if (retry == 10) {
2138 dev_err(codec->dev, "Timed out waiting for FLL\n"); 2232 dev_err(codec->dev, "Timed out waiting for FLL\n");
2139 ret = -ETIMEDOUT; 2233 ret = -ETIMEDOUT;
2140 } else {
2141 ret = 0;
2142 } 2234 }
2143 2235
2144 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2236 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
@@ -2297,12 +2389,94 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2297 2389
2298 /* Enable interrupts and we're off */ 2390 /* Enable interrupts and we're off */
2299 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, 2391 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
2300 WM8996_IM_MICD_EINT, 0); 2392 WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
2301 2393
2302 return 0; 2394 return 0;
2303} 2395}
2304EXPORT_SYMBOL_GPL(wm8996_detect); 2396EXPORT_SYMBOL_GPL(wm8996_detect);
2305 2397
2398static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
2399{
2400 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2401 int val, reg, report;
2402
2403 /* Assume headphone in error conditions; we need to report
2404 * something or we stall our state machine.
2405 */
2406 report = SND_JACK_HEADPHONE;
2407
2408 reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
2409 if (reg < 0) {
2410 dev_err(codec->dev, "Failed to read HPDET status\n");
2411 goto out;
2412 }
2413
2414 if (!(reg & WM8996_HP_DONE)) {
2415 dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
2416 goto out;
2417 }
2418
2419 val = reg & WM8996_HP_LVL_MASK;
2420
2421 dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
2422
2423 /* If we've got high enough impedence then report as line,
2424 * otherwise assume headphone.
2425 */
2426 if (val >= 126)
2427 report = SND_JACK_LINEOUT;
2428 else
2429 report = SND_JACK_HEADPHONE;
2430
2431out:
2432 if (wm8996->jack_mic)
2433 report |= SND_JACK_MICROPHONE;
2434
2435 snd_soc_jack_report(wm8996->jack, report,
2436 SND_JACK_LINEOUT | SND_JACK_HEADSET);
2437
2438 wm8996->detecting = false;
2439
2440 /* If the output isn't running re-clamp it */
2441 if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
2442 (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
2443 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2444 WM8996_HPOUT1L_RMV_SHORT |
2445 WM8996_HPOUT1R_RMV_SHORT, 0);
2446
2447 /* Go back to looking at the microphone */
2448 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2449 WM8996_JD_MODE_MASK, 0);
2450 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
2451 WM8996_MICD_ENA);
2452
2453 snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap");
2454 snd_soc_dapm_sync(&codec->dapm);
2455}
2456
2457static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2458{
2459 /* Unclamp the output, we can't measure while we're shorting it */
2460 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2461 WM8996_HPOUT1L_RMV_SHORT |
2462 WM8996_HPOUT1R_RMV_SHORT,
2463 WM8996_HPOUT1L_RMV_SHORT |
2464 WM8996_HPOUT1R_RMV_SHORT);
2465
2466 /* We need bandgap for HPDET */
2467 snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap");
2468 snd_soc_dapm_sync(&codec->dapm);
2469
2470 /* Go into headphone detect left mode */
2471 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
2472 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2473 WM8996_JD_MODE_MASK, 1);
2474
2475 /* Trigger a measurement */
2476 snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
2477 WM8996_HP_POLL, WM8996_HP_POLL);
2478}
2479
2306static void wm8996_micd(struct snd_soc_codec *codec) 2480static void wm8996_micd(struct snd_soc_codec *codec)
2307{ 2481{
2308 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2482 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2323,28 +2497,36 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2323 wm8996->jack_mic = false; 2497 wm8996->jack_mic = false;
2324 wm8996->detecting = true; 2498 wm8996->detecting = true;
2325 snd_soc_jack_report(wm8996->jack, 0, 2499 snd_soc_jack_report(wm8996->jack, 0,
2326 SND_JACK_HEADSET | SND_JACK_BTN_0); 2500 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2501 SND_JACK_BTN_0);
2502
2327 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2503 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2328 WM8996_MICD_RATE_MASK, 2504 WM8996_MICD_RATE_MASK,
2329 WM8996_MICD_RATE_MASK); 2505 WM8996_MICD_RATE_MASK);
2330 return; 2506 return;
2331 } 2507 }
2332 2508
2333 /* If the measurement is very high we've got a microphone but 2509 /* If the measurement is very high we've got a microphone,
2334 * do a little debounce to account for mechanical issues. 2510 * either we just detected one or if we already reported then
2511 * we've got a button release event.
2335 */ 2512 */
2336 if (val & 0x400) { 2513 if (val & 0x400) {
2337 dev_dbg(codec->dev, "Microphone detected\n"); 2514 if (wm8996->detecting) {
2338 snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, 2515 dev_dbg(codec->dev, "Microphone detected\n");
2339 SND_JACK_HEADSET | SND_JACK_BTN_0); 2516 wm8996->jack_mic = true;
2340 wm8996->jack_mic = true; 2517 wm8996_hpdet_start(codec);
2341 wm8996->detecting = false; 2518
2342 2519 /* Increase poll rate to give better responsiveness
2343 /* Increase poll rate to give better responsiveness 2520 * for buttons */
2344 * for buttons */ 2521 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2345 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2522 WM8996_MICD_RATE_MASK,
2346 WM8996_MICD_RATE_MASK, 2523 5 << WM8996_MICD_RATE_SHIFT);
2347 5 << WM8996_MICD_RATE_SHIFT); 2524 } else {
2525 dev_dbg(codec->dev, "Mic button up\n");
2526 snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
2527 }
2528
2529 return;
2348 } 2530 }
2349 2531
2350 /* If we detected a lower impedence during initial startup 2532 /* If we detected a lower impedence during initial startup
@@ -2376,15 +2558,11 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2376 if (val & 0x3fc) { 2558 if (val & 0x3fc) {
2377 if (wm8996->jack_mic) { 2559 if (wm8996->jack_mic) {
2378 dev_dbg(codec->dev, "Mic button detected\n"); 2560 dev_dbg(codec->dev, "Mic button detected\n");
2379 snd_soc_jack_report(wm8996->jack, 2561 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2380 SND_JACK_HEADSET | SND_JACK_BTN_0,
2381 SND_JACK_HEADSET | SND_JACK_BTN_0);
2382 } else {
2383 dev_dbg(codec->dev, "Headphone detected\n");
2384 snd_soc_jack_report(wm8996->jack,
2385 SND_JACK_HEADPHONE,
2386 SND_JACK_HEADSET |
2387 SND_JACK_BTN_0); 2562 SND_JACK_BTN_0);
2563 } else if (wm8996->detecting) {
2564 dev_dbg(codec->dev, "Headphone detected\n");
2565 wm8996_hpdet_start(codec);
2388 2566
2389 /* Increase the detection rate a bit for 2567 /* Increase the detection rate a bit for
2390 * responsiveness. 2568 * responsiveness.
@@ -2392,8 +2570,6 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2392 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2570 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2393 WM8996_MICD_RATE_MASK, 2571 WM8996_MICD_RATE_MASK,
2394 7 << WM8996_MICD_RATE_SHIFT); 2572 7 << WM8996_MICD_RATE_SHIFT);
2395
2396 wm8996->detecting = false;
2397 } 2573 }
2398 } 2574 }
2399} 2575}
@@ -2412,6 +2588,9 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2412 } 2588 }
2413 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); 2589 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
2414 2590
2591 if (!irq_val)
2592 return IRQ_NONE;
2593
2415 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); 2594 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
2416 2595
2417 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { 2596 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
@@ -2430,10 +2609,10 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2430 if (irq_val & WM8996_MICD_EINT) 2609 if (irq_val & WM8996_MICD_EINT)
2431 wm8996_micd(codec); 2610 wm8996_micd(codec);
2432 2611
2433 if (irq_val) 2612 if (irq_val & WM8996_HP_DONE_EINT)
2434 return IRQ_HANDLED; 2613 wm8996_hpdet_irq(codec);
2435 else 2614
2436 return IRQ_NONE; 2615 return IRQ_HANDLED;
2437} 2616}
2438 2617
2439static irqreturn_t wm8996_edge_irq(int irq, void *data) 2618static irqreturn_t wm8996_edge_irq(int irq, void *data)
@@ -2527,7 +2706,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2527 init_completion(&wm8996->fll_lock); 2706 init_completion(&wm8996->fll_lock);
2528 2707
2529 dapm->idle_bias_off = true; 2708 dapm->idle_bias_off = true;
2530 dapm->bias_level = SND_SOC_BIAS_OFF;
2531 2709
2532 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); 2710 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2533 if (ret != 0) { 2711 if (ret != 0) {
@@ -2548,7 +2726,13 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2548 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; 2726 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2549 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; 2727 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2550 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; 2728 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2551 wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; 2729
2730 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2731 if (IS_ERR(wm8996->cpvdd)) {
2732 ret = PTR_ERR(wm8996->cpvdd);
2733 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2734 goto err_get;
2735 }
2552 2736
2553 /* This should really be moved into the regulator core */ 2737 /* This should really be moved into the regulator core */
2554 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { 2738 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
@@ -2565,7 +2749,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2565 wm8996->supplies); 2749 wm8996->supplies);
2566 if (ret != 0) { 2750 if (ret != 0) {
2567 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 2751 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2568 goto err_get; 2752 goto err_cpvdd;
2569 } 2753 }
2570 2754
2571 if (wm8996->pdata.ldo_ena >= 0) { 2755 if (wm8996->pdata.ldo_ena >= 0) {
@@ -2808,6 +2992,8 @@ err_enable:
2808 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 2992 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
2809 2993
2810 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2994 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2995err_cpvdd:
2996 regulator_put(wm8996->cpvdd);
2811err_get: 2997err_get:
2812 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2998 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2813err: 2999err:
@@ -2831,6 +3017,7 @@ static int wm8996_remove(struct snd_soc_codec *codec)
2831 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3017 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
2832 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3018 regulator_unregister_notifier(wm8996->supplies[i].consumer,
2833 &wm8996->disable_nb[i]); 3019 &wm8996->disable_nb[i]);
3020 regulator_put(wm8996->cpvdd);
2834 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3021 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2835 3022
2836 return 0; 3023 return 0;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a4691321f9b3..3cd35a02c28c 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -157,7 +157,6 @@ static struct {
157 157
158struct wm9081_priv { 158struct wm9081_priv {
159 enum snd_soc_control_type control_type; 159 enum snd_soc_control_type control_type;
160 void *control_data;
161 int sysclk_source; 160 int sysclk_source;
162 int mclk_rate; 161 int mclk_rate;
163 int sysclk_rate; 162 int sysclk_rate;
@@ -174,6 +173,7 @@ static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int re
174{ 173{
175 switch (reg) { 174 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 175 case WM9081_SOFTWARE_RESET:
176 case WM9081_INTERRUPT_STATUS:
177 return 1; 177 return 1;
178 default: 178 default:
179 return 0; 179 return 0;
@@ -820,7 +820,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
820 /* VMID 2*240k */ 820 /* VMID 2*240k */
821 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); 821 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
822 reg &= ~WM9081_VMID_SEL_MASK; 822 reg &= ~WM9081_VMID_SEL_MASK;
823 reg |= 0x40; 823 reg |= 0x04;
824 snd_soc_write(codec, WM9081_VMID_CONTROL, reg); 824 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
825 825
826 /* Standby bias current on */ 826 /* Standby bias current on */
@@ -1120,8 +1120,8 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1120 return 0; 1120 return 0;
1121} 1121}
1122 1122
1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1124 int clk_id, unsigned int freq, int dir) 1124 int source, unsigned int freq, int dir)
1125{ 1125{
1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1127 1127
@@ -1213,7 +1213,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1213 int ret; 1213 int ret;
1214 u16 reg; 1214 u16 reg;
1215 1215
1216 codec->control_data = wm9081->control_data;
1217 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); 1216 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
1218 if (ret != 0) { 1217 if (ret != 0) {
1219 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1218 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -1250,8 +1249,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1250 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, 1249 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1251 reg | WM9081_SPKPGAZC); 1250 reg | WM9081_SPKPGAZC);
1252 1251
1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1254 ARRAY_SIZE(wm9081_snd_controls));
1255 if (!wm9081->pdata.num_retune_configs) { 1252 if (!wm9081->pdata.num_retune_configs) {
1256 dev_dbg(codec->dev, 1253 dev_dbg(codec->dev,
1257 "No ReTune Mobile data, using normal EQ\n"); 1254 "No ReTune Mobile data, using normal EQ\n");
@@ -1311,6 +1308,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1311 .reg_cache_default = wm9081_reg_defaults, 1308 .reg_cache_default = wm9081_reg_defaults,
1312 .volatile_register = wm9081_volatile_register, 1309 .volatile_register = wm9081_volatile_register,
1313 1310
1311 .controls = wm9081_snd_controls,
1312 .num_controls = ARRAY_SIZE(wm9081_snd_controls),
1314 .dapm_widgets = wm9081_dapm_widgets, 1313 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), 1314 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths, 1315 .dapm_routes = wm9081_audio_paths,
@@ -1330,7 +1329,6 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1330 1329
1331 i2c_set_clientdata(i2c, wm9081); 1330 i2c_set_clientdata(i2c, wm9081);
1332 wm9081->control_type = SND_SOC_I2C; 1331 wm9081->control_type = SND_SOC_I2C;
1333 wm9081->control_data = i2c;
1334 1332
1335 if (dev_get_platdata(&i2c->dev)) 1333 if (dev_get_platdata(&i2c->dev))
1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), 1334 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 4de12203e611..2b5252c9e377 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -139,9 +139,7 @@ static const u16 wm9090_reg_defaults[] = {
139 139
140/* This struct is used to save the context */ 140/* This struct is used to save the context */
141struct wm9090_priv { 141struct wm9090_priv {
142 struct mutex mutex;
143 struct wm9090_platform_data pdata; 142 struct wm9090_platform_data pdata;
144 void *control_data;
145}; 143};
146 144
147static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) 145static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
@@ -550,10 +548,8 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
550 548
551static int wm9090_probe(struct snd_soc_codec *codec) 549static int wm9090_probe(struct snd_soc_codec *codec)
552{ 550{
553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
554 int ret; 551 int ret;
555 552
556 codec->control_data = wm9090->control_data;
557 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 553 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
558 if (ret != 0) { 554 if (ret != 0) {
559 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -662,8 +658,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
662 sizeof(wm9090->pdata)); 658 sizeof(wm9090->pdata));
663 659
664 i2c_set_clientdata(i2c, wm9090); 660 i2c_set_clientdata(i2c, wm9090);
665 wm9090->control_data = i2c;
666 mutex_init(&wm9090->mutex);
667 661
668 ret = snd_soc_register_codec(&i2c->dev, 662 ret = snd_soc_register_codec(&i2c->dev,
669 &soc_codec_dev_wm9090, NULL, 0); 663 &soc_codec_dev_wm9090, NULL, 0);
@@ -684,6 +678,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
684 678
685static const struct i2c_device_id wm9090_id[] = { 679static const struct i2c_device_id wm9090_id[] = {
686 { "wm9090", 0 }, 680 { "wm9090", 0 },
681 { "wm9093", 0 },
687 { } 682 { }
688}; 683};
689MODULE_DEVICE_TABLE(i2c, wm9090_id); 684MODULE_DEVICE_TABLE(i2c, wm9090_id);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e763c54c55dc..84f33d4ea2cd 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mfd/wm8994/registers.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
116{ 117{
117 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 118 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
118 s8 offset; 119 s8 offset;
119 u16 reg, reg_l, reg_r, dcs_cfg; 120 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
121
122 switch (hubs->dcs_readback_mode) {
123 case 2:
124 dcs_reg = WM8994_DC_SERVO_4E;
125 break;
126 default:
127 dcs_reg = WM8993_DC_SERVO_3;
128 break;
129 }
120 130
121 /* If we're using a digital only path and have a previously 131 /* If we're using a digital only path and have a previously
122 * callibrated DC servo offset stored then use that. */ 132 * callibrated DC servo offset stored then use that. */
123 if (hubs->class_w && hubs->class_w_dcs) { 133 if (hubs->class_w && hubs->class_w_dcs) {
124 dev_dbg(codec->dev, "Using cached DC servo offset %x\n", 134 dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
125 hubs->class_w_dcs); 135 hubs->class_w_dcs);
126 snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); 136 snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
127 wait_for_dc_servo(codec, 137 wait_for_dc_servo(codec,
128 WM8993_DCS_TRIG_DAC_WR_0 | 138 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1); 139 WM8993_DCS_TRIG_DAC_WR_1);
@@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
154 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) 164 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
155 & WM8993_DCS_INTEG_CHAN_1_MASK; 165 & WM8993_DCS_INTEG_CHAN_1_MASK;
156 break; 166 break;
167 case 2:
157 case 1: 168 case 1:
158 reg = snd_soc_read(codec, WM8993_DC_SERVO_3); 169 reg = snd_soc_read(codec, dcs_reg);
159 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) 170 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
160 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; 171 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
161 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; 172 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
168 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 179 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
169 180
170 /* Apply correction to DC servo result */ 181 /* Apply correction to DC servo result */
171 if (hubs->dcs_codes) { 182 if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
172 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 183 dev_dbg(codec->dev,
173 hubs->dcs_codes); 184 "Applying %d/%d code DC servo correction\n",
185 hubs->dcs_codes_l, hubs->dcs_codes_r);
174 186
175 /* HPOUT1R */ 187 /* HPOUT1R */
176 offset = reg_r; 188 offset = reg_r;
177 offset += hubs->dcs_codes; 189 offset += hubs->dcs_codes_r;
178 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 190 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
179 191
180 /* HPOUT1L */ 192 /* HPOUT1L */
181 offset = reg_l; 193 offset = reg_l;
182 offset += hubs->dcs_codes; 194 offset += hubs->dcs_codes_l;
183 dcs_cfg |= (u8)offset; 195 dcs_cfg |= (u8)offset;
184 196
185 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); 197 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
186 198
187 /* Do it */ 199 /* Do it */
188 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 200 snd_soc_write(codec, dcs_reg, dcs_cfg);
189 wait_for_dc_servo(codec, 201 wait_for_dc_servo(codec,
190 WM8993_DCS_TRIG_DAC_WR_0 | 202 WM8993_DCS_TRIG_DAC_WR_0 |
191 WM8993_DCS_TRIG_DAC_WR_1); 203 WM8993_DCS_TRIG_DAC_WR_1);
@@ -210,14 +222,14 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
210 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 222 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
211 int ret; 223 int ret;
212 224
213 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 225 ret = snd_soc_put_volsw(kcontrol, ucontrol);
214 226
215 /* Updating the analogue gains invalidates the DC servo cache */ 227 /* Updating the analogue gains invalidates the DC servo cache */
216 hubs->class_w_dcs = 0; 228 hubs->class_w_dcs = 0;
217 229
218 /* If we're applying an offset correction then updating the 230 /* If we're applying an offset correction then updating the
219 * callibration would be likely to introduce further offsets. */ 231 * callibration would be likely to introduce further offsets. */
220 if (hubs->dcs_codes || hubs->no_series_update) 232 if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
221 return ret; 233 return ret;
222 234
223 /* Only need to do this if the outputs are active */ 235 /* Only need to do this if the outputs are active */
@@ -350,19 +362,11 @@ SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
350SOC_ENUM("Speaker Reference", speaker_ref), 362SOC_ENUM("Speaker Reference", speaker_ref),
351SOC_ENUM("Speaker Mode", speaker_mode), 363SOC_ENUM("Speaker Mode", speaker_mode),
352 364
353{ 365SOC_DOUBLE_R_EXT_TLV("Headphone Volume",
354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Headphone Volume", 366 WM8993_LEFT_OUTPUT_VOLUME, WM8993_RIGHT_OUTPUT_VOLUME,
355 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | 367 0, 63, 0, snd_soc_get_volsw, wm8993_put_dc_servo,
356 SNDRV_CTL_ELEM_ACCESS_READWRITE, 368 outpga_tlv),
357 .tlv.p = outpga_tlv, 369
358 .info = snd_soc_info_volsw_2r,
359 .get = snd_soc_get_volsw_2r, .put = wm8993_put_dc_servo,
360 .private_value = (unsigned long)&(struct soc_mixer_control) {
361 .reg = WM8993_LEFT_OUTPUT_VOLUME,
362 .rreg = WM8993_RIGHT_OUTPUT_VOLUME,
363 .shift = 0, .max = 63
364 },
365},
366SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME, 370SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME,
367 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0), 371 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0),
368SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME, 372SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME,
@@ -699,6 +703,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
699 { "IN1L PGA", "IN1LP Switch", "IN1LP" }, 703 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
700 { "IN1L PGA", "IN1LN Switch", "IN1LN" }, 704 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
701 705
706 { "IN1L PGA", NULL, "VMID" },
707 { "IN1R PGA", NULL, "VMID" },
708 { "IN2L PGA", NULL, "VMID" },
709 { "IN2R PGA", NULL, "VMID" },
710
702 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 711 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
703 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 712 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
704 713
@@ -716,12 +725,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
716 { "MIXINL", NULL, "Direct Voice" }, 725 { "MIXINL", NULL, "Direct Voice" },
717 { "MIXINL", NULL, "IN1LP" }, 726 { "MIXINL", NULL, "IN1LP" },
718 { "MIXINL", NULL, "Left Output Mixer" }, 727 { "MIXINL", NULL, "Left Output Mixer" },
728 { "MIXINL", NULL, "VMID" },
719 729
720 { "MIXINR", "IN1R Switch", "IN1R PGA" }, 730 { "MIXINR", "IN1R Switch", "IN1R PGA" },
721 { "MIXINR", "IN2R Switch", "IN2R PGA" }, 731 { "MIXINR", "IN2R Switch", "IN2R PGA" },
722 { "MIXINR", NULL, "Direct Voice" }, 732 { "MIXINR", NULL, "Direct Voice" },
723 { "MIXINR", NULL, "IN1RP" }, 733 { "MIXINR", NULL, "IN1RP" },
724 { "MIXINR", NULL, "Right Output Mixer" }, 734 { "MIXINR", NULL, "Right Output Mixer" },
735 { "MIXINR", NULL, "VMID" },
725 736
726 { "ADCL", NULL, "MIXINL" }, 737 { "ADCL", NULL, "MIXINL" },
727 { "ADCR", NULL, "MIXINR" }, 738 { "ADCR", NULL, "MIXINR" },
@@ -752,6 +763,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
752 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" }, 763 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
753 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" }, 764 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
754 765
766 { "Earpiece Driver", NULL, "VMID" },
755 { "Earpiece Driver", NULL, "Earpiece Mixer" }, 767 { "Earpiece Driver", NULL, "Earpiece Mixer" },
756 { "HPOUT2N", NULL, "Earpiece Driver" }, 768 { "HPOUT2N", NULL, "Earpiece Driver" },
757 { "HPOUT2P", NULL, "Earpiece Driver" }, 769 { "HPOUT2P", NULL, "Earpiece Driver" },
@@ -774,9 +786,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
774 { "SPKR Boost", "SPKR Switch", "SPKR" }, 786 { "SPKR Boost", "SPKR Switch", "SPKR" },
775 { "SPKR Boost", "SPKL Switch", "SPKL" }, 787 { "SPKR Boost", "SPKL Switch", "SPKL" },
776 788
789 { "SPKL Driver", NULL, "VMID" },
777 { "SPKL Driver", NULL, "SPKL Boost" }, 790 { "SPKL Driver", NULL, "SPKL Boost" },
778 { "SPKL Driver", NULL, "CLK_SYS" }, 791 { "SPKL Driver", NULL, "CLK_SYS" },
779 792
793 { "SPKR Driver", NULL, "VMID" },
780 { "SPKR Driver", NULL, "SPKR Boost" }, 794 { "SPKR Driver", NULL, "SPKR Boost" },
781 { "SPKR Driver", NULL, "CLK_SYS" }, 795 { "SPKR Driver", NULL, "CLK_SYS" },
782 796
@@ -790,12 +804,18 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
790 804
791 { "Headphone PGA", NULL, "Left Headphone Mux" }, 805 { "Headphone PGA", NULL, "Left Headphone Mux" },
792 { "Headphone PGA", NULL, "Right Headphone Mux" }, 806 { "Headphone PGA", NULL, "Right Headphone Mux" },
807 { "Headphone PGA", NULL, "VMID" },
793 { "Headphone PGA", NULL, "CLK_SYS" }, 808 { "Headphone PGA", NULL, "CLK_SYS" },
794 { "Headphone PGA", NULL, "Headphone Supply" }, 809 { "Headphone PGA", NULL, "Headphone Supply" },
795 810
796 { "HPOUT1L", NULL, "Headphone PGA" }, 811 { "HPOUT1L", NULL, "Headphone PGA" },
797 { "HPOUT1R", NULL, "Headphone PGA" }, 812 { "HPOUT1R", NULL, "Headphone PGA" },
798 813
814 { "LINEOUT1N Driver", NULL, "VMID" },
815 { "LINEOUT1P Driver", NULL, "VMID" },
816 { "LINEOUT2N Driver", NULL, "VMID" },
817 { "LINEOUT2P Driver", NULL, "VMID" },
818
799 { "LINEOUT1N", NULL, "LINEOUT1N Driver" }, 819 { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
800 { "LINEOUT1P", NULL, "LINEOUT1P Driver" }, 820 { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
801 { "LINEOUT2N", NULL, "LINEOUT2N Driver" }, 821 { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 676b1252ab91..c674c7a502a6 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,7 +23,8 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
23 23
24/* This *must* be the first element of the codec->private_data struct */ 24/* This *must* be the first element of the codec->private_data struct */
25struct wm_hubs_data { 25struct wm_hubs_data {
26 int dcs_codes; 26 int dcs_codes_l;
27 int dcs_codes_r;
27 int dcs_readback_mode; 28 int dcs_readback_mode;
28 int hp_startup_mode; 29 int hp_startup_mode;
29 int series_startup; 30 int series_startup;
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index fe7984221eb9..f78c3f0f280c 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -150,8 +150,6 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
150 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 150 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
151 snd_soc_dapm_enable_pin(dapm, "Line In"); 151 snd_soc_dapm_enable_pin(dapm, "Line In");
152 152
153 snd_soc_dapm_sync(dapm);
154
155 return 0; 153 return 0;
156} 154}
157 155
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index d0d60b8a54d4..300e12118c00 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -265,6 +265,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); 265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
266 unsigned int pcr; 266 unsigned int pcr;
267 unsigned int srgr; 267 unsigned int srgr;
268 bool inv_fs = false;
268 /* Attention srgr is updated by hw_params! */ 269 /* Attention srgr is updated by hw_params! */
269 srgr = DAVINCI_MCBSP_SRGR_FSGM | 270 srgr = DAVINCI_MCBSP_SRGR_FSGM |
270 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | 271 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
@@ -330,7 +331,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
330 * more empty bit clock slots between channels as the sample 331 * more empty bit clock slots between channels as the sample
331 * rate is lowered. 332 * rate is lowered.
332 */ 333 */
333 fmt ^= SND_SOC_DAIFMT_NB_IF; 334 inv_fs = true;
334 case SND_SOC_DAIFMT_DSP_A: 335 case SND_SOC_DAIFMT_DSP_A:
335 dev->mode = MOD_DSP_A; 336 dev->mode = MOD_DSP_A;
336 break; 337 break;
@@ -394,6 +395,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
394 default: 395 default:
395 return -EINVAL; 396 return -EINVAL;
396 } 397 }
398 if (inv_fs == true)
399 pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
397 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); 400 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
398 dev->pcr = pcr; 401 dev->pcr = pcr;
399 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); 402 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 8566238db2a5..7173df254a91 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -732,16 +732,19 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
732 davinci_hw_param(dev, substream->stream); 732 davinci_hw_param(dev, substream->stream);
733 733
734 switch (params_format(params)) { 734 switch (params_format(params)) {
735 case SNDRV_PCM_FORMAT_U8:
735 case SNDRV_PCM_FORMAT_S8: 736 case SNDRV_PCM_FORMAT_S8:
736 dma_params->data_type = 1; 737 dma_params->data_type = 1;
737 word_length = DAVINCI_AUDIO_WORD_8; 738 word_length = DAVINCI_AUDIO_WORD_8;
738 break; 739 break;
739 740
741 case SNDRV_PCM_FORMAT_U16_LE:
740 case SNDRV_PCM_FORMAT_S16_LE: 742 case SNDRV_PCM_FORMAT_S16_LE:
741 dma_params->data_type = 2; 743 dma_params->data_type = 2;
742 word_length = DAVINCI_AUDIO_WORD_16; 744 word_length = DAVINCI_AUDIO_WORD_16;
743 break; 745 break;
744 746
747 case SNDRV_PCM_FORMAT_U32_LE:
745 case SNDRV_PCM_FORMAT_S32_LE: 748 case SNDRV_PCM_FORMAT_S32_LE:
746 dma_params->data_type = 4; 749 dma_params->data_type = 4;
747 word_length = DAVINCI_AUDIO_WORD_32; 750 word_length = DAVINCI_AUDIO_WORD_32;
@@ -818,6 +821,13 @@ static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
818 821
819}; 822};
820 823
824#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
825 SNDRV_PCM_FMTBIT_U8 | \
826 SNDRV_PCM_FMTBIT_S16_LE | \
827 SNDRV_PCM_FMTBIT_U16_LE | \
828 SNDRV_PCM_FMTBIT_S32_LE | \
829 SNDRV_PCM_FMTBIT_U32_LE)
830
821static struct snd_soc_dai_driver davinci_mcasp_dai[] = { 831static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
822 { 832 {
823 .name = "davinci-mcasp.0", 833 .name = "davinci-mcasp.0",
@@ -825,17 +835,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
825 .channels_min = 2, 835 .channels_min = 2,
826 .channels_max = 2, 836 .channels_max = 2,
827 .rates = DAVINCI_MCASP_RATES, 837 .rates = DAVINCI_MCASP_RATES,
828 .formats = SNDRV_PCM_FMTBIT_S8 | 838 .formats = DAVINCI_MCASP_PCM_FMTS,
829 SNDRV_PCM_FMTBIT_S16_LE |
830 SNDRV_PCM_FMTBIT_S32_LE,
831 }, 839 },
832 .capture = { 840 .capture = {
833 .channels_min = 2, 841 .channels_min = 2,
834 .channels_max = 2, 842 .channels_max = 2,
835 .rates = DAVINCI_MCASP_RATES, 843 .rates = DAVINCI_MCASP_RATES,
836 .formats = SNDRV_PCM_FMTBIT_S8 | 844 .formats = DAVINCI_MCASP_PCM_FMTS,
837 SNDRV_PCM_FMTBIT_S16_LE |
838 SNDRV_PCM_FMTBIT_S32_LE,
839 }, 845 },
840 .ops = &davinci_mcasp_dai_ops, 846 .ops = &davinci_mcasp_dai_ops,
841 847
@@ -846,7 +852,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
846 .channels_min = 1, 852 .channels_min = 1,
847 .channels_max = 384, 853 .channels_max = 384,
848 .rates = DAVINCI_MCASP_RATES, 854 .rates = DAVINCI_MCASP_RATES,
849 .formats = SNDRV_PCM_FMTBIT_S16_LE, 855 .formats = DAVINCI_MCASP_PCM_FMTS,
850 }, 856 },
851 .ops = &davinci_mcasp_dai_ops, 857 .ops = &davinci_mcasp_dai_ops,
852 }, 858 },
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a49e667373bc..d5fe08cc5db7 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
180{ 180{
181 struct davinci_runtime_data *prtd = substream->runtime->private_data; 181 struct davinci_runtime_data *prtd = substream->runtime->private_data;
182 struct snd_pcm_runtime *runtime = substream->runtime; 182 struct snd_pcm_runtime *runtime = substream->runtime;
183 int link = prtd->asp_link[0];
184 unsigned int period_size; 183 unsigned int period_size;
185 unsigned int dma_offset; 184 unsigned int dma_offset;
186 dma_addr_t dma_pos; 185 dma_addr_t dma_pos;
@@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
198 fifo_level = prtd->params->fifo_level; 197 fifo_level = prtd->params->fifo_level;
199 198
200 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 199 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
201 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); 200 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
201 period_size);
202 202
203 data_type = prtd->params->data_type; 203 data_type = prtd->params->data_type;
204 count = period_size / data_type; 204 count = period_size / data_type;
@@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
222 } 222 }
223 223
224 acnt = prtd->params->acnt; 224 acnt = prtd->params->acnt;
225 edma_set_src(link, src, INCR, W8BIT); 225 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
226 edma_set_dest(link, dst, INCR, W8BIT); 226 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
227 227
228 edma_set_src_index(link, src_bidx, src_cidx); 228 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
229 edma_set_dest_index(link, dst_bidx, dst_cidx); 229 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
230 230
231 if (!fifo_level) 231 if (!fifo_level)
232 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); 232 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
233 ASYNC);
233 else 234 else
234 edma_set_transfer_params(link, acnt, fifo_level, count, 235 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
235 fifo_level, ABSYNC); 236 count, fifo_level,
237 ABSYNC);
236} 238}
237 239
238static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
@@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
305 unsigned int acnt = params->acnt; 307 unsigned int acnt = params->acnt;
306 /* divide by 2 for ping/pong */ 308 /* divide by 2 for ping/pong */
307 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; 309 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
308 int link = prtd->asp_link[1];
309 unsigned int fifo_level = prtd->params->fifo_level; 310 unsigned int fifo_level = prtd->params->fifo_level;
310 unsigned int count; 311 unsigned int count;
311 if ((data_type == 0) || (data_type > 4)) { 312 if ((data_type == 0) || (data_type > 4)) {
@@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
316 dma_addr_t asp_src_pong = iram_dma->addr + ping_size; 317 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
317 ram_src_cidx = ping_size; 318 ram_src_cidx = ping_size;
318 ram_dst_cidx = -ping_size; 319 ram_dst_cidx = -ping_size;
319 edma_set_src(link, asp_src_pong, INCR, W8BIT); 320 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
320 321
321 link = prtd->asp_link[0]; 322 edma_set_src_index(prtd->asp_link[0], data_type,
322 edma_set_src_index(link, data_type, data_type * fifo_level); 323 data_type * fifo_level);
323 link = prtd->asp_link[1]; 324 edma_set_src_index(prtd->asp_link[1], data_type,
324 edma_set_src_index(link, data_type, data_type * fifo_level); 325 data_type * fifo_level);
325 326
326 link = prtd->ram_link; 327 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
327 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
328 } else { 328 } else {
329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; 329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
330 ram_src_cidx = -ping_size; 330 ram_src_cidx = -ping_size;
331 ram_dst_cidx = ping_size; 331 ram_dst_cidx = ping_size;
332 edma_set_dest(link, asp_dst_pong, INCR, W8BIT); 332 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
333 333
334 link = prtd->asp_link[0]; 334 edma_set_dest_index(prtd->asp_link[0], data_type,
335 edma_set_dest_index(link, data_type, data_type * fifo_level); 335 data_type * fifo_level);
336 link = prtd->asp_link[1]; 336 edma_set_dest_index(prtd->asp_link[1], data_type,
337 edma_set_dest_index(link, data_type, data_type * fifo_level); 337 data_type * fifo_level);
338 338
339 link = prtd->ram_link; 339 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
340 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
341 } 340 }
342 341
343 if (!fifo_level) { 342 if (!fifo_level) {
@@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
354 count, fifo_level, ABSYNC); 353 count, fifo_level, ABSYNC);
355 } 354 }
356 355
357 link = prtd->ram_link; 356 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
358 edma_set_src_index(link, ping_size, ram_src_cidx); 357 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
359 edma_set_dest_index(link, ping_size, ram_dst_cidx); 358 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
360 edma_set_transfer_params(link, ping_size, 2,
361 runtime->periods, 2, ASYNC); 359 runtime->periods, 2, ASYNC);
362 360
363 /* init master params */ 361 /* init master params */
@@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
406{ 404{
407 dma_addr_t asp_src_ping; 405 dma_addr_t asp_src_ping;
408 dma_addr_t asp_dst_ping; 406 dma_addr_t asp_dst_ping;
409 int link; 407 int ret;
410 struct davinci_pcm_dma_params *params = prtd->params; 408 struct davinci_pcm_dma_params *params = prtd->params;
411 409
412 /* Request ram master channel */ 410 /* Request ram master channel */
413 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, 411 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
414 davinci_pcm_dma_irq, substream, 412 davinci_pcm_dma_irq, substream,
415 prtd->params->ram_chan_q); 413 prtd->params->ram_chan_q);
416 if (link < 0) 414 if (ret < 0)
417 goto exit1; 415 goto exit1;
418 416
419 /* Request ram link channel */ 417 /* Request ram link channel */
420 link = prtd->ram_link = edma_alloc_slot( 418 ret = prtd->ram_link = edma_alloc_slot(
421 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 419 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
422 if (link < 0) 420 if (ret < 0)
423 goto exit2; 421 goto exit2;
424 422
425 link = prtd->asp_link[1] = edma_alloc_slot( 423 ret = prtd->asp_link[1] = edma_alloc_slot(
426 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 424 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
427 if (link < 0) 425 if (ret < 0)
428 goto exit3; 426 goto exit3;
429 427
430 prtd->ram_link2 = -1; 428 prtd->ram_link2 = -1;
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
432 link = prtd->ram_link2 = edma_alloc_slot( 430 ret = prtd->ram_link2 = edma_alloc_slot(
433 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 431 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
434 if (link < 0) 432 if (ret < 0)
435 goto exit4; 433 goto exit4;
436 } 434 }
437 /* circle ping-pong buffers */ 435 /* circle ping-pong buffers */
@@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
448 asp_dst_ping = iram_dma->addr; 446 asp_dst_ping = iram_dma->addr;
449 } 447 }
450 /* ping */ 448 /* ping */
451 link = prtd->asp_link[0]; 449 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
452 edma_set_src(link, asp_src_ping, INCR, W16BIT); 450 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
453 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 451 edma_set_src_index(prtd->asp_link[0], 0, 0);
454 edma_set_src_index(link, 0, 0); 452 edma_set_dest_index(prtd->asp_link[0], 0, 0);
455 edma_set_dest_index(link, 0, 0);
456 453
457 edma_read_slot(link, &prtd->asp_params); 454 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
458 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); 455 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
459 prtd->asp_params.opt |= TCCHEN | 456 prtd->asp_params.opt |= TCCHEN |
460 EDMA_TCC(prtd->ram_channel & 0x3f); 457 EDMA_TCC(prtd->ram_channel & 0x3f);
461 edma_write_slot(link, &prtd->asp_params); 458 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
462 459
463 /* pong */ 460 /* pong */
464 link = prtd->asp_link[1]; 461 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
465 edma_set_src(link, asp_src_ping, INCR, W16BIT); 462 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
466 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 463 edma_set_src_index(prtd->asp_link[1], 0, 0);
467 edma_set_src_index(link, 0, 0); 464 edma_set_dest_index(prtd->asp_link[1], 0, 0);
468 edma_set_dest_index(link, 0, 0);
469 465
470 edma_read_slot(link, &prtd->asp_params); 466 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
471 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); 467 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
472 /* interrupt after every pong completion */ 468 /* interrupt after every pong completion */
473 prtd->asp_params.opt |= TCINTEN | TCCHEN | 469 prtd->asp_params.opt |= TCINTEN | TCCHEN |
474 EDMA_TCC(prtd->ram_channel & 0x3f); 470 EDMA_TCC(prtd->ram_channel & 0x3f);
475 edma_write_slot(link, &prtd->asp_params); 471 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
476 472
477 /* ram */ 473 /* ram */
478 link = prtd->ram_link; 474 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
479 edma_set_src(link, iram_dma->addr, INCR, W32BIT); 475 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
480 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
481 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," 476 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
482 "for asp:%u %u %u\n", __func__, 477 "for asp:%u %u %u\n", __func__,
483 prtd->ram_channel, prtd->ram_link, prtd->ram_link2, 478 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
@@ -494,7 +489,7 @@ exit2:
494 edma_free_channel(prtd->ram_channel); 489 edma_free_channel(prtd->ram_channel);
495 prtd->ram_channel = -1; 490 prtd->ram_channel = -1;
496exit1: 491exit1:
497 return link; 492 return ret;
498} 493}
499 494
500static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
@@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
502 struct snd_dma_buffer *iram_dma; 497 struct snd_dma_buffer *iram_dma;
503 struct davinci_runtime_data *prtd = substream->runtime->private_data; 498 struct davinci_runtime_data *prtd = substream->runtime->private_data;
504 struct davinci_pcm_dma_params *params = prtd->params; 499 struct davinci_pcm_dma_params *params = prtd->params;
505 int link; 500 int ret;
506 501
507 if (!params) 502 if (!params)
508 return -ENODEV; 503 return -ENODEV;
509 504
510 /* Request asp master DMA channel */ 505 /* Request asp master DMA channel */
511 link = prtd->asp_channel = edma_alloc_channel(params->channel, 506 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
512 davinci_pcm_dma_irq, substream, 507 davinci_pcm_dma_irq, substream,
513 prtd->params->asp_chan_q); 508 prtd->params->asp_chan_q);
514 if (link < 0) 509 if (ret < 0)
515 goto exit1; 510 goto exit1;
516 511
517 /* Request asp link channels */ 512 /* Request asp link channels */
518 link = prtd->asp_link[0] = edma_alloc_slot( 513 ret = prtd->asp_link[0] = edma_alloc_slot(
519 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 514 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
520 if (link < 0) 515 if (ret < 0)
521 goto exit2; 516 goto exit2;
522 517
523 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; 518 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
@@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
537 * the buffer and its length (ccnt) ... use it as a template 532 * the buffer and its length (ccnt) ... use it as a template
538 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 533 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
539 */ 534 */
540 edma_read_slot(link, &prtd->asp_params); 535 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
541 prtd->asp_params.opt |= TCINTEN | 536 prtd->asp_params.opt |= TCINTEN |
542 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); 537 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
543 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; 538 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
544 edma_write_slot(link, &prtd->asp_params); 539 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
545 return 0; 540 return 0;
546exit2: 541exit2:
547 edma_free_channel(prtd->asp_channel); 542 edma_free_channel(prtd->asp_channel);
548 prtd->asp_channel = -1; 543 prtd->asp_channel = -1;
549exit1: 544exit1:
550 return link; 545 return ret;
551} 546}
552 547
553static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index d3aa15119d26..0134d4e9131c 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -28,12 +28,6 @@
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include "ep93xx-pcm.h" 29#include "ep93xx-pcm.h"
30 30
31#define edb93xx_has_audio() (machine_is_edb9301() || \
32 machine_is_edb9302() || \
33 machine_is_edb9302a() || \
34 machine_is_edb9307a() || \
35 machine_is_edb9315a())
36
37static int edb93xx_hw_params(struct snd_pcm_substream *substream, 31static int edb93xx_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
39{ 33{
@@ -94,49 +88,61 @@ static struct snd_soc_card snd_soc_edb93xx = {
94 .num_links = 1, 88 .num_links = 1,
95}; 89};
96 90
97static struct platform_device *edb93xx_snd_device; 91static int __devinit edb93xx_probe(struct platform_device *pdev)
98
99static int __init edb93xx_init(void)
100{ 92{
93 struct snd_soc_card *card = &snd_soc_edb93xx;
101 int ret; 94 int ret;
102 95
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 96 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 97 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL); 98 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret) 99 if (ret)
110 return ret; 100 return ret;
111 101
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1); 102 card->dev = &pdev->dev;
113 if (!edb93xx_snd_device) { 103
114 ret = -ENOMEM; 104 ret = snd_soc_register_card(card);
115 goto free_i2s; 105 if (ret) {
106 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
107 ret);
108 ep93xx_i2s_release();
116 } 109 }
117 110
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx); 111 return ret;
119 ret = platform_device_add(edb93xx_snd_device); 112}
120 if (ret)
121 goto device_put;
122 113
123 return 0; 114static int __devexit edb93xx_remove(struct platform_device *pdev)
115{
116 struct snd_soc_card *card = platform_get_drvdata(pdev);
124 117
125device_put: 118 snd_soc_unregister_card(card);
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release(); 119 ep93xx_i2s_release();
129 return ret; 120
121 return 0;
122}
123
124static struct platform_driver edb93xx_driver = {
125 .driver = {
126 .name = "edb93xx-audio",
127 .owner = THIS_MODULE,
128 },
129 .probe = edb93xx_probe,
130 .remove = __devexit_p(edb93xx_remove),
131};
132
133static int __init edb93xx_init(void)
134{
135 return platform_driver_register(&edb93xx_driver);
130} 136}
131module_init(edb93xx_init); 137module_init(edb93xx_init);
132 138
133static void __exit edb93xx_exit(void) 139static void __exit edb93xx_exit(void)
134{ 140{
135 platform_device_unregister(edb93xx_snd_device); 141 platform_driver_unregister(&edb93xx_driver);
136 ep93xx_i2s_release();
137} 142}
138module_exit(edb93xx_exit); 143module_exit(edb93xx_exit);
139 144
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 145MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx"); 146MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL"); 147MODULE_LICENSE("GPL");
148MODULE_ALIAS("platform:edb93xx-audio");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index c7417c76552b..3cd6158d83e1 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -335,7 +335,7 @@ static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
335 .trigger = ep93xx_ac97_trigger, 335 .trigger = ep93xx_ac97_trigger,
336}; 336};
337 337
338struct snd_soc_dai_driver ep93xx_ac97_dai = { 338static struct snd_soc_dai_driver ep93xx_ac97_dai = {
339 .name = "ep93xx-ac97", 339 .name = "ep93xx-ac97",
340 .id = 0, 340 .id = 0,
341 .ac97_control = 1, 341 .ac97_control = 1,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 8dfd3ad84b19..d00230a591b1 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -355,3 +355,4 @@ module_exit(ep93xx_soc_platform_exit);
355MODULE_AUTHOR("Ryan Mallon"); 355MODULE_AUTHOR("Ryan Mallon");
356MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); 356MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
357MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
358MODULE_ALIAS("platform:ep93xx-pcm-audio");
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c
index 286817946c56..968cb316d511 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/ep93xx/simone.c
@@ -39,53 +39,61 @@ static struct snd_soc_card snd_soc_simone = {
39}; 39};
40 40
41static struct platform_device *simone_snd_ac97_device; 41static struct platform_device *simone_snd_ac97_device;
42static struct platform_device *simone_snd_device;
43 42
44static int __init simone_init(void) 43static int __devinit simone_probe(struct platform_device *pdev)
45{ 44{
45 struct snd_soc_card *card = &snd_soc_simone;
46 int ret; 46 int ret;
47 47
48 if (!machine_is_sim_one()) 48 simone_snd_ac97_device = platform_device_register_simple("ac97-codec",
49 return -ENODEV; 49 -1, NULL, 0);
50 50 if (IS_ERR(simone_snd_ac97_device))
51 simone_snd_ac97_device = platform_device_alloc("ac97-codec", -1); 51 return PTR_ERR(simone_snd_ac97_device);
52 if (!simone_snd_ac97_device)
53 return -ENOMEM;
54 52
55 ret = platform_device_add(simone_snd_ac97_device); 53 card->dev = &pdev->dev;
56 if (ret)
57 goto fail1;
58 54
59 simone_snd_device = platform_device_alloc("soc-audio", -1); 55 ret = snd_soc_register_card(card);
60 if (!simone_snd_device) { 56 if (ret) {
61 ret = -ENOMEM; 57 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
62 goto fail2; 58 ret);
59 platform_device_unregister(simone_snd_ac97_device);
63 } 60 }
64 61
65 platform_set_drvdata(simone_snd_device, &snd_soc_simone); 62 return ret;
66 ret = platform_device_add(simone_snd_device); 63}
67 if (ret) 64
68 goto fail3; 65static int __devexit simone_remove(struct platform_device *pdev)
66{
67 struct snd_soc_card *card = platform_get_drvdata(pdev);
68
69 snd_soc_unregister_card(card);
70 platform_device_unregister(simone_snd_ac97_device);
69 71
70 return 0; 72 return 0;
73}
71 74
72fail3: 75static struct platform_driver simone_driver = {
73 platform_device_put(simone_snd_device); 76 .driver = {
74fail2: 77 .name = "simone-audio",
75 platform_device_del(simone_snd_ac97_device); 78 .owner = THIS_MODULE,
76fail1: 79 },
77 platform_device_put(simone_snd_ac97_device); 80 .probe = simone_probe,
78 return ret; 81 .remove = __devexit_p(simone_remove),
82};
83
84static int __init simone_init(void)
85{
86 return platform_driver_register(&simone_driver);
79} 87}
80module_init(simone_init); 88module_init(simone_init);
81 89
82static void __exit simone_exit(void) 90static void __exit simone_exit(void)
83{ 91{
84 platform_device_unregister(simone_snd_device); 92 platform_driver_unregister(&simone_driver);
85 platform_device_unregister(simone_snd_ac97_device);
86} 93}
87module_exit(simone_exit); 94module_exit(simone_exit);
88 95
89MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); 96MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
90MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); 97MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
91MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
99MODULE_ALIAS("platform:simone-audio");
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index c8aa8a5003ca..f74ac54c285a 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -104,37 +104,56 @@ static struct snd_soc_card snd_soc_snappercl15 = {
104 .num_links = 1, 104 .num_links = 1,
105}; 105};
106 106
107static struct platform_device *snappercl15_snd_device; 107static int __devinit snappercl15_probe(struct platform_device *pdev)
108
109static int __init snappercl15_init(void)
110{ 108{
109 struct snd_soc_card *card = &snd_soc_snappercl15;
111 int ret; 110 int ret;
112 111
113 if (!machine_is_snapper_cl15())
114 return -ENODEV;
115
116 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 112 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
117 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 113 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
118 EP93XX_SYSCON_I2SCLKDIV_SPOL); 114 EP93XX_SYSCON_I2SCLKDIV_SPOL);
119 if (ret) 115 if (ret)
120 return ret; 116 return ret;
121 117
122 snappercl15_snd_device = platform_device_alloc("soc-audio", -1); 118 card->dev = &pdev->dev;
123 if (!snappercl15_snd_device) 119
124 return -ENOMEM; 120 ret = snd_soc_register_card(card);
125 121 if (ret) {
126 platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); 122 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
127 ret = platform_device_add(snappercl15_snd_device); 123 ret);
128 if (ret) 124 ep93xx_i2s_release();
129 platform_device_put(snappercl15_snd_device); 125 }
130 126
131 return ret; 127 return ret;
132} 128}
133 129
134static void __exit snappercl15_exit(void) 130static int __devexit snappercl15_remove(struct platform_device *pdev)
135{ 131{
136 platform_device_unregister(snappercl15_snd_device); 132 struct snd_soc_card *card = platform_get_drvdata(pdev);
133
134 snd_soc_unregister_card(card);
137 ep93xx_i2s_release(); 135 ep93xx_i2s_release();
136
137 return 0;
138}
139
140static struct platform_driver snappercl15_driver = {
141 .driver = {
142 .name = "snappercl15-audio",
143 .owner = THIS_MODULE,
144 },
145 .probe = snappercl15_probe,
146 .remove = __devexit_p(snappercl15_remove),
147};
148
149static int __init snappercl15_init(void)
150{
151 return platform_driver_register(&snappercl15_driver);
152}
153
154static void __exit snappercl15_exit(void)
155{
156 platform_driver_unregister(&snappercl15_driver);
138} 157}
139 158
140module_init(snappercl15_init); 159module_init(snappercl15_init);
@@ -143,4 +162,4 @@ module_exit(snappercl15_exit);
143MODULE_AUTHOR("Ryan Mallon"); 162MODULE_AUTHOR("Ryan Mallon");
144MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); 163MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
145MODULE_LICENSE("GPL"); 164MODULE_LICENSE("GPL");
146 165MODULE_ALIAS("platform:snappercl15-audio");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index cb50598338e9..ef15402a3bc4 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -297,7 +297,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) 297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
298{ 298{
299 struct snd_card *card = rtd->card->snd_card; 299 struct snd_card *card = rtd->card->snd_card;
300 struct snd_soc_dai *dai = rtd->cpu_dai;
301 struct snd_pcm *pcm = rtd->pcm; 300 struct snd_pcm *pcm = rtd->pcm;
302 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); 301 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
303 int ret; 302 int ret;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d48afea5d93d..0268cf989736 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -78,7 +78,6 @@
78 * @second_stream: pointer to second stream 78 * @second_stream: pointer to second stream
79 * @playback: the number of playback streams opened 79 * @playback: the number of playback streams opened
80 * @capture: the number of capture streams opened 80 * @capture: the number of capture streams opened
81 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
82 * @cpu_dai: the CPU DAI for this device 81 * @cpu_dai: the CPU DAI for this device
83 * @dev_attr: the sysfs device attribute structure 82 * @dev_attr: the sysfs device attribute structure
84 * @stats: SSI statistics 83 * @stats: SSI statistics
@@ -90,9 +89,6 @@ struct fsl_ssi_private {
90 unsigned int irq; 89 unsigned int irq;
91 struct snd_pcm_substream *first_stream; 90 struct snd_pcm_substream *first_stream;
92 struct snd_pcm_substream *second_stream; 91 struct snd_pcm_substream *second_stream;
93 unsigned int playback;
94 unsigned int capture;
95 int asynchronous;
96 unsigned int fifo_depth; 92 unsigned int fifo_depth;
97 struct snd_soc_dai_driver cpu_dai_drv; 93 struct snd_soc_dai_driver cpu_dai_drv;
98 struct device_attribute dev_attr; 94 struct device_attribute dev_attr;
@@ -281,24 +277,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
281 struct snd_soc_dai *dai) 277 struct snd_soc_dai *dai)
282{ 278{
283 struct snd_soc_pcm_runtime *rtd = substream->private_data; 279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 280 struct fsl_ssi_private *ssi_private =
281 snd_soc_dai_get_drvdata(rtd->cpu_dai);
282 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
285 283
286 /* 284 /*
287 * If this is the first stream opened, then request the IRQ 285 * If this is the first stream opened, then request the IRQ
288 * and initialize the SSI registers. 286 * and initialize the SSI registers.
289 */ 287 */
290 if (!ssi_private->playback && !ssi_private->capture) { 288 if (!ssi_private->first_stream) {
291 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 289 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
292 int ret; 290
293 291 ssi_private->first_stream = substream;
294 /* The 'name' should not have any slashes in it. */
295 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
296 ssi_private->name, ssi_private);
297 if (ret < 0) {
298 dev_err(substream->pcm->card->dev,
299 "could not claim irq %u\n", ssi_private->irq);
300 return ret;
301 }
302 292
303 /* 293 /*
304 * Section 16.5 of the MPC8610 reference manual says that the 294 * Section 16.5 of the MPC8610 reference manual says that the
@@ -316,7 +306,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
316 clrsetbits_be32(&ssi->scr, 306 clrsetbits_be32(&ssi->scr,
317 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
318 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
319 | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN)); 309 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
320 310
321 out_be32(&ssi->stcr, 311 out_be32(&ssi->stcr,
322 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
@@ -333,7 +323,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
333 * master. 323 * master.
334 */ 324 */
335 325
336 /* 4. Enable the interrupts and DMA requests */ 326 /* Enable the interrupts and DMA requests */
337 out_be32(&ssi->sier, SIER_FLAGS); 327 out_be32(&ssi->sier, SIER_FLAGS);
338 328
339 /* 329 /*
@@ -362,58 +352,47 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
362 * this is bad is because at this point, the PCM driver has not 352 * this is bad is because at this point, the PCM driver has not
363 * finished initializing the DMA controller. 353 * finished initializing the DMA controller.
364 */ 354 */
365 } 355 } else {
356 if (synchronous) {
357 struct snd_pcm_runtime *first_runtime =
358 ssi_private->first_stream->runtime;
359 /*
360 * This is the second stream open, and we're in
361 * synchronous mode, so we need to impose sample
362 * sample size constraints. This is because STCCR is
363 * used for playback and capture in synchronous mode,
364 * so there's no way to specify different word
365 * lengths.
366 *
367 * Note that this can cause a race condition if the
368 * second stream is opened before the first stream is
369 * fully initialized. We provide some protection by
370 * checking to make sure the first stream is
371 * initialized, but it's not perfect. ALSA sometimes
372 * re-initializes the driver with a different sample
373 * rate or size. If the second stream is opened
374 * before the first stream has received its final
375 * parameters, then the second stream may be
376 * constrained to the wrong sample rate or size.
377 */
378 if (!first_runtime->sample_bits) {
379 dev_err(substream->pcm->card->dev,
380 "set sample size in %s stream first\n",
381 substream->stream ==
382 SNDRV_PCM_STREAM_PLAYBACK
383 ? "capture" : "playback");
384 return -EAGAIN;
385 }
366 386
367 if (!ssi_private->first_stream)
368 ssi_private->first_stream = substream;
369 else {
370 /* This is the second stream open, so we need to impose sample
371 * rate and maybe sample size constraints. Note that this can
372 * cause a race condition if the second stream is opened before
373 * the first stream is fully initialized.
374 *
375 * We provide some protection by checking to make sure the first
376 * stream is initialized, but it's not perfect. ALSA sometimes
377 * re-initializes the driver with a different sample rate or
378 * size. If the second stream is opened before the first stream
379 * has received its final parameters, then the second stream may
380 * be constrained to the wrong sample rate or size.
381 *
382 * FIXME: This code does not handle opening and closing streams
383 * repeatedly. If you open two streams and then close the first
384 * one, you may not be able to open another stream until you
385 * close the second one as well.
386 */
387 struct snd_pcm_runtime *first_runtime =
388 ssi_private->first_stream->runtime;
389
390 if (!first_runtime->sample_bits) {
391 dev_err(substream->pcm->card->dev,
392 "set sample size in %s stream first\n",
393 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
394 ? "capture" : "playback");
395 return -EAGAIN;
396 }
397
398 /* If we're in synchronous mode, then we need to constrain
399 * the sample size as well. We don't support independent sample
400 * rates in asynchronous mode.
401 */
402 if (!ssi_private->asynchronous)
403 snd_pcm_hw_constraint_minmax(substream->runtime, 387 snd_pcm_hw_constraint_minmax(substream->runtime,
404 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 388 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
405 first_runtime->sample_bits, 389 first_runtime->sample_bits,
406 first_runtime->sample_bits); 390 first_runtime->sample_bits);
391 }
407 392
408 ssi_private->second_stream = substream; 393 ssi_private->second_stream = substream;
409 } 394 }
410 395
411 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
412 ssi_private->playback++;
413
414 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
415 ssi_private->capture++;
416
417 return 0; 396 return 0;
418} 397}
419 398
@@ -434,24 +413,35 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) 413 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
435{ 414{
436 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 415 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
416 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
417 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
437 421
438 if (substream == ssi_private->first_stream) { 422 /*
439 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 423 * If we're in synchronous mode, and the SSI is already enabled,
440 unsigned int sample_size = 424 * then STCCR is already set properly.
441 snd_pcm_format_width(params_format(hw_params)); 425 */
442 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 426 if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
427 return 0;
443 428
444 /* The SSI should always be disabled at this points (SSIEN=0) */ 429 /*
430 * FIXME: The documentation says that SxCCR[WL] should not be
431 * modified while the SSI is enabled. The only time this can
432 * happen is if we're trying to do simultaneous playback and
433 * capture in asynchronous mode. Unfortunately, I have been enable
434 * to get that to work at all on the P1022DS. Therefore, we don't
435 * bother to disable/enable the SSI when setting SxCCR[WL], because
436 * the SSI will stop anyway. Maybe one day, this will get fixed.
437 */
445 438
446 /* In synchronous mode, the SSI uses STCCR for capture */ 439 /* In synchronous mode, the SSI uses STCCR for capture */
447 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
448 !ssi_private->asynchronous) 441 ssi_private->cpu_dai_drv.symmetric_rates)
449 clrsetbits_be32(&ssi->stccr, 442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
450 CCSR_SSI_SxCCR_WL_MASK, wl); 443 else
451 else 444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
452 clrsetbits_be32(&ssi->srccr,
453 CCSR_SSI_SxCCR_WL_MASK, wl);
454 }
455 445
456 return 0; 446 return 0;
457} 447}
@@ -474,7 +464,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
474 464
475 switch (cmd) { 465 switch (cmd) {
476 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
477 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
478 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
480 setbits32(&ssi->scr, 469 setbits32(&ssi->scr,
@@ -510,27 +499,18 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
511 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 500 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
512 501
513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
514 ssi_private->playback--;
515
516 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
517 ssi_private->capture--;
518
519 if (ssi_private->first_stream == substream) 502 if (ssi_private->first_stream == substream)
520 ssi_private->first_stream = ssi_private->second_stream; 503 ssi_private->first_stream = ssi_private->second_stream;
521 504
522 ssi_private->second_stream = NULL; 505 ssi_private->second_stream = NULL;
523 506
524 /* 507 /*
525 * If this is the last active substream, disable the SSI and release 508 * If this is the last active substream, disable the SSI.
526 * the IRQ.
527 */ 509 */
528 if (!ssi_private->playback && !ssi_private->capture) { 510 if (!ssi_private->first_stream) {
529 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
530 512
531 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
532
533 free_irq(ssi_private->irq, ssi_private);
534 } 514 }
535} 515}
536 516
@@ -675,22 +655,33 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
675 ret = of_address_to_resource(np, 0, &res); 655 ret = of_address_to_resource(np, 0, &res);
676 if (ret) { 656 if (ret) {
677 dev_err(&pdev->dev, "could not determine device resources\n"); 657 dev_err(&pdev->dev, "could not determine device resources\n");
678 kfree(ssi_private); 658 goto error_kmalloc;
679 return ret;
680 } 659 }
681 ssi_private->ssi = of_iomap(np, 0); 660 ssi_private->ssi = of_iomap(np, 0);
682 if (!ssi_private->ssi) { 661 if (!ssi_private->ssi) {
683 dev_err(&pdev->dev, "could not map device resources\n"); 662 dev_err(&pdev->dev, "could not map device resources\n");
684 kfree(ssi_private); 663 ret = -ENOMEM;
685 return -ENOMEM; 664 goto error_kmalloc;
686 } 665 }
687 ssi_private->ssi_phys = res.start; 666 ssi_private->ssi_phys = res.start;
667
688 ssi_private->irq = irq_of_parse_and_map(np, 0); 668 ssi_private->irq = irq_of_parse_and_map(np, 0);
669 if (ssi_private->irq == NO_IRQ) {
670 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
671 ret = -ENXIO;
672 goto error_iomap;
673 }
674
675 /* The 'name' should not have any slashes in it. */
676 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
677 ssi_private);
678 if (ret < 0) {
679 dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
680 goto error_irqmap;
681 }
689 682
690 /* Are the RX and the TX clocks locked? */ 683 /* Are the RX and the TX clocks locked? */
691 if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) 684 if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
692 ssi_private->asynchronous = 1;
693 else
694 ssi_private->cpu_dai_drv.symmetric_rates = 1; 685 ssi_private->cpu_dai_drv.symmetric_rates = 1;
695 686
696 /* Determine the FIFO depth. */ 687 /* Determine the FIFO depth. */
@@ -711,7 +702,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
711 if (ret) { 702 if (ret) {
712 dev_err(&pdev->dev, "could not create sysfs %s file\n", 703 dev_err(&pdev->dev, "could not create sysfs %s file\n",
713 ssi_private->dev_attr.attr.name); 704 ssi_private->dev_attr.attr.name);
714 goto error; 705 goto error_irq;
715 } 706 }
716 707
717 /* Register with ASoC */ 708 /* Register with ASoC */
@@ -720,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
720 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); 711 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
721 if (ret) { 712 if (ret) {
722 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 713 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
723 goto error; 714 goto error_dev;
724 } 715 }
725 716
726 /* Trigger the machine driver's probe function. The platform driver 717 /* Trigger the machine driver's probe function. The platform driver
@@ -741,18 +732,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
741 if (IS_ERR(ssi_private->pdev)) { 732 if (IS_ERR(ssi_private->pdev)) {
742 ret = PTR_ERR(ssi_private->pdev); 733 ret = PTR_ERR(ssi_private->pdev);
743 dev_err(&pdev->dev, "failed to register platform: %d\n", ret); 734 dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
744 goto error; 735 goto error_dai;
745 } 736 }
746 737
747 return 0; 738 return 0;
748 739
749error: 740error_dai:
750 snd_soc_unregister_dai(&pdev->dev); 741 snd_soc_unregister_dai(&pdev->dev);
742
743error_dev:
751 dev_set_drvdata(&pdev->dev, NULL); 744 dev_set_drvdata(&pdev->dev, NULL);
752 if (dev_attr) 745 device_remove_file(&pdev->dev, dev_attr);
753 device_remove_file(&pdev->dev, dev_attr); 746
747error_irq:
748 free_irq(ssi_private->irq, ssi_private);
749
750error_irqmap:
754 irq_dispose_mapping(ssi_private->irq); 751 irq_dispose_mapping(ssi_private->irq);
752
753error_iomap:
755 iounmap(ssi_private->ssi); 754 iounmap(ssi_private->ssi);
755
756error_kmalloc:
756 kfree(ssi_private); 757 kfree(ssi_private);
757 758
758 return ret; 759 return ret;
@@ -766,6 +767,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
766 snd_soc_unregister_dai(&pdev->dev); 767 snd_soc_unregister_dai(&pdev->dev);
767 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 768 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
768 769
770 free_irq(ssi_private->irq, ssi_private);
771 irq_dispose_mapping(ssi_private->irq);
772
769 kfree(ssi_private); 773 kfree(ssi_private);
770 dev_set_drvdata(&pdev->dev, NULL); 774 dev_set_drvdata(&pdev->dev, NULL);
771 775
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 358f0baaf71b..31af405bda84 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -505,7 +505,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
505 return 0; 505 return 0;
506 506
507error_sound: 507error_sound:
508 platform_device_unregister(sound_device); 508 platform_device_put(sound_device);
509error: 509error:
510 kfree(machine_data); 510 kfree(machine_data);
511error_alloc: 511error_alloc:
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index fcb862eb0c73..2c064a9824ad 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -267,7 +267,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
267 if (bus < 0) 267 if (bus < 0)
268 return bus; 268 return bus;
269 269
270 snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr); 270 snprintf(buf, len, "%s.%u-%04x", temp, bus, addr);
271 271
272 return 0; 272 return 0;
273} 273}
@@ -506,7 +506,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
506 506
507error: 507error:
508 if (sound_device) 508 if (sound_device)
509 platform_device_unregister(sound_device); 509 platform_device_put(sound_device);
510 510
511 kfree(mdata); 511 kfree(mdata);
512error_put: 512error_put:
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index bb699bb55a50..b133bfcc5848 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -29,7 +29,7 @@ config SND_MXC_SOC_WM1133_EV1
29config SND_SOC_MX27VIS_AIC32X4 29config SND_SOC_MX27VIS_AIC32X4
30 tristate "SoC audio support for Visstrim M10 boards" 30 tristate "SoC audio support for Visstrim M10 boards"
31 depends on MACH_IMX27_VISSTRIM_M10 31 depends on MACH_IMX27_VISSTRIM_M10
32 select SND_SOC_TVL320AIC32X4 32 select SND_SOC_TLV320AIC32X4
33 select SND_MXC_SOC_MX2 33 select SND_MXC_SOC_MX2
34 help 34 help
35 Say Y if you want to add support for SoC audio on Visstrim SM10 35 Say Y if you want to add support for SoC audio on Visstrim SM10
@@ -50,6 +50,7 @@ config SND_SOC_EUKREA_TLV320
50 || MACH_EUKREA_MBIMXSD25_BASEBOARD \ 50 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
51 || MACH_EUKREA_MBIMXSD35_BASEBOARD \ 51 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
52 || MACH_EUKREA_MBIMXSD51_BASEBOARD 52 || MACH_EUKREA_MBIMXSD51_BASEBOARD
53 depends on I2C
53 select SND_SOC_TLV320AIC23 54 select SND_SOC_TLV320AIC23
54 select SND_MXC_SOC_FIQ 55 select SND_MXC_SOC_FIQ
55 help 56 help
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index 7945625e0e08..8df0fae21943 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -240,25 +240,23 @@ static int ssi_irq = 0;
240 240
241static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) 241static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
242{ 242{
243 struct snd_soc_dai *dai = rtd->cpu_dai;
244 struct snd_pcm *pcm = rtd->pcm; 243 struct snd_pcm *pcm = rtd->pcm;
244 struct snd_pcm_substream *substream;
245 int ret; 245 int ret;
246 246
247 ret = imx_pcm_new(rtd); 247 ret = imx_pcm_new(rtd);
248 if (ret) 248 if (ret)
249 return ret; 249 return ret;
250 250
251 if (dai->driver->playback.channels_min) { 251 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
252 struct snd_pcm_substream *substream = 252 if (substream) {
253 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
254 struct snd_dma_buffer *buf = &substream->dma_buffer; 253 struct snd_dma_buffer *buf = &substream->dma_buffer;
255 254
256 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; 255 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
257 } 256 }
258 257
259 if (dai->driver->capture.channels_min) { 258 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
260 struct snd_pcm_substream *substream = 259 if (substream) {
261 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
262 struct snd_dma_buffer *buf = &substream->dma_buffer; 260 struct snd_dma_buffer *buf = &substream->dma_buffer;
263 261
264 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area; 262 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 10a8e2783751..4c05e2b8f4d2 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -357,8 +357,8 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
357 struct snd_pcm_runtime *runtime = substream->runtime; 357 struct snd_pcm_runtime *runtime = substream->runtime;
358 int ret; 358 int ret;
359 359
360 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area, 360 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
361 runtime->dma_addr, runtime->dma_bytes); 361 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
362 362
363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
364 runtime->dma_area, 364 runtime->dma_area,
@@ -391,7 +391,6 @@ static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
391int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) 391int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
392{ 392{
393 struct snd_card *card = rtd->card->snd_card; 393 struct snd_card *card = rtd->card->snd_card;
394 struct snd_soc_dai *dai = rtd->cpu_dai;
395 struct snd_pcm *pcm = rtd->pcm; 394 struct snd_pcm *pcm = rtd->pcm;
396 int ret = 0; 395 int ret = 0;
397 396
@@ -399,14 +398,14 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
399 card->dev->dma_mask = &imx_pcm_dmamask; 398 card->dev->dma_mask = &imx_pcm_dmamask;
400 if (!card->dev->coherent_dma_mask) 399 if (!card->dev->coherent_dma_mask)
401 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 400 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
402 if (dai->driver->playback.channels_min) { 401 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
403 ret = imx_pcm_preallocate_dma_buffer(pcm, 402 ret = imx_pcm_preallocate_dma_buffer(pcm,
404 SNDRV_PCM_STREAM_PLAYBACK); 403 SNDRV_PCM_STREAM_PLAYBACK);
405 if (ret) 404 if (ret)
406 goto out; 405 goto out;
407 } 406 }
408 407
409 if (dai->driver->capture.channels_min) { 408 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
410 ret = imx_pcm_preallocate_dma_buffer(pcm, 409 ret = imx_pcm_preallocate_dma_buffer(pcm,
411 SNDRV_PCM_STREAM_CAPTURE); 410 SNDRV_PCM_STREAM_CAPTURE);
412 if (ret) 411 if (ret)
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 0a84cec3599e..1072dfb53e47 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -218,12 +218,6 @@ struct imx_ssi {
218 struct platform_device *soc_platform_pdev_fiq; 218 struct platform_device *soc_platform_pdev_fiq;
219}; 219};
220 220
221struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
222 struct imx_ssi *ssi);
223void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi);
224struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
225 struct imx_ssi *ssi);
226
227int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); 221int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
228int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); 222int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
229void imx_pcm_free(struct snd_pcm *pcm); 223void imx_pcm_free(struct snd_pcm *pcm);
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
index a7c9578be983..d1989cde9f14 100644
--- a/sound/soc/jz4740/jz4740-pcm.c
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -299,7 +299,7 @@ static void jz4740_pcm_free(struct snd_pcm *pcm)
299 299
300static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); 300static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32);
301 301
302int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) 302static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd)
303{ 303{
304 struct snd_card *card = rtd->card->snd_card; 304 struct snd_card *card = rtd->card->snd_card;
305 struct snd_soc_dai *dai = rtd->cpu_dai; 305 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index d0bcf3fcea01..715e841c0507 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -476,7 +476,7 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
476 476
477static struct platform_driver kirkwood_i2s_driver = { 477static struct platform_driver kirkwood_i2s_driver = {
478 .probe = kirkwood_i2s_dev_probe, 478 .probe = kirkwood_i2s_dev_probe,
479 .remove = kirkwood_i2s_dev_remove, 479 .remove = __devexit_p(kirkwood_i2s_dev_remove),
480 .driver = { 480 .driver = {
481 .name = DRV_NAME, 481 .name = DRV_NAME,
482 .owner = THIS_MODULE, 482 .owner = THIS_MODULE,
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index c8d21956ab52..c772b3cf4039 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -79,8 +79,6 @@ static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
80 snd_soc_dapm_enable_pin(dapm, "Speaker"); 80 snd_soc_dapm_enable_pin(dapm, "Speaker");
81 81
82 snd_soc_dapm_sync(dapm);
83
84 return 0; 82 return 0;
85} 83}
86 84
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 429aa1be2cff..598f48c0d8f5 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -54,9 +54,7 @@ static unsigned int hs_switch;
54static unsigned int lo_dac; 54static unsigned int lo_dac;
55 55
56struct mfld_mc_private { 56struct mfld_mc_private {
57 struct platform_device *socdev;
58 void __iomem *int_base; 57 void __iomem *int_base;
59 struct snd_soc_codec *codec;
60 u8 interrupt_status; 58 u8 interrupt_status;
61}; 59};
62 60
@@ -235,7 +233,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
235 /* always connected */ 233 /* always connected */
236 snd_soc_dapm_enable_pin(dapm, "Headphones"); 234 snd_soc_dapm_enable_pin(dapm, "Headphones");
237 snd_soc_dapm_enable_pin(dapm, "Mic"); 235 snd_soc_dapm_enable_pin(dapm, "Mic");
238 snd_soc_dapm_sync(dapm);
239 236
240 ret_val = snd_soc_add_controls(codec, mfld_snd_controls, 237 ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
241 ARRAY_SIZE(mfld_snd_controls)); 238 ARRAY_SIZE(mfld_snd_controls));
@@ -253,7 +250,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
253 /* we dont use linein in this so set to NC */ 250 /* we dont use linein in this so set to NC */
254 snd_soc_dapm_disable_pin(dapm, "LINEINL"); 251 snd_soc_dapm_disable_pin(dapm, "LINEINL");
255 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 252 snd_soc_dapm_disable_pin(dapm, "LINEINR");
256 snd_soc_dapm_sync(dapm);
257 253
258 /* Headset and button jack detection */ 254 /* Headset and button jack detection */
259 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", 255 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 3e7826058efe..7df8c58ba50a 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -63,7 +63,7 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = {
63}; 63};
64 64
65/* MFLD - MSIC */ 65/* MFLD - MSIC */
66struct snd_soc_dai_driver sst_platform_dai[] = { 66static struct snd_soc_dai_driver sst_platform_dai[] = {
67{ 67{
68 .name = "Headset-cpu-dai", 68 .name = "Headset-cpu-dai",
69 .id = 0, 69 .id = 0,
@@ -226,13 +226,18 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
226 226
227static int sst_platform_open(struct snd_pcm_substream *substream) 227static int sst_platform_open(struct snd_pcm_substream *substream)
228{ 228{
229 struct snd_pcm_runtime *runtime; 229 struct snd_pcm_runtime *runtime = substream->runtime;
230 struct sst_runtime_stream *stream; 230 struct sst_runtime_stream *stream;
231 int ret_val = 0; 231 int ret_val = 0;
232 232
233 pr_debug("sst_platform_open called\n"); 233 pr_debug("sst_platform_open called\n");
234 runtime = substream->runtime; 234
235 runtime->hw = sst_platform_pcm_hw; 235 snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
236 ret_val = snd_pcm_hw_constraint_integer(runtime,
237 SNDRV_PCM_HW_PARAM_PERIODS);
238 if (ret_val < 0)
239 return ret_val;
240
236 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 241 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
237 if (!stream) 242 if (!stream)
238 return -ENOMEM; 243 return -ENOMEM;
@@ -259,8 +264,8 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
259 return ret_val; 264 return ret_val;
260 } 265 }
261 runtime->private_data = stream; 266 runtime->private_data = stream;
262 return snd_pcm_hw_constraint_integer(runtime, 267
263 SNDRV_PCM_HW_PARAM_PERIODS); 268 return 0;
264} 269}
265 270
266static int sst_platform_close(struct snd_pcm_substream *substream) 271static int sst_platform_close(struct snd_pcm_substream *substream)
@@ -469,7 +474,7 @@ static struct platform_driver sst_platform_driver = {
469static int __init sst_soc_platform_init(void) 474static int __init sst_soc_platform_init(void)
470{ 475{
471 pr_debug("sst_soc_platform_init called\n"); 476 pr_debug("sst_soc_platform_init called\n");
472 return platform_driver_register(&sst_platform_driver); 477 return platform_driver_register(&sst_platform_driver);
473} 478}
474module_init(sst_soc_platform_init); 479module_init(sst_soc_platform_init);
475 480
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
new file mode 100644
index 000000000000..e4ba8d5f25fa
--- /dev/null
+++ b/sound/soc/mxs/Kconfig
@@ -0,0 +1,20 @@
1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS
4 select SND_PCM
5 help
6 Say Y or M if you want to add support for codecs attached to
7 the MXS SAIF interface.
8
9
10if SND_MXS_SOC
11
12config SND_SOC_MXS_SGTL5000
13 tristate "SoC Audio support for i.MX boards with sgtl5000"
14 depends on I2C
15 select SND_SOC_SGTL5000
16 help
17 Say Y if you want to add support for SoC audio on an MXS board with
18 a sgtl5000 codec.
19
20endif # SND_MXS_SOC
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
new file mode 100644
index 000000000000..565b5b51e8b7
--- /dev/null
+++ b/sound/soc/mxs/Makefile
@@ -0,0 +1,10 @@
1# MXS Platform Support
2snd-soc-mxs-objs := mxs-saif.o
3snd-soc-mxs-pcm-objs := mxs-pcm.o
4
5obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o
6
7# i.MX Machine Support
8snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
9
10obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
new file mode 100644
index 000000000000..dea5aa4aa647
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -0,0 +1,359 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Based on sound/soc/imx/imx-pcm-dma-mx2.c
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/dma-mapping.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <linux/dmaengine.h>
31
32#include <sound/core.h>
33#include <sound/initval.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37
38#include <mach/dma.h>
39#include "mxs-pcm.h"
40
41static struct snd_pcm_hardware snd_mxs_hardware = {
42 .info = SNDRV_PCM_INFO_MMAP |
43 SNDRV_PCM_INFO_MMAP_VALID |
44 SNDRV_PCM_INFO_PAUSE |
45 SNDRV_PCM_INFO_RESUME |
46 SNDRV_PCM_INFO_INTERLEAVED,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE |
48 SNDRV_PCM_FMTBIT_S20_3LE |
49 SNDRV_PCM_FMTBIT_S24_LE,
50 .channels_min = 2,
51 .channels_max = 2,
52 .period_bytes_min = 32,
53 .period_bytes_max = 8192,
54 .periods_min = 1,
55 .periods_max = 52,
56 .buffer_bytes_max = 64 * 1024,
57 .fifo_size = 32,
58
59};
60
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)
73{
74 struct mxs_pcm_runtime_data *iprtd = param;
75 struct mxs_pcm_dma_params *dma_params = iprtd->dma_params;
76
77 if (!mxs_dma_is_apbx(chan))
78 return false;
79
80 if (chan->chan_id != dma_params->chan_num)
81 return false;
82
83 chan->private = &iprtd->dma_data;
84
85 return true;
86}
87
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,
109 struct snd_pcm_hw_params *params)
110{
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);
130
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_TO_DEVICE : DMA_FROM_DEVICE);
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;
187}
188
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)
199{
200 struct snd_pcm_runtime *runtime = substream->runtime;
201 struct mxs_pcm_runtime_data *iprtd;
202 int ret;
203
204 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
205 if (iprtd == NULL)
206 return -ENOMEM;
207 runtime->private_data = iprtd;
208
209 ret = snd_pcm_hw_constraint_integer(substream->runtime,
210 SNDRV_PCM_HW_PARAM_PERIODS);
211 if (ret < 0) {
212 kfree(iprtd);
213 return ret;
214 }
215
216 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
217
218 return 0;
219}
220
221static int snd_mxs_close(struct snd_pcm_substream *substream)
222{
223 struct snd_pcm_runtime *runtime = substream->runtime;
224 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
225
226 kfree(iprtd);
227
228 return 0;
229}
230
231static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
232 struct vm_area_struct *vma)
233{
234 struct snd_pcm_runtime *runtime = substream->runtime;
235
236 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
237 runtime->dma_area,
238 runtime->dma_addr,
239 runtime->dma_bytes);
240}
241
242static struct snd_pcm_ops mxs_pcm_ops = {
243 .open = snd_mxs_open,
244 .close = snd_mxs_close,
245 .ioctl = snd_pcm_lib_ioctl,
246 .hw_params = snd_mxs_pcm_hw_params,
247 .hw_free = snd_mxs_pcm_hw_free,
248 .trigger = snd_mxs_pcm_trigger,
249 .pointer = snd_mxs_pcm_pointer,
250 .mmap = snd_mxs_pcm_mmap,
251};
252
253static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
254{
255 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
256 struct snd_dma_buffer *buf = &substream->dma_buffer;
257 size_t size = snd_mxs_hardware.buffer_bytes_max;
258
259 buf->dev.type = SNDRV_DMA_TYPE_DEV;
260 buf->dev.dev = pcm->card->dev;
261 buf->private_data = NULL;
262 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
263 &buf->addr, GFP_KERNEL);
264 if (!buf->area)
265 return -ENOMEM;
266 buf->bytes = size;
267
268 return 0;
269}
270
271static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
272static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
273{
274 struct snd_card *card = rtd->card->snd_card;
275 struct snd_pcm *pcm = rtd->pcm;
276 int ret = 0;
277
278 if (!card->dev->dma_mask)
279 card->dev->dma_mask = &mxs_pcm_dmamask;
280 if (!card->dev->coherent_dma_mask)
281 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
282
283 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
284 ret = mxs_pcm_preallocate_dma_buffer(pcm,
285 SNDRV_PCM_STREAM_PLAYBACK);
286 if (ret)
287 goto out;
288 }
289
290 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
291 ret = mxs_pcm_preallocate_dma_buffer(pcm,
292 SNDRV_PCM_STREAM_CAPTURE);
293 if (ret)
294 goto out;
295 }
296
297out:
298 return ret;
299}
300
301static void mxs_pcm_free(struct snd_pcm *pcm)
302{
303 struct snd_pcm_substream *substream;
304 struct snd_dma_buffer *buf;
305 int stream;
306
307 for (stream = 0; stream < 2; stream++) {
308 substream = pcm->streams[stream].substream;
309 if (!substream)
310 continue;
311
312 buf = &substream->dma_buffer;
313 if (!buf->area)
314 continue;
315
316 dma_free_writecombine(pcm->card->dev, buf->bytes,
317 buf->area, buf->addr);
318 buf->area = NULL;
319 }
320}
321
322static struct snd_soc_platform_driver mxs_soc_platform = {
323 .ops = &mxs_pcm_ops,
324 .pcm_new = mxs_pcm_new,
325 .pcm_free = mxs_pcm_free,
326};
327
328static int __devinit mxs_soc_platform_probe(struct platform_device *pdev)
329{
330 return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform);
331}
332
333static int __devexit mxs_soc_platform_remove(struct platform_device *pdev)
334{
335 snd_soc_unregister_platform(&pdev->dev);
336
337 return 0;
338}
339
340static struct platform_driver mxs_pcm_driver = {
341 .driver = {
342 .name = "mxs-pcm-audio",
343 .owner = THIS_MODULE,
344 },
345 .probe = mxs_soc_platform_probe,
346 .remove = __devexit_p(mxs_soc_platform_remove),
347};
348
349static int __init snd_mxs_pcm_init(void)
350{
351 return platform_driver_register(&mxs_pcm_driver);
352}
353module_init(snd_mxs_pcm_init);
354
355static void __exit snd_mxs_pcm_exit(void)
356{
357 platform_driver_unregister(&mxs_pcm_driver);
358}
359module_exit(snd_mxs_pcm_exit);
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
new file mode 100644
index 000000000000..f55ac4f7a76a
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H
21
22#include <mach/dma.h>
23
24struct mxs_pcm_dma_params {
25 int chan_irq;
26 int chan_num;
27};
28
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
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
new file mode 100644
index 000000000000..76dc74d24fc2
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.c
@@ -0,0 +1,798 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/clk.h>
25#include <linux/delay.h>
26#include <linux/time.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/saif.h>
32#include <mach/dma.h>
33#include <asm/mach-types.h>
34#include <mach/hardware.h>
35#include <mach/mxs.h>
36
37#include "mxs-saif.h"
38
39static struct mxs_saif *mxs_saif[2];
40
41/*
42 * SAIF is a little different with other normal SOC DAIs on clock using.
43 *
44 * For MXS, two SAIF modules are instantiated on-chip.
45 * Each SAIF has a set of clock pins and can be operating in master
46 * mode simultaneously if they are connected to different off-chip codecs.
47 * Also, one of the two SAIFs can master or drive the clock pins while the
48 * other SAIF, in slave mode, receives clocking from the master SAIF.
49 * This also means that both SAIFs must operate at the same sample rate.
50 *
51 * We abstract this as each saif has a master, the master could be
52 * himself or other saifs. In the generic saif driver, saif does not need
53 * to know the different clkmux. Saif only needs to know who is his master
54 * and operating his master to generate the proper clock rate for him.
55 * The master id is provided in mach-specific layer according to different
56 * clkmux setting.
57 */
58
59static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
60 int clk_id, unsigned int freq, int dir)
61{
62 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
63
64 switch (clk_id) {
65 case MXS_SAIF_MCLK:
66 saif->mclk = freq;
67 break;
68 default:
69 return -EINVAL;
70 }
71 return 0;
72}
73
74/*
75 * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK
76 * is provided by other SAIF, we provide a interface here to get its master
77 * from its master_id.
78 * Note that the master could be himself.
79 */
80static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif)
81{
82 return mxs_saif[saif->master_id];
83}
84
85/*
86 * Set SAIF clock and MCLK
87 */
88static int mxs_saif_set_clk(struct mxs_saif *saif,
89 unsigned int mclk,
90 unsigned int rate)
91{
92 u32 scr;
93 int ret;
94 struct mxs_saif *master_saif;
95
96 dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate);
97
98 /* Set master saif to generate proper clock */
99 master_saif = mxs_saif_get_master(saif);
100 if (!master_saif)
101 return -EINVAL;
102
103 dev_dbg(saif->dev, "master saif%d\n", master_saif->id);
104
105 /* Checking if can playback and capture simutaneously */
106 if (master_saif->ongoing && rate != master_saif->cur_rate) {
107 dev_err(saif->dev,
108 "can not change clock, master saif%d(rate %d) is ongoing\n",
109 master_saif->id, master_saif->cur_rate);
110 return -EINVAL;
111 }
112
113 scr = __raw_readl(master_saif->base + SAIF_CTRL);
114 scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
115 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
116
117 /*
118 * Set SAIF clock
119 *
120 * The SAIF clock should be either 384*fs or 512*fs.
121 * If MCLK is used, the SAIF clk ratio need to match mclk ratio.
122 * For 32x mclk, set saif clk as 512*fs.
123 * For 48x mclk, set saif clk as 384*fs.
124 *
125 * If MCLK is not used, we just set saif clk to 512*fs.
126 */
127 if (master_saif->mclk_in_use) {
128 if (mclk % 32 == 0) {
129 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
130 ret = clk_set_rate(master_saif->clk, 512 * rate);
131 } else if (mclk % 48 == 0) {
132 scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
133 ret = clk_set_rate(master_saif->clk, 384 * rate);
134 } else {
135 /* SAIF MCLK should be either 32x or 48x */
136 return -EINVAL;
137 }
138 } else {
139 ret = clk_set_rate(master_saif->clk, 512 * rate);
140 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
141 }
142
143 if (ret)
144 return ret;
145
146 master_saif->cur_rate = rate;
147
148 if (!master_saif->mclk_in_use) {
149 __raw_writel(scr, master_saif->base + SAIF_CTRL);
150 return 0;
151 }
152
153 /*
154 * Program the over-sample rate for MCLK output
155 *
156 * The available MCLK range is 32x, 48x... 512x. The rate
157 * could be from 8kHz to 192kH.
158 */
159 switch (mclk / rate) {
160 case 32:
161 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
162 break;
163 case 64:
164 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
165 break;
166 case 128:
167 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
168 break;
169 case 256:
170 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
171 break;
172 case 512:
173 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
174 break;
175 case 48:
176 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
177 break;
178 case 96:
179 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
180 break;
181 case 192:
182 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
183 break;
184 case 384:
185 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
186 break;
187 default:
188 return -EINVAL;
189 }
190
191 __raw_writel(scr, master_saif->base + SAIF_CTRL);
192
193 return 0;
194}
195
196/*
197 * Put and disable MCLK.
198 */
199int mxs_saif_put_mclk(unsigned int saif_id)
200{
201 struct mxs_saif *saif = mxs_saif[saif_id];
202 u32 stat;
203
204 if (!saif)
205 return -EINVAL;
206
207 stat = __raw_readl(saif->base + SAIF_STAT);
208 if (stat & BM_SAIF_STAT_BUSY) {
209 dev_err(saif->dev, "error: busy\n");
210 return -EBUSY;
211 }
212
213 clk_disable(saif->clk);
214
215 /* disable MCLK output */
216 __raw_writel(BM_SAIF_CTRL_CLKGATE,
217 saif->base + SAIF_CTRL + MXS_SET_ADDR);
218 __raw_writel(BM_SAIF_CTRL_RUN,
219 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
220
221 saif->mclk_in_use = 0;
222 return 0;
223}
224
225/*
226 * Get MCLK and set clock rate, then enable it
227 *
228 * This interface is used for codecs who are using MCLK provided
229 * by saif.
230 */
231int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
232 unsigned int rate)
233{
234 struct mxs_saif *saif = mxs_saif[saif_id];
235 u32 stat;
236 int ret;
237 struct mxs_saif *master_saif;
238
239 if (!saif)
240 return -EINVAL;
241
242 /* Clear Reset */
243 __raw_writel(BM_SAIF_CTRL_SFTRST,
244 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
245
246 /* FIXME: need clear clk gate for register r/w */
247 __raw_writel(BM_SAIF_CTRL_CLKGATE,
248 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
249
250 master_saif = mxs_saif_get_master(saif);
251 if (saif != master_saif) {
252 dev_err(saif->dev, "can not get mclk from a non-master saif\n");
253 return -EINVAL;
254 }
255
256 stat = __raw_readl(saif->base + SAIF_STAT);
257 if (stat & BM_SAIF_STAT_BUSY) {
258 dev_err(saif->dev, "error: busy\n");
259 return -EBUSY;
260 }
261
262 saif->mclk_in_use = 1;
263 ret = mxs_saif_set_clk(saif, mclk, rate);
264 if (ret)
265 return ret;
266
267 ret = clk_enable(saif->clk);
268 if (ret)
269 return ret;
270
271 /* enable MCLK output */
272 __raw_writel(BM_SAIF_CTRL_RUN,
273 saif->base + SAIF_CTRL + MXS_SET_ADDR);
274
275 return 0;
276}
277
278/*
279 * SAIF DAI format configuration.
280 * Should only be called when port is inactive.
281 */
282static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
283{
284 u32 scr, stat;
285 u32 scr0;
286 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
287
288 stat = __raw_readl(saif->base + SAIF_STAT);
289 if (stat & BM_SAIF_STAT_BUSY) {
290 dev_err(cpu_dai->dev, "error: busy\n");
291 return -EBUSY;
292 }
293
294 scr0 = __raw_readl(saif->base + SAIF_CTRL);
295 scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
296 & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
297 scr = 0;
298
299 /* DAI mode */
300 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301 case SND_SOC_DAIFMT_I2S:
302 /* data frame low 1clk before data */
303 scr |= BM_SAIF_CTRL_DELAY;
304 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
305 break;
306 case SND_SOC_DAIFMT_LEFT_J:
307 /* data frame high with data */
308 scr &= ~BM_SAIF_CTRL_DELAY;
309 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
310 scr &= ~BM_SAIF_CTRL_JUSTIFY;
311 break;
312 default:
313 return -EINVAL;
314 }
315
316 /* DAI clock inversion */
317 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
318 case SND_SOC_DAIFMT_IB_IF:
319 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
320 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
321 break;
322 case SND_SOC_DAIFMT_IB_NF:
323 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
324 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
325 break;
326 case SND_SOC_DAIFMT_NB_IF:
327 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
328 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
329 break;
330 case SND_SOC_DAIFMT_NB_NF:
331 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
332 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
333 break;
334 }
335
336 /*
337 * Note: We simply just support master mode since SAIF TX can only
338 * work as master.
339 * Here the master is relative to codec side.
340 * Saif internally could be slave when working on EXTMASTER mode.
341 * We just hide this to machine driver.
342 */
343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344 case SND_SOC_DAIFMT_CBS_CFS:
345 if (saif->id == saif->master_id)
346 scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
347 else
348 scr |= BM_SAIF_CTRL_SLAVE_MODE;
349
350 __raw_writel(scr | scr0, saif->base + SAIF_CTRL);
351 break;
352 default:
353 return -EINVAL;
354 }
355
356 return 0;
357}
358
359static int mxs_saif_startup(struct snd_pcm_substream *substream,
360 struct snd_soc_dai *cpu_dai)
361{
362 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
363 snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param);
364
365 /* clear error status to 0 for each re-open */
366 saif->fifo_underrun = 0;
367 saif->fifo_overrun = 0;
368
369 /* Clear Reset for normal operations */
370 __raw_writel(BM_SAIF_CTRL_SFTRST,
371 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
372
373 /* clear clock gate */
374 __raw_writel(BM_SAIF_CTRL_CLKGATE,
375 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
376
377 return 0;
378}
379
380/*
381 * Should only be called when port is inactive.
382 * although can be called multiple times by upper layers.
383 */
384static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
385 struct snd_pcm_hw_params *params,
386 struct snd_soc_dai *cpu_dai)
387{
388 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
389 u32 scr, stat;
390 int ret;
391
392 /* mclk should already be set */
393 if (!saif->mclk && saif->mclk_in_use) {
394 dev_err(cpu_dai->dev, "set mclk first\n");
395 return -EINVAL;
396 }
397
398 stat = __raw_readl(saif->base + SAIF_STAT);
399 if (stat & BM_SAIF_STAT_BUSY) {
400 dev_err(cpu_dai->dev, "error: busy\n");
401 return -EBUSY;
402 }
403
404 /*
405 * Set saif clk based on sample rate.
406 * If mclk is used, we also set mclk, if not, saif->mclk is
407 * default 0, means not used.
408 */
409 ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
410 if (ret) {
411 dev_err(cpu_dai->dev, "unable to get proper clk\n");
412 return ret;
413 }
414
415 scr = __raw_readl(saif->base + SAIF_CTRL);
416
417 scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
418 scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
419 switch (params_format(params)) {
420 case SNDRV_PCM_FORMAT_S16_LE:
421 scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
422 break;
423 case SNDRV_PCM_FORMAT_S20_3LE:
424 scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
425 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
426 break;
427 case SNDRV_PCM_FORMAT_S24_LE:
428 scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
429 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
430 break;
431 default:
432 return -EINVAL;
433 }
434
435 /* Tx/Rx config */
436 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
437 /* enable TX mode */
438 scr &= ~BM_SAIF_CTRL_READ_MODE;
439 } else {
440 /* enable RX mode */
441 scr |= BM_SAIF_CTRL_READ_MODE;
442 }
443
444 __raw_writel(scr, saif->base + SAIF_CTRL);
445 return 0;
446}
447
448static int mxs_saif_prepare(struct snd_pcm_substream *substream,
449 struct snd_soc_dai *cpu_dai)
450{
451 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
452
453 /* enable FIFO error irqs */
454 __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
455 saif->base + SAIF_CTRL + MXS_SET_ADDR);
456
457 return 0;
458}
459
460static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
461 struct snd_soc_dai *cpu_dai)
462{
463 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
464 struct mxs_saif *master_saif;
465 u32 delay;
466
467 master_saif = mxs_saif_get_master(saif);
468 if (!master_saif)
469 return -EINVAL;
470
471 switch (cmd) {
472 case SNDRV_PCM_TRIGGER_START:
473 case SNDRV_PCM_TRIGGER_RESUME:
474 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
475 dev_dbg(cpu_dai->dev, "start\n");
476
477 clk_enable(master_saif->clk);
478 if (!master_saif->mclk_in_use)
479 __raw_writel(BM_SAIF_CTRL_RUN,
480 master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
481
482 /*
483 * If the saif's master is not himself, we also need to enable
484 * itself clk for its internal basic logic to work.
485 */
486 if (saif != master_saif) {
487 clk_enable(saif->clk);
488 __raw_writel(BM_SAIF_CTRL_RUN,
489 saif->base + SAIF_CTRL + MXS_SET_ADDR);
490 }
491
492 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
493 /*
494 * write a data to saif data register to trigger
495 * the transfer
496 */
497 __raw_writel(0, saif->base + SAIF_DATA);
498 } else {
499 /*
500 * read a data from saif data register to trigger
501 * the receive
502 */
503 __raw_readl(saif->base + SAIF_DATA);
504 }
505
506 master_saif->ongoing = 1;
507
508 dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
509 __raw_readl(saif->base + SAIF_CTRL),
510 __raw_readl(saif->base + SAIF_STAT));
511
512 dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n",
513 __raw_readl(master_saif->base + SAIF_CTRL),
514 __raw_readl(master_saif->base + SAIF_STAT));
515 break;
516 case SNDRV_PCM_TRIGGER_SUSPEND:
517 case SNDRV_PCM_TRIGGER_STOP:
518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
519 dev_dbg(cpu_dai->dev, "stop\n");
520
521 /* wait a while for the current sample to complete */
522 delay = USEC_PER_SEC / master_saif->cur_rate;
523
524 if (!master_saif->mclk_in_use) {
525 __raw_writel(BM_SAIF_CTRL_RUN,
526 master_saif->base + SAIF_CTRL + MXS_CLR_ADDR);
527 udelay(delay);
528 }
529 clk_disable(master_saif->clk);
530
531 if (saif != master_saif) {
532 __raw_writel(BM_SAIF_CTRL_RUN,
533 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
534 udelay(delay);
535 clk_disable(saif->clk);
536 }
537
538 master_saif->ongoing = 0;
539
540 break;
541 default:
542 return -EINVAL;
543 }
544
545 return 0;
546}
547
548#define MXS_SAIF_RATES SNDRV_PCM_RATE_8000_192000
549#define MXS_SAIF_FORMATS \
550 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
551 SNDRV_PCM_FMTBIT_S24_LE)
552
553static struct snd_soc_dai_ops mxs_saif_dai_ops = {
554 .startup = mxs_saif_startup,
555 .trigger = mxs_saif_trigger,
556 .prepare = mxs_saif_prepare,
557 .hw_params = mxs_saif_hw_params,
558 .set_sysclk = mxs_saif_set_dai_sysclk,
559 .set_fmt = mxs_saif_set_dai_fmt,
560};
561
562static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
563{
564 struct mxs_saif *saif = dev_get_drvdata(dai->dev);
565
566 snd_soc_dai_set_drvdata(dai, saif);
567
568 return 0;
569}
570
571static struct snd_soc_dai_driver mxs_saif_dai = {
572 .name = "mxs-saif",
573 .probe = mxs_saif_dai_probe,
574 .playback = {
575 .channels_min = 2,
576 .channels_max = 2,
577 .rates = MXS_SAIF_RATES,
578 .formats = MXS_SAIF_FORMATS,
579 },
580 .capture = {
581 .channels_min = 2,
582 .channels_max = 2,
583 .rates = MXS_SAIF_RATES,
584 .formats = MXS_SAIF_FORMATS,
585 },
586 .ops = &mxs_saif_dai_ops,
587};
588
589static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
590{
591 struct mxs_saif *saif = dev_id;
592 unsigned int stat;
593
594 stat = __raw_readl(saif->base + SAIF_STAT);
595 if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
596 BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
597 return IRQ_NONE;
598
599 if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
600 dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
601 __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
602 saif->base + SAIF_STAT + MXS_CLR_ADDR);
603 }
604
605 if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
606 dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
607 __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
608 saif->base + SAIF_STAT + MXS_CLR_ADDR);
609 }
610
611 dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
612 __raw_readl(saif->base + SAIF_CTRL),
613 __raw_readl(saif->base + SAIF_STAT));
614
615 return IRQ_HANDLED;
616}
617
618static int mxs_saif_probe(struct platform_device *pdev)
619{
620 struct resource *iores, *dmares;
621 struct mxs_saif *saif;
622 struct mxs_saif_platform_data *pdata;
623 int ret = 0;
624
625 if (pdev->id >= ARRAY_SIZE(mxs_saif))
626 return -EINVAL;
627
628 pdata = pdev->dev.platform_data;
629 if (pdata && pdata->init) {
630 ret = pdata->init();
631 if (ret)
632 return ret;
633 }
634
635 saif = kzalloc(sizeof(*saif), GFP_KERNEL);
636 if (!saif)
637 return -ENOMEM;
638
639 mxs_saif[pdev->id] = saif;
640 saif->id = pdev->id;
641
642 saif->master_id = saif->id;
643 if (pdata && pdata->get_master_id) {
644 saif->master_id = pdata->get_master_id(saif->id);
645 if (saif->master_id < 0 ||
646 saif->master_id >= ARRAY_SIZE(mxs_saif))
647 return -EINVAL;
648 }
649
650 saif->clk = clk_get(&pdev->dev, NULL);
651 if (IS_ERR(saif->clk)) {
652 ret = PTR_ERR(saif->clk);
653 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
654 ret);
655 goto failed_clk;
656 }
657
658 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
659 if (!iores) {
660 ret = -ENODEV;
661 dev_err(&pdev->dev, "failed to get io resource: %d\n",
662 ret);
663 goto failed_get_resource;
664 }
665
666 if (!request_mem_region(iores->start, resource_size(iores),
667 "mxs-saif")) {
668 dev_err(&pdev->dev, "request_mem_region failed\n");
669 ret = -EBUSY;
670 goto failed_get_resource;
671 }
672
673 saif->base = ioremap(iores->start, resource_size(iores));
674 if (!saif->base) {
675 dev_err(&pdev->dev, "ioremap failed\n");
676 ret = -ENODEV;
677 goto failed_ioremap;
678 }
679
680 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
681 if (!dmares) {
682 ret = -ENODEV;
683 dev_err(&pdev->dev, "failed to get dma resource: %d\n",
684 ret);
685 goto failed_ioremap;
686 }
687 saif->dma_param.chan_num = dmares->start;
688
689 saif->irq = platform_get_irq(pdev, 0);
690 if (saif->irq < 0) {
691 ret = saif->irq;
692 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
693 ret);
694 goto failed_get_irq1;
695 }
696
697 saif->dev = &pdev->dev;
698 ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
699 if (ret) {
700 dev_err(&pdev->dev, "failed to request irq\n");
701 goto failed_get_irq1;
702 }
703
704 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
705 if (saif->dma_param.chan_irq < 0) {
706 ret = saif->dma_param.chan_irq;
707 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
708 ret);
709 goto failed_get_irq2;
710 }
711
712 platform_set_drvdata(pdev, saif);
713
714 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
715 if (ret) {
716 dev_err(&pdev->dev, "register DAI failed\n");
717 goto failed_register;
718 }
719
720 saif->soc_platform_pdev = platform_device_alloc(
721 "mxs-pcm-audio", pdev->id);
722 if (!saif->soc_platform_pdev) {
723 ret = -ENOMEM;
724 goto failed_pdev_alloc;
725 }
726
727 platform_set_drvdata(saif->soc_platform_pdev, saif);
728 ret = platform_device_add(saif->soc_platform_pdev);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to add soc platform device\n");
731 goto failed_pdev_add;
732 }
733
734 return 0;
735
736failed_pdev_add:
737 platform_device_put(saif->soc_platform_pdev);
738failed_pdev_alloc:
739 snd_soc_unregister_dai(&pdev->dev);
740failed_register:
741failed_get_irq2:
742 free_irq(saif->irq, saif);
743failed_get_irq1:
744 iounmap(saif->base);
745failed_ioremap:
746 release_mem_region(iores->start, resource_size(iores));
747failed_get_resource:
748 clk_put(saif->clk);
749failed_clk:
750 kfree(saif);
751
752 return ret;
753}
754
755static int __devexit mxs_saif_remove(struct platform_device *pdev)
756{
757 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
758 struct mxs_saif *saif = platform_get_drvdata(pdev);
759
760 platform_device_unregister(saif->soc_platform_pdev);
761
762 snd_soc_unregister_dai(&pdev->dev);
763
764 iounmap(saif->base);
765 release_mem_region(res->start, resource_size(res));
766 free_irq(saif->irq, saif);
767
768 clk_put(saif->clk);
769 kfree(saif);
770
771 return 0;
772}
773
774static struct platform_driver mxs_saif_driver = {
775 .probe = mxs_saif_probe,
776 .remove = __devexit_p(mxs_saif_remove),
777
778 .driver = {
779 .name = "mxs-saif",
780 .owner = THIS_MODULE,
781 },
782};
783
784static int __init mxs_saif_init(void)
785{
786 return platform_driver_register(&mxs_saif_driver);
787}
788
789static void __exit mxs_saif_exit(void)
790{
791 platform_driver_unregister(&mxs_saif_driver);
792}
793
794module_init(mxs_saif_init);
795module_exit(mxs_saif_exit);
796MODULE_AUTHOR("Freescale Semiconductor, Inc.");
797MODULE_DESCRIPTION("MXS ASoC SAIF driver");
798MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
new file mode 100644
index 000000000000..12c91e4eb941
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#ifndef _MXS_SAIF_H
21#define _MXS_SAIF_H
22
23#define SAIF_CTRL 0x0
24#define SAIF_STAT 0x10
25#define SAIF_DATA 0x20
26#define SAIF_VERSION 0X30
27
28/* SAIF_CTRL */
29#define BM_SAIF_CTRL_SFTRST 0x80000000
30#define BM_SAIF_CTRL_CLKGATE 0x40000000
31#define BP_SAIF_CTRL_BITCLK_MULT_RATE 27
32#define BM_SAIF_CTRL_BITCLK_MULT_RATE 0x38000000
33#define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \
34 (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE)
35#define BM_SAIF_CTRL_BITCLK_BASE_RATE 0x04000000
36#define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000
37#define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN 0x01000000
38#define BP_SAIF_CTRL_RSRVD2 21
39#define BM_SAIF_CTRL_RSRVD2 0x00E00000
40
41#define BP_SAIF_CTRL_DMAWAIT_COUNT 16
42#define BM_SAIF_CTRL_DMAWAIT_COUNT 0x001F0000
43#define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \
44 (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT)
45#define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14
46#define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000
47#define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \
48 (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT)
49#define BM_SAIF_CTRL_LRCLK_PULSE 0x00002000
50#define BM_SAIF_CTRL_BIT_ORDER 0x00001000
51#define BM_SAIF_CTRL_DELAY 0x00000800
52#define BM_SAIF_CTRL_JUSTIFY 0x00000400
53#define BM_SAIF_CTRL_LRCLK_POLARITY 0x00000200
54#define BM_SAIF_CTRL_BITCLK_EDGE 0x00000100
55#define BP_SAIF_CTRL_WORD_LENGTH 4
56#define BM_SAIF_CTRL_WORD_LENGTH 0x000000F0
57#define BF_SAIF_CTRL_WORD_LENGTH(v) \
58 (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH)
59#define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE 0x00000008
60#define BM_SAIF_CTRL_SLAVE_MODE 0x00000004
61#define BM_SAIF_CTRL_READ_MODE 0x00000002
62#define BM_SAIF_CTRL_RUN 0x00000001
63
64/* SAIF_STAT */
65#define BM_SAIF_STAT_PRESENT 0x80000000
66#define BP_SAIF_STAT_RSRVD2 17
67#define BM_SAIF_STAT_RSRVD2 0x7FFE0000
68#define BF_SAIF_STAT_RSRVD2(v) \
69 (((v) << 17) & BM_SAIF_STAT_RSRVD2)
70#define BM_SAIF_STAT_DMA_PREQ 0x00010000
71#define BP_SAIF_STAT_RSRVD1 7
72#define BM_SAIF_STAT_RSRVD1 0x0000FF80
73#define BF_SAIF_STAT_RSRVD1(v) \
74 (((v) << 7) & BM_SAIF_STAT_RSRVD1)
75
76#define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040
77#define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020
78#define BM_SAIF_STAT_FIFO_SERVICE_IRQ 0x00000010
79#define BP_SAIF_STAT_RSRVD0 1
80#define BM_SAIF_STAT_RSRVD0 0x0000000E
81#define BF_SAIF_STAT_RSRVD0(v) \
82 (((v) << 1) & BM_SAIF_STAT_RSRVD0)
83#define BM_SAIF_STAT_BUSY 0x00000001
84
85/* SAFI_DATA */
86#define BP_SAIF_DATA_PCM_RIGHT 16
87#define BM_SAIF_DATA_PCM_RIGHT 0xFFFF0000
88#define BF_SAIF_DATA_PCM_RIGHT(v) \
89 (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT)
90#define BP_SAIF_DATA_PCM_LEFT 0
91#define BM_SAIF_DATA_PCM_LEFT 0x0000FFFF
92#define BF_SAIF_DATA_PCM_LEFT(v) \
93 (((v) << 0) & BM_SAIF_DATA_PCM_LEFT)
94
95/* SAIF_VERSION */
96#define BP_SAIF_VERSION_MAJOR 24
97#define BM_SAIF_VERSION_MAJOR 0xFF000000
98#define BF_SAIF_VERSION_MAJOR(v) \
99 (((v) << 24) & BM_SAIF_VERSION_MAJOR)
100#define BP_SAIF_VERSION_MINOR 16
101#define BM_SAIF_VERSION_MINOR 0x00FF0000
102#define BF_SAIF_VERSION_MINOR(v) \
103 (((v) << 16) & BM_SAIF_VERSION_MINOR)
104#define BP_SAIF_VERSION_STEP 0
105#define BM_SAIF_VERSION_STEP 0x0000FFFF
106#define BF_SAIF_VERSION_STEP(v) \
107 (((v) << 0) & BM_SAIF_VERSION_STEP)
108
109#define MXS_SAIF_MCLK 0
110
111#include "mxs-pcm.h"
112
113struct mxs_saif {
114 struct device *dev;
115 struct clk *clk;
116 unsigned int mclk;
117 unsigned int mclk_in_use;
118 void __iomem *base;
119 int irq;
120 struct mxs_pcm_dma_params dma_param;
121 unsigned int id;
122 unsigned int master_id;
123 unsigned int cur_rate;
124 unsigned int ongoing;
125
126 struct platform_device *soc_platform_pdev;
127 u32 fifo_underrun;
128 u32 fifo_overrun;
129};
130
131extern int mxs_saif_put_mclk(unsigned int saif_id);
132extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
133 unsigned int rate);
134#endif
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
new file mode 100644
index 000000000000..7fbeaec06eb4
--- /dev/null
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -0,0 +1,173 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include <sound/soc-dapm.h>
26#include <asm/mach-types.h>
27
28#include "../codecs/sgtl5000.h"
29#include "mxs-saif.h"
30
31static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params)
33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
37 unsigned int rate = params_rate(params);
38 u32 dai_format, mclk;
39 int ret;
40
41 /* sgtl5000 does not support 512*rate when in 96000 fs */
42 switch (rate) {
43 case 96000:
44 mclk = 256 * rate;
45 break;
46 default:
47 mclk = 512 * rate;
48 break;
49 }
50
51 /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
52 if (mclk < 8000000 || mclk > 27000000)
53 return -EINVAL;
54
55 /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
56 ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
57 if (ret)
58 return ret;
59
60 /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
61 ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
62 if (ret)
63 return ret;
64
65 /* set codec to slave mode */
66 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBS_CFS;
68
69 /* set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
71 if (ret)
72 return ret;
73
74 /* set cpu DAI configuration */
75 ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
76 if (ret)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops mxs_sgtl5000_hifi_ops = {
83 .hw_params = mxs_sgtl5000_hw_params,
84};
85
86static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
87 {
88 .name = "HiFi Tx",
89 .stream_name = "HiFi Playback",
90 .codec_dai_name = "sgtl5000",
91 .codec_name = "sgtl5000.0-000a",
92 .cpu_dai_name = "mxs-saif.0",
93 .platform_name = "mxs-pcm-audio.0",
94 .ops = &mxs_sgtl5000_hifi_ops,
95 }, {
96 .name = "HiFi Rx",
97 .stream_name = "HiFi Capture",
98 .codec_dai_name = "sgtl5000",
99 .codec_name = "sgtl5000.0-000a",
100 .cpu_dai_name = "mxs-saif.1",
101 .platform_name = "mxs-pcm-audio.1",
102 .ops = &mxs_sgtl5000_hifi_ops,
103 },
104};
105
106static struct snd_soc_card mxs_sgtl5000 = {
107 .name = "mxs_sgtl5000",
108 .dai_link = mxs_sgtl5000_dai,
109 .num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
110};
111
112static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
113{
114 struct snd_soc_card *card = &mxs_sgtl5000;
115 int ret;
116
117 /*
118 * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
119 * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
120 * should be >= 8MHz and <= 27M.
121 */
122 ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
123 if (ret)
124 return ret;
125
126 card->dev = &pdev->dev;
127 platform_set_drvdata(pdev, card);
128
129 ret = snd_soc_register_card(card);
130 if (ret) {
131 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
132 ret);
133 return ret;
134 }
135
136 return 0;
137}
138
139static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
140{
141 struct snd_soc_card *card = platform_get_drvdata(pdev);
142
143 mxs_saif_put_mclk(0);
144
145 snd_soc_unregister_card(card);
146
147 return 0;
148}
149
150static struct platform_driver mxs_sgtl5000_audio_driver = {
151 .driver = {
152 .name = "mxs-sgtl5000",
153 .owner = THIS_MODULE,
154 },
155 .probe = mxs_sgtl5000_probe,
156 .remove = __devexit_p(mxs_sgtl5000_remove),
157};
158
159static int __init mxs_sgtl5000_init(void)
160{
161 return platform_driver_register(&mxs_sgtl5000_audio_driver);
162}
163module_init(mxs_sgtl5000_init);
164
165static void __exit mxs_sgtl5000_exit(void)
166{
167 platform_driver_unregister(&mxs_sgtl5000_audio_driver);
168}
169module_exit(mxs_sgtl5000_exit);
170
171MODULE_AUTHOR("Freescale Semiconductor, Inc.");
172MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
173MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index d589ef14e917..ae8d6806966b 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -227,7 +227,7 @@ static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
227 return ret; 227 return ret;
228} 228}
229 229
230int nuc900_dma_getposition(struct snd_pcm_substream *substream, 230static int nuc900_dma_getposition(struct snd_pcm_substream *substream,
231 dma_addr_t *src, dma_addr_t *dst) 231 dma_addr_t *src, dma_addr_t *dst)
232{ 232{
233 struct snd_pcm_runtime *runtime = substream->runtime; 233 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -268,7 +268,7 @@ static int nuc900_dma_open(struct snd_pcm_substream *substream)
268 nuc900_audio = nuc900_ac97_data; 268 nuc900_audio = nuc900_ac97_data;
269 269
270 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt, 270 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt,
271 IRQF_DISABLED, "nuc900-dma", substream)) 271 0, "nuc900-dma", substream))
272 return -EBUSY; 272 return -EBUSY;
273 273
274 runtime->private_data = nuc900_audio; 274 runtime->private_data = nuc900_audio;
@@ -318,7 +318,6 @@ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) 318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
319{ 319{
320 struct snd_card *card = rtd->card->snd_card; 320 struct snd_card *card = rtd->card->snd_card;
321 struct snd_soc_dai *dai = rtd->cpu_dai;
322 struct snd_pcm *pcm = rtd->pcm; 321 struct snd_pcm *pcm = rtd->pcm;
323 322
324 if (!card->dev->dma_mask) 323 if (!card->dev->dma_mask)
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 59e2c8d1e38d..052fd758722e 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-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o 4snd-soc-omap-mcpdm-objs := omap-mcpdm.o
5snd-soc-omap-hdmi-objs := omap-hdmi.o 5snd-soc-omap-hdmi-objs := omap-hdmi.o
6 6
7obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 7obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 73dde4a1adc3..8da55e916451 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -43,26 +43,6 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret; 44 int ret;
45 45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_DSP_B |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_DSP_B |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */ 46 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 47 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
68 CODEC_CLOCK, SND_SOC_CLOCK_IN); 48 CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -110,28 +90,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
110 {"MICIN", NULL, "Mic In"}, 90 {"MICIN", NULL, "Mic In"},
111}; 91};
112 92
113static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
114{
115 struct snd_soc_codec *codec = rtd->codec;
116 struct snd_soc_dapm_context *dapm = &codec->dapm;
117
118 /* Add am3517-evm specific widgets */
119 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
120 ARRAY_SIZE(tlv320aic23_dapm_widgets));
121
122 /* Set up davinci-evm specific audio path audio_map */
123 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
124
125 /* always connected */
126 snd_soc_dapm_enable_pin(dapm, "Line Out");
127 snd_soc_dapm_enable_pin(dapm, "Line In");
128 snd_soc_dapm_enable_pin(dapm, "Mic In");
129
130 snd_soc_dapm_sync(dapm);
131
132 return 0;
133}
134
135/* Digital audio interface glue - connects codec <--> CPU */ 93/* Digital audio interface glue - connects codec <--> CPU */
136static struct snd_soc_dai_link am3517evm_dai = { 94static struct snd_soc_dai_link am3517evm_dai = {
137 .name = "TLV320AIC23", 95 .name = "TLV320AIC23",
@@ -140,7 +98,8 @@ static struct snd_soc_dai_link am3517evm_dai = {
140 .codec_dai_name = "tlv320aic23-hifi", 98 .codec_dai_name = "tlv320aic23-hifi",
141 .platform_name = "omap-pcm-audio", 99 .platform_name = "omap-pcm-audio",
142 .codec_name = "tlv320aic23-codec.2-001a", 100 .codec_name = "tlv320aic23-codec.2-001a",
143 .init = am3517evm_aic23_init, 101 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBM_CFM,
144 .ops = &am3517evm_ops, 103 .ops = &am3517evm_ops,
145}; 104};
146 105
@@ -149,6 +108,11 @@ static struct snd_soc_card snd_soc_am3517evm = {
149 .name = "am3517evm", 108 .name = "am3517evm",
150 .dai_link = &am3517evm_dai, 109 .dai_link = &am3517evm_dai,
151 .num_links = 1, 110 .num_links = 1,
111
112 .dapm_widgets = tlv320aic23_dapm_widgets,
113 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
114 .dapm_routes = audio_map,
115 .num_dapm_routes = ARRAY_SIZE(audio_map),
152}; 116};
153 117
154static struct platform_device *am3517evm_snd_device; 118static struct platform_device *am3517evm_snd_device;
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 0aa475f92efa..dcb7b689a4ea 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -569,7 +569,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
569 snd_soc_dapm_disable_pin(dapm, "Speaker"); 569 snd_soc_dapm_disable_pin(dapm, "Speaker");
570 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 570 snd_soc_dapm_disable_pin(dapm, "AGCIN");
571 snd_soc_dapm_disable_pin(dapm, "AGCOUT"); 571 snd_soc_dapm_disable_pin(dapm, "AGCOUT");
572 snd_soc_dapm_sync(dapm);
573 572
574 /* Add virtual switch */ 573 /* Add virtual switch */
575 ret = snd_soc_add_controls(codec, ams_delta_audio_controls, 574 ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index 0ae34702995b..84615a7de6ad 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -38,29 +38,8 @@ static int igep2_hw_params(struct snd_pcm_substream *substream,
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 *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 int ret; 41 int ret;
43 42
44 /* Set codec DAI configuration */
45 ret = snd_soc_dai_set_fmt(codec_dai,
46 SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0) {
50 printk(KERN_ERR "can't set codec DAI configuration\n");
51 return ret;
52 }
53
54 /* Set cpu DAI configuration */
55 ret = snd_soc_dai_set_fmt(cpu_dai,
56 SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF |
58 SND_SOC_DAIFMT_CBM_CFM);
59 if (ret < 0) {
60 printk(KERN_ERR "can't set cpu DAI configuration\n");
61 return ret;
62 }
63
64 /* Set the codec system clock for DAC and ADC */ 43 /* Set the codec system clock for DAC and ADC */
65 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
66 SND_SOC_CLOCK_IN); 45 SND_SOC_CLOCK_IN);
@@ -84,6 +63,8 @@ static struct snd_soc_dai_link igep2_dai = {
84 .codec_dai_name = "twl4030-hifi", 63 .codec_dai_name = "twl4030-hifi",
85 .platform_name = "omap-pcm-audio", 64 .platform_name = "omap-pcm-audio",
86 .codec_name = "twl4030-codec", 65 .codec_name = "twl4030-codec",
66 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBM_CFM,
87 .ops = &igep2_ops, 68 .ops = &igep2_ops,
88}; 69};
89 70
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
deleted file mode 100644
index 50e59194ad81..000000000000
--- a/sound/soc/omap/mcpdm.c
+++ /dev/null
@@ -1,470 +0,0 @@
1/*
2 * mcpdm.c -- McPDM interface driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc.
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/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/wait.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/delay.h>
33#include <linux/io.h>
34#include <linux/irq.h>
35
36#include "mcpdm.h"
37
38static struct omap_mcpdm *mcpdm;
39
40static inline void omap_mcpdm_write(u16 reg, u32 val)
41{
42 __raw_writel(val, mcpdm->io_base + reg);
43}
44
45static inline int omap_mcpdm_read(u16 reg)
46{
47 return __raw_readl(mcpdm->io_base + reg);
48}
49
50static void omap_mcpdm_reg_dump(void)
51{
52 dev_dbg(mcpdm->dev, "***********************\n");
53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
56 omap_mcpdm_read(MCPDM_IRQSTATUS));
57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
58 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
62 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
64 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
68 omap_mcpdm_read(MCPDM_DMAWAKEEN));
69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
70 omap_mcpdm_read(MCPDM_CTRL));
71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
72 omap_mcpdm_read(MCPDM_DN_DATA));
73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
74 omap_mcpdm_read(MCPDM_UP_DATA));
75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
80 omap_mcpdm_read(MCPDM_DN_OFFSET));
81 dev_dbg(mcpdm->dev, "***********************\n");
82}
83
84/*
85 * Takes the McPDM module in and out of reset state.
86 * Uplink and downlink can be reset individually.
87 */
88static void omap_mcpdm_reset_capture(int reset)
89{
90 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
91
92 if (reset)
93 ctrl |= SW_UP_RST;
94 else
95 ctrl &= ~SW_UP_RST;
96
97 omap_mcpdm_write(MCPDM_CTRL, ctrl);
98}
99
100static void omap_mcpdm_reset_playback(int reset)
101{
102 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
103
104 if (reset)
105 ctrl |= SW_DN_RST;
106 else
107 ctrl &= ~SW_DN_RST;
108
109 omap_mcpdm_write(MCPDM_CTRL, ctrl);
110}
111
112/*
113 * Enables the transfer through the PDM interface to/from the Phoenix
114 * codec by enabling the corresponding UP or DN channels.
115 */
116void omap_mcpdm_start(int stream)
117{
118 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
119
120 if (stream)
121 ctrl |= mcpdm->up_channels;
122 else
123 ctrl |= mcpdm->dn_channels;
124
125 omap_mcpdm_write(MCPDM_CTRL, ctrl);
126}
127
128/*
129 * Disables the transfer through the PDM interface to/from the Phoenix
130 * codec by disabling the corresponding UP or DN channels.
131 */
132void omap_mcpdm_stop(int stream)
133{
134 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
135
136 if (stream)
137 ctrl &= ~mcpdm->up_channels;
138 else
139 ctrl &= ~mcpdm->dn_channels;
140
141 omap_mcpdm_write(MCPDM_CTRL, ctrl);
142}
143
144/*
145 * Configures McPDM uplink for audio recording.
146 * This function should be called before omap_mcpdm_start.
147 */
148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
149{
150 int irq_mask = 0;
151 int ctrl;
152
153 if (!uplink)
154 return -EINVAL;
155
156 mcpdm->uplink = uplink;
157
158 /* Enable irq request generation */
159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
161
162 /* Configure uplink threshold */
163 if (uplink->threshold > UP_THRES_MAX)
164 uplink->threshold = UP_THRES_MAX;
165
166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
167
168 /* Configure DMA controller */
169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
170
171 /* Set pdm out format */
172 ctrl = omap_mcpdm_read(MCPDM_CTRL);
173 ctrl &= ~PDMOUTFORMAT;
174 ctrl |= uplink->format & PDMOUTFORMAT;
175
176 /* Uplink channels */
177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
178
179 omap_mcpdm_write(MCPDM_CTRL, ctrl);
180
181 return 0;
182}
183
184/*
185 * Configures McPDM downlink for audio playback.
186 * This function should be called before omap_mcpdm_start.
187 */
188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
189{
190 int irq_mask = 0;
191 int ctrl;
192
193 if (!downlink)
194 return -EINVAL;
195
196 mcpdm->downlink = downlink;
197
198 /* Enable irq request generation */
199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
201
202 /* Configure uplink threshold */
203 if (downlink->threshold > DN_THRES_MAX)
204 downlink->threshold = DN_THRES_MAX;
205
206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
207
208 /* Enable DMA request generation */
209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
210
211 /* Set pdm out format */
212 ctrl = omap_mcpdm_read(MCPDM_CTRL);
213 ctrl &= ~PDMOUTFORMAT;
214 ctrl |= downlink->format & PDMOUTFORMAT;
215
216 /* Downlink channels */
217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
218
219 omap_mcpdm_write(MCPDM_CTRL, ctrl);
220
221 return 0;
222}
223
224/*
225 * Cleans McPDM uplink configuration.
226 * This function should be called when the stream is closed.
227 */
228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
229{
230 int irq_mask = 0;
231
232 if (!uplink)
233 return -EINVAL;
234
235 /* Disable irq request generation */
236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
238
239 /* Disable DMA request generation */
240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
241
242 /* Clear Downlink channels */
243 mcpdm->up_channels = 0;
244
245 mcpdm->uplink = NULL;
246
247 return 0;
248}
249
250/*
251 * Cleans McPDM downlink configuration.
252 * This function should be called when the stream is closed.
253 */
254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
255{
256 int irq_mask = 0;
257
258 if (!downlink)
259 return -EINVAL;
260
261 /* Disable irq request generation */
262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
264
265 /* Disable DMA request generation */
266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
267
268 /* clear Downlink channels */
269 mcpdm->dn_channels = 0;
270
271 mcpdm->downlink = NULL;
272
273 return 0;
274}
275
276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
277{
278 struct omap_mcpdm *mcpdm_irq = dev_id;
279 int irq_status;
280
281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
282
283 /* Acknowledge irq event */
284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
285
286 if (irq & MCPDM_DN_IRQ_FULL) {
287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
288 omap_mcpdm_reset_playback(1);
289 omap_mcpdm_playback_open(mcpdm_irq->downlink);
290 omap_mcpdm_reset_playback(0);
291 }
292
293 if (irq & MCPDM_DN_IRQ_EMPTY) {
294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
295 omap_mcpdm_reset_playback(1);
296 omap_mcpdm_playback_open(mcpdm_irq->downlink);
297 omap_mcpdm_reset_playback(0);
298 }
299
300 if (irq & MCPDM_DN_IRQ) {
301 dev_dbg(mcpdm_irq->dev, "DN write request\n");
302 }
303
304 if (irq & MCPDM_UP_IRQ_FULL) {
305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
306 omap_mcpdm_reset_capture(1);
307 omap_mcpdm_capture_open(mcpdm_irq->uplink);
308 omap_mcpdm_reset_capture(0);
309 }
310
311 if (irq & MCPDM_UP_IRQ_EMPTY) {
312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
313 omap_mcpdm_reset_capture(1);
314 omap_mcpdm_capture_open(mcpdm_irq->uplink);
315 omap_mcpdm_reset_capture(0);
316 }
317
318 if (irq & MCPDM_UP_IRQ) {
319 dev_dbg(mcpdm_irq->dev, "UP write request\n");
320 }
321
322 return IRQ_HANDLED;
323}
324
325int omap_mcpdm_request(void)
326{
327 int ret;
328
329 clk_enable(mcpdm->clk);
330
331 spin_lock(&mcpdm->lock);
332
333 if (!mcpdm->free) {
334 dev_err(mcpdm->dev, "McPDM interface is in use\n");
335 spin_unlock(&mcpdm->lock);
336 ret = -EBUSY;
337 goto err;
338 }
339 mcpdm->free = 0;
340
341 spin_unlock(&mcpdm->lock);
342
343 /* Disable lines while request is ongoing */
344 omap_mcpdm_write(MCPDM_CTRL, 0x00);
345
346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
347 0, "McPDM", (void *)mcpdm);
348 if (ret) {
349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
350 goto err;
351 }
352
353 return 0;
354
355err:
356 clk_disable(mcpdm->clk);
357 return ret;
358}
359
360void omap_mcpdm_free(void)
361{
362 spin_lock(&mcpdm->lock);
363 if (mcpdm->free) {
364 dev_err(mcpdm->dev, "McPDM interface is already free\n");
365 spin_unlock(&mcpdm->lock);
366 return;
367 }
368 mcpdm->free = 1;
369 spin_unlock(&mcpdm->lock);
370
371 clk_disable(mcpdm->clk);
372
373 free_irq(mcpdm->irq, (void *)mcpdm);
374}
375
376/* Enable/disable DC offset cancelation for the analog
377 * headset path (PDM channels 1 and 2).
378 */
379int omap_mcpdm_set_offset(int offset1, int offset2)
380{
381 int offset;
382
383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
384 return -EINVAL;
385
386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
387
388 /* offset cancellation for channel 1 */
389 if (offset1)
390 offset |= DN_OFST_RX1_EN;
391 else
392 offset &= ~DN_OFST_RX1_EN;
393
394 /* offset cancellation for channel 2 */
395 if (offset2)
396 offset |= DN_OFST_RX2_EN;
397 else
398 offset &= ~DN_OFST_RX2_EN;
399
400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
401
402 return 0;
403}
404
405int __devinit omap_mcpdm_probe(struct platform_device *pdev)
406{
407 struct resource *res;
408 int ret = 0;
409
410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
411 if (!mcpdm) {
412 ret = -ENOMEM;
413 goto exit;
414 }
415
416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417 if (res == NULL) {
418 dev_err(&pdev->dev, "no resource\n");
419 goto err_resource;
420 }
421
422 spin_lock_init(&mcpdm->lock);
423 mcpdm->free = 1;
424 mcpdm->io_base = ioremap(res->start, resource_size(res));
425 if (!mcpdm->io_base) {
426 ret = -ENOMEM;
427 goto err_resource;
428 }
429
430 mcpdm->irq = platform_get_irq(pdev, 0);
431
432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
433 if (IS_ERR(mcpdm->clk)) {
434 ret = PTR_ERR(mcpdm->clk);
435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
436 goto err_clk;
437 }
438
439 mcpdm->dev = &pdev->dev;
440 platform_set_drvdata(pdev, mcpdm);
441
442 return 0;
443
444err_clk:
445 iounmap(mcpdm->io_base);
446err_resource:
447 kfree(mcpdm);
448exit:
449 return ret;
450}
451
452int omap_mcpdm_remove(struct platform_device *pdev)
453{
454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
455
456 platform_set_drvdata(pdev, NULL);
457
458 clk_put(mcpdm_ptr->clk);
459
460 iounmap(mcpdm_ptr->io_base);
461
462 mcpdm_ptr->clk = NULL;
463 mcpdm_ptr->free = 0;
464 mcpdm_ptr->dev = NULL;
465
466 kfree(mcpdm_ptr);
467
468 return 0;
469}
470
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
deleted file mode 100644
index 20c20a8649fe..000000000000
--- a/sound/soc/omap/mcpdm.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * mcpdm.h -- Defines for McPDM driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@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/* McPDM registers */
23
24#define MCPDM_REVISION 0x00
25#define MCPDM_SYSCONFIG 0x10
26#define MCPDM_IRQSTATUS_RAW 0x24
27#define MCPDM_IRQSTATUS 0x28
28#define MCPDM_IRQENABLE_SET 0x2C
29#define MCPDM_IRQENABLE_CLR 0x30
30#define MCPDM_IRQWAKE_EN 0x34
31#define MCPDM_DMAENABLE_SET 0x38
32#define MCPDM_DMAENABLE_CLR 0x3C
33#define MCPDM_DMAWAKEEN 0x40
34#define MCPDM_CTRL 0x44
35#define MCPDM_DN_DATA 0x48
36#define MCPDM_UP_DATA 0x4C
37#define MCPDM_FIFO_CTRL_DN 0x50
38#define MCPDM_FIFO_CTRL_UP 0x54
39#define MCPDM_DN_OFFSET 0x58
40
41/*
42 * MCPDM_IRQ bit fields
43 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
44 */
45
46#define MCPDM_DN_IRQ (1 << 0)
47#define MCPDM_DN_IRQ_EMPTY (1 << 1)
48#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
49#define MCPDM_DN_IRQ_FULL (1 << 3)
50
51#define MCPDM_UP_IRQ (1 << 8)
52#define MCPDM_UP_IRQ_EMPTY (1 << 9)
53#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
54#define MCPDM_UP_IRQ_FULL (1 << 11)
55
56#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
57#define MCPDM_UPLINK_IRQ_MASK 0xF00
58
59/*
60 * MCPDM_DMAENABLE bit fields
61 */
62
63#define DMA_DN_ENABLE 0x1
64#define DMA_UP_ENABLE 0x2
65
66/*
67 * MCPDM_CTRL bit fields
68 */
69
70#define PDM_UP1_EN 0x0001
71#define PDM_UP2_EN 0x0002
72#define PDM_UP3_EN 0x0004
73#define PDM_DN1_EN 0x0008
74#define PDM_DN2_EN 0x0010
75#define PDM_DN3_EN 0x0020
76#define PDM_DN4_EN 0x0040
77#define PDM_DN5_EN 0x0080
78#define PDMOUTFORMAT 0x0100
79#define CMD_INT 0x0200
80#define STATUS_INT 0x0400
81#define SW_UP_RST 0x0800
82#define SW_DN_RST 0x1000
83#define PDM_UP_MASK 0x007
84#define PDM_DN_MASK 0x0F8
85#define PDM_CMD_MASK 0x200
86#define PDM_STATUS_MASK 0x400
87
88
89#define PDMOUTFORMAT_LJUST (0 << 8)
90#define PDMOUTFORMAT_RJUST (1 << 8)
91
92/*
93 * MCPDM_FIFO_CTRL bit fields
94 */
95
96#define UP_THRES_MAX 0xF
97#define DN_THRES_MAX 0xF
98
99/*
100 * MCPDM_DN_OFFSET bit fields
101 */
102
103#define DN_OFST_RX1_EN 0x0001
104#define DN_OFST_RX2_EN 0x0100
105
106#define DN_OFST_RX1 1
107#define DN_OFST_RX2 9
108#define DN_OFST_MAX 0x1F
109
110#define MCPDM_UPLINK 1
111#define MCPDM_DOWNLINK 2
112
113struct omap_mcpdm_link {
114 int irq_mask;
115 int threshold;
116 int format;
117 int channels;
118};
119
120struct omap_mcpdm_platform_data {
121 unsigned long phys_base;
122 u16 irq;
123};
124
125struct omap_mcpdm {
126 struct device *dev;
127 unsigned long phys_base;
128 void __iomem *io_base;
129 u8 free;
130 int irq;
131
132 spinlock_t lock;
133 struct omap_mcpdm_platform_data *pdata;
134 struct clk *clk;
135 struct omap_mcpdm_link *downlink;
136 struct omap_mcpdm_link *uplink;
137 struct completion irq_completion;
138
139 int dn_channels;
140 int up_channels;
141};
142
143extern void omap_mcpdm_start(int stream);
144extern void omap_mcpdm_stop(int stream);
145extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink);
146extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink);
147extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink);
148extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2);
152int __devinit omap_mcpdm_probe(struct platform_device *pdev);
153int omap_mcpdm_remove(struct platform_device *pdev);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 62e292f49313..7e3c20c965c6 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -115,25 +115,8 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
115{ 115{
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 116 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *codec_dai = rtd->codec_dai; 117 struct snd_soc_dai *codec_dai = rtd->codec_dai;
118 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
119 int err; 118 int err;
120 119
121 /* Set codec DAI configuration */
122 err = snd_soc_dai_set_fmt(codec_dai,
123 SND_SOC_DAIFMT_I2S |
124 SND_SOC_DAIFMT_NB_NF |
125 SND_SOC_DAIFMT_CBM_CFM);
126 if (err < 0)
127 return err;
128
129 /* Set cpu DAI configuration */
130 err = snd_soc_dai_set_fmt(cpu_dai,
131 SND_SOC_DAIFMT_I2S |
132 SND_SOC_DAIFMT_NB_NF |
133 SND_SOC_DAIFMT_CBM_CFM);
134 if (err < 0)
135 return err;
136
137 /* Set the codec system clock for DAC and ADC */ 120 /* Set the codec system clock for DAC and ADC */
138 err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, 121 err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000,
139 SND_SOC_CLOCK_IN); 122 SND_SOC_CLOCK_IN);
@@ -274,7 +257,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
274{ 257{
275 struct snd_soc_codec *codec = rtd->codec; 258 struct snd_soc_codec *codec = rtd->codec;
276 struct snd_soc_dapm_context *dapm = &codec->dapm; 259 struct snd_soc_dapm_context *dapm = &codec->dapm;
277 int err;
278 260
279 /* Not connected */ 261 /* Not connected */
280 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); 262 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
@@ -286,21 +268,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
286 snd_soc_dapm_nc_pin(dapm, "LINE2L"); 268 snd_soc_dapm_nc_pin(dapm, "LINE2L");
287 snd_soc_dapm_nc_pin(dapm, "LINE2R"); 269 snd_soc_dapm_nc_pin(dapm, "LINE2R");
288 270
289 /* Add N810 specific controls */
290 err = snd_soc_add_controls(codec, aic33_n810_controls,
291 ARRAY_SIZE(aic33_n810_controls));
292 if (err < 0)
293 return err;
294
295 /* Add N810 specific widgets */
296 snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets,
297 ARRAY_SIZE(aic33_dapm_widgets));
298
299 /* Set up N810 specific audio path audio_map */
300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301
302 snd_soc_dapm_sync(dapm);
303
304 return 0; 271 return 0;
305} 272}
306 273
@@ -312,6 +279,8 @@ static struct snd_soc_dai_link n810_dai = {
312 .platform_name = "omap-pcm-audio", 279 .platform_name = "omap-pcm-audio",
313 .codec_name = "tlv320aic3x-codec.2-0018", 280 .codec_name = "tlv320aic3x-codec.2-0018",
314 .codec_dai_name = "tlv320aic3x-hifi", 281 .codec_dai_name = "tlv320aic3x-hifi",
282 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
283 SND_SOC_DAIFMT_CBM_CFM,
315 .init = n810_aic33_init, 284 .init = n810_aic33_init,
316 .ops = &n810_ops, 285 .ops = &n810_ops,
317}; 286};
@@ -321,6 +290,13 @@ static struct snd_soc_card snd_soc_n810 = {
321 .name = "N810", 290 .name = "N810",
322 .dai_link = &n810_dai, 291 .dai_link = &n810_dai,
323 .num_links = 1, 292 .num_links = 1,
293
294 .controls = aic33_n810_controls,
295 .num_controls = ARRAY_SIZE(aic33_n810_controls),
296 .dapm_widgets = aic33_dapm_widgets,
297 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
298 .dapm_routes = audio_map,
299 .num_dapm_routes = ARRAY_SIZE(audio_map),
324}; 300};
325 301
326static struct platform_device *n810_snd_device; 302static struct platform_device *n810_snd_device;
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 478d60778453..4314647e735e 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -317,6 +317,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
317 return 0; 317 return 0;
318 } 318 }
319 319
320 regs->rcr2 &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7));
321 regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
322 regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
323 regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
320 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 324 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
321 wpf = channels = params_channels(params); 325 wpf = channels = params_channels(params);
322 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || 326 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
@@ -369,6 +373,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
369 framesize = wlen * channels; 373 framesize = wlen * channels;
370 374
371 /* Set FS period and length in terms of bit clock periods */ 375 /* Set FS period and length in terms of bit clock periods */
376 regs->srgr2 &= ~FPER(0xfff);
377 regs->srgr1 &= ~FWID(0xff);
372 switch (format) { 378 switch (format) {
373 case SND_SOC_DAIFMT_I2S: 379 case SND_SOC_DAIFMT_I2S:
374 case SND_SOC_DAIFMT_LEFT_J: 380 case SND_SOC_DAIFMT_LEFT_J:
@@ -398,7 +404,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
398{ 404{
399 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 405 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
400 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 406 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
401 unsigned int temp_fmt = fmt; 407 bool inv_fs = false;
402 408
403 if (mcbsp_data->configured) 409 if (mcbsp_data->configured)
404 return 0; 410 return 0;
@@ -430,21 +436,21 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
430 regs->xcr2 |= XDATDLY(0); 436 regs->xcr2 |= XDATDLY(0);
431 regs->spcr1 |= RJUST(2); 437 regs->spcr1 |= RJUST(2);
432 /* Invert FS polarity configuration */ 438 /* Invert FS polarity configuration */
433 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 439 inv_fs = true;
434 break; 440 break;
435 case SND_SOC_DAIFMT_DSP_A: 441 case SND_SOC_DAIFMT_DSP_A:
436 /* 1-bit data delay */ 442 /* 1-bit data delay */
437 regs->rcr2 |= RDATDLY(1); 443 regs->rcr2 |= RDATDLY(1);
438 regs->xcr2 |= XDATDLY(1); 444 regs->xcr2 |= XDATDLY(1);
439 /* Invert FS polarity configuration */ 445 /* Invert FS polarity configuration */
440 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 446 inv_fs = true;
441 break; 447 break;
442 case SND_SOC_DAIFMT_DSP_B: 448 case SND_SOC_DAIFMT_DSP_B:
443 /* 0-bit data delay */ 449 /* 0-bit data delay */
444 regs->rcr2 |= RDATDLY(0); 450 regs->rcr2 |= RDATDLY(0);
445 regs->xcr2 |= XDATDLY(0); 451 regs->xcr2 |= XDATDLY(0);
446 /* Invert FS polarity configuration */ 452 /* Invert FS polarity configuration */
447 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 453 inv_fs = true;
448 break; 454 break;
449 default: 455 default:
450 /* Unsupported data format */ 456 /* Unsupported data format */
@@ -468,7 +474,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
468 } 474 }
469 475
470 /* Set bit clock (CLKX/CLKR) and FS polarities */ 476 /* Set bit clock (CLKX/CLKR) and FS polarities */
471 switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) { 477 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
472 case SND_SOC_DAIFMT_NB_NF: 478 case SND_SOC_DAIFMT_NB_NF:
473 /* 479 /*
474 * Normal BCLK + FS. 480 * Normal BCLK + FS.
@@ -489,6 +495,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
489 default: 495 default:
490 return -EINVAL; 496 return -EINVAL;
491 } 497 }
498 if (inv_fs == true)
499 regs->pcr0 ^= FSXP | FSRP;
492 500
493 return 0; 501 return 0;
494} 502}
@@ -503,6 +511,7 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
503 return -ENODEV; 511 return -ENODEV;
504 512
505 mcbsp_data->clk_div = div; 513 mcbsp_data->clk_div = div;
514 regs->srgr1 &= ~CLKGDV(0xff);
506 regs->srgr1 |= CLKGDV(div - 1); 515 regs->srgr1 |= CLKGDV(div - 1);
507 516
508 return 0; 517 return 0;
@@ -516,11 +525,12 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
516 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 525 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
517 int err = 0; 526 int err = 0;
518 527
519 if (mcbsp_data->active) 528 if (mcbsp_data->active) {
520 if (freq == mcbsp_data->in_freq) 529 if (freq == mcbsp_data->in_freq)
521 return 0; 530 return 0;
522 else 531 else
523 return -EBUSY; 532 return -EBUSY;
533 }
524 534
525 /* The McBSP signal muxing functions are only available on McBSP1 */ 535 /* The McBSP signal muxing functions are only available on McBSP1 */
526 if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || 536 if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR ||
@@ -531,6 +541,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
531 return -EINVAL; 541 return -EINVAL;
532 542
533 mcbsp_data->in_freq = freq; 543 mcbsp_data->in_freq = freq;
544 regs->srgr2 &= ~CLKSM;
545 regs->pcr0 &= ~SCLKME;
534 546
535 switch (clk_id) { 547 switch (clk_id) {
536 case OMAP_MCBSP_SYSCLK_CLK: 548 case OMAP_MCBSP_SYSCLK_CLK:
@@ -605,8 +617,7 @@ static int mcbsp_dai_probe(struct snd_soc_dai *dai)
605 return 0; 617 return 0;
606} 618}
607 619
608static struct snd_soc_dai_driver omap_mcbsp_dai = 620static struct snd_soc_dai_driver omap_mcbsp_dai = {
609{
610 .probe = mcbsp_dai_probe, 621 .probe = mcbsp_dai_probe,
611 .playback = { 622 .playback = {
612 .channels_min = 1, 623 .channels_min = 1,
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index bed09c27e44c..41d17067cc73 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -1,11 +1,12 @@
1/* 1/*
2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port 2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
3 * 3 *
4 * Copyright (C) 2009 Texas Instruments 4 * Copyright (C) 2009 - 2011 Texas Instruments
5 * 5 *
6 * Author: Misael Lopez Cruz <x0052729@ti.com> 6 * Author: Misael Lopez Cruz <misael.lopez@ti.com>
7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com> 7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
8 * Margarita Olaya <magi.olaya@ti.com> 8 * Margarita Olaya <magi.olaya@ti.com>
9 * Peter Ujfalusi <peter.ujfalusi@ti.com>
9 * 10 *
10 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -25,41 +26,42 @@
25 26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/interrupt.h>
31#include <linux/err.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34#include <linux/slab.h>
35#include <linux/pm_runtime.h>
36
29#include <sound/core.h> 37#include <sound/core.h>
30#include <sound/pcm.h> 38#include <sound/pcm.h>
31#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
32#include <sound/initval.h>
33#include <sound/soc.h> 40#include <sound/soc.h>
34 41
35#include <plat/dma.h> 42#include <plat/dma.h>
36#include <plat/mcbsp.h> 43#include <plat/omap_hwmod.h>
37#include "mcpdm.h" 44#include "omap-mcpdm.h"
38#include "omap-pcm.h" 45#include "omap-pcm.h"
39 46
40struct omap_mcpdm_data { 47struct omap_mcpdm {
41 struct omap_mcpdm_link *links; 48 struct device *dev;
42 int active; 49 unsigned long phys_base;
43}; 50 void __iomem *io_base;
51 int irq;
44 52
45static struct omap_mcpdm_link omap_mcpdm_links[] = { 53 struct mutex mutex;
46 /* downlink */ 54
47 { 55 /* channel data */
48 .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL, 56 u32 dn_channels;
49 .threshold = 1, 57 u32 up_channels;
50 .format = PDMOUTFORMAT_LJUST, 58
51 }, 59 /* McPDM FIFO thresholds */
52 /* uplink */ 60 u32 dn_threshold;
53 { 61 u32 up_threshold;
54 .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL,
55 .threshold = 1,
56 .format = PDMOUTFORMAT_LJUST,
57 },
58};
59 62
60static struct omap_mcpdm_data mcpdm_data = { 63 /* McPDM dn offsets for rx1, and 2 channels */
61 .links = omap_mcpdm_links, 64 u32 dn_rx_offset;
62 .active = 0,
63}; 65};
64 66
65/* 67/*
@@ -71,88 +73,259 @@ static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
71 .dma_req = OMAP44XX_DMA_MCPDM_DL, 73 .dma_req = OMAP44XX_DMA_MCPDM_DL,
72 .data_type = OMAP_DMA_DATA_TYPE_S32, 74 .data_type = OMAP_DMA_DATA_TYPE_S32,
73 .sync_mode = OMAP_DMA_SYNC_PACKET, 75 .sync_mode = OMAP_DMA_SYNC_PACKET,
74 .packet_size = 16, 76 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
75 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA,
76 }, 77 },
77 { 78 {
78 .name = "Audio capture", 79 .name = "Audio capture",
79 .dma_req = OMAP44XX_DMA_MCPDM_UP, 80 .dma_req = OMAP44XX_DMA_MCPDM_UP,
80 .data_type = OMAP_DMA_DATA_TYPE_S32, 81 .data_type = OMAP_DMA_DATA_TYPE_S32,
81 .sync_mode = OMAP_DMA_SYNC_PACKET, 82 .sync_mode = OMAP_DMA_SYNC_PACKET,
82 .packet_size = 16, 83 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
83 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA,
84 }, 84 },
85}; 85};
86 86
87static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, 87static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
88 struct snd_soc_dai *dai)
89{ 88{
90 int err = 0; 89 __raw_writel(val, mcpdm->io_base + reg);
90}
91 91
92 if (!dai->active) 92static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg)
93 err = omap_mcpdm_request(); 93{
94 return __raw_readl(mcpdm->io_base + reg);
95}
94 96
95 return err; 97#ifdef DEBUG
98static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm)
99{
100 dev_dbg(mcpdm->dev, "***********************\n");
101 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
102 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS_RAW));
103 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
104 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS));
105 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
106 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_SET));
107 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
108 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_CLR));
109 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
110 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQWAKE_EN));
111 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
112 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_SET));
113 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
114 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_CLR));
115 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
116 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAWAKEEN));
117 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
118 omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL));
119 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
120 omap_mcpdm_read(mcpdm, MCPDM_REG_DN_DATA));
121 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
122 omap_mcpdm_read(mcpdm, MCPDM_REG_UP_DATA));
123 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
124 omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_DN));
125 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
126 omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_UP));
127 dev_dbg(mcpdm->dev, "***********************\n");
96} 128}
129#else
130static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
131#endif
97 132
98static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, 133/*
99 struct snd_soc_dai *dai) 134 * Enables the transfer through the PDM interface to/from the Phoenix
135 * codec by enabling the corresponding UP or DN channels.
136 */
137static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
138{
139 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
140
141 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
142 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
143
144 ctrl |= mcpdm->dn_channels | mcpdm->up_channels;
145 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
146
147 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
148 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
149}
150
151/*
152 * Disables the transfer through the PDM interface to/from the Phoenix
153 * codec by disabling the corresponding UP or DN channels.
154 */
155static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
156{
157 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
158
159 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
160 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
161
162 ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels);
163 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
164
165 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
166 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
167
168}
169
170/*
171 * Is the physical McPDM interface active.
172 */
173static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm)
174{
175 return omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL) &
176 (MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK);
177}
178
179/*
180 * Configures McPDM uplink, and downlink for audio.
181 * This function should be called before omap_mcpdm_start.
182 */
183static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
184{
185 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET,
186 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL |
187 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
188
189 /* Enable DN RX1/2 offset cancellation feature, if configured */
190 if (mcpdm->dn_rx_offset) {
191 u32 dn_offset = mcpdm->dn_rx_offset;
192
193 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
194 dn_offset |= (MCPDM_DN_OFST_RX1_EN | MCPDM_DN_OFST_RX2_EN);
195 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
196 }
197
198 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold);
199 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
200
201 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
202 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
203}
204
205/*
206 * Cleans McPDM uplink, and downlink configuration.
207 * This function should be called when the stream is closed.
208 */
209static void omap_mcpdm_close_streams(struct omap_mcpdm *mcpdm)
210{
211 /* Disable irq request generation for downlink */
212 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
213 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL);
214
215 /* Disable DMA request generation for downlink */
216 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_DN_ENABLE);
217
218 /* Disable irq request generation for uplink */
219 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
220 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
221
222 /* Disable DMA request generation for uplink */
223 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_UP_ENABLE);
224
225 /* Disable RX1/2 offset cancellation */
226 if (mcpdm->dn_rx_offset)
227 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, 0);
228}
229
230static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
231{
232 struct omap_mcpdm *mcpdm = dev_id;
233 int irq_status;
234
235 irq_status = omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS);
236
237 /* Acknowledge irq event */
238 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQSTATUS, irq_status);
239
240 if (irq_status & MCPDM_DN_IRQ_FULL)
241 dev_dbg(mcpdm->dev, "DN (playback) FIFO Full\n");
242
243 if (irq_status & MCPDM_DN_IRQ_EMPTY)
244 dev_dbg(mcpdm->dev, "DN (playback) FIFO Empty\n");
245
246 if (irq_status & MCPDM_DN_IRQ)
247 dev_dbg(mcpdm->dev, "DN (playback) write request\n");
248
249 if (irq_status & MCPDM_UP_IRQ_FULL)
250 dev_dbg(mcpdm->dev, "UP (capture) FIFO Full\n");
251
252 if (irq_status & MCPDM_UP_IRQ_EMPTY)
253 dev_dbg(mcpdm->dev, "UP (capture) FIFO Empty\n");
254
255 if (irq_status & MCPDM_UP_IRQ)
256 dev_dbg(mcpdm->dev, "UP (capture) write request\n");
257
258 return IRQ_HANDLED;
259}
260
261static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
100{ 263{
101 if (!dai->active) 264 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
102 omap_mcpdm_free(); 265
266 mutex_lock(&mcpdm->mutex);
267
268 if (!dai->active) {
269 pm_runtime_get_sync(mcpdm->dev);
270
271 /* Enable watch dog for ES above ES 1.0 to avoid saturation */
272 if (omap_rev() != OMAP4430_REV_ES1_0) {
273 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
274
275 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL,
276 ctrl | MCPDM_WD_EN);
277 }
278 omap_mcpdm_open_streams(mcpdm);
279 }
280
281 mutex_unlock(&mcpdm->mutex);
282
283 return 0;
103} 284}
104 285
105static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, 286static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai) 287 struct snd_soc_dai *dai)
107{ 288{
108 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 289 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
109 int stream = substream->stream;
110 int err = 0;
111
112 switch (cmd) {
113 case SNDRV_PCM_TRIGGER_START:
114 case SNDRV_PCM_TRIGGER_RESUME:
115 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
116 if (!mcpdm_priv->active++)
117 omap_mcpdm_start(stream);
118 break;
119 290
120 case SNDRV_PCM_TRIGGER_STOP: 291 mutex_lock(&mcpdm->mutex);
121 case SNDRV_PCM_TRIGGER_SUSPEND: 292
122 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 293 if (!dai->active) {
123 if (!--mcpdm_priv->active) 294 if (omap_mcpdm_active(mcpdm)) {
124 omap_mcpdm_stop(stream); 295 omap_mcpdm_stop(mcpdm);
125 break; 296 omap_mcpdm_close_streams(mcpdm);
126 default: 297 }
127 err = -EINVAL; 298
299 if (!omap_mcpdm_active(mcpdm))
300 pm_runtime_put_sync(mcpdm->dev);
128 } 301 }
129 302
130 return err; 303 mutex_unlock(&mcpdm->mutex);
131} 304}
132 305
133static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, 306static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *params, 307 struct snd_pcm_hw_params *params,
135 struct snd_soc_dai *dai) 308 struct snd_soc_dai *dai)
136{ 309{
137 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 310 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
138 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
139 int stream = substream->stream; 311 int stream = substream->stream;
140 int channels, err, link_mask = 0; 312 struct omap_pcm_dma_data *dma_data;
141 313 int channels;
142 snd_soc_dai_set_dma_data(dai, substream, 314 int link_mask = 0;
143 &omap_mcpdm_dai_dma_params[stream]);
144 315
145 channels = params_channels(params); 316 channels = params_channels(params);
146 switch (channels) { 317 switch (channels) {
318 case 5:
319 if (stream == SNDRV_PCM_STREAM_CAPTURE)
320 /* up to 3 channels for capture */
321 return -EINVAL;
322 link_mask |= 1 << 4;
147 case 4: 323 case 4:
148 if (stream == SNDRV_PCM_STREAM_CAPTURE) 324 if (stream == SNDRV_PCM_STREAM_CAPTURE)
149 /* up to 2 channels for capture */ 325 /* up to 3 channels for capture */
150 return -EINVAL; 326 return -EINVAL;
151 link_mask |= 1 << 3; 327 link_mask |= 1 << 3;
152 case 3: 328 case 3:
153 if (stream == SNDRV_PCM_STREAM_CAPTURE)
154 /* up to 2 channels for capture */
155 return -EINVAL;
156 link_mask |= 1 << 2; 329 link_mask |= 1 << 2;
157 case 2: 330 case 2:
158 link_mask |= 1 << 1; 331 link_mask |= 1 << 1;
@@ -164,95 +337,187 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
164 return -EINVAL; 337 return -EINVAL;
165 } 338 }
166 339
340 dma_data = &omap_mcpdm_dai_dma_params[stream];
341
342 /* Configure McPDM channels, and DMA packet size */
167 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 343 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
168 mcpdm_links[stream].channels = link_mask << 3; 344 mcpdm->dn_channels = link_mask << 3;
169 err = omap_mcpdm_playback_open(&mcpdm_links[stream]); 345 dma_data->packet_size =
346 (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels;
170 } else { 347 } else {
171 mcpdm_links[stream].channels = link_mask << 0; 348 mcpdm->up_channels = link_mask << 0;
172 err = omap_mcpdm_capture_open(&mcpdm_links[stream]); 349 dma_data->packet_size = mcpdm->up_threshold * channels;
173 } 350 }
174 351
175 return err; 352 snd_soc_dai_set_dma_data(dai, substream, dma_data);
353
354 return 0;
176} 355}
177 356
178static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, 357static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
179 struct snd_soc_dai *dai) 358 struct snd_soc_dai *dai)
180{ 359{
181 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 360 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
182 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
183 int stream = substream->stream;
184 int err;
185 361
186 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 362 if (!omap_mcpdm_active(mcpdm)) {
187 err = omap_mcpdm_playback_close(&mcpdm_links[stream]); 363 omap_mcpdm_start(mcpdm);
188 else 364 omap_mcpdm_reg_dump(mcpdm);
189 err = omap_mcpdm_capture_close(&mcpdm_links[stream]); 365 }
190 366
191 return err; 367 return 0;
192} 368}
193 369
194static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { 370static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
195 .startup = omap_mcpdm_dai_startup, 371 .startup = omap_mcpdm_dai_startup,
196 .shutdown = omap_mcpdm_dai_shutdown, 372 .shutdown = omap_mcpdm_dai_shutdown,
197 .trigger = omap_mcpdm_dai_trigger,
198 .hw_params = omap_mcpdm_dai_hw_params, 373 .hw_params = omap_mcpdm_dai_hw_params,
199 .hw_free = omap_mcpdm_dai_hw_free, 374 .prepare = omap_mcpdm_prepare,
200}; 375};
201 376
202#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 377static int omap_mcpdm_probe(struct snd_soc_dai *dai)
203#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 378{
379 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
380 int ret;
204 381
205static int omap_mcpdm_dai_probe(struct snd_soc_dai *dai) 382 pm_runtime_enable(mcpdm->dev);
383
384 /* Disable lines while request is ongoing */
385 pm_runtime_get_sync(mcpdm->dev);
386 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
387
388 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
389 0, "McPDM", (void *)mcpdm);
390
391 pm_runtime_put_sync(mcpdm->dev);
392
393 if (ret) {
394 dev_err(mcpdm->dev, "Request for IRQ failed\n");
395 pm_runtime_disable(mcpdm->dev);
396 }
397
398 /* Configure McPDM threshold values */
399 mcpdm->dn_threshold = 2;
400 mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3;
401 return ret;
402}
403
404static int omap_mcpdm_remove(struct snd_soc_dai *dai)
206{ 405{
207 snd_soc_dai_set_drvdata(dai, &mcpdm_data); 406 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
407
408 free_irq(mcpdm->irq, (void *)mcpdm);
409 pm_runtime_disable(mcpdm->dev);
410
208 return 0; 411 return 0;
209} 412}
210 413
414#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
415#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
416
211static struct snd_soc_dai_driver omap_mcpdm_dai = { 417static struct snd_soc_dai_driver omap_mcpdm_dai = {
212 .probe = omap_mcpdm_dai_probe, 418 .probe = omap_mcpdm_probe,
419 .remove = omap_mcpdm_remove,
420 .probe_order = SND_SOC_COMP_ORDER_LATE,
421 .remove_order = SND_SOC_COMP_ORDER_EARLY,
213 .playback = { 422 .playback = {
214 .channels_min = 1, 423 .channels_min = 1,
215 .channels_max = 4, 424 .channels_max = 5,
216 .rates = OMAP_MCPDM_RATES, 425 .rates = OMAP_MCPDM_RATES,
217 .formats = OMAP_MCPDM_FORMATS, 426 .formats = OMAP_MCPDM_FORMATS,
218 }, 427 },
219 .capture = { 428 .capture = {
220 .channels_min = 1, 429 .channels_min = 1,
221 .channels_max = 2, 430 .channels_max = 3,
222 .rates = OMAP_MCPDM_RATES, 431 .rates = OMAP_MCPDM_RATES,
223 .formats = OMAP_MCPDM_FORMATS, 432 .formats = OMAP_MCPDM_FORMATS,
224 }, 433 },
225 .ops = &omap_mcpdm_dai_ops, 434 .ops = &omap_mcpdm_dai_ops,
226}; 435};
227 436
437void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
438 u8 rx1, u8 rx2)
439{
440 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
441
442 mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2);
443}
444EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets);
445
228static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) 446static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
229{ 447{
230 int ret; 448 struct omap_mcpdm *mcpdm;
449 struct resource *res;
450 int ret = 0;
451
452 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
453 if (!mcpdm)
454 return -ENOMEM;
455
456 platform_set_drvdata(pdev, mcpdm);
457
458 mutex_init(&mcpdm->mutex);
459
460 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
461 if (res == NULL) {
462 dev_err(&pdev->dev, "no resource\n");
463 goto err_res;
464 }
465
466 if (!request_mem_region(res->start, resource_size(res), "McPDM")) {
467 ret = -EBUSY;
468 goto err_res;
469 }
470
471 mcpdm->io_base = ioremap(res->start, resource_size(res));
472 if (!mcpdm->io_base) {
473 ret = -ENOMEM;
474 goto err_iomap;
475 }
476
477 mcpdm->irq = platform_get_irq(pdev, 0);
478 if (mcpdm->irq < 0) {
479 ret = mcpdm->irq;
480 goto err_irq;
481 }
482
483 mcpdm->dev = &pdev->dev;
231 484
232 ret = omap_mcpdm_probe(pdev);
233 if (ret < 0)
234 return ret;
235 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); 485 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
236 if (ret < 0) 486 if (!ret)
237 omap_mcpdm_remove(pdev); 487 return 0;
488
489err_irq:
490 iounmap(mcpdm->io_base);
491err_iomap:
492 release_mem_region(res->start, resource_size(res));
493err_res:
494 kfree(mcpdm);
238 return ret; 495 return ret;
239} 496}
240 497
241static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) 498static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
242{ 499{
500 struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
501 struct resource *res;
502
243 snd_soc_unregister_dai(&pdev->dev); 503 snd_soc_unregister_dai(&pdev->dev);
244 omap_mcpdm_remove(pdev); 504
505 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
506 iounmap(mcpdm->io_base);
507 release_mem_region(res->start, resource_size(res));
508
509 kfree(mcpdm);
245 return 0; 510 return 0;
246} 511}
247 512
248static struct platform_driver asoc_mcpdm_driver = { 513static struct platform_driver asoc_mcpdm_driver = {
249 .driver = { 514 .driver = {
250 .name = "omap-mcpdm-dai", 515 .name = "omap-mcpdm",
251 .owner = THIS_MODULE, 516 .owner = THIS_MODULE,
252 }, 517 },
253 518
254 .probe = asoc_mcpdm_probe, 519 .probe = asoc_mcpdm_probe,
255 .remove = __devexit_p(asoc_mcpdm_remove), 520 .remove = __devexit_p(asoc_mcpdm_remove),
256}; 521};
257 522
258static int __init snd_omap_mcpdm_init(void) 523static int __init snd_omap_mcpdm_init(void)
@@ -267,6 +532,6 @@ static void __exit snd_omap_mcpdm_exit(void)
267} 532}
268module_exit(snd_omap_mcpdm_exit); 533module_exit(snd_omap_mcpdm_exit);
269 534
270MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); 535MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
271MODULE_DESCRIPTION("OMAP PDM SoC Interface"); 536MODULE_DESCRIPTION("OMAP PDM SoC Interface");
272MODULE_LICENSE("GPL"); 537MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
new file mode 100644
index 000000000000..de8cf26595b1
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -0,0 +1,107 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 - 2011 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <misael.lopez@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __OMAP_MCPDM_H__
25#define __OMAP_MCPDM_H__
26
27#define MCPDM_REG_REVISION 0x00
28#define MCPDM_REG_SYSCONFIG 0x10
29#define MCPDM_REG_IRQSTATUS_RAW 0x24
30#define MCPDM_REG_IRQSTATUS 0x28
31#define MCPDM_REG_IRQENABLE_SET 0x2C
32#define MCPDM_REG_IRQENABLE_CLR 0x30
33#define MCPDM_REG_IRQWAKE_EN 0x34
34#define MCPDM_REG_DMAENABLE_SET 0x38
35#define MCPDM_REG_DMAENABLE_CLR 0x3C
36#define MCPDM_REG_DMAWAKEEN 0x40
37#define MCPDM_REG_CTRL 0x44
38#define MCPDM_REG_DN_DATA 0x48
39#define MCPDM_REG_UP_DATA 0x4C
40#define MCPDM_REG_FIFO_CTRL_DN 0x50
41#define MCPDM_REG_FIFO_CTRL_UP 0x54
42#define MCPDM_REG_DN_OFFSET 0x58
43
44/*
45 * MCPDM_IRQ bit fields
46 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
47 */
48
49#define MCPDM_DN_IRQ (1 << 0)
50#define MCPDM_DN_IRQ_EMPTY (1 << 1)
51#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
52#define MCPDM_DN_IRQ_FULL (1 << 3)
53
54#define MCPDM_UP_IRQ (1 << 8)
55#define MCPDM_UP_IRQ_EMPTY (1 << 9)
56#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
57#define MCPDM_UP_IRQ_FULL (1 << 11)
58
59#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
60#define MCPDM_UPLINK_IRQ_MASK 0xF00
61
62/*
63 * MCPDM_DMAENABLE bit fields
64 */
65
66#define MCPDM_DMA_DN_ENABLE (1 << 0)
67#define MCPDM_DMA_UP_ENABLE (1 << 1)
68
69/*
70 * MCPDM_CTRL bit fields
71 */
72
73#define MCPDM_PDM_UPLINK_EN(x) (1 << (x - 1)) /* ch1 is at bit 0 */
74#define MCPDM_PDM_DOWNLINK_EN(x) (1 << (x + 2)) /* ch1 is at bit 3 */
75#define MCPDM_PDMOUTFORMAT (1 << 8)
76#define MCPDM_CMD_INT (1 << 9)
77#define MCPDM_STATUS_INT (1 << 10)
78#define MCPDM_SW_UP_RST (1 << 11)
79#define MCPDM_SW_DN_RST (1 << 12)
80#define MCPDM_WD_EN (1 << 14)
81#define MCPDM_PDM_UP_MASK 0x7
82#define MCPDM_PDM_DN_MASK (0x1f << 3)
83
84
85#define MCPDM_PDMOUTFORMAT_LJUST (0 << 8)
86#define MCPDM_PDMOUTFORMAT_RJUST (1 << 8)
87
88/*
89 * MCPDM_FIFO_CTRL bit fields
90 */
91
92#define MCPDM_UP_THRES_MAX 0xF
93#define MCPDM_DN_THRES_MAX 0xF
94
95/*
96 * MCPDM_DN_OFFSET bit fields
97 */
98
99#define MCPDM_DN_OFST_RX1_EN (1 << 0)
100#define MCPDM_DNOFST_RX1(x) ((x & 0x1f) << 1)
101#define MCPDM_DN_OFST_RX2_EN (1 << 8)
102#define MCPDM_DNOFST_RX2(x) ((x & 0x1f) << 9)
103
104void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
105 u8 rx1, u8 rx2);
106
107#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 9b5c88ac35b9..5e37ec915de2 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -198,6 +198,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); 198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
199 else if (!substream->runtime->no_period_wakeup) 199 else if (!substream->runtime->no_period_wakeup)
200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
201 else {
202 /*
203 * No period wakeup:
204 * we need to disable BLOCK_IRQ, which is enabled by the omap
205 * dma core at request dma time.
206 */
207 omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
208 }
201 209
202 if (!(cpu_class_is_omap1())) { 210 if (!(cpu_class_is_omap1())) {
203 omap_set_dma_src_burst_mode(prtd->dma_ch, 211 omap_set_dma_src_burst_mode(prtd->dma_ch,
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 0daa04469836..bf9ae2a6f901 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -36,29 +36,8 @@ static int omap3evm_hw_params(struct snd_pcm_substream *substream,
36{ 36{
37 struct snd_soc_pcm_runtime *rtd = substream->private_data; 37 struct snd_soc_pcm_runtime *rtd = substream->private_data;
38 struct snd_soc_dai *codec_dai = rtd->codec_dai; 38 struct snd_soc_dai *codec_dai = rtd->codec_dai;
39 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
40 int ret; 39 int ret;
41 40
42 /* Set codec DAI configuration */
43 ret = snd_soc_dai_set_fmt(codec_dai,
44 SND_SOC_DAIFMT_I2S |
45 SND_SOC_DAIFMT_NB_NF |
46 SND_SOC_DAIFMT_CBM_CFM);
47 if (ret < 0) {
48 printk(KERN_ERR "Can't set codec DAI configuration\n");
49 return ret;
50 }
51
52 /* Set cpu DAI configuration */
53 ret = snd_soc_dai_set_fmt(cpu_dai,
54 SND_SOC_DAIFMT_I2S |
55 SND_SOC_DAIFMT_NB_NF |
56 SND_SOC_DAIFMT_CBM_CFM);
57 if (ret < 0) {
58 printk(KERN_ERR "Can't set cpu DAI configuration\n");
59 return ret;
60 }
61
62 /* Set the codec system clock for DAC and ADC */ 41 /* Set the codec system clock for DAC and ADC */
63 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 42 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
64 SND_SOC_CLOCK_IN); 43 SND_SOC_CLOCK_IN);
@@ -82,6 +61,8 @@ static struct snd_soc_dai_link omap3evm_dai = {
82 .codec_dai_name = "twl4030-hifi", 61 .codec_dai_name = "twl4030-hifi",
83 .platform_name = "omap-pcm-audio", 62 .platform_name = "omap-pcm-audio",
84 .codec_name = "twl4030-codec", 63 .codec_name = "twl4030-codec",
64 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
65 SND_SOC_DAIFMT_CBM_CFM,
85 .ops = &omap3evm_ops, 66 .ops = &omap3evm_ops,
86}; 67};
87 68
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 8047c521e318..30a75b406aea 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -48,24 +48,8 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
48 struct snd_soc_pcm_runtime *rtd = substream->private_data; 48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->codec_dai; 49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
52 SND_SOC_DAIFMT_CBS_CFS;
53 int ret; 51 int ret;
54 52
55 /* Set codec DAI configuration */
56 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
57 if (ret < 0) {
58 pr_err(PREFIX "can't set codec DAI configuration\n");
59 return ret;
60 }
61
62 /* Set cpu DAI configuration */
63 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
64 if (ret < 0) {
65 pr_err(PREFIX "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */ 53 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 54 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN); 55 SND_SOC_CLOCK_IN);
@@ -189,10 +173,8 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
189 if (ret < 0) 173 if (ret < 0)
190 return ret; 174 return ret;
191 175
192 snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, 176 return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
193 ARRAY_SIZE(omap3pandora_out_map)); 177 ARRAY_SIZE(omap3pandora_out_map));
194
195 return snd_soc_dapm_sync(dapm);
196} 178}
197 179
198static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) 180static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
@@ -212,10 +194,8 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
212 if (ret < 0) 194 if (ret < 0)
213 return ret; 195 return ret;
214 196
215 snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, 197 return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
216 ARRAY_SIZE(omap3pandora_in_map)); 198 ARRAY_SIZE(omap3pandora_in_map));
217
218 return snd_soc_dapm_sync(dapm);
219} 199}
220 200
221static struct snd_soc_ops omap3pandora_ops = { 201static struct snd_soc_ops omap3pandora_ops = {
@@ -231,6 +211,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
231 .codec_dai_name = "twl4030-hifi", 211 .codec_dai_name = "twl4030-hifi",
232 .platform_name = "omap-pcm-audio", 212 .platform_name = "omap-pcm-audio",
233 .codec_name = "twl4030-codec", 213 .codec_name = "twl4030-codec",
214 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
215 SND_SOC_DAIFMT_CBS_CFS,
234 .ops = &omap3pandora_ops, 216 .ops = &omap3pandora_ops,
235 .init = omap3pandora_out_init, 217 .init = omap3pandora_out_init,
236 }, { 218 }, {
@@ -240,6 +222,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
240 .codec_dai_name = "twl4030-hifi", 222 .codec_dai_name = "twl4030-hifi",
241 .platform_name = "omap-pcm-audio", 223 .platform_name = "omap-pcm-audio",
242 .codec_name = "twl4030-codec", 224 .codec_name = "twl4030-codec",
225 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
226 SND_SOC_DAIFMT_CBS_CFS,
243 .ops = &omap3pandora_ops, 227 .ops = &omap3pandora_ops,
244 .init = omap3pandora_in_init, 228 .init = omap3pandora_in_init,
245 } 229 }
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 7e75e775fb4a..db91ccaf6c97 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -55,29 +55,8 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
55{ 55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 struct snd_soc_dai *codec_dai = rtd->codec_dai; 57 struct snd_soc_dai *codec_dai = rtd->codec_dai;
58 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
59 int err; 58 int err;
60 59
61 /* Set codec DAI configuration */
62 err = snd_soc_dai_set_fmt(codec_dai,
63 SND_SOC_DAIFMT_DSP_B |
64 SND_SOC_DAIFMT_NB_NF |
65 SND_SOC_DAIFMT_CBM_CFM);
66 if (err < 0) {
67 printk(KERN_ERR "can't set codec DAI configuration\n");
68 return err;
69 }
70
71 /* Set cpu DAI configuration */
72 err = snd_soc_dai_set_fmt(cpu_dai,
73 SND_SOC_DAIFMT_DSP_B |
74 SND_SOC_DAIFMT_NB_NF |
75 SND_SOC_DAIFMT_CBM_CFM);
76 if (err < 0) {
77 printk(KERN_ERR "can't set cpu DAI configuration\n");
78 return err;
79 }
80
81 /* Set the codec system clock for DAC and ADC */ 60 /* Set the codec system clock for DAC and ADC */
82 err = 61 err =
83 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); 62 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -112,27 +91,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
112 {"MICIN", NULL, "Mic Jack"}, 91 {"MICIN", NULL, "Mic Jack"},
113}; 92};
114 93
115static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
116{
117 struct snd_soc_codec *codec = rtd->codec;
118 struct snd_soc_dapm_context *dapm = &codec->dapm;
119
120 /* Add osk5912 specific widgets */
121 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
122 ARRAY_SIZE(tlv320aic23_dapm_widgets));
123
124 /* Set up osk5912 specific audio path audio_map */
125 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
126
127 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
128 snd_soc_dapm_enable_pin(dapm, "Line In");
129 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
130
131 snd_soc_dapm_sync(dapm);
132
133 return 0;
134}
135
136/* Digital audio interface glue - connects codec <--> CPU */ 94/* Digital audio interface glue - connects codec <--> CPU */
137static struct snd_soc_dai_link osk_dai = { 95static struct snd_soc_dai_link osk_dai = {
138 .name = "TLV320AIC23", 96 .name = "TLV320AIC23",
@@ -141,7 +99,8 @@ static struct snd_soc_dai_link osk_dai = {
141 .codec_dai_name = "tlv320aic23-hifi", 99 .codec_dai_name = "tlv320aic23-hifi",
142 .platform_name = "omap-pcm-audio", 100 .platform_name = "omap-pcm-audio",
143 .codec_name = "tlv320aic23-codec", 101 .codec_name = "tlv320aic23-codec",
144 .init = osk_tlv320aic23_init, 102 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
103 SND_SOC_DAIFMT_CBM_CFM,
145 .ops = &osk_ops, 104 .ops = &osk_ops,
146}; 105};
147 106
@@ -150,6 +109,11 @@ static struct snd_soc_card snd_soc_card_osk = {
150 .name = "OSK5912", 109 .name = "OSK5912",
151 .dai_link = &osk_dai, 110 .dai_link = &osk_dai,
152 .num_links = 1, 111 .num_links = 1,
112
113 .dapm_widgets = tlv320aic23_dapm_widgets,
114 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
115 .dapm_routes = audio_map,
116 .num_dapm_routes = ARRAY_SIZE(audio_map),
153}; 117};
154 118
155static struct platform_device *osk_snd_device; 119static struct platform_device *osk_snd_device;
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index bbcf380bfb56..739efe9e327a 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -38,29 +38,8 @@ static int overo_hw_params(struct snd_pcm_substream *substream,
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 *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 int ret; 41 int ret;
43 42
44 /* Set codec DAI configuration */
45 ret = snd_soc_dai_set_fmt(codec_dai,
46 SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0) {
50 printk(KERN_ERR "can't set codec DAI configuration\n");
51 return ret;
52 }
53
54 /* Set cpu DAI configuration */
55 ret = snd_soc_dai_set_fmt(cpu_dai,
56 SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF |
58 SND_SOC_DAIFMT_CBM_CFM);
59 if (ret < 0) {
60 printk(KERN_ERR "can't set cpu DAI configuration\n");
61 return ret;
62 }
63
64 /* Set the codec system clock for DAC and ADC */ 43 /* Set the codec system clock for DAC and ADC */
65 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
66 SND_SOC_CLOCK_IN); 45 SND_SOC_CLOCK_IN);
@@ -84,6 +63,8 @@ static struct snd_soc_dai_link overo_dai = {
84 .codec_dai_name = "twl4030-hifi", 63 .codec_dai_name = "twl4030-hifi",
85 .platform_name = "omap-pcm-audio", 64 .platform_name = "omap-pcm-audio",
86 .codec_name = "twl4030-codec", 65 .codec_name = "twl4030-codec",
66 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBM_CFM,
87 .ops = &overo_ops, 68 .ops = &overo_ops,
88}; 69};
89 70
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 893300a53bab..a56842380c72 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -115,24 +115,6 @@ static int rx51_hw_params(struct snd_pcm_substream *substream,
115{ 115{
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 116 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *codec_dai = rtd->codec_dai; 117 struct snd_soc_dai *codec_dai = rtd->codec_dai;
118 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
119 int err;
120
121 /* Set codec DAI configuration */
122 err = snd_soc_dai_set_fmt(codec_dai,
123 SND_SOC_DAIFMT_DSP_A |
124 SND_SOC_DAIFMT_IB_NF |
125 SND_SOC_DAIFMT_CBM_CFM);
126 if (err < 0)
127 return err;
128
129 /* Set cpu DAI configuration */
130 err = snd_soc_dai_set_fmt(cpu_dai,
131 SND_SOC_DAIFMT_DSP_A |
132 SND_SOC_DAIFMT_IB_NF |
133 SND_SOC_DAIFMT_CBM_CFM);
134 if (err < 0)
135 return err;
136 118
137 /* Set the codec system clock for DAC and ADC */ 119 /* Set the codec system clock for DAC and ADC */
138 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000, 120 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
@@ -335,8 +317,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
335 if (err < 0) 317 if (err < 0)
336 return err; 318 return err;
337 319
338 snd_soc_dapm_sync(dapm);
339
340 /* AV jack detection */ 320 /* AV jack detection */
341 err = snd_soc_jack_new(codec, "AV Jack", 321 err = snd_soc_jack_new(codec, "AV Jack",
342 SND_JACK_HEADSET | SND_JACK_VIDEOOUT, 322 SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
@@ -377,6 +357,8 @@ static struct snd_soc_dai_link rx51_dai[] = {
377 .codec_dai_name = "tlv320aic3x-hifi", 357 .codec_dai_name = "tlv320aic3x-hifi",
378 .platform_name = "omap-pcm-audio", 358 .platform_name = "omap-pcm-audio",
379 .codec_name = "tlv320aic3x-codec.2-0018", 359 .codec_name = "tlv320aic3x-codec.2-0018",
360 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
361 SND_SOC_DAIFMT_CBM_CFM,
380 .init = rx51_aic34_init, 362 .init = rx51_aic34_init,
381 .ops = &rx51_ops, 363 .ops = &rx51_ops,
382 }, 364 },
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 9f6a758029d1..4f1969de91a7 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -53,29 +53,8 @@ static int sdp3430_hw_params(struct snd_pcm_substream *substream,
53{ 53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data; 54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->codec_dai; 55 struct snd_soc_dai *codec_dai = rtd->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
57 int ret; 56 int ret;
58 57
59 /* Set codec DAI configuration */
60 ret = snd_soc_dai_set_fmt(codec_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set codec DAI configuration\n");
66 return ret;
67 }
68
69 /* Set cpu DAI configuration */
70 ret = snd_soc_dai_set_fmt(cpu_dai,
71 SND_SOC_DAIFMT_I2S |
72 SND_SOC_DAIFMT_NB_NF |
73 SND_SOC_DAIFMT_CBM_CFM);
74 if (ret < 0) {
75 printk(KERN_ERR "can't set cpu DAI configuration\n");
76 return ret;
77 }
78
79 /* Set the codec system clock for DAC and ADC */ 58 /* Set the codec system clock for DAC and ADC */
80 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 59 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
81 SND_SOC_CLOCK_IN); 60 SND_SOC_CLOCK_IN);
@@ -91,49 +70,6 @@ static struct snd_soc_ops sdp3430_ops = {
91 .hw_params = sdp3430_hw_params, 70 .hw_params = sdp3430_hw_params,
92}; 71};
93 72
94static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream,
95 struct snd_pcm_hw_params *params)
96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
98 struct snd_soc_dai *codec_dai = rtd->codec_dai;
99 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
100 int ret;
101
102 /* Set codec DAI configuration */
103 ret = snd_soc_dai_set_fmt(codec_dai,
104 SND_SOC_DAIFMT_DSP_A |
105 SND_SOC_DAIFMT_IB_NF |
106 SND_SOC_DAIFMT_CBM_CFM);
107 if (ret) {
108 printk(KERN_ERR "can't set codec DAI configuration\n");
109 return ret;
110 }
111
112 /* Set cpu DAI configuration */
113 ret = snd_soc_dai_set_fmt(cpu_dai,
114 SND_SOC_DAIFMT_DSP_A |
115 SND_SOC_DAIFMT_IB_NF |
116 SND_SOC_DAIFMT_CBM_CFM);
117 if (ret < 0) {
118 printk(KERN_ERR "can't set cpu DAI configuration\n");
119 return ret;
120 }
121
122 /* Set the codec system clock for DAC and ADC */
123 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
124 SND_SOC_CLOCK_IN);
125 if (ret < 0) {
126 printk(KERN_ERR "can't set codec system clock\n");
127 return ret;
128 }
129
130 return 0;
131}
132
133static struct snd_soc_ops sdp3430_voice_ops = {
134 .hw_params = sdp3430_hw_voice_params,
135};
136
137/* Headset jack */ 73/* Headset jack */
138static struct snd_soc_jack hs_jack; 74static struct snd_soc_jack hs_jack;
139 75
@@ -193,15 +129,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
193 struct snd_soc_dapm_context *dapm = &codec->dapm; 129 struct snd_soc_dapm_context *dapm = &codec->dapm;
194 int ret; 130 int ret;
195 131
196 /* Add SDP3430 specific widgets */
197 ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets,
198 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
199 if (ret)
200 return ret;
201
202 /* Set up SDP3430 specific audio path audio_map */
203 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
204
205 /* SDP3430 connected pins */ 132 /* SDP3430 connected pins */
206 snd_soc_dapm_enable_pin(dapm, "Ext Mic"); 133 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
207 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 134 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
@@ -223,10 +150,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
223 snd_soc_dapm_nc_pin(dapm, "CARKITL"); 150 snd_soc_dapm_nc_pin(dapm, "CARKITL");
224 snd_soc_dapm_nc_pin(dapm, "CARKITR"); 151 snd_soc_dapm_nc_pin(dapm, "CARKITR");
225 152
226 ret = snd_soc_dapm_sync(dapm);
227 if (ret)
228 return ret;
229
230 /* Headset jack detection */ 153 /* Headset jack detection */
231 ret = snd_soc_jack_new(codec, "Headset Jack", 154 ret = snd_soc_jack_new(codec, "Headset Jack",
232 SND_JACK_HEADSET, &hs_jack); 155 SND_JACK_HEADSET, &hs_jack);
@@ -267,6 +190,8 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
267 .codec_dai_name = "twl4030-hifi", 190 .codec_dai_name = "twl4030-hifi",
268 .platform_name = "omap-pcm-audio", 191 .platform_name = "omap-pcm-audio",
269 .codec_name = "twl4030-codec", 192 .codec_name = "twl4030-codec",
193 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
194 SND_SOC_DAIFMT_CBM_CFM,
270 .init = sdp3430_twl4030_init, 195 .init = sdp3430_twl4030_init,
271 .ops = &sdp3430_ops, 196 .ops = &sdp3430_ops,
272 }, 197 },
@@ -277,8 +202,10 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
277 .codec_dai_name = "twl4030-voice", 202 .codec_dai_name = "twl4030-voice",
278 .platform_name = "omap-pcm-audio", 203 .platform_name = "omap-pcm-audio",
279 .codec_name = "twl4030-codec", 204 .codec_name = "twl4030-codec",
205 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
206 SND_SOC_DAIFMT_CBM_CFM,
280 .init = sdp3430_twl4030_voice_init, 207 .init = sdp3430_twl4030_voice_init,
281 .ops = &sdp3430_voice_ops, 208 .ops = &sdp3430_ops,
282 }, 209 },
283}; 210};
284 211
@@ -287,6 +214,11 @@ static struct snd_soc_card snd_soc_sdp3430 = {
287 .name = "SDP3430", 214 .name = "SDP3430",
288 .dai_link = sdp3430_dai, 215 .dai_link = sdp3430_dai,
289 .num_links = ARRAY_SIZE(sdp3430_dai), 216 .num_links = ARRAY_SIZE(sdp3430_dai),
217
218 .dapm_widgets = sdp3430_twl4030_dapm_widgets,
219 .num_dapm_widgets = ARRAY_SIZE(sdp3430_twl4030_dapm_widgets),
220 .dapm_routes = audio_map,
221 .num_dapm_routes = ARRAY_SIZE(audio_map),
290}; 222};
291 223
292static struct platform_device *sdp3430_snd_device; 224static struct platform_device *sdp3430_snd_device;
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index b80efb02bfca..cc3d792af5ea 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -32,7 +32,7 @@
32#include <plat/hardware.h> 32#include <plat/hardware.h>
33#include <plat/mux.h> 33#include <plat/mux.h>
34 34
35#include "mcpdm.h" 35#include "omap-mcpdm.h"
36#include "omap-pcm.h" 36#include "omap-pcm.h"
37#include "../codecs/twl6040.h" 37#include "../codecs/twl6040.h"
38 38
@@ -88,7 +88,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
88 SND_SOC_DAPM_MIC("Headset Mic", NULL), 88 SND_SOC_DAPM_MIC("Headset Mic", NULL),
89 SND_SOC_DAPM_HP("Headset Stereophone", NULL), 89 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
90 SND_SOC_DAPM_SPK("Earphone Spk", NULL), 90 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
91 SND_SOC_DAPM_INPUT("Aux/FM Stereo In"), 91 SND_SOC_DAPM_INPUT("FM Stereo In"),
92}; 92};
93 93
94static const struct snd_soc_dapm_route audio_map[] = { 94static const struct snd_soc_dapm_route audio_map[] = {
@@ -113,36 +113,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
113 {"Earphone Spk", NULL, "EP"}, 113 {"Earphone Spk", NULL, "EP"},
114 114
115 /* Aux/FM Stereo In: AFML, AFMR */ 115 /* Aux/FM Stereo In: AFML, AFMR */
116 {"AFML", NULL, "Aux/FM Stereo In"}, 116 {"AFML", NULL, "FM Stereo In"},
117 {"AFMR", NULL, "Aux/FM Stereo In"}, 117 {"AFMR", NULL, "FM Stereo In"},
118}; 118};
119 119
120static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) 120static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
121{ 121{
122 struct snd_soc_codec *codec = rtd->codec; 122 struct snd_soc_codec *codec = rtd->codec;
123 struct snd_soc_dapm_context *dapm = &codec->dapm; 123 int ret, hs_trim;
124 int ret;
125
126 /* Add SDP4430 specific widgets */
127 ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
128 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
129 if (ret)
130 return ret;
131
132 /* Set up SDP4430 specific audio path audio_map */
133 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
134 124
135 /* SDP4430 connected pins */ 125 /*
136 snd_soc_dapm_enable_pin(dapm, "Ext Mic"); 126 * Configure McPDM offset cancellation based on the HSOTRIM value from
137 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 127 * twl6040.
138 snd_soc_dapm_enable_pin(dapm, "AFML"); 128 */
139 snd_soc_dapm_enable_pin(dapm, "AFMR"); 129 hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
140 snd_soc_dapm_enable_pin(dapm, "Headset Mic"); 130 omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
141 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); 131 TWL6040_HSF_TRIM_RIGHT(hs_trim));
142
143 ret = snd_soc_dapm_sync(dapm);
144 if (ret)
145 return ret;
146 132
147 /* Headset jack detection */ 133 /* Headset jack detection */
148 ret = snd_soc_jack_new(codec, "Headset Jack", 134 ret = snd_soc_jack_new(codec, "Headset Jack",
@@ -165,8 +151,8 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
165static struct snd_soc_dai_link sdp4430_dai = { 151static struct snd_soc_dai_link sdp4430_dai = {
166 .name = "TWL6040", 152 .name = "TWL6040",
167 .stream_name = "TWL6040", 153 .stream_name = "TWL6040",
168 .cpu_dai_name ="omap-mcpdm-dai", 154 .cpu_dai_name = "omap-mcpdm",
169 .codec_dai_name = "twl6040-hifi", 155 .codec_dai_name = "twl6040-legacy",
170 .platform_name = "omap-pcm-audio", 156 .platform_name = "omap-pcm-audio",
171 .codec_name = "twl6040-codec", 157 .codec_name = "twl6040-codec",
172 .init = sdp4430_twl6040_init, 158 .init = sdp4430_twl6040_init,
@@ -178,6 +164,11 @@ static struct snd_soc_card snd_soc_sdp4430 = {
178 .name = "SDP4430", 164 .name = "SDP4430",
179 .dai_link = &sdp4430_dai, 165 .dai_link = &sdp4430_dai,
180 .num_links = 1, 166 .num_links = 1,
167
168 .dapm_widgets = sdp4430_twl6040_dapm_widgets,
169 .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
170 .dapm_routes = audio_map,
171 .num_dapm_routes = ARRAY_SIZE(audio_map),
181}; 172};
182 173
183static struct platform_device *sdp4430_snd_device; 174static struct platform_device *sdp4430_snd_device;
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 9a2666ffc16c..7cf35c82368a 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -44,29 +44,8 @@ static int zoom2_hw_params(struct snd_pcm_substream *substream,
44{ 44{
45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 struct snd_soc_pcm_runtime *rtd = substream->private_data;
46 struct snd_soc_dai *codec_dai = rtd->codec_dai; 46 struct snd_soc_dai *codec_dai = rtd->codec_dai;
47 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
48 int ret; 47 int ret;
49 48
50 /* Set codec DAI configuration */
51 ret = snd_soc_dai_set_fmt(codec_dai,
52 SND_SOC_DAIFMT_I2S |
53 SND_SOC_DAIFMT_NB_NF |
54 SND_SOC_DAIFMT_CBM_CFM);
55 if (ret < 0) {
56 printk(KERN_ERR "can't set codec DAI configuration\n");
57 return ret;
58 }
59
60 /* Set cpu DAI configuration */
61 ret = snd_soc_dai_set_fmt(cpu_dai,
62 SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_NF |
64 SND_SOC_DAIFMT_CBM_CFM);
65 if (ret < 0) {
66 printk(KERN_ERR "can't set cpu DAI configuration\n");
67 return ret;
68 }
69
70 /* Set the codec system clock for DAC and ADC */ 49 /* Set the codec system clock for DAC and ADC */
71 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 50 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
72 SND_SOC_CLOCK_IN); 51 SND_SOC_CLOCK_IN);
@@ -82,49 +61,6 @@ static struct snd_soc_ops zoom2_ops = {
82 .hw_params = zoom2_hw_params, 61 .hw_params = zoom2_hw_params,
83}; 62};
84 63
85static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 int ret;
92
93 /* Set codec DAI configuration */
94 ret = snd_soc_dai_set_fmt(codec_dai,
95 SND_SOC_DAIFMT_DSP_A |
96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBM_CFM);
98 if (ret) {
99 printk(KERN_ERR "can't set codec DAI configuration\n");
100 return ret;
101 }
102
103 /* Set cpu DAI configuration */
104 ret = snd_soc_dai_set_fmt(cpu_dai,
105 SND_SOC_DAIFMT_DSP_A |
106 SND_SOC_DAIFMT_IB_NF |
107 SND_SOC_DAIFMT_CBM_CFM);
108 if (ret < 0) {
109 printk(KERN_ERR "can't set cpu DAI configuration\n");
110 return ret;
111 }
112
113 /* Set the codec system clock for DAC and ADC */
114 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
115 SND_SOC_CLOCK_IN);
116 if (ret < 0) {
117 printk(KERN_ERR "can't set codec system clock\n");
118 return ret;
119 }
120
121 return 0;
122}
123
124static struct snd_soc_ops zoom2_voice_ops = {
125 .hw_params = zoom2_hw_voice_params,
126};
127
128/* Zoom2 machine DAPM */ 64/* Zoom2 machine DAPM */
129static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = { 65static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = {
130 SND_SOC_DAPM_MIC("Ext Mic", NULL), 66 SND_SOC_DAPM_MIC("Ext Mic", NULL),
@@ -162,23 +98,6 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
162{ 98{
163 struct snd_soc_codec *codec = rtd->codec; 99 struct snd_soc_codec *codec = rtd->codec;
164 struct snd_soc_dapm_context *dapm = &codec->dapm; 100 struct snd_soc_dapm_context *dapm = &codec->dapm;
165 int ret;
166
167 /* Add Zoom2 specific widgets */
168 ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets,
169 ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
170 if (ret)
171 return ret;
172
173 /* Set up Zoom2 specific audio path audio_map */
174 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
175
176 /* Zoom2 connected pins */
177 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
178 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
179 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
180 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
181 snd_soc_dapm_enable_pin(dapm, "Aux In");
182 101
183 /* TWL4030 not connected pins */ 102 /* TWL4030 not connected pins */
184 snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); 103 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
@@ -190,9 +109,7 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
190 snd_soc_dapm_nc_pin(dapm, "CARKITL"); 109 snd_soc_dapm_nc_pin(dapm, "CARKITL");
191 snd_soc_dapm_nc_pin(dapm, "CARKITR"); 110 snd_soc_dapm_nc_pin(dapm, "CARKITR");
192 111
193 ret = snd_soc_dapm_sync(dapm); 112 return 0;
194
195 return ret;
196} 113}
197 114
198static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd) 115static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
@@ -217,6 +134,8 @@ static struct snd_soc_dai_link zoom2_dai[] = {
217 .codec_dai_name = "twl4030-hifi", 134 .codec_dai_name = "twl4030-hifi",
218 .platform_name = "omap-pcm-audio", 135 .platform_name = "omap-pcm-audio",
219 .codec_name = "twl4030-codec", 136 .codec_name = "twl4030-codec",
137 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
138 SND_SOC_DAIFMT_CBM_CFM,
220 .init = zoom2_twl4030_init, 139 .init = zoom2_twl4030_init,
221 .ops = &zoom2_ops, 140 .ops = &zoom2_ops,
222 }, 141 },
@@ -227,8 +146,10 @@ static struct snd_soc_dai_link zoom2_dai[] = {
227 .codec_dai_name = "twl4030-voice", 146 .codec_dai_name = "twl4030-voice",
228 .platform_name = "omap-pcm-audio", 147 .platform_name = "omap-pcm-audio",
229 .codec_name = "twl4030-codec", 148 .codec_name = "twl4030-codec",
149 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
150 SND_SOC_DAIFMT_CBM_CFM,
230 .init = zoom2_twl4030_voice_init, 151 .init = zoom2_twl4030_voice_init,
231 .ops = &zoom2_voice_ops, 152 .ops = &zoom2_ops,
232 }, 153 },
233}; 154};
234 155
@@ -237,6 +158,11 @@ static struct snd_soc_card snd_soc_zoom2 = {
237 .name = "Zoom2", 158 .name = "Zoom2",
238 .dai_link = zoom2_dai, 159 .dai_link = zoom2_dai,
239 .num_links = ARRAY_SIZE(zoom2_dai), 160 .num_links = ARRAY_SIZE(zoom2_dai),
161
162 .dapm_widgets = zoom2_twl4030_dapm_widgets,
163 .num_dapm_widgets = ARRAY_SIZE(zoom2_twl4030_dapm_widgets),
164 .dapm_routes = audio_map,
165 .num_dapm_routes = ARRAY_SIZE(audio_map),
240}; 166};
241 167
242static struct platform_device *zoom2_snd_device; 168static struct platform_device *zoom2_snd_device;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 33ebc46b45b5..ffd2242e305f 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -121,6 +121,7 @@ config SND_PXA2XX_SOC_PALM27X
121config SND_SOC_SAARB 121config SND_SOC_SAARB
122 tristate "SoC Audio support for Marvell Saarb" 122 tristate "SoC Audio support for Marvell Saarb"
123 depends on SND_PXA2XX_SOC && MACH_SAARB 123 depends on SND_PXA2XX_SOC && MACH_SAARB
124 select MFD_88PM860X
124 select SND_PXA_SOC_SSP 125 select SND_PXA_SOC_SSP
125 select SND_SOC_88PM860X 126 select SND_SOC_88PM860X
126 help 127 help
@@ -130,6 +131,7 @@ config SND_SOC_SAARB
130config SND_SOC_TAVOREVB3 131config SND_SOC_TAVOREVB3
131 tristate "SoC Audio support for Marvell Tavor EVB3" 132 tristate "SoC Audio support for Marvell Tavor EVB3"
132 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3 133 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
134 select MFD_88PM860X
133 select SND_PXA_SOC_SSP 135 select SND_PXA_SOC_SSP
134 select SND_SOC_88PM860X 136 select SND_SOC_88PM860X
135 help 137 help
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 28757fb9df31..b0e2fb720910 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -299,7 +299,6 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
299 /* Set up corgi specific audio path audio_map */ 299 /* Set up corgi specific audio path audio_map */
300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301 301
302 snd_soc_dapm_sync(dapm);
303 return 0; 302 return 0;
304} 303}
305 304
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index dc65650a6fa1..35ed7eb8cff2 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -108,8 +108,6 @@ static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
108 108
109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
110 110
111 snd_soc_dapm_sync(dapm);
112
113 return 0; 111 return 0;
114} 112}
115 113
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 51897fcd911b..ce5f056009a7 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -90,8 +90,6 @@ static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
90 90
91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
92 92
93 snd_soc_dapm_sync(dapm);
94
95 return 0; 93 return 0;
96} 94}
97 95
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 053ed208e59f..6a8f38b6c379 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -80,7 +80,6 @@ static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
80 ARRAY_SIZE(e800_dapm_widgets)); 80 ARRAY_SIZE(e800_dapm_widgets));
81 81
82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
83 snd_soc_dapm_sync(dapm);
84 83
85 return 0; 84 return 0;
86} 85}
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 67dcc36cd621..e79f516c400e 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -92,11 +92,10 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->codec_dai; 93 struct snd_soc_dai *codec_dai = rtd->codec_dai;
94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
95 unsigned int acps, acds, width, rate; 95 unsigned int acps, acds, width;
96 unsigned int div4 = PXA_SSP_CLK_SCDB_4; 96 unsigned int div4 = PXA_SSP_CLK_SCDB_4;
97 int ret = 0; 97 int ret = 0;
98 98
99 rate = params_rate(params);
100 width = snd_pcm_format_physical_width(params_format(params)); 99 width = snd_pcm_format_physical_width(params_format(params));
101 100
102 /* 101 /*
@@ -424,7 +423,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
424 /* Set up magician specific audio path interconnects */ 423 /* Set up magician specific audio path interconnects */
425 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 424 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
426 425
427 snd_soc_dapm_sync(dapm);
428 return 0; 426 return 0;
429} 427}
430 428
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 38ca6759907e..0b8d1ee738a4 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -151,7 +151,6 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
151 snd_soc_dapm_enable_pin(dapm, "Front Mic"); 151 snd_soc_dapm_enable_pin(dapm, "Front Mic");
152 snd_soc_dapm_enable_pin(dapm, "GSM Line In"); 152 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); 153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
154 snd_soc_dapm_sync(dapm);
155 154
156 return 0; 155 return 0;
157} 156}
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 504e4004f004..7edc1fb71fae 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -107,10 +107,6 @@ static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
107 snd_soc_dapm_nc_pin(dapm, "PHONE"); 107 snd_soc_dapm_nc_pin(dapm, "PHONE");
108 snd_soc_dapm_nc_pin(dapm, "MIC2"); 108 snd_soc_dapm_nc_pin(dapm, "MIC2");
109 109
110 err = snd_soc_dapm_sync(dapm);
111 if (err)
112 return err;
113
114 /* Jack detection API stuff */ 110 /* Jack detection API stuff */
115 err = snd_soc_jack_new(codec, "Headphone Jack", 111 err = snd_soc_jack_new(codec, "Headphone Jack",
116 SND_JACK_HEADPHONE, &hs_jack); 112 SND_JACK_HEADPHONE, &hs_jack);
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index da3ae4316cf2..4c29bc1f9cfe 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -265,7 +265,6 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
265 /* Set up poodle specific audio path audio_map */ 265 /* Set up poodle specific audio path audio_map */
266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
267 267
268 snd_soc_dapm_sync(dapm);
269 return 0; 268 return 0;
270} 269}
271 270
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 1a591f1ebfbd..b899a3bc8f42 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -306,8 +306,10 @@ static int __init raumfeld_audio_init(void)
306 &snd_soc_raumfeld_connector); 306 &snd_soc_raumfeld_connector);
307 307
308 ret = platform_device_add(raumfeld_audio_device); 308 ret = platform_device_add(raumfeld_audio_device);
309 if (ret < 0) 309 if (ret < 0) {
310 platform_device_put(raumfeld_audio_device);
310 return ret; 311 return ret;
312 }
311 313
312 raumfeld_enable_audio(true); 314 raumfeld_enable_audio(true);
313 return 0; 315 return 0;
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index 9595189fc681..d9467a2c6de0 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -146,10 +146,6 @@ static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */ 149 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE 150 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, 151 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index b253d864868a..c2d6ff9b1588 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -301,7 +301,6 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
301 /* Set up spitz specific audio paths */ 301 /* Set up spitz specific audio paths */
302 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 302 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
303 303
304 snd_soc_dapm_sync(dapm);
305 return 0; 304 return 0;
306} 305}
307 306
@@ -312,7 +311,7 @@ static struct snd_soc_dai_link spitz_dai = {
312 .cpu_dai_name = "pxa2xx-i2s", 311 .cpu_dai_name = "pxa2xx-i2s",
313 .codec_dai_name = "wm8750-hifi", 312 .codec_dai_name = "wm8750-hifi",
314 .platform_name = "pxa-pcm-audio", 313 .platform_name = "pxa-pcm-audio",
315 .codec_name = "wm8750-codec.0-001b", 314 .codec_name = "wm8750.0-001b",
316 .init = spitz_wm8750_init, 315 .init = spitz_wm8750_init,
317 .ops = &spitz_ops, 316 .ops = &spitz_ops,
318}; 317};
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index f881f65ec172..eeec892e0e04 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -146,10 +146,6 @@ static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */ 149 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE 150 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, 151 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 9a2351366957..620fc69ae632 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -211,7 +211,6 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
211 /* set up tosa specific audio path audio_map */ 211 /* set up tosa specific audio path audio_map */
212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
213 213
214 snd_soc_dapm_sync(dapm);
215 return 0; 214 return 0;
216} 215}
217 216
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index d69d9fc32233..b311ffe04b71 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -161,10 +161,6 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
161 /* Set up z2 specific audio paths */ 161 /* Set up z2 specific audio paths */
162 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 162 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
163 163
164 ret = snd_soc_dapm_sync(dapm);
165 if (ret)
166 goto err;
167
168 /* Jack detection API stuff */ 164 /* Jack detection API stuff */
169 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 165 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
170 &hs_jack); 166 &hs_jack);
@@ -198,7 +194,7 @@ static struct snd_soc_dai_link z2_dai = {
198 .cpu_dai_name = "pxa2xx-i2s", 194 .cpu_dai_name = "pxa2xx-i2s",
199 .codec_dai_name = "wm8750-hifi", 195 .codec_dai_name = "wm8750-hifi",
200 .platform_name = "pxa-pcm-audio", 196 .platform_name = "pxa-pcm-audio",
201 .codec_name = "wm8750-codec.0-001b", 197 .codec_name = "wm8750.0-001b",
202 .init = z2_wm8750_init, 198 .init = z2_wm8750_init,
203 .ops = &z2_ops, 199 .ops = &z2_ops,
204}; 200};
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 2b8350b52232..580aae38e502 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -87,7 +87,6 @@ static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
87 snd_soc_dapm_enable_pin(dapm, "Headphone"); 87 snd_soc_dapm_enable_pin(dapm, "Headphone");
88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); 88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
89 89
90 snd_soc_dapm_sync(dapm);
91 return 0; 90 return 0;
92} 91}
93 92
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 80c85fd64e1a..55efc2bdf0bd 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -446,7 +446,6 @@ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) 446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
447{ 447{
448 struct snd_card *card = runtime->card->snd_card; 448 struct snd_card *card = runtime->card->snd_card;
449 struct snd_soc_dai *dai = runtime->cpu_dai;
450 struct snd_pcm *pcm = runtime->pcm; 449 struct snd_pcm *pcm = runtime->pcm;
451 struct s6000_pcm_dma_params *params; 450 struct s6000_pcm_dma_params *params;
452 int res; 451 int res;
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 65f980ef2870..53aaa69eda03 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -63,7 +63,9 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8994 64config SND_SOC_SAMSUNG_SMDK_WM8994
65 tristate "SoC I2S Audio support for WM8994 on SMDK" 65 tristate "SoC I2S Audio support for WM8994 on SMDK"
66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210) 66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212)
67 depends on I2C=y && GENERIC_HARDIRQS
68 select MFD_WM8994
67 select SND_SOC_WM8994 69 select SND_SOC_WM8994
68 select SND_SAMSUNG_I2S 70 select SND_SAMSUNG_I2S
69 help 71 help
@@ -150,7 +152,9 @@ config SND_SOC_SMARTQ
150config SND_SOC_GONI_AQUILA_WM8994 152config SND_SOC_GONI_AQUILA_WM8994
151 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" 153 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
152 depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) 154 depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
155 depends on I2C=y && GENERIC_HARDIRQS
153 select SND_SAMSUNG_I2S 156 select SND_SAMSUNG_I2S
157 select MFD_WM8994
154 select SND_SOC_WM8994 158 select SND_SOC_WM8994
155 help 159 help
156 Say Y if you want to add support for SoC audio on goni or aquila 160 Say Y if you want to add support for SoC audio on goni or aquila
@@ -158,7 +162,7 @@ config SND_SOC_GONI_AQUILA_WM8994
158 162
159config SND_SOC_SAMSUNG_SMDK_SPDIF 163config SND_SOC_SAMSUNG_SMDK_SPDIF
160 tristate "SoC S/PDIF Audio support for SMDK" 164 tristate "SoC S/PDIF Audio support for SMDK"
161 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310) 165 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212)
162 select SND_SAMSUNG_SPDIF 166 select SND_SAMSUNG_SPDIF
163 help 167 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
@@ -173,7 +177,9 @@ config SND_SOC_SMDK_WM8580_PCM
173 177
174config SND_SOC_SMDK_WM8994_PCM 178config SND_SOC_SMDK_WM8994_PCM
175 tristate "SoC PCM Audio support for WM8994 on SMDK" 179 tristate "SoC PCM Audio support for WM8994 on SMDK"
176 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310) 180 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212)
181 depends on I2C=y && GENERIC_HARDIRQS
182 select MFD_WM8994
177 select SND_SOC_WM8994 183 select SND_SOC_WM8994
178 select SND_SAMSUNG_PCM 184 select SND_SAMSUNG_PCM
179 help 185 help
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index f97110e72e85..b5e922f469d5 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -444,7 +444,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
444 } 444 }
445 445
446 ret = request_irq(irq_res->start, s3c_ac97_irq, 446 ret = request_irq(irq_res->start, s3c_ac97_irq,
447 IRQF_DISABLED, "AC97", NULL); 447 0, "AC97", NULL);
448 if (ret < 0) { 448 if (ret < 0) {
449 dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); 449 dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
450 goto err4; 450 goto err4;
@@ -495,7 +495,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev)
495 495
496static struct platform_driver s3c_ac97_driver = { 496static struct platform_driver s3c_ac97_driver = {
497 .probe = s3c_ac97_probe, 497 .probe = s3c_ac97_probe,
498 .remove = s3c_ac97_remove, 498 .remove = __devexit_p(s3c_ac97_remove),
499 .driver = { 499 .driver = {
500 .name = "samsung-ac97", 500 .name = "samsung-ac97",
501 .owner = THIS_MODULE, 501 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index eb6d72ed55a7..4a34f608e131 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -99,14 +99,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
99 struct snd_soc_dapm_context *dapm = &codec->dapm; 99 struct snd_soc_dapm_context *dapm = &codec->dapm;
100 int ret; 100 int ret;
101 101
102 /* add goni specific widgets */
103 snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
104 ARRAY_SIZE(goni_dapm_widgets));
105
106 /* set up goni specific audio routes */
107 snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
108 ARRAY_SIZE(goni_dapm_routes));
109
110 /* set endpoints to not connected */ 102 /* set endpoints to not connected */
111 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); 103 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
112 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); 104 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
@@ -120,8 +112,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
120 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); 112 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
121 } 113 }
122 114
123 snd_soc_dapm_sync(dapm);
124
125 /* Headset jack detection */ 115 /* Headset jack detection */
126 ret = snd_soc_jack_new(codec, "Headset Jack", 116 ret = snd_soc_jack_new(codec, "Headset Jack",
127 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, 117 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
@@ -255,6 +245,11 @@ static struct snd_soc_card goni = {
255 .name = "goni", 245 .name = "goni",
256 .dai_link = goni_dai, 246 .dai_link = goni_dai,
257 .num_links = ARRAY_SIZE(goni_dai), 247 .num_links = ARRAY_SIZE(goni_dai),
248
249 .dapm_widgets = goni_dapm_widgets,
250 .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets),
251 .dapm_routes = goni_dapm_routes,
252 .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes),
258}; 253};
259 254
260static int __init goni_init(void) 255static int __init goni_init(void)
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c6c65892294e..f75a4b60cf38 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -182,24 +182,10 @@ static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
182 struct snd_soc_dapm_context *dapm = &codec->dapm; 182 struct snd_soc_dapm_context *dapm = &codec->dapm;
183 int err; 183 int err;
184 184
185 /* Add h1940 specific widgets */
186 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
187 ARRAY_SIZE(uda1380_dapm_widgets));
188 if (err)
189 return err;
190
191 /* Set up h1940 specific audio path audio_mapnects */
192 err = snd_soc_dapm_add_routes(dapm, audio_map,
193 ARRAY_SIZE(audio_map));
194 if (err)
195 return err;
196
197 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 185 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
198 snd_soc_dapm_enable_pin(dapm, "Speaker"); 186 snd_soc_dapm_enable_pin(dapm, "Speaker");
199 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 187 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
200 188
201 snd_soc_dapm_sync(dapm);
202
203 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 189 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
204 &hp_jack); 190 &hp_jack);
205 191
@@ -230,6 +216,11 @@ static struct snd_soc_card h1940_asoc = {
230 .name = "h1940", 216 .name = "h1940",
231 .dai_link = h1940_uda1380_dai, 217 .dai_link = h1940_uda1380_dai,
232 .num_links = ARRAY_SIZE(h1940_uda1380_dai), 218 .num_links = ARRAY_SIZE(h1940_uda1380_dai),
219
220 .dapm_widgets = uda1380_dapm_widgets,
221 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
222 .dapm_routes = audio_map,
223 .num_dapm_routes = ARRAY_SIZE(audio_map),
233}; 224};
234 225
235static int __init h1940_init(void) 226static int __init h1940_init(void)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index c086b78539ee..0c9ac20d2223 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1136,7 +1136,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev)
1136 1136
1137static struct platform_driver samsung_i2s_driver = { 1137static struct platform_driver samsung_i2s_driver = {
1138 .probe = samsung_i2s_probe, 1138 .probe = samsung_i2s_probe,
1139 .remove = samsung_i2s_remove, 1139 .remove = __devexit_p(samsung_i2s_remove),
1140 .driver = { 1140 .driver = {
1141 .name = "samsung-i2s", 1141 .name = "samsung-i2s",
1142 .owner = THIS_MODULE, 1142 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 14eb6ea69e7c..f5f7c6f822d5 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -110,18 +110,6 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
110 snd_soc_dapm_nc_pin(dapm, "OUT3"); 110 snd_soc_dapm_nc_pin(dapm, "OUT3");
111 snd_soc_dapm_nc_pin(dapm, "MONO"); 111 snd_soc_dapm_nc_pin(dapm, "MONO");
112 112
113 /* Add jive specific widgets */
114 err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
115 ARRAY_SIZE(wm8750_dapm_widgets));
116 if (err) {
117 printk(KERN_ERR "%s: failed to add widgets (%d)\n",
118 __func__, err);
119 return err;
120 }
121
122 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
123 snd_soc_dapm_sync(dapm);
124
125 return 0; 113 return 0;
126} 114}
127 115
@@ -131,7 +119,7 @@ static struct snd_soc_dai_link jive_dai = {
131 .cpu_dai_name = "s3c2412-i2s", 119 .cpu_dai_name = "s3c2412-i2s",
132 .codec_dai_name = "wm8750-hifi", 120 .codec_dai_name = "wm8750-hifi",
133 .platform_name = "samsung-audio", 121 .platform_name = "samsung-audio",
134 .codec_name = "wm8750-codec.0-001a", 122 .codec_name = "wm8750.0-001a",
135 .init = jive_wm8750_init, 123 .init = jive_wm8750_init,
136 .ops = &jive_ops, 124 .ops = &jive_ops,
137}; 125};
@@ -141,6 +129,11 @@ static struct snd_soc_card snd_soc_machine_jive = {
141 .name = "Jive", 129 .name = "Jive",
142 .dai_link = &jive_dai, 130 .dai_link = &jive_dai,
143 .num_links = 1, 131 .num_links = 1,
132
133 .dapm_widgtets = wm8750_dapm_widgets,
134 .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
135 .dapm_routes = audio_map,
136 .num_dapm_routes = ARRAY_SIZE(audio_map),
144}; 137};
145 138
146static struct platform_device *jive_snd_device; 139static struct platform_device *jive_snd_device;
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 16152ed08648..7207189cd211 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -367,8 +367,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
367 return ret; 367 return ret;
368 } 368 }
369 369
370 snd_soc_dapm_sync(dapm);
371
372 return 0; 370 return 0;
373} 371}
374 372
@@ -409,8 +407,6 @@ static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
409 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); 407 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
410 snd_soc_dapm_ignore_suspend(dapm, "Headphone"); 408 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
411 409
412 snd_soc_dapm_sync(dapm);
413
414 return 0; 410 return 0;
415} 411}
416 412
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 9c7e8b48aed6..e55d7a5c4bdc 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -624,7 +624,7 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
624 624
625static struct platform_driver s3c_pcm_driver = { 625static struct platform_driver s3c_pcm_driver = {
626 .probe = s3c_pcm_dev_probe, 626 .probe = s3c_pcm_dev_probe,
627 .remove = s3c_pcm_dev_remove, 627 .remove = __devexit_p(s3c_pcm_dev_remove),
628 .driver = { 628 .driver = {
629 .name = "samsung-pcm", 629 .name = "samsung-pcm",
630 .owner = THIS_MODULE, 630 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index bc8c1676459f..aea7f1b24e6b 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -90,12 +90,6 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
90 }, 90 },
91}; 91};
92 92
93static struct snd_soc_card rx1950_asoc = {
94 .name = "rx1950",
95 .dai_link = rx1950_uda1380_dai,
96 .num_links = ARRAY_SIZE(rx1950_uda1380_dai),
97};
98
99/* rx1950 machine dapm widgets */ 93/* rx1950 machine dapm widgets */
100static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { 94static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
101 SND_SOC_DAPM_HP("Headphone Jack", NULL), 95 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -117,6 +111,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
117 {"VINM", NULL, "Mic Jack"}, 111 {"VINM", NULL, "Mic Jack"},
118}; 112};
119 113
114static struct snd_soc_card rx1950_asoc = {
115 .name = "rx1950",
116 .dai_link = rx1950_uda1380_dai,
117 .num_links = ARRAY_SIZE(rx1950_uda1380_dai),
118
119 .dapm_widgets = uda1380_dapm_widgets,
120 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
121 .dapm_routes = audio_map,
122 .num_dapm_routes = ARRAY_SIZE(audio_map),
123};
124
120static struct platform_device *s3c24xx_snd_device; 125static struct platform_device *s3c24xx_snd_device;
121 126
122static int rx1950_startup(struct snd_pcm_substream *substream) 127static int rx1950_startup(struct snd_pcm_substream *substream)
@@ -220,26 +225,10 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
220 struct snd_soc_dapm_context *dapm = &codec->dapm; 225 struct snd_soc_dapm_context *dapm = &codec->dapm;
221 int err; 226 int err;
222 227
223 /* Add rx1950 specific widgets */
224 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
225 ARRAY_SIZE(uda1380_dapm_widgets));
226
227 if (err)
228 return err;
229
230 /* Set up rx1950 specific audio path audio_mapnects */
231 err = snd_soc_dapm_add_routes(dapm, audio_map,
232 ARRAY_SIZE(audio_map));
233
234 if (err)
235 return err;
236
237 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 228 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
238 snd_soc_dapm_enable_pin(dapm, "Speaker"); 229 snd_soc_dapm_enable_pin(dapm, "Speaker");
239 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 230 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
240 231
241 snd_soc_dapm_sync(dapm);
242
243 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 232 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
244 &hp_jack); 233 &hp_jack);
245 234
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 52074a2b0696..7a73380b3560 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -16,6 +16,7 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/module.h>
19#include <linux/delay.h> 20#include <linux/delay.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 841ab14c1100..f26a8bfb2357 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -69,10 +69,10 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
70 70
71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); 71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
72 if (s3c2412_i2s.iis_cclk == NULL) { 72 if (IS_ERR(s3c2412_i2s.iis_cclk)) {
73 pr_err("failed to get i2sclk clock\n"); 73 pr_err("failed to get i2sclk clock\n");
74 iounmap(s3c2412_i2s.regs); 74 iounmap(s3c2412_i2s.regs);
75 return -ENODEV; 75 return PTR_ERR(s3c2412_i2s.iis_cclk);
76 } 76 }
77 77
78 /* Set MPLL as the source for IIS CLK */ 78 /* Set MPLL as the source for IIS CLK */
@@ -176,7 +176,7 @@ static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
176 176
177static struct platform_driver s3c2412_iis_driver = { 177static struct platform_driver s3c2412_iis_driver = {
178 .probe = s3c2412_iis_dev_probe, 178 .probe = s3c2412_iis_dev_probe,
179 .remove = s3c2412_iis_dev_remove, 179 .remove = __devexit_p(s3c2412_iis_dev_remove),
180 .driver = { 180 .driver = {
181 .name = "s3c2412-iis", 181 .name = "s3c2412-iis",
182 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 63d8849d80bd..c08117e658db 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -383,10 +383,10 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
383 return -ENXIO; 383 return -ENXIO;
384 384
385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); 385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
386 if (s3c24xx_i2s.iis_clk == NULL) { 386 if (IS_ERR(s3c24xx_i2s.iis_clk)) {
387 pr_err("failed to get iis_clock\n"); 387 pr_err("failed to get iis_clock\n");
388 iounmap(s3c24xx_i2s.regs); 388 iounmap(s3c24xx_i2s.regs);
389 return -ENODEV; 389 return PTR_ERR(s3c24xx_i2s.iis_clk);
390 } 390 }
391 clk_enable(s3c24xx_i2s.iis_clk); 391 clk_enable(s3c24xx_i2s.iis_clk);
392 392
@@ -481,7 +481,7 @@ static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev)
481 481
482static struct platform_driver s3c24xx_iis_driver = { 482static struct platform_driver s3c24xx_iis_driver = {
483 .probe = s3c24xx_iis_dev_probe, 483 .probe = s3c24xx_iis_dev_probe,
484 .remove = s3c24xx_iis_dev_remove, 484 .remove = __devexit_p(s3c24xx_iis_dev_remove),
485 .driver = { 485 .driver = {
486 .name = "s3c24xx-iis", 486 .name = "s3c24xx-iis",
487 .owner = THIS_MODULE, 487 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index 349566f0686b..c8d525bf6122 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -300,7 +300,7 @@ static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd)
300} 300}
301 301
302#ifdef CONFIG_PM 302#ifdef CONFIG_PM
303int simtec_audio_resume(struct device *dev) 303static int simtec_audio_resume(struct device *dev)
304{ 304{
305 simtec_call_startup(pdata); 305 simtec_call_startup(pdata);
306 return 0; 306 return 0;
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index ce6aef604179..6bc5a36af1d9 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -65,18 +65,12 @@ static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
65 struct snd_soc_codec *codec = rtd->codec; 65 struct snd_soc_codec *codec = rtd->codec;
66 struct snd_soc_dapm_context *dapm = &codec->dapm; 66 struct snd_soc_dapm_context *dapm = &codec->dapm;
67 67
68 snd_soc_dapm_new_controls(dapm, dapm_widgets,
69 ARRAY_SIZE(dapm_widgets));
70
71 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
72
73 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 68 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
74 snd_soc_dapm_enable_pin(dapm, "Line In"); 69 snd_soc_dapm_enable_pin(dapm, "Line In");
75 snd_soc_dapm_enable_pin(dapm, "Line Out"); 70 snd_soc_dapm_enable_pin(dapm, "Line Out");
76 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 71 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
77 72
78 simtec_audio_init(rtd); 73 simtec_audio_init(rtd);
79 snd_soc_dapm_sync(dapm);
80 74
81 return 0; 75 return 0;
82} 76}
@@ -96,6 +90,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
96 .name = "Simtec-Hermes", 90 .name = "Simtec-Hermes",
97 .dai_link = &simtec_dai_aic33, 91 .dai_link = &simtec_dai_aic33,
98 .num_links = 1, 92 .num_links = 1,
93
94 .dapm_widgets = dapm_widgets,
95 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
96 .dapm_routes = base_map,
97 .num_dapm_routes = ARRAY_SIZE(base_map),
99}; 98};
100 99
101static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) 100static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index a7ef7db54687..7bdda7674008 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -54,18 +54,12 @@ static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
54 struct snd_soc_codec *codec = rtd->codec; 54 struct snd_soc_codec *codec = rtd->codec;
55 struct snd_soc_dapm_context *dapm = &codec->dapm; 55 struct snd_soc_dapm_context *dapm = &codec->dapm;
56 56
57 snd_soc_dapm_new_controls(dapm, dapm_widgets,
58 ARRAY_SIZE(dapm_widgets));
59
60 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
61
62 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
63 snd_soc_dapm_enable_pin(dapm, "Line In"); 58 snd_soc_dapm_enable_pin(dapm, "Line In");
64 snd_soc_dapm_enable_pin(dapm, "Line Out"); 59 snd_soc_dapm_enable_pin(dapm, "Line Out");
65 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 60 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
66 61
67 simtec_audio_init(rtd); 62 simtec_audio_init(rtd);
68 snd_soc_dapm_sync(dapm);
69 63
70 return 0; 64 return 0;
71} 65}
@@ -85,6 +79,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
85 .name = "Simtec", 79 .name = "Simtec",
86 .dai_link = &simtec_dai_aic23, 80 .dai_link = &simtec_dai_aic23,
87 .num_links = 1, 81 .num_links = 1,
82
83 .dapm_widgets = dapm_widgets,
84 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
85 .dapm_routes = base_map,
86 .num_dapm_routes = ARRAY_SIZE(base_map),
88}; 87};
89 88
90static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) 89static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index dc9d551f6788..65c1cfd47d8a 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -66,17 +66,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
66 pr_debug("%s %d\n", __func__, clk_users); 66 pr_debug("%s %d\n", __func__, clk_users);
67 if (clk_users == 0) { 67 if (clk_users == 0) {
68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); 68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
69 if (!xtal) { 69 if (IS_ERR(xtal)) {
70 printk(KERN_ERR "%s cannot get xtal\n", __func__); 70 printk(KERN_ERR "%s cannot get xtal\n", __func__);
71 ret = -EBUSY; 71 ret = PTR_ERR(xtal);
72 } else { 72 } else {
73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, 73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
74 "pclk"); 74 "pclk");
75 if (!pclk) { 75 if (IS_ERR(pclk)) {
76 printk(KERN_ERR "%s cannot get pclk\n", 76 printk(KERN_ERR "%s cannot get pclk\n",
77 __func__); 77 __func__);
78 clk_put(xtal); 78 clk_put(xtal);
79 ret = -EBUSY; 79 ret = PTR_ERR(pclk);
80 } 80 }
81 } 81 }
82 if (!ret) { 82 if (!ret) {
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 0a2c4f223038..6ac6bc2bcc4e 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -153,20 +153,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
153 struct snd_soc_dapm_context *dapm = &codec->dapm; 153 struct snd_soc_dapm_context *dapm = &codec->dapm;
154 int err = 0; 154 int err = 0;
155 155
156 /* Add SmartQ specific widgets */
157 snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets,
158 ARRAY_SIZE(wm8987_dapm_widgets));
159
160 /* add SmartQ specific controls */
161 err = snd_soc_add_controls(codec, wm8987_smartq_controls,
162 ARRAY_SIZE(wm8987_smartq_controls));
163
164 if (err < 0)
165 return err;
166
167 /* setup SmartQ specific audio path */
168 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
169
170 /* set endpoints to not connected */ 156 /* set endpoints to not connected */
171 snd_soc_dapm_nc_pin(dapm, "LINPUT1"); 157 snd_soc_dapm_nc_pin(dapm, "LINPUT1");
172 snd_soc_dapm_nc_pin(dapm, "RINPUT1"); 158 snd_soc_dapm_nc_pin(dapm, "RINPUT1");
@@ -178,10 +164,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
178 snd_soc_dapm_enable_pin(dapm, "Internal Mic"); 164 snd_soc_dapm_enable_pin(dapm, "Internal Mic");
179 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 165 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
180 166
181 err = snd_soc_dapm_sync(dapm);
182 if (err)
183 return err;
184
185 /* Headphone jack detection */ 167 /* Headphone jack detection */
186 err = snd_soc_jack_new(codec, "Headphone Jack", 168 err = snd_soc_jack_new(codec, "Headphone Jack",
187 SND_JACK_HEADPHONE, &smartq_jack); 169 SND_JACK_HEADPHONE, &smartq_jack);
@@ -207,7 +189,7 @@ static struct snd_soc_dai_link smartq_dai[] = {
207 .cpu_dai_name = "samsung-i2s.0", 189 .cpu_dai_name = "samsung-i2s.0",
208 .codec_dai_name = "wm8750-hifi", 190 .codec_dai_name = "wm8750-hifi",
209 .platform_name = "samsung-audio", 191 .platform_name = "samsung-audio",
210 .codec_name = "wm8750-codec.0-0x1a", 192 .codec_name = "wm8750.0-0x1a",
211 .init = smartq_wm8987_init, 193 .init = smartq_wm8987_init,
212 .ops = &smartq_hifi_ops, 194 .ops = &smartq_hifi_ops,
213 }, 195 },
@@ -217,6 +199,13 @@ static struct snd_soc_card snd_soc_smartq = {
217 .name = "SmartQ", 199 .name = "SmartQ",
218 .dai_link = smartq_dai, 200 .dai_link = smartq_dai,
219 .num_links = ARRAY_SIZE(smartq_dai), 201 .num_links = ARRAY_SIZE(smartq_dai),
202
203 .dapm_widgets = wm8987_dapm_widgets,
204 .num_dapm_widgets = ARRAY_SIZE(wm8987_dapm_widgets),
205 .dapm_routes = audio_map,
206 .num_dapm_routes = ARRAY_SIZE(audio_map),
207 .controls = wm8987_smartq_controls,
208 .num_controls = ARRAY_SIZE(wm8987_smartq_controls),
220}; 209};
221 210
222static struct platform_device *smartq_snd_device; 211static struct platform_device *smartq_snd_device;
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 3d26f6607aa4..8f92ffceb5ca 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -119,30 +119,24 @@ static struct snd_soc_ops smdk_ops = {
119}; 119};
120 120
121/* SMDK Playback widgets */ 121/* SMDK Playback widgets */
122static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { 122static const struct snd_soc_dapm_widget smdk_wm8580_dapm_widgets[] = {
123 SND_SOC_DAPM_HP("Front", NULL), 123 SND_SOC_DAPM_HP("Front", NULL),
124 SND_SOC_DAPM_HP("Center+Sub", NULL), 124 SND_SOC_DAPM_HP("Center+Sub", NULL),
125 SND_SOC_DAPM_HP("Rear", NULL), 125 SND_SOC_DAPM_HP("Rear", NULL),
126};
127 126
128/* SMDK Capture widgets */
129static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
130 SND_SOC_DAPM_MIC("MicIn", NULL), 127 SND_SOC_DAPM_MIC("MicIn", NULL),
131 SND_SOC_DAPM_LINE("LineIn", NULL), 128 SND_SOC_DAPM_LINE("LineIn", NULL),
132}; 129};
133 130
134/* SMDK-PAIFTX connections */ 131/* SMDK-PAIFTX connections */
135static const struct snd_soc_dapm_route audio_map_tx[] = { 132static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = {
136 /* MicIn feeds AINL */ 133 /* MicIn feeds AINL */
137 {"AINL", NULL, "MicIn"}, 134 {"AINL", NULL, "MicIn"},
138 135
139 /* LineIn feeds AINL/R */ 136 /* LineIn feeds AINL/R */
140 {"AINL", NULL, "LineIn"}, 137 {"AINL", NULL, "LineIn"},
141 {"AINR", NULL, "LineIn"}, 138 {"AINR", NULL, "LineIn"},
142};
143 139
144/* SMDK-PAIFRX connections */
145static const struct snd_soc_dapm_route audio_map_rx[] = {
146 /* Front Left/Right are fed VOUT1L/R */ 140 /* Front Left/Right are fed VOUT1L/R */
147 {"Front", NULL, "VOUT1L"}, 141 {"Front", NULL, "VOUT1L"},
148 {"Front", NULL, "VOUT1R"}, 142 {"Front", NULL, "VOUT1R"},
@@ -161,39 +155,11 @@ static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
161 struct snd_soc_codec *codec = rtd->codec; 155 struct snd_soc_codec *codec = rtd->codec;
162 struct snd_soc_dapm_context *dapm = &codec->dapm; 156 struct snd_soc_dapm_context *dapm = &codec->dapm;
163 157
164 /* Add smdk specific Capture widgets */
165 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt,
166 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
167
168 /* Set up PAIFTX audio path */
169 snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx));
170
171 /* Enabling the microphone requires the fitting of a 0R 158 /* Enabling the microphone requires the fitting of a 0R
172 * resistor to connect the line from the microphone jack. 159 * resistor to connect the line from the microphone jack.
173 */ 160 */
174 snd_soc_dapm_disable_pin(dapm, "MicIn"); 161 snd_soc_dapm_disable_pin(dapm, "MicIn");
175 162
176 /* signal a DAPM event */
177 snd_soc_dapm_sync(dapm);
178
179 return 0;
180}
181
182static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
183{
184 struct snd_soc_codec *codec = rtd->codec;
185 struct snd_soc_dapm_context *dapm = &codec->dapm;
186
187 /* Add smdk specific Playback widgets */
188 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk,
189 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
190
191 /* Set up PAIFRX audio path */
192 snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx));
193
194 /* signal a DAPM event */
195 snd_soc_dapm_sync(dapm);
196
197 return 0; 163 return 0;
198} 164}
199 165
@@ -210,8 +176,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
210 .cpu_dai_name = "samsung-i2s.0", 176 .cpu_dai_name = "samsung-i2s.0",
211 .codec_dai_name = "wm8580-hifi-playback", 177 .codec_dai_name = "wm8580-hifi-playback",
212 .platform_name = "samsung-audio", 178 .platform_name = "samsung-audio",
213 .codec_name = "wm8580-codec.0-001b", 179 .codec_name = "wm8580.0-001b",
214 .init = smdk_wm8580_init_paifrx,
215 .ops = &smdk_ops, 180 .ops = &smdk_ops,
216 }, 181 },
217 [PRI_CAPTURE] = { /* Primary Capture i/f */ 182 [PRI_CAPTURE] = { /* Primary Capture i/f */
@@ -220,7 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
220 .cpu_dai_name = "samsung-i2s.0", 185 .cpu_dai_name = "samsung-i2s.0",
221 .codec_dai_name = "wm8580-hifi-capture", 186 .codec_dai_name = "wm8580-hifi-capture",
222 .platform_name = "samsung-audio", 187 .platform_name = "samsung-audio",
223 .codec_name = "wm8580-codec.0-001b", 188 .codec_name = "wm8580.0-001b",
224 .init = smdk_wm8580_init_paiftx, 189 .init = smdk_wm8580_init_paiftx,
225 .ops = &smdk_ops, 190 .ops = &smdk_ops,
226 }, 191 },
@@ -230,8 +195,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
230 .cpu_dai_name = "samsung-i2s.x", 195 .cpu_dai_name = "samsung-i2s.x",
231 .codec_dai_name = "wm8580-hifi-playback", 196 .codec_dai_name = "wm8580-hifi-playback",
232 .platform_name = "samsung-audio", 197 .platform_name = "samsung-audio",
233 .codec_name = "wm8580-codec.0-001b", 198 .codec_name = "wm8580.0-001b",
234 .init = smdk_wm8580_init_paifrx,
235 .ops = &smdk_ops, 199 .ops = &smdk_ops,
236 }, 200 },
237}; 201};
@@ -240,6 +204,11 @@ static struct snd_soc_card smdk = {
240 .name = "SMDK-I2S", 204 .name = "SMDK-I2S",
241 .dai_link = smdk_dai, 205 .dai_link = smdk_dai,
242 .num_links = 2, 206 .num_links = 2,
207
208 .dapm_widgets = smdk_wm8580_dapm_widgets,
209 .num_dapm_widgets = ARRAY_SIZE(smdk_wm8580_dapm_widgets),
210 .dapm_routes = smdk_wm8580_audio_map,
211 .num_dapm_routes = ARRAY_SIZE(smdk_wm8580_audio_map),
243}; 212};
244 213
245static struct platform_device *smdk_snd_device; 214static struct platform_device *smdk_snd_device;
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index 0d12092df164..4b9c73477ce0 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
127 .cpu_dai_name = "samsung-pcm.0", 127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback", 128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio", 129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b", 130 .codec_name = "wm8580.0-001b",
131 .ops = &smdk_wm8580_pcm_ops, 131 .ops = &smdk_wm8580_pcm_ops,
132 }, { 132 }, {
133 .name = "WM8580 PAIF PCM TX", 133 .name = "WM8580 PAIF PCM TX",
@@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
135 .cpu_dai_name = "samsung-pcm.0", 135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture", 136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio", 137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b", 138 .codec_name = "wm8580.0-001b",
139 .ops = &smdk_wm8580_pcm_ops, 139 .ops = &smdk_wm8580_pcm_ops,
140 }, 140 },
141}; 141};
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 45fbe2b3727f..f75e43997d5b 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -117,8 +117,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
117 snd_soc_dapm_nc_pin(dapm, "IN1RP"); 117 snd_soc_dapm_nc_pin(dapm, "IN1RP");
118 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); 118 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
119 119
120 snd_soc_dapm_sync(dapm);
121
122 return 0; 120 return 0;
123} 121}
124 122
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 28c491dacf7a..3122f3154bfa 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -340,7 +340,7 @@ static struct snd_soc_dai_ops spdif_dai_ops = {
340 .shutdown = spdif_shutdown, 340 .shutdown = spdif_shutdown,
341}; 341};
342 342
343struct snd_soc_dai_driver samsung_spdif_dai = { 343static struct snd_soc_dai_driver samsung_spdif_dai = {
344 .name = "samsung-spdif", 344 .name = "samsung-spdif",
345 .playback = { 345 .playback = {
346 .stream_name = "S/PDIF Playback", 346 .stream_name = "S/PDIF Playback",
@@ -475,7 +475,7 @@ static __devexit int spdif_remove(struct platform_device *pdev)
475 475
476static struct platform_driver samsung_spdif_driver = { 476static struct platform_driver samsung_spdif_driver = {
477 .probe = spdif_probe, 477 .probe = spdif_probe,
478 .remove = spdif_remove, 478 .remove = __devexit_p(spdif_remove),
479 .driver = { 479 .driver = {
480 .name = "samsung-spdif", 480 .name = "samsung-spdif",
481 .owner = THIS_MODULE, 481 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 590e9274b062..b9e213f6cc06 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -125,10 +125,6 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = {
125 .pin = "Headset Mic", 125 .pin = "Headset Mic",
126 .mask = SND_JACK_MICROPHONE, 126 .mask = SND_JACK_MICROPHONE,
127 }, 127 },
128 {
129 .pin = "Headphone",
130 .mask = SND_JACK_HEADPHONE,
131 },
132}; 128};
133 129
134/* Default the headphone selection to active high */ 130/* Default the headphone selection to active high */
@@ -171,7 +167,8 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
171 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); 167 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
172 168
173 ret = snd_soc_jack_new(codec, "Headset", 169 ret = snd_soc_jack_new(codec, "Headset",
174 SND_JACK_HEADSET | SND_JACK_BTN_0, 170 SND_JACK_LINEOUT | SND_JACK_HEADSET |
171 SND_JACK_BTN_0,
175 &speyside_headset); 172 &speyside_headset);
176 if (ret) 173 if (ret)
177 return ret; 174 return ret;
@@ -227,7 +224,7 @@ static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
227 snd_soc_dapm_nc_pin(dapm, "LINEOUT"); 224 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
228 225
229 /* At any time the WM9081 is active it will have this clock */ 226 /* At any time the WM9081 is active it will have this clock */
230 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 227 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
231 48000 * 256, 0); 228 48000 * 256, 0);
232} 229}
233 230
@@ -252,6 +249,7 @@ static const struct snd_kcontrol_new controls[] = {
252 SOC_DAPM_PIN_SWITCH("Main AMIC"), 249 SOC_DAPM_PIN_SWITCH("Main AMIC"),
253 SOC_DAPM_PIN_SWITCH("WM1250 Input"), 250 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
254 SOC_DAPM_PIN_SWITCH("WM1250 Output"), 251 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
252 SOC_DAPM_PIN_SWITCH("Headphone"),
255}; 253};
256 254
257static struct snd_soc_dapm_widget widgets[] = { 255static struct snd_soc_dapm_widget widgets[] = {
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/speyside_wm8962.c
index 72535f2daaf2..8a082044436e 100644
--- a/sound/soc/samsung/speyside_wm8962.c
+++ b/sound/soc/samsung/speyside_wm8962.c
@@ -16,6 +16,8 @@
16 16
17#include "../codecs/wm8962.h" 17#include "../codecs/wm8962.h"
18 18
19static int sample_rate = 44100;
20
19static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, 21static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
20 struct snd_soc_dapm_context *dapm, 22 struct snd_soc_dapm_context *dapm,
21 enum snd_soc_bias_level level) 23 enum snd_soc_bias_level level)
@@ -31,13 +33,13 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
31 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 33 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
32 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 34 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
33 WM8962_FLL_MCLK, 32768, 35 WM8962_FLL_MCLK, 32768,
34 44100 * 256); 36 sample_rate * 512);
35 if (ret < 0) 37 if (ret < 0)
36 pr_err("Failed to start FLL: %d\n", ret); 38 pr_err("Failed to start FLL: %d\n", ret);
37 39
38 ret = snd_soc_dai_set_sysclk(codec_dai, 40 ret = snd_soc_dai_set_sysclk(codec_dai,
39 WM8962_SYSCLK_FLL, 41 WM8962_SYSCLK_FLL,
40 44100 * 256, 42 sample_rate * 512,
41 SND_SOC_CLOCK_IN); 43 SND_SOC_CLOCK_IN);
42 if (ret < 0) { 44 if (ret < 0) {
43 pr_err("Failed to set SYSCLK: %d\n", ret); 45 pr_err("Failed to set SYSCLK: %d\n", ret);
@@ -92,22 +94,7 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
92static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, 94static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params) 95 struct snd_pcm_hw_params *params)
94{ 96{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 97 sample_rate = params_rate(params);
96 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
97 struct snd_soc_dai *codec_dai = rtd->codec_dai;
98 int ret;
99
100 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
101 | SND_SOC_DAIFMT_NB_NF
102 | SND_SOC_DAIFMT_CBM_CFM);
103 if (ret < 0)
104 return ret;
105
106 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
107 | SND_SOC_DAIFMT_NB_NF
108 | SND_SOC_DAIFMT_CBM_CFM);
109 if (ret < 0)
110 return ret;
111 98
112 return 0; 99 return 0;
113} 100}
@@ -124,12 +111,15 @@ static struct snd_soc_dai_link speyside_wm8962_dai[] = {
124 .codec_dai_name = "wm8962", 111 .codec_dai_name = "wm8962",
125 .platform_name = "samsung-audio", 112 .platform_name = "samsung-audio",
126 .codec_name = "wm8962.1-001a", 113 .codec_name = "wm8962.1-001a",
114 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
115 | SND_SOC_DAIFMT_CBM_CFM,
127 .ops = &speyside_wm8962_ops, 116 .ops = &speyside_wm8962_ops,
128 }, 117 },
129}; 118};
130 119
131static const struct snd_kcontrol_new controls[] = { 120static const struct snd_kcontrol_new controls[] = {
132 SOC_DAPM_PIN_SWITCH("Main Speaker"), 121 SOC_DAPM_PIN_SWITCH("Main Speaker"),
122 SOC_DAPM_PIN_SWITCH("DMIC"),
133}; 123};
134 124
135static struct snd_soc_dapm_widget widgets[] = { 125static struct snd_soc_dapm_widget widgets[] = {
@@ -137,6 +127,7 @@ static struct snd_soc_dapm_widget widgets[] = {
137 SND_SOC_DAPM_MIC("Headset Mic", NULL), 127 SND_SOC_DAPM_MIC("Headset Mic", NULL),
138 128
139 SND_SOC_DAPM_MIC("DMIC", NULL), 129 SND_SOC_DAPM_MIC("DMIC", NULL),
130 SND_SOC_DAPM_MIC("AMIC", NULL),
140 131
141 SND_SOC_DAPM_SPK("Main Speaker", NULL), 132 SND_SOC_DAPM_SPK("Main Speaker", NULL),
142}; 133};
@@ -148,12 +139,16 @@ static struct snd_soc_dapm_route audio_paths[] = {
148 { "Main Speaker", NULL, "SPKOUTL" }, 139 { "Main Speaker", NULL, "SPKOUTL" },
149 { "Main Speaker", NULL, "SPKOUTR" }, 140 { "Main Speaker", NULL, "SPKOUTR" },
150 141
151 { "MICBIAS", NULL, "Headset Mic" }, 142 { "Headset Mic", NULL, "MICBIAS" },
152 { "IN4L", NULL, "MICBIAS" }, 143 { "IN4L", NULL, "Headset Mic" },
153 { "IN4R", NULL, "MICBIAS" }, 144 { "IN4R", NULL, "Headset Mic" },
145
146 { "AMIC", NULL, "MICBIAS" },
147 { "IN1L", NULL, "AMIC" },
148 { "IN1R", NULL, "AMIC" },
154 149
155 { "MICBIAS", NULL, "DMIC" }, 150 { "DMIC", NULL, "MICBIAS" },
156 { "DMICDAT", NULL, "MICBIAS" }, 151 { "DMICDAT", NULL, "DMIC" },
157}; 152};
158 153
159static struct snd_soc_jack speyside_wm8962_headset; 154static struct snd_soc_jack speyside_wm8962_headset;
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 8e112ccffb13..a32fd16ad668 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -210,7 +210,7 @@ struct fsi_master {
210 * basic read write function 210 * basic read write function
211 */ 211 */
212 212
213static void __fsi_reg_write(u32 reg, u32 data) 213static void __fsi_reg_write(u32 __iomem *reg, u32 data)
214{ 214{
215 /* valid data area is 24bit */ 215 /* valid data area is 24bit */
216 data &= 0x00ffffff; 216 data &= 0x00ffffff;
@@ -218,12 +218,12 @@ static void __fsi_reg_write(u32 reg, u32 data)
218 __raw_writel(data, reg); 218 __raw_writel(data, reg);
219} 219}
220 220
221static u32 __fsi_reg_read(u32 reg) 221static u32 __fsi_reg_read(u32 __iomem *reg)
222{ 222{
223 return __raw_readl(reg); 223 return __raw_readl(reg);
224} 224}
225 225
226static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 226static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
227{ 227{
228 u32 val = __fsi_reg_read(reg); 228 u32 val = __fsi_reg_read(reg);
229 229
@@ -250,7 +250,7 @@ static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
250 unsigned long flags; 250 unsigned long flags;
251 251
252 spin_lock_irqsave(&master->lock, flags); 252 spin_lock_irqsave(&master->lock, flags);
253 ret = __fsi_reg_read((u32)(master->base + reg)); 253 ret = __fsi_reg_read(master->base + reg);
254 spin_unlock_irqrestore(&master->lock, flags); 254 spin_unlock_irqrestore(&master->lock, flags);
255 255
256 return ret; 256 return ret;
@@ -264,7 +264,7 @@ static void _fsi_master_mask_set(struct fsi_master *master,
264 unsigned long flags; 264 unsigned long flags;
265 265
266 spin_lock_irqsave(&master->lock, flags); 266 spin_lock_irqsave(&master->lock, flags);
267 __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 267 __fsi_reg_mask_set(master->base + reg, mask, data);
268 spin_unlock_irqrestore(&master->lock, flags); 268 spin_unlock_irqrestore(&master->lock, flags);
269} 269}
270 270
@@ -1285,7 +1285,7 @@ static int fsi_probe(struct platform_device *pdev)
1285 pm_runtime_enable(&pdev->dev); 1285 pm_runtime_enable(&pdev->dev);
1286 dev_set_drvdata(&pdev->dev, master); 1286 dev_set_drvdata(&pdev->dev, master);
1287 1287
1288 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, 1288 ret = request_irq(irq, &fsi_interrupt, 0,
1289 id_entry->name, master); 1289 id_entry->name, master);
1290 if (ret) { 1290 if (ret) {
1291 dev_err(&pdev->dev, "irq request err\n"); 1291 dev_err(&pdev->dev, "irq request err\n");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 917d3ceadc9d..c62ae689c4a1 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -20,12 +20,6 @@
20extern struct snd_soc_dai_driver sh4_hac_dai[2]; 20extern struct snd_soc_dai_driver sh4_hac_dai[2];
21extern struct snd_soc_platform_driver sh7760_soc_platform; 21extern struct snd_soc_platform_driver sh7760_soc_platform;
22 22
23static int machine_init(struct snd_soc_pcm_runtime *rtd)
24{
25 snd_soc_dapm_sync(&rtd->codec->dapm);
26 return 0;
27}
28
29static struct snd_soc_dai_link sh7760_ac97_dai = { 23static struct snd_soc_dai_link sh7760_ac97_dai = {
30 .name = "AC97", 24 .name = "AC97",
31 .stream_name = "AC97 HiFi", 25 .stream_name = "AC97 HiFi",
@@ -33,7 +27,6 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
33 .codec_dai_name = "ac97-hifi", 27 .codec_dai_name = "ac97-hifi",
34 .platform_name = "sh7760-pcm-audio", 28 .platform_name = "sh7760-pcm-audio",
35 .codec_name = "ac97-codec", 29 .codec_name = "ac97-codec",
36 .init = machine_init,
37 .ops = NULL, 30 .ops = NULL,
38}; 31};
39 32
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 05192d97b377..e0c621c0553b 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -342,7 +342,7 @@ static struct snd_soc_dai_ops ssi_dai_ops = {
342 .set_fmt = ssi_set_fmt, 342 .set_fmt = ssi_set_fmt,
343}; 343};
344 344
345struct snd_soc_dai_driver sh4_ssi_dai[] = { 345static struct snd_soc_dai_driver sh4_ssi_dai[] = {
346{ 346{
347 .name = "ssi-dai.0", 347 .name = "ssi-dai.0",
348 .playback = { 348 .playback = {
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 20b7f3b003a3..143c705ac27b 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -548,9 +548,6 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
548 548
549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
550{ 550{
551 const struct snd_soc_codec_driver *codec_drv;
552
553 codec_drv = codec->driver;
554 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); 551 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
555} 552}
556 553
@@ -868,10 +865,6 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
868 865
869static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 866static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
870{ 867{
871 const struct snd_soc_codec_driver *codec_drv;
872
873 codec_drv = codec->driver;
874
875 if (codec->reg_def_copy) 868 if (codec->reg_def_copy)
876 codec->reg_cache = kmemdup(codec->reg_def_copy, 869 codec->reg_cache = kmemdup(codec->reg_def_copy,
877 codec->reg_size, GFP_KERNEL); 870 codec->reg_size, GFP_KERNEL);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ef69f5a02709..a5d3685a5d38 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -106,7 +106,7 @@ static int format_register_str(struct snd_soc_codec *codec,
106 if (wordsize + regsize + 2 + 1 != len) 106 if (wordsize + regsize + 2 + 1 != len)
107 return -EINVAL; 107 return -EINVAL;
108 108
109 ret = snd_soc_read(codec , reg); 109 ret = snd_soc_read(codec, reg);
110 if (ret < 0) { 110 if (ret < 0) {
111 memset(regbuf, 'X', regsize); 111 memset(regbuf, 'X', regsize);
112 regbuf[regsize] = '\0'; 112 regbuf[regsize] = '\0';
@@ -144,7 +144,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
144 step = codec->driver->reg_cache_step; 144 step = codec->driver->reg_cache_step;
145 145
146 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 146 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
147 if (codec->readable_register && !codec->readable_register(codec, i)) 147 if (!snd_soc_codec_readable_register(codec, i))
148 continue; 148 continue;
149 if (codec->driver->display_register) { 149 if (codec->driver->display_register) {
150 count += codec->driver->display_register(codec, buf + count, 150 count += codec->driver->display_register(codec, buf + count,
@@ -245,7 +245,6 @@ static ssize_t codec_reg_write_file(struct file *file,
245 size_t buf_size; 245 size_t buf_size;
246 char *start = buf; 246 char *start = buf;
247 unsigned long reg, value; 247 unsigned long reg, value;
248 int step = 1;
249 struct snd_soc_codec *codec = file->private_data; 248 struct snd_soc_codec *codec = file->private_data;
250 249
251 buf_size = min(count, (sizeof(buf)-1)); 250 buf_size = min(count, (sizeof(buf)-1));
@@ -253,9 +252,6 @@ static ssize_t codec_reg_write_file(struct file *file,
253 return -EFAULT; 252 return -EFAULT;
254 buf[buf_size] = 0; 253 buf[buf_size] = 0;
255 254
256 if (codec->driver->reg_cache_step)
257 step = codec->driver->reg_cache_step;
258
259 while (*start == ' ') 255 while (*start == ' ')
260 start++; 256 start++;
261 reg = simple_strtoul(start, &start, 16); 257 reg = simple_strtoul(start, &start, 16);
@@ -957,6 +953,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
957 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 953 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
958 driver->num_dapm_widgets); 954 driver->num_dapm_widgets);
959 955
956 codec->dapm.idle_bias_off = driver->idle_bias_off;
957
960 if (driver->probe) { 958 if (driver->probe) {
961 ret = driver->probe(codec); 959 ret = driver->probe(codec);
962 if (ret < 0) { 960 if (ret < 0) {
@@ -1057,6 +1055,9 @@ static int soc_post_component_init(struct snd_soc_card *card,
1057 } 1055 }
1058 rtd->card = card; 1056 rtd->card = card;
1059 1057
1058 /* Make sure all DAPM widgets are instantiated */
1059 snd_soc_dapm_new_widgets(&codec->dapm);
1060
1060 /* machine controls, routes and widgets are not prefixed */ 1061 /* machine controls, routes and widgets are not prefixed */
1061 temp = codec->name_prefix; 1062 temp = codec->name_prefix;
1062 codec->name_prefix = NULL; 1063 codec->name_prefix = NULL;
@@ -1072,9 +1073,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1072 } 1073 }
1073 codec->name_prefix = temp; 1074 codec->name_prefix = temp;
1074 1075
1075 /* Make sure all DAPM widgets are instantiated */
1076 snd_soc_dapm_new_widgets(&codec->dapm);
1077
1078 /* register the rtd device */ 1076 /* register the rtd device */
1079 rtd->codec = codec; 1077 rtd->codec = codec;
1080 rtd->dev.parent = card->dev; 1078 rtd->dev.parent = card->dev;
@@ -1319,6 +1317,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1319 struct snd_soc_codec *codec; 1317 struct snd_soc_codec *codec;
1320 struct snd_soc_codec_conf *codec_conf; 1318 struct snd_soc_codec_conf *codec_conf;
1321 enum snd_soc_compress_type compress_type; 1319 enum snd_soc_compress_type compress_type;
1320 struct snd_soc_dai_link *dai_link;
1322 int ret, i, order; 1321 int ret, i, order;
1323 1322
1324 mutex_lock(&card->mutex); 1323 mutex_lock(&card->mutex);
@@ -1431,6 +1430,28 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1431 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1430 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1432 card->num_dapm_routes); 1431 card->num_dapm_routes);
1433 1432
1433 snd_soc_dapm_new_widgets(&card->dapm);
1434
1435 for (i = 0; i < card->num_links; i++) {
1436 dai_link = &card->dai_link[i];
1437
1438 if (dai_link->dai_fmt) {
1439 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
1440 dai_link->dai_fmt);
1441 if (ret != 0)
1442 dev_warn(card->rtd[i].codec_dai->dev,
1443 "Failed to set DAI format: %d\n",
1444 ret);
1445
1446 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1447 dai_link->dai_fmt);
1448 if (ret != 0)
1449 dev_warn(card->rtd[i].cpu_dai->dev,
1450 "Failed to set DAI format: %d\n",
1451 ret);
1452 }
1453 }
1454
1434 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1455 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1435 "%s", card->name); 1456 "%s", card->name);
1436 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1457 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1459,6 +1480,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1459 } 1480 }
1460 } 1481 }
1461 1482
1483 snd_soc_dapm_new_widgets(&card->dapm);
1484
1462 ret = snd_card_register(card->snd_card); 1485 ret = snd_card_register(card->snd_card);
1463 if (ret < 0) { 1486 if (ret < 0) {
1464 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1487 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -1479,6 +1502,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1479#endif 1502#endif
1480 1503
1481 card->instantiated = 1; 1504 card->instantiated = 1;
1505 snd_soc_dapm_sync(&card->dapm);
1482 mutex_unlock(&card->mutex); 1506 mutex_unlock(&card->mutex);
1483 return; 1507 return;
1484 1508
@@ -2229,7 +2253,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
2229 * @kcontrol: mixer control 2253 * @kcontrol: mixer control
2230 * @uinfo: control element information 2254 * @uinfo: control element information
2231 * 2255 *
2232 * Callback to provide information about a single mixer control. 2256 * Callback to provide information about a single mixer control, or a double
2257 * mixer control that spans 2 registers.
2233 * 2258 *
2234 * Returns 0 for success. 2259 * Returns 0 for success.
2235 */ 2260 */
@@ -2239,8 +2264,6 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2239 struct soc_mixer_control *mc = 2264 struct soc_mixer_control *mc =
2240 (struct soc_mixer_control *)kcontrol->private_value; 2265 (struct soc_mixer_control *)kcontrol->private_value;
2241 int platform_max; 2266 int platform_max;
2242 unsigned int shift = mc->shift;
2243 unsigned int rshift = mc->rshift;
2244 2267
2245 if (!mc->platform_max) 2268 if (!mc->platform_max)
2246 mc->platform_max = mc->max; 2269 mc->platform_max = mc->max;
@@ -2251,7 +2274,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2251 else 2274 else
2252 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2253 2276
2254 uinfo->count = shift == rshift ? 1 : 2; 2277 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
2255 uinfo->value.integer.min = 0; 2278 uinfo->value.integer.min = 0;
2256 uinfo->value.integer.max = platform_max; 2279 uinfo->value.integer.max = platform_max;
2257 return 0; 2280 return 0;
@@ -2263,7 +2286,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
2263 * @kcontrol: mixer control 2286 * @kcontrol: mixer control
2264 * @ucontrol: control element information 2287 * @ucontrol: control element information
2265 * 2288 *
2266 * Callback to get the value of a single mixer control. 2289 * Callback to get the value of a single mixer control, or a double mixer
2290 * control that spans 2 registers.
2267 * 2291 *
2268 * Returns 0 for success. 2292 * Returns 0 for success.
2269 */ 2293 */
@@ -2274,6 +2298,7 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2274 (struct soc_mixer_control *)kcontrol->private_value; 2298 (struct soc_mixer_control *)kcontrol->private_value;
2275 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2299 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2276 unsigned int reg = mc->reg; 2300 unsigned int reg = mc->reg;
2301 unsigned int reg2 = mc->rreg;
2277 unsigned int shift = mc->shift; 2302 unsigned int shift = mc->shift;
2278 unsigned int rshift = mc->rshift; 2303 unsigned int rshift = mc->rshift;
2279 int max = mc->max; 2304 int max = mc->max;
@@ -2282,13 +2307,18 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2282 2307
2283 ucontrol->value.integer.value[0] = 2308 ucontrol->value.integer.value[0] =
2284 (snd_soc_read(codec, reg) >> shift) & mask; 2309 (snd_soc_read(codec, reg) >> shift) & mask;
2285 if (shift != rshift) 2310 if (invert)
2286 ucontrol->value.integer.value[1] =
2287 (snd_soc_read(codec, reg) >> rshift) & mask;
2288 if (invert) {
2289 ucontrol->value.integer.value[0] = 2311 ucontrol->value.integer.value[0] =
2290 max - ucontrol->value.integer.value[0]; 2312 max - ucontrol->value.integer.value[0];
2291 if (shift != rshift) 2313
2314 if (snd_soc_volsw_is_stereo(mc)) {
2315 if (reg == reg2)
2316 ucontrol->value.integer.value[1] =
2317 (snd_soc_read(codec, reg) >> rshift) & mask;
2318 else
2319 ucontrol->value.integer.value[1] =
2320 (snd_soc_read(codec, reg2) >> shift) & mask;
2321 if (invert)
2292 ucontrol->value.integer.value[1] = 2322 ucontrol->value.integer.value[1] =
2293 max - ucontrol->value.integer.value[1]; 2323 max - ucontrol->value.integer.value[1];
2294 } 2324 }
@@ -2302,7 +2332,8 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
2302 * @kcontrol: mixer control 2332 * @kcontrol: mixer control
2303 * @ucontrol: control element information 2333 * @ucontrol: control element information
2304 * 2334 *
2305 * Callback to set the value of a single mixer control. 2335 * Callback to set the value of a single mixer control, or a double mixer
2336 * control that spans 2 registers.
2306 * 2337 *
2307 * Returns 0 for success. 2338 * Returns 0 for success.
2308 */ 2339 */
@@ -2313,143 +2344,44 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2313 (struct soc_mixer_control *)kcontrol->private_value; 2344 (struct soc_mixer_control *)kcontrol->private_value;
2314 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2345 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2315 unsigned int reg = mc->reg; 2346 unsigned int reg = mc->reg;
2347 unsigned int reg2 = mc->rreg;
2316 unsigned int shift = mc->shift; 2348 unsigned int shift = mc->shift;
2317 unsigned int rshift = mc->rshift; 2349 unsigned int rshift = mc->rshift;
2318 int max = mc->max; 2350 int max = mc->max;
2319 unsigned int mask = (1 << fls(max)) - 1; 2351 unsigned int mask = (1 << fls(max)) - 1;
2320 unsigned int invert = mc->invert; 2352 unsigned int invert = mc->invert;
2321 unsigned int val, val2, val_mask; 2353 int err;
2354 bool type_2r = 0;
2355 unsigned int val2 = 0;
2356 unsigned int val, val_mask;
2322 2357
2323 val = (ucontrol->value.integer.value[0] & mask); 2358 val = (ucontrol->value.integer.value[0] & mask);
2324 if (invert) 2359 if (invert)
2325 val = max - val; 2360 val = max - val;
2326 val_mask = mask << shift; 2361 val_mask = mask << shift;
2327 val = val << shift; 2362 val = val << shift;
2328 if (shift != rshift) { 2363 if (snd_soc_volsw_is_stereo(mc)) {
2329 val2 = (ucontrol->value.integer.value[1] & mask); 2364 val2 = (ucontrol->value.integer.value[1] & mask);
2330 if (invert) 2365 if (invert)
2331 val2 = max - val2; 2366 val2 = max - val2;
2332 val_mask |= mask << rshift; 2367 if (reg == reg2) {
2333 val |= val2 << rshift; 2368 val_mask |= mask << rshift;
2334 } 2369 val |= val2 << rshift;
2335 return snd_soc_update_bits_locked(codec, reg, val_mask, val); 2370 } else {
2336} 2371 val2 = val2 << shift;
2337EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 2372 type_2r = 1;
2338 2373 }
2339/**
2340 * snd_soc_info_volsw_2r - double mixer info callback
2341 * @kcontrol: mixer control
2342 * @uinfo: control element information
2343 *
2344 * Callback to provide information about a double mixer control that
2345 * spans 2 codec registers.
2346 *
2347 * Returns 0 for success.
2348 */
2349int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
2350 struct snd_ctl_elem_info *uinfo)
2351{
2352 struct soc_mixer_control *mc =
2353 (struct soc_mixer_control *)kcontrol->private_value;
2354 int platform_max;
2355
2356 if (!mc->platform_max)
2357 mc->platform_max = mc->max;
2358 platform_max = mc->platform_max;
2359
2360 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2361 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2362 else
2363 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2364
2365 uinfo->count = 2;
2366 uinfo->value.integer.min = 0;
2367 uinfo->value.integer.max = platform_max;
2368 return 0;
2369}
2370EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
2371
2372/**
2373 * snd_soc_get_volsw_2r - double mixer get callback
2374 * @kcontrol: mixer control
2375 * @ucontrol: control element information
2376 *
2377 * Callback to get the value of a double mixer control that spans 2 registers.
2378 *
2379 * Returns 0 for success.
2380 */
2381int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
2382 struct snd_ctl_elem_value *ucontrol)
2383{
2384 struct soc_mixer_control *mc =
2385 (struct soc_mixer_control *)kcontrol->private_value;
2386 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2387 unsigned int reg = mc->reg;
2388 unsigned int reg2 = mc->rreg;
2389 unsigned int shift = mc->shift;
2390 int max = mc->max;
2391 unsigned int mask = (1 << fls(max)) - 1;
2392 unsigned int invert = mc->invert;
2393
2394 ucontrol->value.integer.value[0] =
2395 (snd_soc_read(codec, reg) >> shift) & mask;
2396 ucontrol->value.integer.value[1] =
2397 (snd_soc_read(codec, reg2) >> shift) & mask;
2398 if (invert) {
2399 ucontrol->value.integer.value[0] =
2400 max - ucontrol->value.integer.value[0];
2401 ucontrol->value.integer.value[1] =
2402 max - ucontrol->value.integer.value[1];
2403 }
2404
2405 return 0;
2406}
2407EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
2408
2409/**
2410 * snd_soc_put_volsw_2r - double mixer set callback
2411 * @kcontrol: mixer control
2412 * @ucontrol: control element information
2413 *
2414 * Callback to set the value of a double mixer control that spans 2 registers.
2415 *
2416 * Returns 0 for success.
2417 */
2418int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
2419 struct snd_ctl_elem_value *ucontrol)
2420{
2421 struct soc_mixer_control *mc =
2422 (struct soc_mixer_control *)kcontrol->private_value;
2423 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2424 unsigned int reg = mc->reg;
2425 unsigned int reg2 = mc->rreg;
2426 unsigned int shift = mc->shift;
2427 int max = mc->max;
2428 unsigned int mask = (1 << fls(max)) - 1;
2429 unsigned int invert = mc->invert;
2430 int err;
2431 unsigned int val, val2, val_mask;
2432
2433 val_mask = mask << shift;
2434 val = (ucontrol->value.integer.value[0] & mask);
2435 val2 = (ucontrol->value.integer.value[1] & mask);
2436
2437 if (invert) {
2438 val = max - val;
2439 val2 = max - val2;
2440 } 2374 }
2441
2442 val = val << shift;
2443 val2 = val2 << shift;
2444
2445 err = snd_soc_update_bits_locked(codec, reg, val_mask, val); 2375 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2446 if (err < 0) 2376 if (err < 0)
2447 return err; 2377 return err;
2448 2378
2449 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2); 2379 if (type_2r)
2380 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
2381
2450 return err; 2382 return err;
2451} 2383}
2452EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 2384EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
2453 2385
2454/** 2386/**
2455 * snd_soc_info_volsw_s8 - signed mixer info callback 2387 * snd_soc_info_volsw_s8 - signed mixer info callback
@@ -2680,7 +2612,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2680 if (dai->driver && dai->driver->ops->set_sysclk) 2612 if (dai->driver && dai->driver->ops->set_sysclk)
2681 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 2613 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
2682 else if (dai->codec && dai->codec->driver->set_sysclk) 2614 else if (dai->codec && dai->codec->driver->set_sysclk)
2683 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 2615 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0,
2684 freq, dir); 2616 freq, dir);
2685 else 2617 else
2686 return -EINVAL; 2618 return -EINVAL;
@@ -2691,16 +2623,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2691 * snd_soc_codec_set_sysclk - configure CODEC system or master clock. 2623 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
2692 * @codec: CODEC 2624 * @codec: CODEC
2693 * @clk_id: DAI specific clock ID 2625 * @clk_id: DAI specific clock ID
2626 * @source: Source for the clock
2694 * @freq: new clock frequency in Hz 2627 * @freq: new clock frequency in Hz
2695 * @dir: new clock direction - input/output. 2628 * @dir: new clock direction - input/output.
2696 * 2629 *
2697 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. 2630 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
2698 */ 2631 */
2699int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 2632int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
2700 unsigned int freq, int dir) 2633 int source, unsigned int freq, int dir)
2701{ 2634{
2702 if (codec->driver->set_sysclk) 2635 if (codec->driver->set_sysclk)
2703 return codec->driver->set_sysclk(codec, clk_id, freq, dir); 2636 return codec->driver->set_sysclk(codec, clk_id, source,
2637 freq, dir);
2704 else 2638 else
2705 return -EINVAL; 2639 return -EINVAL;
2706} 2640}
@@ -2895,6 +2829,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2895 card->rtd[i].dai_link = &card->dai_link[i]; 2829 card->rtd[i].dai_link = &card->dai_link[i];
2896 2830
2897 INIT_LIST_HEAD(&card->list); 2831 INIT_LIST_HEAD(&card->list);
2832 INIT_LIST_HEAD(&card->dapm_dirty);
2898 card->instantiated = 0; 2833 card->instantiated = 0;
2899 mutex_init(&card->mutex); 2834 mutex_init(&card->mutex);
2900 2835
@@ -3153,6 +3088,7 @@ int snd_soc_register_platform(struct device *dev,
3153 platform->driver = platform_drv; 3088 platform->driver = platform_drv;
3154 platform->dapm.dev = dev; 3089 platform->dapm.dev = dev;
3155 platform->dapm.platform = platform; 3090 platform->dapm.platform = platform;
3091 platform->dapm.stream_event = platform_drv->stream_event;
3156 3092
3157 mutex_lock(&client_mutex); 3093 mutex_lock(&client_mutex);
3158 list_add(&platform->list, &platform_list); 3094 list_add(&platform->list, &platform_list);
@@ -3265,6 +3201,7 @@ int snd_soc_register_codec(struct device *dev,
3265 codec->dapm.dev = dev; 3201 codec->dapm.dev = dev;
3266 codec->dapm.codec = codec; 3202 codec->dapm.codec = codec;
3267 codec->dapm.seq_notifier = codec_drv->seq_notifier; 3203 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3204 codec->dapm.stream_event = codec_drv->stream_event;
3268 codec->dev = dev; 3205 codec->dev = dev;
3269 codec->driver = codec_drv; 3206 codec->driver = codec_drv;
3270 codec->num_dai = num_dai; 3207 codec->num_dai = num_dai;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d67c637557a7..f42e8b9fb17d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -48,6 +48,8 @@
48 48
49#include <trace/events/asoc.h> 49#include <trace/events/asoc.h>
50 50
51#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
52
51/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
52static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
53 [snd_soc_dapm_pre] = 0, 55 [snd_soc_dapm_pre] = 0,
@@ -117,6 +119,21 @@ static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
117 kfree(buf); 119 kfree(buf);
118} 120}
119 121
122static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
123{
124 return !list_empty(&w->dirty);
125}
126
127void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
128{
129 if (!dapm_dirty_widget(w)) {
130 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
131 w->name, reason);
132 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
133 }
134}
135EXPORT_SYMBOL_GPL(dapm_mark_dirty);
136
120/* create a new dapm widget */ 137/* create a new dapm widget */
121static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 138static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
122 const struct snd_soc_dapm_widget *_widget) 139 const struct snd_soc_dapm_widget *_widget)
@@ -316,7 +333,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
316 } 333 }
317 } 334 }
318 break; 335 break;
319 /* does not effect routing - always connected */ 336 /* does not affect routing - always connected */
320 case snd_soc_dapm_pga: 337 case snd_soc_dapm_pga:
321 case snd_soc_dapm_out_drv: 338 case snd_soc_dapm_out_drv:
322 case snd_soc_dapm_output: 339 case snd_soc_dapm_output:
@@ -328,13 +345,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
328 case snd_soc_dapm_supply: 345 case snd_soc_dapm_supply:
329 case snd_soc_dapm_aif_in: 346 case snd_soc_dapm_aif_in:
330 case snd_soc_dapm_aif_out: 347 case snd_soc_dapm_aif_out:
331 p->connect = 1;
332 break;
333 /* does effect routing - dynamically connected */
334 case snd_soc_dapm_hp: 348 case snd_soc_dapm_hp:
335 case snd_soc_dapm_mic: 349 case snd_soc_dapm_mic:
336 case snd_soc_dapm_spk: 350 case snd_soc_dapm_spk:
337 case snd_soc_dapm_line: 351 case snd_soc_dapm_line:
352 p->connect = 1;
353 break;
354 /* does affect routing - dynamically connected */
338 case snd_soc_dapm_pre: 355 case snd_soc_dapm_pre:
339 case snd_soc_dapm_post: 356 case snd_soc_dapm_post:
340 p->connect = 0; 357 p->connect = 0;
@@ -443,6 +460,11 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
443 if (path->name != (char *)w->kcontrol_news[i].name) 460 if (path->name != (char *)w->kcontrol_news[i].name)
444 continue; 461 continue;
445 462
463 if (w->kcontrols[i]) {
464 path->kcontrol = w->kcontrols[i];
465 continue;
466 }
467
446 wlistsize = sizeof(struct snd_soc_dapm_widget_list) + 468 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
447 sizeof(struct snd_soc_dapm_widget *), 469 sizeof(struct snd_soc_dapm_widget *),
448 wlist = kzalloc(wlistsize, GFP_KERNEL); 470 wlist = kzalloc(wlistsize, GFP_KERNEL);
@@ -579,8 +601,8 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
579 name + prefix_len, prefix); 601 name + prefix_len, prefix);
580 ret = snd_ctl_add(card, kcontrol); 602 ret = snd_ctl_add(card, kcontrol);
581 if (ret < 0) { 603 if (ret < 0) {
582 dev_err(dapm->dev, 604 dev_err(dapm->dev, "failed to add kcontrol %s: %d\n",
583 "asoc: failed to add kcontrol %s\n", w->name); 605 w->name, ret);
584 kfree(wlist); 606 kfree(wlist);
585 return ret; 607 return ret;
586 } 608 }
@@ -644,30 +666,45 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
644 struct snd_soc_dapm_path *path; 666 struct snd_soc_dapm_path *path;
645 int con = 0; 667 int con = 0;
646 668
669 if (widget->outputs >= 0)
670 return widget->outputs;
671
672 DAPM_UPDATE_STAT(widget, path_checks);
673
647 if (widget->id == snd_soc_dapm_supply) 674 if (widget->id == snd_soc_dapm_supply)
648 return 0; 675 return 0;
649 676
650 switch (widget->id) { 677 switch (widget->id) {
651 case snd_soc_dapm_adc: 678 case snd_soc_dapm_adc:
652 case snd_soc_dapm_aif_out: 679 case snd_soc_dapm_aif_out:
653 if (widget->active) 680 if (widget->active) {
654 return snd_soc_dapm_suspend_check(widget); 681 widget->outputs = snd_soc_dapm_suspend_check(widget);
682 return widget->outputs;
683 }
655 default: 684 default:
656 break; 685 break;
657 } 686 }
658 687
659 if (widget->connected) { 688 if (widget->connected) {
660 /* connected pin ? */ 689 /* connected pin ? */
661 if (widget->id == snd_soc_dapm_output && !widget->ext) 690 if (widget->id == snd_soc_dapm_output && !widget->ext) {
662 return snd_soc_dapm_suspend_check(widget); 691 widget->outputs = snd_soc_dapm_suspend_check(widget);
692 return widget->outputs;
693 }
663 694
664 /* connected jack or spk ? */ 695 /* connected jack or spk ? */
665 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 696 if (widget->id == snd_soc_dapm_hp ||
666 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) 697 widget->id == snd_soc_dapm_spk ||
667 return snd_soc_dapm_suspend_check(widget); 698 (widget->id == snd_soc_dapm_line &&
699 !list_empty(&widget->sources))) {
700 widget->outputs = snd_soc_dapm_suspend_check(widget);
701 return widget->outputs;
702 }
668 } 703 }
669 704
670 list_for_each_entry(path, &widget->sinks, list_source) { 705 list_for_each_entry(path, &widget->sinks, list_source) {
706 DAPM_UPDATE_STAT(widget, neighbour_checks);
707
671 if (path->weak) 708 if (path->weak)
672 continue; 709 continue;
673 710
@@ -680,6 +717,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
680 } 717 }
681 } 718 }
682 719
720 widget->outputs = con;
721
683 return con; 722 return con;
684} 723}
685 724
@@ -692,6 +731,11 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
692 struct snd_soc_dapm_path *path; 731 struct snd_soc_dapm_path *path;
693 int con = 0; 732 int con = 0;
694 733
734 if (widget->inputs >= 0)
735 return widget->inputs;
736
737 DAPM_UPDATE_STAT(widget, path_checks);
738
695 if (widget->id == snd_soc_dapm_supply) 739 if (widget->id == snd_soc_dapm_supply)
696 return 0; 740 return 0;
697 741
@@ -699,28 +743,40 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
699 switch (widget->id) { 743 switch (widget->id) {
700 case snd_soc_dapm_dac: 744 case snd_soc_dapm_dac:
701 case snd_soc_dapm_aif_in: 745 case snd_soc_dapm_aif_in:
702 if (widget->active) 746 if (widget->active) {
703 return snd_soc_dapm_suspend_check(widget); 747 widget->inputs = snd_soc_dapm_suspend_check(widget);
748 return widget->inputs;
749 }
704 default: 750 default:
705 break; 751 break;
706 } 752 }
707 753
708 if (widget->connected) { 754 if (widget->connected) {
709 /* connected pin ? */ 755 /* connected pin ? */
710 if (widget->id == snd_soc_dapm_input && !widget->ext) 756 if (widget->id == snd_soc_dapm_input && !widget->ext) {
711 return snd_soc_dapm_suspend_check(widget); 757 widget->inputs = snd_soc_dapm_suspend_check(widget);
758 return widget->inputs;
759 }
712 760
713 /* connected VMID/Bias for lower pops */ 761 /* connected VMID/Bias for lower pops */
714 if (widget->id == snd_soc_dapm_vmid) 762 if (widget->id == snd_soc_dapm_vmid) {
715 return snd_soc_dapm_suspend_check(widget); 763 widget->inputs = snd_soc_dapm_suspend_check(widget);
764 return widget->inputs;
765 }
716 766
717 /* connected jack ? */ 767 /* connected jack ? */
718 if (widget->id == snd_soc_dapm_mic || 768 if (widget->id == snd_soc_dapm_mic ||
719 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 769 (widget->id == snd_soc_dapm_line &&
720 return snd_soc_dapm_suspend_check(widget); 770 !list_empty(&widget->sinks))) {
771 widget->inputs = snd_soc_dapm_suspend_check(widget);
772 return widget->inputs;
773 }
774
721 } 775 }
722 776
723 list_for_each_entry(path, &widget->sources, list_sink) { 777 list_for_each_entry(path, &widget->sources, list_sink) {
778 DAPM_UPDATE_STAT(widget, neighbour_checks);
779
724 if (path->weak) 780 if (path->weak)
725 continue; 781 continue;
726 782
@@ -733,6 +789,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
733 } 789 }
734 } 790 }
735 791
792 widget->inputs = con;
793
736 return con; 794 return con;
737} 795}
738 796
@@ -756,12 +814,29 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
756} 814}
757EXPORT_SYMBOL_GPL(dapm_reg_event); 815EXPORT_SYMBOL_GPL(dapm_reg_event);
758 816
817static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
818{
819 if (w->power_checked)
820 return w->new_power;
821
822 if (w->force)
823 w->new_power = 1;
824 else
825 w->new_power = w->power_check(w);
826
827 w->power_checked = true;
828
829 return w->new_power;
830}
831
759/* Generic check to see if a widget should be powered. 832/* Generic check to see if a widget should be powered.
760 */ 833 */
761static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 834static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
762{ 835{
763 int in, out; 836 int in, out;
764 837
838 DAPM_UPDATE_STAT(w, power_checks);
839
765 in = is_connected_input_ep(w); 840 in = is_connected_input_ep(w);
766 dapm_clear_walk(w->dapm); 841 dapm_clear_walk(w->dapm);
767 out = is_connected_output_ep(w); 842 out = is_connected_output_ep(w);
@@ -774,6 +849,8 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
774{ 849{
775 int in; 850 int in;
776 851
852 DAPM_UPDATE_STAT(w, power_checks);
853
777 if (w->active) { 854 if (w->active) {
778 in = is_connected_input_ep(w); 855 in = is_connected_input_ep(w);
779 dapm_clear_walk(w->dapm); 856 dapm_clear_walk(w->dapm);
@@ -788,6 +865,8 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
788{ 865{
789 int out; 866 int out;
790 867
868 DAPM_UPDATE_STAT(w, power_checks);
869
791 if (w->active) { 870 if (w->active) {
792 out = is_connected_output_ep(w); 871 out = is_connected_output_ep(w);
793 dapm_clear_walk(w->dapm); 872 dapm_clear_walk(w->dapm);
@@ -801,10 +880,13 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
801static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) 880static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
802{ 881{
803 struct snd_soc_dapm_path *path; 882 struct snd_soc_dapm_path *path;
804 int power = 0; 883
884 DAPM_UPDATE_STAT(w, power_checks);
805 885
806 /* Check if one of our outputs is connected */ 886 /* Check if one of our outputs is connected */
807 list_for_each_entry(path, &w->sinks, list_source) { 887 list_for_each_entry(path, &w->sinks, list_source) {
888 DAPM_UPDATE_STAT(w, neighbour_checks);
889
808 if (path->weak) 890 if (path->weak)
809 continue; 891 continue;
810 892
@@ -815,21 +897,18 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
815 if (!path->sink) 897 if (!path->sink)
816 continue; 898 continue;
817 899
818 if (path->sink->force) { 900 if (dapm_widget_power_check(path->sink))
819 power = 1; 901 return 1;
820 break;
821 }
822
823 if (path->sink->power_check &&
824 path->sink->power_check(path->sink)) {
825 power = 1;
826 break;
827 }
828 } 902 }
829 903
830 dapm_clear_walk(w->dapm); 904 dapm_clear_walk(w->dapm);
831 905
832 return power; 906 return 0;
907}
908
909static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
910{
911 return 1;
833} 912}
834 913
835static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 914static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
@@ -1172,6 +1251,85 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1172 } 1251 }
1173} 1252}
1174 1253
1254static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer,
1255 bool power, bool connect)
1256{
1257 /* If a connection is being made or broken then that update
1258 * will have marked the peer dirty, otherwise the widgets are
1259 * not connected and this update has no impact. */
1260 if (!connect)
1261 return;
1262
1263 /* If the peer is already in the state we're moving to then we
1264 * won't have an impact on it. */
1265 if (power != peer->power)
1266 dapm_mark_dirty(peer, "peer state change");
1267}
1268
1269static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1270 struct list_head *up_list,
1271 struct list_head *down_list)
1272{
1273 struct snd_soc_dapm_path *path;
1274
1275 if (w->power == power)
1276 return;
1277
1278 trace_snd_soc_dapm_widget_power(w, power);
1279
1280 /* If we changed our power state perhaps our neigbours changed
1281 * also.
1282 */
1283 list_for_each_entry(path, &w->sources, list_sink) {
1284 if (path->source) {
1285 dapm_widget_set_peer_power(path->source, power,
1286 path->connect);
1287 }
1288 }
1289 switch (w->id) {
1290 case snd_soc_dapm_supply:
1291 /* Supplies can't affect their outputs, only their inputs */
1292 break;
1293 default:
1294 list_for_each_entry(path, &w->sinks, list_source) {
1295 if (path->sink) {
1296 dapm_widget_set_peer_power(path->sink, power,
1297 path->connect);
1298 }
1299 }
1300 break;
1301 }
1302
1303 if (power)
1304 dapm_seq_insert(w, up_list, true);
1305 else
1306 dapm_seq_insert(w, down_list, false);
1307
1308 w->power = power;
1309}
1310
1311static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
1312 struct list_head *up_list,
1313 struct list_head *down_list)
1314{
1315 int power;
1316
1317 switch (w->id) {
1318 case snd_soc_dapm_pre:
1319 dapm_seq_insert(w, down_list, false);
1320 break;
1321 case snd_soc_dapm_post:
1322 dapm_seq_insert(w, up_list, true);
1323 break;
1324
1325 default:
1326 power = dapm_widget_power_check(w);
1327
1328 dapm_widget_set_power(w, power, up_list, down_list);
1329 break;
1330 }
1331}
1332
1175/* 1333/*
1176 * Scan each dapm widget for complete audio path. 1334 * Scan each dapm widget for complete audio path.
1177 * A complete path is a route that has valid endpoints i.e.:- 1335 * A complete path is a route that has valid endpoints i.e.:-
@@ -1190,7 +1348,6 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1190 LIST_HEAD(down_list); 1348 LIST_HEAD(down_list);
1191 LIST_HEAD(async_domain); 1349 LIST_HEAD(async_domain);
1192 enum snd_soc_bias_level bias; 1350 enum snd_soc_bias_level bias;
1193 int power;
1194 1351
1195 trace_snd_soc_dapm_start(card); 1352 trace_snd_soc_dapm_start(card);
1196 1353
@@ -1203,61 +1360,47 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1203 } 1360 }
1204 } 1361 }
1205 1362
1206 /* Check which widgets we need to power and store them in 1363 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
1207 * lists indicating if they should be powered up or down. 1364
1208 */
1209 list_for_each_entry(w, &card->widgets, list) { 1365 list_for_each_entry(w, &card->widgets, list) {
1210 switch (w->id) { 1366 w->power_checked = false;
1211 case snd_soc_dapm_pre: 1367 w->inputs = -1;
1212 dapm_seq_insert(w, &down_list, false); 1368 w->outputs = -1;
1213 break; 1369 }
1214 case snd_soc_dapm_post:
1215 dapm_seq_insert(w, &up_list, true);
1216 break;
1217 1370
1218 default: 1371 /* Check which widgets we need to power and store them in
1219 if (!w->power_check) 1372 * lists indicating if they should be powered up or down. We
1220 continue; 1373 * only check widgets that have been flagged as dirty but note
1374 * that new widgets may be added to the dirty list while we
1375 * iterate.
1376 */
1377 list_for_each_entry(w, &card->dapm_dirty, dirty) {
1378 dapm_power_one_widget(w, &up_list, &down_list);
1379 }
1221 1380
1222 if (!w->force) 1381 list_for_each_entry(w, &card->widgets, list) {
1223 power = w->power_check(w); 1382 list_del_init(&w->dirty);
1224 else
1225 power = 1;
1226 1383
1227 if (power) { 1384 if (w->power) {
1228 d = w->dapm; 1385 d = w->dapm;
1229 1386
1230 /* Supplies and micbiases only bring 1387 /* Supplies and micbiases only bring the
1231 * the context up to STANDBY as unless 1388 * context up to STANDBY as unless something
1232 * something else is active and 1389 * else is active and passing audio they
1233 * passing audio they generally don't 1390 * generally don't require full power.
1234 * require full power. 1391 */
1235 */ 1392 switch (w->id) {
1236 switch (w->id) { 1393 case snd_soc_dapm_supply:
1237 case snd_soc_dapm_supply: 1394 case snd_soc_dapm_micbias:
1238 case snd_soc_dapm_micbias: 1395 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1239 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1396 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1240 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1397 break;
1241 break; 1398 default:
1242 default: 1399 d->target_bias_level = SND_SOC_BIAS_ON;
1243 d->target_bias_level = SND_SOC_BIAS_ON; 1400 break;
1244 break;
1245 }
1246 } 1401 }
1247
1248 if (w->power == power)
1249 continue;
1250
1251 trace_snd_soc_dapm_widget_power(w, power);
1252
1253 if (power)
1254 dapm_seq_insert(w, &up_list, true);
1255 else
1256 dapm_seq_insert(w, &down_list, false);
1257
1258 w->power = power;
1259 break;
1260 } 1402 }
1403
1261 } 1404 }
1262 1405
1263 /* If there are no DAPM widgets then try to figure out power from the 1406 /* If there are no DAPM widgets then try to figure out power from the
@@ -1286,14 +1429,18 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1286 } 1429 }
1287 } 1430 }
1288 1431
1289 /* Force all contexts in the card to the same bias state */ 1432 /* Force all contexts in the card to the same bias state if
1433 * they're not ground referenced.
1434 */
1290 bias = SND_SOC_BIAS_OFF; 1435 bias = SND_SOC_BIAS_OFF;
1291 list_for_each_entry(d, &card->dapm_list, list) 1436 list_for_each_entry(d, &card->dapm_list, list)
1292 if (d->target_bias_level > bias) 1437 if (d->target_bias_level > bias)
1293 bias = d->target_bias_level; 1438 bias = d->target_bias_level;
1294 list_for_each_entry(d, &card->dapm_list, list) 1439 list_for_each_entry(d, &card->dapm_list, list)
1295 d->target_bias_level = bias; 1440 if (!d->idle_bias_off)
1441 d->target_bias_level = bias;
1296 1442
1443 trace_snd_soc_dapm_walk_done(card);
1297 1444
1298 /* Run all the bias changes in parallel */ 1445 /* Run all the bias changes in parallel */
1299 list_for_each_entry(d, &dapm->card->dapm_list, list) 1446 list_for_each_entry(d, &dapm->card->dapm_list, list)
@@ -1524,14 +1671,21 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1524 1671
1525 found = 1; 1672 found = 1;
1526 /* we now need to match the string in the enum to the path */ 1673 /* we now need to match the string in the enum to the path */
1527 if (!(strcmp(path->name, e->texts[mux]))) 1674 if (!(strcmp(path->name, e->texts[mux]))) {
1528 path->connect = 1; /* new connection */ 1675 path->connect = 1; /* new connection */
1529 else 1676 dapm_mark_dirty(path->source, "mux connection");
1677 } else {
1678 if (path->connect)
1679 dapm_mark_dirty(path->source,
1680 "mux disconnection");
1530 path->connect = 0; /* old connection must be powered down */ 1681 path->connect = 0; /* old connection must be powered down */
1682 }
1531 } 1683 }
1532 1684
1533 if (found) 1685 if (found) {
1686 dapm_mark_dirty(widget, "mux change");
1534 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1687 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1688 }
1535 1689
1536 return 0; 1690 return 0;
1537} 1691}
@@ -1556,11 +1710,13 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1556 /* found, now check type */ 1710 /* found, now check type */
1557 found = 1; 1711 found = 1;
1558 path->connect = connect; 1712 path->connect = connect;
1559 break; 1713 dapm_mark_dirty(path->source, "mixer connection");
1560 } 1714 }
1561 1715
1562 if (found) 1716 if (found) {
1717 dapm_mark_dirty(widget, "mixer update");
1563 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1718 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1719 }
1564 1720
1565 return 0; 1721 return 0;
1566} 1722}
@@ -1704,6 +1860,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1704 w->connected = status; 1860 w->connected = status;
1705 if (status == 0) 1861 if (status == 0)
1706 w->force = 0; 1862 w->force = 0;
1863 dapm_mark_dirty(w, "pin configuration");
1707 1864
1708 return 0; 1865 return 0;
1709} 1866}
@@ -1719,6 +1876,13 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1719 */ 1876 */
1720int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 1877int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1721{ 1878{
1879 /*
1880 * Suppress early reports (eg, jacks syncing their state) to avoid
1881 * silly DAPM runs during card startup.
1882 */
1883 if (!dapm->card || !dapm->card->instantiated)
1884 return 0;
1885
1722 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 1886 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
1723} 1887}
1724EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1888EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
@@ -2004,42 +2168,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2004 case snd_soc_dapm_switch: 2168 case snd_soc_dapm_switch:
2005 case snd_soc_dapm_mixer: 2169 case snd_soc_dapm_mixer:
2006 case snd_soc_dapm_mixer_named_ctl: 2170 case snd_soc_dapm_mixer_named_ctl:
2007 w->power_check = dapm_generic_check_power;
2008 dapm_new_mixer(w); 2171 dapm_new_mixer(w);
2009 break; 2172 break;
2010 case snd_soc_dapm_mux: 2173 case snd_soc_dapm_mux:
2011 case snd_soc_dapm_virt_mux: 2174 case snd_soc_dapm_virt_mux:
2012 case snd_soc_dapm_value_mux: 2175 case snd_soc_dapm_value_mux:
2013 w->power_check = dapm_generic_check_power;
2014 dapm_new_mux(w); 2176 dapm_new_mux(w);
2015 break; 2177 break;
2016 case snd_soc_dapm_adc:
2017 case snd_soc_dapm_aif_out:
2018 w->power_check = dapm_adc_check_power;
2019 break;
2020 case snd_soc_dapm_dac:
2021 case snd_soc_dapm_aif_in:
2022 w->power_check = dapm_dac_check_power;
2023 break;
2024 case snd_soc_dapm_pga: 2178 case snd_soc_dapm_pga:
2025 case snd_soc_dapm_out_drv: 2179 case snd_soc_dapm_out_drv:
2026 w->power_check = dapm_generic_check_power;
2027 dapm_new_pga(w); 2180 dapm_new_pga(w);
2028 break; 2181 break;
2029 case snd_soc_dapm_input: 2182 default:
2030 case snd_soc_dapm_output:
2031 case snd_soc_dapm_micbias:
2032 case snd_soc_dapm_spk:
2033 case snd_soc_dapm_hp:
2034 case snd_soc_dapm_mic:
2035 case snd_soc_dapm_line:
2036 w->power_check = dapm_generic_check_power;
2037 break;
2038 case snd_soc_dapm_supply:
2039 w->power_check = dapm_supply_check_power;
2040 case snd_soc_dapm_vmid:
2041 case snd_soc_dapm_pre:
2042 case snd_soc_dapm_post:
2043 break; 2183 break;
2044 } 2184 }
2045 2185
@@ -2056,6 +2196,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2056 2196
2057 w->new = 1; 2197 w->new = 1;
2058 2198
2199 dapm_mark_dirty(w, "new widget");
2059 dapm_debugfs_add_widget(w); 2200 dapm_debugfs_add_widget(w);
2060 } 2201 }
2061 2202
@@ -2530,6 +2671,44 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2530 else 2671 else
2531 snprintf(w->name, name_len, "%s", widget->name); 2672 snprintf(w->name, name_len, "%s", widget->name);
2532 2673
2674 switch (w->id) {
2675 case snd_soc_dapm_switch:
2676 case snd_soc_dapm_mixer:
2677 case snd_soc_dapm_mixer_named_ctl:
2678 w->power_check = dapm_generic_check_power;
2679 break;
2680 case snd_soc_dapm_mux:
2681 case snd_soc_dapm_virt_mux:
2682 case snd_soc_dapm_value_mux:
2683 w->power_check = dapm_generic_check_power;
2684 break;
2685 case snd_soc_dapm_adc:
2686 case snd_soc_dapm_aif_out:
2687 w->power_check = dapm_adc_check_power;
2688 break;
2689 case snd_soc_dapm_dac:
2690 case snd_soc_dapm_aif_in:
2691 w->power_check = dapm_dac_check_power;
2692 break;
2693 case snd_soc_dapm_pga:
2694 case snd_soc_dapm_out_drv:
2695 case snd_soc_dapm_input:
2696 case snd_soc_dapm_output:
2697 case snd_soc_dapm_micbias:
2698 case snd_soc_dapm_spk:
2699 case snd_soc_dapm_hp:
2700 case snd_soc_dapm_mic:
2701 case snd_soc_dapm_line:
2702 w->power_check = dapm_generic_check_power;
2703 break;
2704 case snd_soc_dapm_supply:
2705 w->power_check = dapm_supply_check_power;
2706 break;
2707 default:
2708 w->power_check = dapm_always_on_check_power;
2709 break;
2710 }
2711
2533 dapm->n_widgets++; 2712 dapm->n_widgets++;
2534 w->dapm = dapm; 2713 w->dapm = dapm;
2535 w->codec = dapm->codec; 2714 w->codec = dapm->codec;
@@ -2537,6 +2716,7 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2537 INIT_LIST_HEAD(&w->sources); 2716 INIT_LIST_HEAD(&w->sources);
2538 INIT_LIST_HEAD(&w->sinks); 2717 INIT_LIST_HEAD(&w->sinks);
2539 INIT_LIST_HEAD(&w->list); 2718 INIT_LIST_HEAD(&w->list);
2719 INIT_LIST_HEAD(&w->dirty);
2540 list_add(&w->list, &dapm->card->widgets); 2720 list_add(&w->list, &dapm->card->widgets);
2541 2721
2542 /* machine layer set ups unconnected pins and insertions */ 2722 /* machine layer set ups unconnected pins and insertions */
@@ -2584,9 +2764,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2584 { 2764 {
2585 if (!w->sname || w->dapm != dapm) 2765 if (!w->sname || w->dapm != dapm)
2586 continue; 2766 continue;
2587 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2767 dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2588 w->name, w->sname, stream, event); 2768 w->name, w->sname, stream, event);
2589 if (strstr(w->sname, stream)) { 2769 if (strstr(w->sname, stream)) {
2770 dapm_mark_dirty(w, "stream event");
2590 switch(event) { 2771 switch(event) {
2591 case SND_SOC_DAPM_STREAM_START: 2772 case SND_SOC_DAPM_STREAM_START:
2592 w->active = 1; 2773 w->active = 1;
@@ -2604,6 +2785,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2604 } 2785 }
2605 2786
2606 dapm_power_widgets(dapm, event); 2787 dapm_power_widgets(dapm, event);
2788
2789 /* do we need to notify any clients that DAPM stream is complete */
2790 if (dapm->stream_event)
2791 dapm->stream_event(dapm, event);
2607} 2792}
2608 2793
2609/** 2794/**
@@ -2672,6 +2857,7 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2672 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); 2857 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
2673 w->connected = 1; 2858 w->connected = 1;
2674 w->force = 1; 2859 w->force = 1;
2860 dapm_mark_dirty(w, "force enable");
2675 2861
2676 return 0; 2862 return 0;
2677} 2863}
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index a62f7dd4ba96..dd89933e2c72 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -13,26 +13,14 @@
13 13
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/regmap.h>
16#include <sound/soc.h> 17#include <sound/soc.h>
17 18
18#include <trace/events/asoc.h> 19#include <trace/events/asoc.h>
19 20
20#ifdef CONFIG_SPI_MASTER 21#ifdef CONFIG_REGMAP
21static int do_spi_write(void *control, const char *data, int len) 22static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
22{ 23 unsigned int value)
23 struct spi_device *spi = control;
24 int ret;
25
26 ret = spi_write(spi, data, len);
27 if (ret < 0)
28 return ret;
29
30 return len;
31}
32#endif
33
34static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
35 unsigned int value, const void *data, int len)
36{ 24{
37 int ret; 25 int ret;
38 26
@@ -49,13 +37,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
49 return 0; 37 return 0;
50 } 38 }
51 39
52 ret = codec->hw_write(codec->control_data, data, len); 40 return regmap_write(codec->control_data, reg, value);
53 if (ret == len)
54 return 0;
55 if (ret < 0)
56 return ret;
57 else
58 return -EIO;
59} 41}
60 42
61static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) 43static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
@@ -69,8 +51,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
69 if (codec->cache_only) 51 if (codec->cache_only)
70 return -1; 52 return -1;
71 53
72 BUG_ON(!codec->hw_read); 54 ret = regmap_read(codec->control_data, reg, &val);
73 return codec->hw_read(codec, reg); 55 if (ret == 0)
56 return val;
57 else
58 return -1;
74 } 59 }
75 60
76 ret = snd_soc_cache_read(codec, reg, &val); 61 ret = snd_soc_cache_read(codec, reg, &val);
@@ -79,202 +64,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
79 return val; 64 return val;
80} 65}
81 66
82static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u16 data;
86
87 data = cpu_to_be16((reg << 12) | (value & 0xffffff));
88
89 return do_hw_write(codec, reg, value, &data, 2);
90}
91
92static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 u16 data;
96
97 data = cpu_to_be16((reg << 9) | (value & 0x1ff));
98
99 return do_hw_write(codec, reg, value, &data, 2);
100}
101
102static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
103 unsigned int value)
104{
105 u8 data[2];
106
107 reg &= 0xff;
108 data[0] = reg;
109 data[1] = value & 0xff;
110
111 return do_hw_write(codec, reg, value, data, 2);
112}
113
114static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
115 unsigned int value)
116{
117 u8 data[3];
118 u16 val = cpu_to_be16(value);
119
120 data[0] = reg;
121 memcpy(&data[1], &val, sizeof(val));
122
123 return do_hw_write(codec, reg, value, data, 3);
124}
125
126#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
127static unsigned int do_i2c_read(struct snd_soc_codec *codec,
128 void *reg, int reglen,
129 void *data, int datalen)
130{
131 struct i2c_msg xfer[2];
132 int ret;
133 struct i2c_client *client = codec->control_data;
134
135 /* Write register */
136 xfer[0].addr = client->addr;
137 xfer[0].flags = 0;
138 xfer[0].len = reglen;
139 xfer[0].buf = reg;
140
141 /* Read data */
142 xfer[1].addr = client->addr;
143 xfer[1].flags = I2C_M_RD;
144 xfer[1].len = datalen;
145 xfer[1].buf = data;
146
147 ret = i2c_transfer(client->adapter, xfer, 2);
148 if (ret == 2)
149 return 0;
150 else if (ret < 0)
151 return ret;
152 else
153 return -EIO;
154}
155#endif
156
157#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
158static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
159 unsigned int r)
160{
161 u8 reg = r;
162 u8 data;
163 int ret;
164
165 ret = do_i2c_read(codec, &reg, 1, &data, 1);
166 if (ret < 0)
167 return 0;
168 return data;
169}
170#else
171#define snd_soc_8_8_read_i2c NULL
172#endif
173
174#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
175static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
176 unsigned int r)
177{
178 u8 reg = r;
179 u16 data;
180 int ret;
181
182 ret = do_i2c_read(codec, &reg, 1, &data, 2);
183 if (ret < 0)
184 return 0;
185 return (data >> 8) | ((data & 0xff) << 8);
186}
187#else
188#define snd_soc_8_16_read_i2c NULL
189#endif
190
191#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
192static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
193 unsigned int r)
194{
195 u16 reg = r;
196 u8 data;
197 int ret;
198
199 ret = do_i2c_read(codec, &reg, 2, &data, 1);
200 if (ret < 0)
201 return 0;
202 return data;
203}
204#else
205#define snd_soc_16_8_read_i2c NULL
206#endif
207
208#if defined(CONFIG_SPI_MASTER)
209static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
210 unsigned int r)
211{
212 struct spi_device *spi = codec->control_data;
213
214 const u16 reg = cpu_to_be16(r | 0x100);
215 u8 data;
216 int ret;
217
218 ret = spi_write_then_read(spi, &reg, 2, &data, 1);
219 if (ret < 0)
220 return 0;
221 return data;
222}
223#else
224#define snd_soc_16_8_read_spi NULL
225#endif
226
227static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
228 unsigned int value)
229{
230 u8 data[3];
231 u16 rval = cpu_to_be16(reg);
232
233 memcpy(data, &rval, sizeof(rval));
234 data[2] = value;
235
236 return do_hw_write(codec, reg, value, data, 3);
237}
238
239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
240static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
241 unsigned int r)
242{
243 u16 reg = cpu_to_be16(r);
244 u16 data;
245 int ret;
246
247 ret = do_i2c_read(codec, &reg, 2, &data, 2);
248 if (ret < 0)
249 return 0;
250 return be16_to_cpu(data);
251}
252#else
253#define snd_soc_16_16_read_i2c NULL
254#endif
255
256static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
257 unsigned int value)
258{
259 u16 data[2];
260
261 data[0] = cpu_to_be16(reg);
262 data[1] = cpu_to_be16(value);
263
264 return do_hw_write(codec, reg, value, data, sizeof(data));
265}
266
267/* Primitive bulk write support for soc-cache. The data pointed to by 67/* Primitive bulk write support for soc-cache. The data pointed to by
268 * `data' needs to already be in the form the hardware expects 68 * `data' needs to already be in the form the hardware expects. Any
269 * including any leading register specific data. Any data written 69 * data written through this function will not go through the cache as
270 * through this function will not go through the cache as it only 70 * it only handles writing to volatile or out of bounds registers.
271 * handles writing to volatile or out of bounds registers. 71 *
72 * This is currently only supported for devices using the regmap API
73 * wrappers.
272 */ 74 */
273static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, 75static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
76 unsigned int reg,
274 const void *data, size_t len) 77 const void *data, size_t len)
275{ 78{
276 int ret;
277
278 /* To ensure that we don't get out of sync with the cache, check 79 /* To ensure that we don't get out of sync with the cache, check
279 * whether the base register is volatile or if we've directly asked 80 * whether the base register is volatile or if we've directly asked
280 * to bypass the cache. Out of bounds registers are considered 81 * to bypass the cache. Out of bounds registers are considered
@@ -285,68 +86,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r
285 && reg < codec->driver->reg_cache_size) 86 && reg < codec->driver->reg_cache_size)
286 return -EINVAL; 87 return -EINVAL;
287 88
288 switch (codec->control_type) { 89 return regmap_raw_write(codec->control_data, reg, data, len);
289#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
290 case SND_SOC_I2C:
291 ret = i2c_master_send(to_i2c_client(codec->dev), data, len);
292 break;
293#endif
294#if defined(CONFIG_SPI_MASTER)
295 case SND_SOC_SPI:
296 ret = spi_write(to_spi_device(codec->dev), data, len);
297 break;
298#endif
299 default:
300 BUG();
301 }
302
303 if (ret == len)
304 return 0;
305 if (ret < 0)
306 return ret;
307 else
308 return -EIO;
309} 90}
310 91
311static struct {
312 int addr_bits;
313 int data_bits;
314 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
315 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
316 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
317 unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
318} io_types[] = {
319 {
320 .addr_bits = 4, .data_bits = 12,
321 .write = snd_soc_4_12_write,
322 },
323 {
324 .addr_bits = 7, .data_bits = 9,
325 .write = snd_soc_7_9_write,
326 },
327 {
328 .addr_bits = 8, .data_bits = 8,
329 .write = snd_soc_8_8_write,
330 .i2c_read = snd_soc_8_8_read_i2c,
331 },
332 {
333 .addr_bits = 8, .data_bits = 16,
334 .write = snd_soc_8_16_write,
335 .i2c_read = snd_soc_8_16_read_i2c,
336 },
337 {
338 .addr_bits = 16, .data_bits = 8,
339 .write = snd_soc_16_8_write,
340 .i2c_read = snd_soc_16_8_read_i2c,
341 .spi_read = snd_soc_16_8_read_spi,
342 },
343 {
344 .addr_bits = 16, .data_bits = 16,
345 .write = snd_soc_16_16_write,
346 .i2c_read = snd_soc_16_16_read_i2c,
347 },
348};
349
350/** 92/**
351 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 93 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
352 * 94 *
@@ -370,50 +112,51 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
370 int addr_bits, int data_bits, 112 int addr_bits, int data_bits,
371 enum snd_soc_control_type control) 113 enum snd_soc_control_type control)
372{ 114{
373 int i; 115 struct regmap_config config;
374
375 for (i = 0; i < ARRAY_SIZE(io_types); i++)
376 if (io_types[i].addr_bits == addr_bits &&
377 io_types[i].data_bits == data_bits)
378 break;
379 if (i == ARRAY_SIZE(io_types)) {
380 printk(KERN_ERR
381 "No I/O functions for %d bit address %d bit data\n",
382 addr_bits, data_bits);
383 return -EINVAL;
384 }
385 116
386 codec->write = io_types[i].write; 117 memset(&config, 0, sizeof(config));
118 codec->write = hw_write;
387 codec->read = hw_read; 119 codec->read = hw_read;
388 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; 120 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
389 121
122 config.reg_bits = addr_bits;
123 config.val_bits = data_bits;
124
390 switch (control) { 125 switch (control) {
126#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
391 case SND_SOC_I2C: 127 case SND_SOC_I2C:
392#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 128 codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
393 codec->hw_write = (hw_write_t)i2c_master_send; 129 &config);
394#endif
395 if (io_types[i].i2c_read)
396 codec->hw_read = io_types[i].i2c_read;
397
398 codec->control_data = container_of(codec->dev,
399 struct i2c_client,
400 dev);
401 break; 130 break;
131#endif
402 132
133#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
403 case SND_SOC_SPI: 134 case SND_SOC_SPI:
404#ifdef CONFIG_SPI_MASTER 135 codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
405 codec->hw_write = do_spi_write; 136 &config);
137 break;
406#endif 138#endif
407 if (io_types[i].spi_read)
408 codec->hw_read = io_types[i].spi_read;
409 139
410 codec->control_data = container_of(codec->dev, 140 case SND_SOC_REGMAP:
411 struct spi_device, 141 /* Device has made its own regmap arrangements */
412 dev);
413 break; 142 break;
143
144 default:
145 return -EINVAL;
414 } 146 }
415 147
148 if (IS_ERR(codec->control_data))
149 return PTR_ERR(codec->control_data);
150
416 return 0; 151 return 0;
417} 152}
418EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 153EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
419 154#else
155int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
156 int addr_bits, int data_bits,
157 enum snd_soc_control_type control)
158{
159 return -ENOTSUPP;
160}
161EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
162#endif
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fa31d9c2abd8..52db96636290 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -188,6 +188,8 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
188 list_add(&(pins[i].list), &jack->pins); 188 list_add(&(pins[i].list), &jack->pins);
189 } 189 }
190 190
191 snd_soc_dapm_new_widgets(&jack->codec->card->dapm);
192
191 /* Update to reflect the last reported status; canned jack 193 /* Update to reflect the last reported status; canned jack
192 * implementations are likely to set their state before the 194 * implementations are likely to set their state before the
193 * card has an opportunity to associate pins. 195 * card has an opportunity to associate pins.
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 2879c883eebc..ee15337353fa 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -27,17 +27,13 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29 29
30static DEFINE_MUTEX(pcm_mutex); 30static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
31 31 struct snd_soc_dai *soc_dai)
32static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
33{ 32{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 int ret; 34 int ret;
38 35
39 if (!codec_dai->driver->symmetric_rates && 36 if (!soc_dai->driver->symmetric_rates &&
40 !cpu_dai->driver->symmetric_rates &&
41 !rtd->dai_link->symmetric_rates) 37 !rtd->dai_link->symmetric_rates)
42 return 0; 38 return 0;
43 39
@@ -45,19 +41,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
45 * the second can need to get its constraints before the first has 41 * the second can need to get its constraints before the first has
46 * picked a rate. Complain and allow the application to carry on. 42 * picked a rate. Complain and allow the application to carry on.
47 */ 43 */
48 if (!rtd->rate) { 44 if (!soc_dai->rate) {
49 dev_warn(&rtd->dev, 45 dev_warn(soc_dai->dev,
50 "Not enforcing symmetric_rates due to race\n"); 46 "Not enforcing symmetric_rates due to race\n");
51 return 0; 47 return 0;
52 } 48 }
53 49
54 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate); 50 dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
55 51
56 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 52 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
57 SNDRV_PCM_HW_PARAM_RATE, 53 SNDRV_PCM_HW_PARAM_RATE,
58 rtd->rate, rtd->rate); 54 soc_dai->rate, soc_dai->rate);
59 if (ret < 0) { 55 if (ret < 0) {
60 dev_err(&rtd->dev, 56 dev_err(soc_dai->dev,
61 "Unable to apply rate symmetry constraint: %d\n", ret); 57 "Unable to apply rate symmetry constraint: %d\n", ret);
62 return ret; 58 return ret;
63 } 59 }
@@ -187,8 +183,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
187 } 183 }
188 184
189 /* Symmetry only applies if we've already got an active stream. */ 185 /* Symmetry only applies if we've already got an active stream. */
190 if (cpu_dai->active || codec_dai->active) { 186 if (cpu_dai->active) {
191 ret = soc_pcm_apply_symmetry(substream); 187 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
188 if (ret != 0)
189 goto config_err;
190 }
191
192 if (codec_dai->active) {
193 ret = soc_pcm_apply_symmetry(substream, codec_dai);
192 if (ret != 0) 194 if (ret != 0)
193 goto config_err; 195 goto config_err;
194 } 196 }
@@ -290,8 +292,12 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
290 codec_dai->active--; 292 codec_dai->active--;
291 codec->active--; 293 codec->active--;
292 294
293 if (!cpu_dai->active && !codec_dai->active) 295 /* clear the corresponding DAIs rate when inactive */
294 rtd->rate = 0; 296 if (!cpu_dai->active)
297 cpu_dai->rate = 0;
298
299 if (!codec_dai->active)
300 codec_dai->rate = 0;
295 301
296 /* Muting the DAC suppresses artifacts caused during digital 302 /* Muting the DAC suppresses artifacts caused during digital
297 * shutdown, for example from stopping clocks. 303 * shutdown, for example from stopping clocks.
@@ -313,10 +319,17 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
313 cpu_dai->runtime = NULL; 319 cpu_dai->runtime = NULL;
314 320
315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
316 /* start delayed pop wq here for playback streams */ 322 if (unlikely(codec->ignore_pmdown_time)) {
317 codec_dai->pop_wait = 1; 323 /* powered down playback stream now */
318 schedule_delayed_work(&rtd->delayed_work, 324 snd_soc_dapm_stream_event(rtd,
319 msecs_to_jiffies(rtd->pmdown_time)); 325 codec_dai->driver->playback.stream_name,
326 SND_SOC_DAPM_STREAM_STOP);
327 } else {
328 /* start delayed pop wq here for playback streams */
329 codec_dai->pop_wait = 1;
330 schedule_delayed_work(&rtd->delayed_work,
331 msecs_to_jiffies(rtd->pmdown_time));
332 }
320 } else { 333 } else {
321 /* capture streams can be powered down now */ 334 /* capture streams can be powered down now */
322 snd_soc_dapm_stream_event(rtd, 335 snd_soc_dapm_stream_event(rtd,
@@ -449,7 +462,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
449 } 462 }
450 } 463 }
451 464
452 rtd->rate = params_rate(params); 465 /* store the rate for each DAIs */
466 cpu_dai->rate = params_rate(params);
467 codec_dai->rate = params_rate(params);
453 468
454out: 469out:
455 mutex_unlock(&rtd->pcm_mutex); 470 mutex_unlock(&rtd->pcm_mutex);
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
index 9f24ef73f2cb..3b55a44146af 100644
--- a/sound/soc/tegra/tegra_das.c
+++ b/sound/soc/tegra/tegra_das.c
@@ -212,7 +212,7 @@ err_release:
212 release_mem_region(res->start, resource_size(res)); 212 release_mem_region(res->start, resource_size(res));
213err_free: 213err_free:
214 kfree(das); 214 kfree(das);
215 das = 0; 215 das = NULL;
216exit: 216exit:
217 return ret; 217 return ret;
218} 218}
@@ -234,7 +234,7 @@ static int __devexit tegra_das_remove(struct platform_device *pdev)
234 release_mem_region(res->start, resource_size(res)); 234 release_mem_region(res->start, resource_size(res));
235 235
236 kfree(das); 236 kfree(das);
237 das = 0; 237 das = NULL;
238 238
239 return 0; 239 return 0;
240} 240}
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index f36b9969cfec..6728fab8c411 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -312,7 +312,7 @@ static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
312 .trigger = tegra_i2s_trigger, 312 .trigger = tegra_i2s_trigger,
313}; 313};
314 314
315struct snd_soc_dai_driver tegra_i2s_dai[] = { 315static struct snd_soc_dai_driver tegra_i2s_dai[] = {
316 { 316 {
317 .name = DRV_NAME ".0", 317 .name = DRV_NAME ".0",
318 .probe = tegra_i2s_probe, 318 .probe = tegra_i2s_probe,
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c7cfd96e991e..436def1dfa39 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -367,7 +367,7 @@ static void tegra_pcm_free(struct snd_pcm *pcm)
367 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); 367 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
368} 368}
369 369
370struct snd_soc_platform_driver tegra_pcm_platform = { 370static struct snd_soc_platform_driver tegra_pcm_platform = {
371 .ops = &tegra_pcm_ops, 371 .ops = &tegra_pcm_ops,
372 .pcm_new = tegra_pcm_new, 372 .pcm_new = tegra_pcm_new,
373 .pcm_free = tegra_pcm_free, 373 .pcm_free = tegra_pcm_free,
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
index abe606b0a29e..dd11d0c63474 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -127,7 +127,7 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
127{ 127{
128 struct device *dev = substream->pcm->card->dev; 128 struct device *dev = substream->pcm->card->dev;
129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
130 int ret, srate, spdifclock; 130 int ret, spdifclock;
131 131
132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; 132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK;
133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; 133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK;
@@ -140,7 +140,6 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
140 return -EINVAL; 140 return -EINVAL;
141 } 141 }
142 142
143 srate = params_rate(params);
144 switch (params_rate(params)) { 143 switch (params_rate(params)) {
145 case 32000: 144 case 32000:
146 spdifclock = 4096000; 145 spdifclock = 4096000;
@@ -232,7 +231,7 @@ static struct snd_soc_dai_ops tegra_spdif_dai_ops = {
232 .trigger = tegra_spdif_trigger, 231 .trigger = tegra_spdif_trigger,
233}; 232};
234 233
235struct snd_soc_dai_driver tegra_spdif_dai = { 234static struct snd_soc_dai_driver tegra_spdif_dai = {
236 .name = DRV_NAME, 235 .name = DRV_NAME,
237 .probe = tegra_spdif_probe, 236 .probe = tegra_spdif_probe,
238 .playback = { 237 .playback = {
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index be27f1d229af..a81cf39257bf 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -339,8 +339,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
339 snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); 339 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
340 } 340 }
341 341
342 snd_soc_dapm_sync(dapm);
343
344 return 0; 342 return 0;
345} 343}
346 344
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 8fc07e9adf2e..b3a7efa6d960 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -124,8 +124,6 @@ static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
124 snd_soc_dapm_nc_pin(dapm, "RHPOUT"); 124 snd_soc_dapm_nc_pin(dapm, "RHPOUT");
125 snd_soc_dapm_nc_pin(dapm, "MICIN"); 125 snd_soc_dapm_nc_pin(dapm, "MICIN");
126 126
127 snd_soc_dapm_sync(dapm);
128
129 return 0; 127 return 0;
130} 128}
131 129
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 743d07b82c06..a4e3f5501847 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -201,7 +201,7 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
201 if (!drvdata->base) 201 if (!drvdata->base)
202 return -EBUSY; 202 return -EBUSY;
203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, 203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,
204 IRQF_DISABLED, dev_name(&pdev->dev), drvdata); 204 0, dev_name(&pdev->dev), drvdata);
205 if (err < 0) 205 if (err < 0)
206 return err; 206 return err;
207 207
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 6770e7166be4..9b5e283af51c 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -62,7 +62,7 @@ static int __exit txx9aclc_generic_remove(struct platform_device *pdev)
62} 62}
63 63
64static struct platform_driver txx9aclc_generic_driver = { 64static struct platform_driver txx9aclc_generic_driver = {
65 .remove = txx9aclc_generic_remove, 65 .remove = __exit_p(txx9aclc_generic_remove),
66 .driver = { 66 .driver = {
67 .name = "txx9aclc-generic", 67 .name = "txx9aclc-generic",
68 .owner = THIS_MODULE, 68 .owner = THIS_MODULE,