summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2010-12-15 11:58:03 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2010-12-15 11:58:03 +1100
commit9c130023368e0deb4ab21c40fe92243396d505f7 (patch)
tree9ea4d60cf42b0bea7f5d693c0030ca6cfaf4bdae
parent0181acbb072631bea62cc896ff64385be56e6da8 (diff)
parent77358d4035f1382fe47bccc5ed59a64c853f765b (diff)
Merge remote branch 'sound/for-next'
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt12
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt1
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c2
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c15
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c2
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c2
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c2
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c5
-rw-r--r--arch/arm/plat-s3c24xx/devs.c19
-rw-r--r--arch/arm/plat-samsung/Makefile1
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c25
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h2
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c5
-rw-r--r--drivers/gpio/wm8994-gpio.c24
-rw-r--r--drivers/mfd/wm8994-core.c93
-rw-r--r--drivers/regulator/wm8994-regulator.c23
-rw-r--r--include/linux/mfd/wm8994/core.h8
-rw-r--r--include/linux/mfd/wm8994/pdata.h17
-rw-r--r--include/linux/mfd/wm8994/registers.h302
-rw-r--r--include/sound/alc5623.h15
-rw-r--r--include/sound/asound.h3
-rw-r--r--include/sound/hdsp.h1
-rw-r--r--include/sound/minors.h4
-rw-r--r--include/sound/pcm.h1
-rw-r--r--include/sound/soc-dai.h4
-rw-r--r--include/sound/soc-dapm.h60
-rw-r--r--include/sound/soc.h112
-rw-r--r--include/trace/events/asoc.h235
-rw-r--r--sound/ac97_bus.c4
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/aoa/core/gpio-feature.c7
-rw-r--r--sound/aoa/core/gpio-pmf.c7
-rw-r--r--sound/core/pcm_lib.c22
-rw-r--r--sound/core/pcm_native.c3
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c18
-rw-r--r--sound/core/timer.c7
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/i2c/other/ak4113.c5
-rw-r--r--sound/i2c/other/ak4114.c5
-rw-r--r--sound/pci/Kconfig19
-rw-r--r--sound/pci/ac97/ac97_codec.c6
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_conexant.c32
-rw-r--r--sound/pci/hda/patch_hdmi.c43
-rw-r--r--sound/pci/hda/patch_realtek.c132
-rw-r--r--sound/pci/hda/patch_sigmatel.c3
-rw-r--r--sound/pci/hda/patch_via.c3
-rw-r--r--sound/pci/ice1712/delta.c49
-rw-r--r--sound/pci/ice1712/delta.h11
-rw-r--r--sound/pci/oxygen/Makefile2
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c133
-rw-r--r--sound/pci/oxygen/oxygen.h4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c24
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c55
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c14
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c70
-rw-r--r--sound/pci/oxygen/xonar_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c234
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c73
-rw-r--r--sound/pci/rme9652/hdsp.c538
-rw-r--r--sound/soc/Kconfig4
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c12
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c18
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c14
-rw-r--r--sound/soc/au1x/db1200.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c1
-rw-r--r--sound/soc/codecs/88pm860x-codec.c22
-rw-r--r--sound/soc/codecs/Kconfig13
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ad1836.c7
-rw-r--r--sound/soc/codecs/ad193x.c7
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ak4535.c20
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c10
-rw-r--r--sound/soc/codecs/alc5623.c1117
-rw-r--r--sound/soc/codecs/alc5623.h161
-rw-r--r--sound/soc/codecs/cq93vc.c4
-rw-r--r--sound/soc/codecs/cs42l51.c6
-rw-r--r--sound/soc/codecs/cx20442.c15
-rw-r--r--sound/soc/codecs/da7210.c2
-rw-r--r--sound/soc/codecs/jz4740.c11
-rw-r--r--sound/soc/codecs/max98088.c13
-rw-r--r--sound/soc/codecs/ssm2602.c10
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tlv320aic23.c10
-rw-r--r--sound/soc/codecs/tlv320aic26.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c56
-rw-r--r--sound/soc/codecs/tlv320dac33.c16
-rw-r--r--sound/soc/codecs/tpa6130a2.c12
-rw-r--r--sound/soc/codecs/twl4030.c51
-rw-r--r--sound/soc/codecs/twl6040.c13
-rw-r--r--sound/soc/codecs/uda134x.c3
-rw-r--r--sound/soc/codecs/uda1380.c14
-rw-r--r--sound/soc/codecs/wl1273.c3
-rw-r--r--sound/soc/codecs/wm2000.c6
-rw-r--r--sound/soc/codecs/wm8350.c34
-rw-r--r--sound/soc/codecs/wm8400.c12
-rw-r--r--sound/soc/codecs/wm8510.c12
-rw-r--r--sound/soc/codecs/wm8523.c12
-rw-r--r--sound/soc/codecs/wm8580.c24
-rw-r--r--sound/soc/codecs/wm8711.c10
-rw-r--r--sound/soc/codecs/wm8728.c12
-rw-r--r--sound/soc/codecs/wm8731.c101
-rw-r--r--sound/soc/codecs/wm8737.c754
-rw-r--r--sound/soc/codecs/wm8737.h322
-rw-r--r--sound/soc/codecs/wm8741.c10
-rw-r--r--sound/soc/codecs/wm8750.c12
-rw-r--r--sound/soc/codecs/wm8753.c49
-rw-r--r--sound/soc/codecs/wm8770.c749
-rw-r--r--sound/soc/codecs/wm8770.h51
-rw-r--r--sound/soc/codecs/wm8776.c10
-rw-r--r--sound/soc/codecs/wm8804.c7
-rw-r--r--sound/soc/codecs/wm8900.c12
-rw-r--r--sound/soc/codecs/wm8903.c194
-rw-r--r--sound/soc/codecs/wm8904.c39
-rw-r--r--sound/soc/codecs/wm8940.c7
-rw-r--r--sound/soc/codecs/wm8955.c15
-rw-r--r--sound/soc/codecs/wm8960.c29
-rw-r--r--sound/soc/codecs/wm8961.c12
-rw-r--r--sound/soc/codecs/wm8962.c36
-rw-r--r--sound/soc/codecs/wm8971.c30
-rw-r--r--sound/soc/codecs/wm8974.c12
-rw-r--r--sound/soc/codecs/wm8978.c12
-rw-r--r--sound/soc/codecs/wm8985.c12
-rw-r--r--sound/soc/codecs/wm8988.c10
-rw-r--r--sound/soc/codecs/wm8990.c12
-rw-r--r--sound/soc/codecs/wm8993.c20
-rw-r--r--sound/soc/codecs/wm8994-tables.c3147
-rw-r--r--sound/soc/codecs/wm8994.c2529
-rw-r--r--sound/soc/codecs/wm8994.h14
-rw-r--r--sound/soc/codecs/wm9081.c14
-rw-r--r--sound/soc/codecs/wm9090.c18
-rw-r--r--sound/soc/codecs/wm9705.c7
-rw-r--r--sound/soc/codecs/wm9712.c10
-rw-r--r--sound/soc/codecs/wm9713.c9
-rw-r--r--sound/soc/codecs/wm_hubs.c108
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c22
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c4
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/ep93xx/snappercl15.c6
-rw-r--r--sound/soc/imx/eukrea-tlv320.c1
-rw-r--r--sound/soc/imx/imx-ssi.c4
-rw-r--r--sound/soc/imx/phycore-ac97.c1
-rw-r--r--sound/soc/imx/wm1133-ev1.c8
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c1
-rw-r--r--sound/soc/jz4740/qi_lb60.c14
-rw-r--r--sound/soc/kirkwood/Kconfig11
-rw-r--r--sound/soc/kirkwood/Makefile2
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c141
-rw-r--r--sound/soc/nuc900/nuc900-audio.c1
-rw-r--r--sound/soc/omap/am3517evm.c14
-rw-r--r--sound/soc/omap/ams-delta.c82
-rw-r--r--sound/soc/omap/igep0020.c1
-rw-r--r--sound/soc/omap/n810.c43
-rw-r--r--sound/soc/omap/omap2evm.c1
-rw-r--r--sound/soc/omap/omap3beagle.c1
-rw-r--r--sound/soc/omap/omap3evm.c1
-rw-r--r--sound/soc/omap/omap3pandora.c45
-rw-r--r--sound/soc/omap/osk5912.c14
-rw-r--r--sound/soc/omap/overo.c1
-rw-r--r--sound/soc/omap/rx51.c26
-rw-r--r--sound/soc/omap/sdp3430.c44
-rw-r--r--sound/soc/omap/sdp4430.c20
-rw-r--r--sound/soc/omap/zoom2.c36
-rw-r--r--sound/soc/pxa/corgi.c52
-rw-r--r--sound/soc/pxa/e740_wm9705.c30
-rw-r--r--sound/soc/pxa/e750_wm9705.c30
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c1
-rw-r--r--sound/soc/pxa/magician.c36
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c18
-rw-r--r--sound/soc/pxa/palm27x.c34
-rw-r--r--sound/soc/pxa/poodle.c26
-rw-r--r--sound/soc/pxa/raumfeld.c1
-rw-r--r--sound/soc/pxa/saarb.c18
-rw-r--r--sound/soc/pxa/spitz.c70
-rw-r--r--sound/soc/pxa/tavorevb3.c18
-rw-r--r--sound/soc/pxa/tosa.c38
-rw-r--r--sound/soc/pxa/z2.c16
-rw-r--r--sound/soc/pxa/zylonite.c12
-rw-r--r--sound/soc/s3c24xx/Kconfig171
-rw-r--r--sound/soc/s3c24xx/Makefile55
-rw-r--r--sound/soc/s3c24xx/aquila_wm8994.c295
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c230
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c242
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h41
-rw-r--r--sound/soc/s6000/s6105-ipcam.c41
-rw-r--r--sound/soc/samsung/Kconfig163
-rw-r--r--sound/soc/samsung/Makefile53
-rw-r--r--sound/soc/samsung/ac97.c (renamed from sound/soc/s3c24xx/s3c-ac97.c)22
-rw-r--r--sound/soc/samsung/ac97.h (renamed from sound/soc/s3c24xx/s3c-ac97.h)8
-rw-r--r--sound/soc/samsung/dma.c (renamed from sound/soc/s3c24xx/s3c-dma.c)134
-rw-r--r--sound/soc/samsung/dma.h (renamed from sound/soc/s3c24xx/s3c-dma.h)2
-rw-r--r--sound/soc/samsung/goni_wm8994.c (renamed from sound/soc/s3c24xx/goni_wm8994.c)64
-rw-r--r--sound/soc/samsung/h1940_uda1380.c296
-rw-r--r--sound/soc/samsung/i2s.c1256
-rw-r--r--sound/soc/samsung/i2s.h29
-rw-r--r--sound/soc/samsung/jive_wm8750.c (renamed from sound/soc/s3c24xx/jive_wm8750.c)26
-rw-r--r--sound/soc/samsung/lm4857.h (renamed from sound/soc/s3c24xx/lm4857.h)0
-rw-r--r--sound/soc/samsung/ln2440sbc_alc650.c (renamed from sound/soc/s3c24xx/ln2440sbc_alc650.c)9
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_gta02_wm8753.c)72
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_wm8753.c)130
-rw-r--r--sound/soc/samsung/pcm.c (renamed from sound/soc/s3c24xx/s3c-pcm.c)6
-rw-r--r--sound/soc/samsung/pcm.h (renamed from sound/soc/s3c24xx/s3c-pcm.h)2
-rw-r--r--sound/soc/samsung/regs-i2s-v2.h (renamed from sound/soc/s3c24xx/regs-i2s-v2.h)0
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c (renamed from sound/soc/s3c24xx/rx1950_uda1380.c)16
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c (renamed from sound/soc/s3c24xx/s3c-i2s-v2.c)4
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h (renamed from sound/soc/s3c24xx/s3c-i2s-v2.h)2
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c (renamed from sound/soc/s3c24xx/s3c2412-i2s.c)4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.h (renamed from sound/soc/s3c24xx/s3c2412-i2s.h)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c (renamed from sound/soc/s3c24xx/s3c24xx-i2s.c)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.h (renamed from sound/soc/s3c24xx/s3c24xx-i2s.h)0
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec.c)5
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.h (renamed from sound/soc/s3c24xx/s3c24xx_simtec.h)2
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_hermes.c)22
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c)22
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c (renamed from sound/soc/s3c24xx/s3c24xx_uda134x.c)5
-rw-r--r--sound/soc/samsung/smartq_wm8987.c (renamed from sound/soc/s3c24xx/smartq_wm8987.c)64
-rw-r--r--sound/soc/samsung/smdk2443_wm9710.c (renamed from sound/soc/s3c24xx/smdk2443_wm9710.c)9
-rw-r--r--sound/soc/samsung/smdk_spdif.c (renamed from sound/soc/s3c24xx/smdk_spdif.c)21
-rw-r--r--sound/soc/samsung/smdk_wm8580.c (renamed from sound/soc/s3c24xx/smdk64xx_wm8580.c)173
-rw-r--r--sound/soc/samsung/smdk_wm9713.c (renamed from sound/soc/s3c24xx/smdk_wm9713.c)25
-rw-r--r--sound/soc/samsung/spdif.c (renamed from sound/soc/s3c24xx/spdif.c)4
-rw-r--r--sound/soc/samsung/spdif.h (renamed from sound/soc/s3c24xx/spdif.h)2
-rw-r--r--sound/soc/sh/fsi-ak4642.c140
-rw-r--r--sound/soc/sh/fsi.c207
-rw-r--r--sound/soc/sh/migor.c6
-rw-r--r--sound/soc/sh/sh7760-ac97.c3
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_dai.c2
-rw-r--r--sound/soc/sh/siu_pcm.c2
-rw-r--r--sound/soc/soc-cache.c1058
-rw-r--r--sound/soc/soc-core.c561
-rw-r--r--sound/soc/soc-dapm.c593
-rw-r--r--sound/soc/soc-jack.c31
250 files changed, 14828 insertions, 5422 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index d0eb696d32e8..7124340038ea 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -974,13 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
See hdspm.txt for details.
- Module snd-hifier
- -----------------
-
- Module for the MediaTek/TempoTec HiFier Fantasia sound card.
-
- This module supports autoprobe and multiple cards.
-
Module snd-ice1712
------------------
@@ -1531,15 +1524,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-oxygen
-----------------
- Module for sound cards based on the C-Media CMI8788 chip:
+ Module for sound cards based on the C-Media CMI8787/8788 chip:
* Asound A-8788
* AuzenTech X-Meridian
* Bgears b-Enspirer
* Club3D Theatron DTS
* HT-Omega Claro (plus)
* HT-Omega Claro halo (XT)
+ * Kuroutoshikou CMI8787-HG2PCI
* Razer Barracuda AC-1
* Sondigo Inferno
+ * TempoTec HiFier Fantasia
+ * TempoTec HiFier Serenade
This module supports autoprobe and multiple cards.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 37c6aad5e590..16ae4300c747 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -149,7 +149,6 @@ ALC882/883/885/888/889
acer-aspire-7730g Acer Aspire 7730G
acer-aspire-8930g Acer Aspire 8930G
medion Medion Laptops
- medion-md2 Medion MD2
targa-dig Targa/MSI
targa-2ch-dig Targa/MSI with 2-channel
targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
diff --git a/MAINTAINERS b/MAINTAINERS
index 70a626a5003e..e35b593a9fa0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5142,7 +5142,7 @@ SAMSUNG AUDIO (ASoC) DRIVERS
M: Jassi Brar <jassi.brar@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
-F: sound/soc/s3c24xx
+F: sound/soc/samsung
TLG2300 VIDEO4LINUX-2 DRIVER
M: Huang Shijie <shijie8@gmail.com>
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index c9d77fad10ab..cfcca4174e25 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -171,7 +171,7 @@ static void __init openrd_init(void)
kirkwood_i2c_init();
- if (machine_is_openrd_client()) {
+ if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
i2c_register_board_info(0, i2c_board_info,
ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init();
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index d7ada8c7e41f..1a81fe12ccd7 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -387,7 +387,7 @@ static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c_device_usbgadget,
&h1940_device_leds,
&h1940_device_bluetooth,
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index e0622bbb6dfa..eab6ae50683c 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -692,7 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c_device_usbgadget,
&s3c_device_rtc,
&s3c_device_nand,
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 7618627b98f5..cad67022fa25 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -296,7 +296,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata;
static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s3c64xx_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
.resource = s3c64xx_ac97_resource,
@@ -315,16 +315,3 @@ void __init s3c64xx_ac97_setup_gpio(int num)
else
s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
}
-
-static u64 s3c_device_audio_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_pcm = {
- .name = "s3c24xx-pcm-audio",
- .id = -1,
- .dev = {
- .dma_mask = &s3c_device_audio_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-EXPORT_SYMBOL(s3c_device_pcm);
-
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 77488facfe4c..e85192a86fbe 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -283,7 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_ohci,
&s3c_device_usb_hsotg,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c64xx_device_iisv4,
&samsung_device_keypad,
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index 10ab275ebd63..ab2d27172cbc 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -281,7 +281,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = {
static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pc100_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s5pc100_ac97_resource),
.resource = s5pc100_ac97_resource,
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 18b405d514d6..dd192a27524d 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -96,6 +96,7 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
/* I2C0 */
static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("wm8580", 0x1b),},
};
/* I2C1 */
@@ -190,6 +191,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s3c_device_ts,
&s3c_device_wdt,
&smdkc100_lcd_powerdev,
+ &samsung_asoc_dma,
&s5pc100_device_iis0,
&samsung_device_keypad,
&s5pc100_device_ac97,
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index ddd2704b3467..8d58f1926241 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -311,7 +311,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = {
static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv210_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s5pv210_ac97_resource),
.resource = s5pv210_ac97_resource,
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 677f81c16352..e521c669ca9b 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -740,6 +740,10 @@ static struct platform_device fsi_device = {
},
};
+static struct platform_device fsi_ak4643_device = {
+ .name = "sh_fsi2_a_ak4643",
+};
+
static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
@@ -938,6 +942,7 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&sdhi1_device,
&usb1_host_device,
&fsi_device,
+ &fsi_ak4643_device,
&sh_mmcif_device,
&lcdc1_device,
&lcdc_device,
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 2f91057a0c02..8a42bc48dbf0 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -259,21 +259,6 @@ struct platform_device s3c_device_iis = {
EXPORT_SYMBOL(s3c_device_iis);
-/* ASoC PCM DMA */
-
-static u64 s3c_device_audio_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_pcm = {
- .name = "s3c24xx-pcm-audio",
- .id = -1,
- .dev = {
- .dma_mask = &s3c_device_audio_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-
-EXPORT_SYMBOL(s3c_device_pcm);
-
/* RTC */
static struct resource s3c_rtc_resource[] = {
@@ -496,8 +481,10 @@ static struct resource s3c_ac97_resource[] = {
},
};
+static u64 s3c_device_audio_dmamask = 0xffffffffUL;
+
struct platform_device s3c_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_ac97_resource),
.resource = s3c_ac97_resource,
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index afcce474af8e..19d8a16c3066 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -17,6 +17,7 @@ obj-y += clock.o
obj-y += pwm-clock.o
obj-y += gpio.o
obj-y += gpio-config.o
+obj-y += dev-asocdma.o
obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o
obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
new file mode 100644
index 000000000000..a068c4f42d56
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-samsung/dev-asocdma.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <plat/devs.h>
+
+static u64 audio_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_dma = {
+ .name = "samsung-audio",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_dma);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index dec0ded6a5ee..e9e3b6e3ec74 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -32,7 +32,7 @@ extern struct platform_device s3c64xx_device_iisv4;
extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
-extern struct platform_device s3c_device_pcm;
+extern struct platform_device samsung_asoc_dma;
extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 527a0cd956b5..b710757c33c3 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -318,6 +318,10 @@ static struct platform_device fsi_device = {
},
};
+static struct platform_device fsi_ak4642_device = {
+ .name = "sh_fsi_a_ak4642",
+};
+
/* KEYSC in SoC (Needs SW33-2 set to ON) */
static struct sh_keysc_info keysc_info = {
.mode = SH_KEYSC_MODE_1,
@@ -590,6 +594,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
&sh7724_usb0_host_device,
&sh7724_usb1_gadget_device,
&fsi_device,
+ &fsi_ak4642_device,
&sdhi0_cn7_device,
&sdhi1_cn8_device,
&irda_device,
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
index 618398e4ed8e..c822baacd8fc 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -35,6 +35,29 @@ static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip)
return container_of(chip, struct wm8994_gpio, gpio_chip);
}
+static int wm8994_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ switch (wm8994->type) {
+ case WM8958:
+ switch (offset) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ return -EINVAL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
@@ -136,6 +159,7 @@ static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
static struct gpio_chip template_chip = {
.label = "wm8994",
.owner = THIS_MODULE,
+ .request = wm8994_gpio_request,
.direction_input = wm8994_gpio_direction_in,
.get = wm8994_gpio_get,
.direction_output = wm8994_gpio_direction_out,
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index b3b2aaf89dbe..8d221ba5e38d 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -218,6 +218,18 @@ static const char *wm8994_main_supplies[] = {
"SPKVDD2",
};
+static const char *wm8958_main_supplies[] = {
+ "DBVDD1",
+ "DBVDD2",
+ "DBVDD3",
+ "DCVDD",
+ "AVDD1",
+ "AVDD2",
+ "CPVDD",
+ "SPKVDD1",
+ "SPKVDD2",
+};
+
#ifdef CONFIG_PM
static int wm8994_device_suspend(struct device *dev)
{
@@ -239,7 +251,7 @@ static int wm8994_device_suspend(struct device *dev)
if (ret < 0)
dev_err(dev, "Failed to save LDO registers: %d\n", ret);
- ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ ret = regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(dev, "Failed to disable supplies: %d\n", ret);
@@ -254,7 +266,7 @@ static int wm8994_device_resume(struct device *dev)
struct wm8994 *wm8994 = dev_get_drvdata(dev);
int ret;
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+ ret = regulator_bulk_enable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(dev, "Failed to enable supplies: %d\n", ret);
@@ -305,9 +317,10 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
/*
* Instantiate the generic non-control parts of the device.
*/
-static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
+static int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ const char *devname;
int ret, i;
mutex_init(&wm8994->io_lock);
@@ -323,25 +336,48 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
goto err;
}
+ switch (wm8994->type) {
+ case WM8994:
+ wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
+ break;
+ case WM8958:
+ wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
- ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->num_supplies,
GFP_KERNEL);
if (!wm8994->supplies) {
ret = -ENOMEM;
goto err;
}
- for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
- wm8994->supplies[i].supply = wm8994_main_supplies[i];
-
- ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies),
+ switch (wm8994->type) {
+ case WM8994:
+ for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
+ wm8994->supplies[i].supply = wm8994_main_supplies[i];
+ break;
+ case WM8958:
+ for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)
+ wm8994->supplies[i].supply = wm8958_main_supplies[i];
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
goto err_supplies;
}
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+ ret = regulator_bulk_enable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
@@ -353,7 +389,22 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
dev_err(wm8994->dev, "Failed to read ID register\n");
goto err_enable;
}
- if (ret != 0x8994) {
+ switch (ret) {
+ case 0x8994:
+ devname = "WM8994";
+ if (wm8994->type != WM8994)
+ dev_warn(wm8994->dev, "Device registered as type %d\n",
+ wm8994->type);
+ wm8994->type = WM8994;
+ break;
+ case 0x8958:
+ devname = "WM8958";
+ if (wm8994->type != WM8958)
+ dev_warn(wm8994->dev, "Device registered as type %d\n",
+ wm8994->type);
+ wm8994->type = WM8958;
+ break;
+ default:
dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
ret);
ret = -EINVAL;
@@ -370,14 +421,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
switch (ret) {
case 0:
case 1:
- dev_warn(wm8994->dev, "revision %c not fully supported\n",
- 'A' + ret);
+ if (wm8994->type == WM8994)
+ dev_warn(wm8994->dev,
+ "revision %c not fully supported\n",
+ 'A' + ret);
break;
default:
- dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
break;
}
+ dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret);
if (pdata) {
wm8994->irq_base = pdata->irq_base;
@@ -423,10 +476,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
err_irq:
wm8994_irq_exit(wm8994);
err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+ regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
err_supplies:
kfree(wm8994->supplies);
err:
@@ -439,9 +492,9 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
{
mfd_remove_devices(wm8994->dev);
wm8994_irq_exit(wm8994);
- regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+ regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
kfree(wm8994->supplies);
kfree(wm8994);
}
@@ -506,8 +559,9 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
wm8994->read_dev = wm8994_i2c_read_device;
wm8994->write_dev = wm8994_i2c_write_device;
wm8994->irq = i2c->irq;
+ wm8994->type = id->driver_data;
- return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
+ return wm8994_device_init(wm8994, i2c->irq);
}
static int wm8994_i2c_remove(struct i2c_client *i2c)
@@ -535,7 +589,8 @@ static int wm8994_i2c_resume(struct i2c_client *i2c)
#endif
static const struct i2c_device_id wm8994_i2c_id[] = {
- { "wm8994", 0 },
+ { "wm8994", WM8994 },
+ { "wm8958", WM8958 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 03713bc66e4a..21fefef02a43 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -131,10 +131,19 @@ static struct regulator_ops wm8994_ldo1_ops = {
static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
unsigned int selector)
{
+ struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+
if (selector > WM8994_LDO2_MAX_SELECTOR)
return -EINVAL;
- return (selector * 100000) + 900000;
+ switch (ldo->wm8994->type) {
+ case WM8994:
+ return (selector * 100000) + 900000;
+ case WM8958:
+ return (selector * 100000) + 1000000;
+ default:
+ return -EINVAL;
+ }
}
static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev)
@@ -157,7 +166,17 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int selector, v;
- selector = (min_uV - 900000) / 100000;
+ switch (ldo->wm8994->type) {
+ case WM8994:
+ selector = (min_uV - 900000) / 100000;
+ break;
+ case WM8958:
+ selector = (min_uV - 1000000) / 100000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
v = wm8994_ldo2_list_voltage(rdev, selector);
if (v < 0 || v > max_uV)
return -EINVAL;
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index de79baee4925..3fd36845ca45 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -17,6 +17,11 @@
#include <linux/interrupt.h>
+enum wm8994_type {
+ WM8994 = 0,
+ WM8958 = 1,
+};
+
struct regulator_dev;
struct regulator_bulk_data;
@@ -48,6 +53,8 @@ struct wm8994 {
struct mutex io_lock;
struct mutex irq_lock;
+ enum wm8994_type type;
+
struct device *dev;
int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
int bytes, void *dest);
@@ -68,6 +75,7 @@ struct wm8994 {
u16 gpio_regs[WM8994_NUM_GPIO_REGS];
struct regulator_dev *dbvdd;
+ int num_supplies;
struct regulator_bulk_data *supplies;
};
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index add8a1b8bcf0..9eab263658be 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -30,6 +30,8 @@ struct wm8994_ldo_pdata {
#define WM8994_DRC_REGS 5
#define WM8994_EQ_REGS 20
+#define WM8958_MBC_CUTOFF_REGS 20
+#define WM8958_MBC_COEFF_REGS 48
/**
* DRC configurations are specified with a label and a set of register
@@ -59,6 +61,18 @@ struct wm8994_retune_mobile_cfg {
u16 regs[WM8994_EQ_REGS];
};
+/**
+ * Multiband compressor configurations are specified with a label and
+ * two sets of values to write. Configurations are expected to be
+ * generated using the multiband compressor configuration panel in
+ * WISCE - see http://www.wolfsonmicro.com/wisce/
+ */
+struct wm8958_mbc_cfg {
+ const char *name;
+ u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS];
+ u16 coeff_regs[WM8958_MBC_COEFF_REGS];
+};
+
struct wm8994_pdata {
int gpio_base;
@@ -78,6 +92,9 @@ struct wm8994_pdata {
int num_retune_mobile_cfgs;
struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
+ int num_mbc_cfgs;
+ struct wm8958_mbc_cfg *mbc_cfgs;
+
/* LINEOUT can be differential or single ended */
unsigned int lineout1_diff:1;
unsigned int lineout2_diff:1;
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index 967f62f54159..be072faec6f0 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -64,12 +64,16 @@
#define WM8994_LDO_1 0x3B
#define WM8994_LDO_2 0x3C
#define WM8994_CHARGE_PUMP_1 0x4C
+#define WM8958_CHARGE_PUMP_2 0x4D
#define WM8994_CLASS_W_1 0x51
#define WM8994_DC_SERVO_1 0x54
#define WM8994_DC_SERVO_2 0x55
#define WM8994_DC_SERVO_4 0x57
#define WM8994_DC_SERVO_READBACK 0x58
#define WM8994_ANALOGUE_HP_1 0x60
+#define WM8958_MIC_DETECT_1 0xD0
+#define WM8958_MIC_DETECT_2 0xD1
+#define WM8958_MIC_DETECT_3 0xD2
#define WM8994_CHIP_REVISION 0x100
#define WM8994_CONTROL_INTERFACE 0x101
#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110
@@ -109,6 +113,10 @@
#define WM8994_AIF2DAC_LRCLK 0x315
#define WM8994_AIF2DAC_DATA 0x316
#define WM8994_AIF2ADC_DATA 0x317
+#define WM8958_AIF3_CONTROL_1 0x320
+#define WM8958_AIF3_CONTROL_2 0x321
+#define WM8958_AIF3DAC_DATA 0x322
+#define WM8958_AIF3ADC_DATA 0x323
#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
@@ -242,6 +250,83 @@
#define WM8994_INTERRUPT_STATUS_2_MASK 0x739
#define WM8994_INTERRUPT_CONTROL 0x740
#define WM8994_IRQ_DEBOUNCE 0x748
+#define WM8958_DSP2_PROGRAM 0x900
+#define WM8958_DSP2_CONFIG 0x901
+#define WM8958_DSP2_MAGICNUM 0xA00
+#define WM8958_DSP2_RELEASEYEAR 0xA01
+#define WM8958_DSP2_RELEASEMONTHDAY 0xA02
+#define WM8958_DSP2_RELEASETIME 0xA03
+#define WM8958_DSP2_VERMAJMIN 0xA04
+#define WM8958_DSP2_VERBUILD 0xA05
+#define WM8958_DSP2_EXECCONTROL 0xA0D
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 0x2200
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_2 0x2201
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_1 0x2202
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_2 0x2203
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_1 0x2204
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_2 0x2205
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_1 0x2206
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_2 0x2207
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_1 0x2208
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_2 0x2209
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_1 0x220A
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_2 0x220B
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_1 0x220C
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_2 0x220D
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_1 0x220E
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_2 0x220F
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_1 0x2210
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_2 0x2211
+#define WM8958_MBC_BAND_1_LOWER_CUTOFF_1 0x2212
+#define WM8958_MBC_BAND_1_LOWER_CUTOFF_2 0x2213
+#define WM8958_MBC_BAND_1_K_1 0x2400
+#define WM8958_MBC_BAND_1_K_2 0x2401
+#define WM8958_MBC_BAND_1_N1_1 0x2402
+#define WM8958_MBC_BAND_1_N1_2 0x2403
+#define WM8958_MBC_BAND_1_N2_1 0x2404
+#define WM8958_MBC_BAND_1_N2_2 0x2405
+#define WM8958_MBC_BAND_1_N3_1 0x2406
+#define WM8958_MBC_BAND_1_N3_2 0x2407
+#define WM8958_MBC_BAND_1_N4_1 0x2408
+#define WM8958_MBC_BAND_1_N4_2 0x2409
+#define WM8958_MBC_BAND_1_N5_1 0x240A
+#define WM8958_MBC_BAND_1_N5_2 0x240B
+#define WM8958_MBC_BAND_1_X1_1 0x240C
+#define WM8958_MBC_BAND_1_X1_2 0x240D
+#define WM8958_MBC_BAND_1_X2_1 0x240E
+#define WM8958_MBC_BAND_1_X2_2 0x240F
+#define WM8958_MBC_BAND_1_X3_1 0x2410
+#define WM8958_MBC_BAND_1_X3_2 0x2411
+#define WM8958_MBC_BAND_1_ATTACK_1 0x2412
+#define WM8958_MBC_BAND_1_ATTACK_2 0x2413
+#define WM8958_MBC_BAND_1_DECAY_1 0x2414
+#define WM8958_MBC_BAND_1_DECAY_2 0x2415
+#define WM8958_MBC_BAND_2_K_1 0x2416
+#define WM8958_MBC_BAND_2_K_2 0x2417
+#define WM8958_MBC_BAND_2_N1_1 0x2418
+#define WM8958_MBC_BAND_2_N1_2 0x2419
+#define WM8958_MBC_BAND_2_N2_1 0x241A
+#define WM8958_MBC_BAND_2_N2_2 0x241B
+#define WM8958_MBC_BAND_2_N3_1 0x241C
+#define WM8958_MBC_BAND_2_N3_2 0x241D
+#define WM8958_MBC_BAND_2_N4_1 0x241E
+#define WM8958_MBC_BAND_2_N4_2 0x241F
+#define WM8958_MBC_BAND_2_N5_1 0x2420
+#define WM8958_MBC_BAND_2_N5_2 0x2421
+#define WM8958_MBC_BAND_2_X1_1 0x2422
+#define WM8958_MBC_BAND_2_X1_2 0x2423
+#define WM8958_MBC_BAND_2_X2_1 0x2424
+#define WM8958_MBC_BAND_2_X2_2 0x2425
+#define WM8958_MBC_BAND_2_X3_1 0x2426
+#define WM8958_MBC_BAND_2_X3_2 0x2427
+#define WM8958_MBC_BAND_2_ATTACK_1 0x2428
+#define WM8958_MBC_BAND_2_ATTACK_2 0x2429
+#define WM8958_MBC_BAND_2_DECAY_1 0x242A
+#define WM8958_MBC_BAND_2_DECAY_2 0x242B
+#define WM8958_MBC_B2_PG2_1 0x242C
+#define WM8958_MBC_B2_PG2_2 0x242D
+#define WM8958_MBC_B1_PG2_1 0x242E
+#define WM8958_MBC_B1_PG2_2 0x242F
#define WM8994_WRITE_SEQUENCER_0 0x3000
#define WM8994_WRITE_SEQUENCER_1 0x3001
#define WM8994_WRITE_SEQUENCER_2 0x3002
@@ -992,6 +1077,12 @@
/*
* R6 (0x06) - Power Management (6)
*/
+#define WM8958_AIF3ADC_SRC_MASK 0x0600 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF3ADC_SRC_SHIFT 9 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF3ADC_SRC_WIDTH 2 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF2DAC_SRC_MASK 0x0180 /* AIF2DAC_SRC - [8:7] */
+#define WM8958_AIF2DAC_SRC_SHIFT 7 /* AIF2DAC_SRC - [8:7] */
+#define WM8958_AIF2DAC_SRC_WIDTH 2 /* AIF2DAC_SRC - [8:7] */
#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */
#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
@@ -1836,6 +1927,14 @@
#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */
/*
+ * R77 (0x4D) - Charge Pump (2)
+ */
+#define WM8958_CP_DISCH 0x8000 /* CP_DISCH */
+#define WM8958_CP_DISCH_MASK 0x8000 /* CP_DISCH */
+#define WM8958_CP_DISCH_SHIFT 15 /* CP_DISCH */
+#define WM8958_CP_DISCH_WIDTH 1 /* CP_DISCH */
+
+/*
* R81 (0x51) - Class W (1)
*/
#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
@@ -1952,6 +2051,46 @@
#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
/*
+ * R208 (0xD0) - Mic Detect 1
+ */
+#define WM8958_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_DBTIME 0x0002 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
+#define WM8958_MICD_ENA 0x0001 /* MICD_ENA */
+#define WM8958_MICD_ENA_MASK 0x0001 /* MICD_ENA */
+#define WM8958_MICD_ENA_SHIFT 0 /* MICD_ENA */
+#define WM8958_MICD_ENA_WIDTH 1 /* MICD_ENA */
+
+/*
+ * R209 (0xD1) - Mic Detect 2
+ */
+#define WM8958_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
+#define WM8958_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
+#define WM8958_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
+
+/*
+ * R210 (0xD2) - Mic Detect 3
+ */
+#define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
+#define WM8958_MICD_VALID 0x0002 /* MICD_VALID */
+#define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */
+#define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */
+#define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */
+#define WM8958_MICD_STS 0x0001 /* MICD_STS */
+#define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */
+#define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */
+#define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */
+
+/*
* R256 (0x100) - Chip Revision
*/
#define WM8994_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
@@ -2069,6 +2208,14 @@
/*
* R520 (0x208) - Clocking (1)
*/
+#define WM8958_DSP2CLK_ENA 0x4000 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_MASK 0x4000 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_SHIFT 14 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_WIDTH 1 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_SRC 0x1000 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_MASK 0x1000 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_SHIFT 12 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_WIDTH 1 /* DSP2CLK_SRC */
#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */
#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
@@ -2553,6 +2700,63 @@
#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
/*
+ * R800 (0x320) - AIF3 Control (1)
+ */
+#define WM8958_AIF3_LRCLK_INV 0x0080 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_MASK 0x0080 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_SHIFT 7 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_WIDTH 1 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_WL_MASK 0x0060 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_WL_SHIFT 5 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_WL_WIDTH 2 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_FMT_MASK 0x0018 /* AIF3_FMT - [4:3] */
+#define WM8958_AIF3_FMT_SHIFT 3 /* AIF3_FMT - [4:3] */
+#define WM8958_AIF3_FMT_WIDTH 2 /* AIF3_FMT - [4:3] */
+
+/*
+ * R801 (0x321) - AIF3 Control (2)
+ */
+#define WM8958_AIF3DAC_BOOST_MASK 0x0C00 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_BOOST_SHIFT 10 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_BOOST_WIDTH 2 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_COMP 0x0010 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_MASK 0x0010 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_SHIFT 4 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_WIDTH 1 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMPMODE 0x0008 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_MASK 0x0008 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_SHIFT 3 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_WIDTH 1 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3ADC_COMP 0x0004 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_MASK 0x0004 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_SHIFT 2 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_WIDTH 1 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMPMODE 0x0002 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_MASK 0x0002 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_SHIFT 1 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_WIDTH 1 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3_LOOPBACK 0x0001 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_MASK 0x0001 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_SHIFT 0 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_WIDTH 1 /* AIF3_LOOPBACK */
+
+/*
+ * R802 (0x322) - AIF3DAC Data
+ */
+#define WM8958_AIF3DAC_DAT_INV 0x0001 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_MASK 0x0001 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_SHIFT 0 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_WIDTH 1 /* AIF3DAC_DAT_INV */
+
+/*
+ * R803 (0x323) - AIF3ADC Data
+ */
+#define WM8958_AIF3ADC_DAT_INV 0x0001 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_MASK 0x0001 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_SHIFT 0 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_WIDTH 1 /* AIF3ADC_DAT_INV */
+
+/*
* R1024 (0x400) - AIF1 ADC1 Left Volume
*/
#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
@@ -4289,4 +4493,102 @@
#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
+/*
+ * R2304 (0x900) - DSP2_Program
+ */
+#define WM8958_DSP2_ENA 0x0001 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_MASK 0x0001 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_SHIFT 0 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_WIDTH 1 /* DSP2_ENA */
+
+/*
+ * R2305 (0x901) - DSP2_Config
+ */
+#define WM8958_MBC_SEL_MASK 0x0030 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_SEL_SHIFT 4 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_SEL_WIDTH 2 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_ENA 0x0001 /* MBC_ENA */
+#define WM8958_MBC_ENA_MASK 0x0001 /* MBC_ENA */
+#define WM8958_MBC_ENA_SHIFT 0 /* MBC_ENA */
+#define WM8958_MBC_ENA_WIDTH 1 /* MBC_ENA */
+
+/*
+ * R2560 (0xA00) - DSP2_MagicNum
+ */
+#define WM8958_DSP2_MAGIC_NUM_MASK 0xFFFF /* DSP2_MAGIC_NUM - [15:0] */
+#define WM8958_DSP2_MAGIC_NUM_SHIFT 0 /* DSP2_MAGIC_NUM - [15:0] */
+#define WM8958_DSP2_MAGIC_NUM_WIDTH 16 /* DSP2_MAGIC_NUM - [15:0] */
+
+/*
+ * R2561 (0xA01) - DSP2_ReleaseYear
+ */
+#define WM8958_DSP2_RELEASE_YEAR_MASK 0xFFFF /* DSP2_RELEASE_YEAR - [15:0] */
+#define WM8958_DSP2_RELEASE_YEAR_SHIFT 0 /* DSP2_RELEASE_YEAR - [15:0] */
+#define WM8958_DSP2_RELEASE_YEAR_WIDTH 16 /* DSP2_RELEASE_YEAR - [15:0] */
+
+/*
+ * R2562 (0xA02) - DSP2_ReleaseMonthDay
+ */
+#define WM8958_DSP2_RELEASE_MONTH_MASK 0xFF00 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_MONTH_SHIFT 8 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_MONTH_WIDTH 8 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_DAY_MASK 0x00FF /* DSP2_RELEASE_DAY - [7:0] */
+#define WM8958_DSP2_RELEASE_DAY_SHIFT 0 /* DSP2_RELEASE_DAY - [7:0] */
+#define WM8958_DSP2_RELEASE_DAY_WIDTH 8 /* DSP2_RELEASE_DAY - [7:0] */
+
+/*
+ * R2563 (0xA03) - DSP2_ReleaseTime
+ */
+#define WM8958_DSP2_RELEASE_HOURS_MASK 0xFF00 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_HOURS_SHIFT 8 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_HOURS_WIDTH 8 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_MINS_MASK 0x00FF /* DSP2_RELEASE_MINS - [7:0] */
+#define WM8958_DSP2_RELEASE_MINS_SHIFT 0 /* DSP2_RELEASE_MINS - [7:0] */
+#define WM8958_DSP2_RELEASE_MINS_WIDTH 8 /* DSP2_RELEASE_MINS - [7:0] */
+
+/*
+ * R2564 (0xA04) - DSP2_VerMajMin
+ */
+#define WM8958_DSP2_MAJOR_VER_MASK 0xFF00 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MAJOR_VER_SHIFT 8 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MAJOR_VER_WIDTH 8 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MINOR_VER_MASK 0x00FF /* DSP2_MINOR_VER - [7:0] */
+#define WM8958_DSP2_MINOR_VER_SHIFT 0 /* DSP2_MINOR_VER - [7:0] */
+#define WM8958_DSP2_MINOR_VER_WIDTH 8 /* DSP2_MINOR_VER - [7:0] */
+
+/*
+ * R2565 (0xA05) - DSP2_VerBuild
+ */
+#define WM8958_DSP2_BUILD_VER_MASK 0xFFFF /* DSP2_BUILD_VER - [15:0] */
+#define WM8958_DSP2_BUILD_VER_SHIFT 0 /* DSP2_BUILD_VER - [15:0] */
+#define WM8958_DSP2_BUILD_VER_WIDTH 16 /* DSP2_BUILD_VER - [15:0] */
+
+/*
+ * R2573 (0xA0D) - DSP2_ExecControl
+ */
+#define WM8958_DSP2_STOPC 0x0020 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_MASK 0x0020 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_SHIFT 5 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_WIDTH 1 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPS 0x0010 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_MASK 0x0010 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_SHIFT 4 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_WIDTH 1 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPI 0x0008 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_MASK 0x0008 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_SHIFT 3 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_WIDTH 1 /* DSP2_STOPI */
+#define WM8958_DSP2_STOP 0x0004 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_MASK 0x0004 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_SHIFT 2 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_WIDTH 1 /* DSP2_STOP */
+#define WM8958_DSP2_RUNR 0x0002 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_MASK 0x0002 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_SHIFT 1 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_WIDTH 1 /* DSP2_RUNR */
+#define WM8958_DSP2_RUN 0x0001 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_MASK 0x0001 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_SHIFT 0 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_WIDTH 1 /* DSP2_RUN */
+
#endif
diff --git a/include/sound/alc5623.h b/include/sound/alc5623.h
new file mode 100644
index 000000000000..422c97d43df3
--- /dev/null
+++ b/include/sound/alc5623.h
@@ -0,0 +1,15 @@
+#ifndef _INCLUDE_SOUND_ALC5623_H
+#define _INCLUDE_SOUND_ALC5623_H
+struct alc5623_platform_data {
+ /* configure : */
+ /* Lineout/Speaker Amps Vmid ratio control */
+ /* enable/disable adc/dac high pass filters */
+ unsigned int add_ctrl;
+ /* configure : */
+ /* output to enable when jack is low */
+ /* output to enable when jack is high */
+ /* jack detect (gpio/nc/jack detect [12] */
+ unsigned int jack_det_ctrl;
+};
+#endif
+
diff --git a/include/sound/asound.h b/include/sound/asound.h
index a1803ecea34d..5d6074faa279 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -259,6 +259,7 @@ typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
+#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */
#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */
typedef int __bitwise snd_pcm_state_t;
@@ -334,6 +335,8 @@ typedef int snd_pcm_hw_param_t;
#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
+#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */
+#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */
struct snd_interval {
unsigned int min, max;
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
index d98a78dff2db..0909a3843479 100644
--- a/include/sound/hdsp.h
+++ b/include/sound/hdsp.h
@@ -28,6 +28,7 @@ enum HDSP_IO_Type {
Multiface,
H9652,
H9632,
+ RPM,
Undefined,
};
diff --git a/include/sound/minors.h b/include/sound/minors.h
index a81798ab73ed..8f764204a856 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -31,8 +31,8 @@
/* these minors can still be used for autoloading devices (/dev/aload*) */
#define SNDRV_MINOR_CONTROL 0 /* 0 */
#define SNDRV_MINOR_GLOBAL 1 /* 1 */
-#define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32)
-#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32)
+#define SNDRV_MINOR_SEQUENCER 1 /* SNDRV_MINOR_GLOBAL + 0 * 32 */
+#define SNDRV_MINOR_TIMER 33 /* SNDRV_MINOR_GLOBAL + 1 * 32 */
#ifndef CONFIG_SND_DYNAMIC_MINORS
/* 2 - 3 (reserved) */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index dfd9b76b1853..e731f8d71934 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -297,6 +297,7 @@ struct snd_pcm_runtime {
unsigned int info;
unsigned int rate_num;
unsigned int rate_den;
+ unsigned int no_period_wakeup: 1;
/* -- SW params -- */
int tstamp_mode; /* mmap timestamp is updated */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index e7b680248006..1bafe95dcf41 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -16,8 +16,6 @@
#include <linux/list.h>
-#include <sound/soc.h>
-
struct snd_pcm_substream;
/*
@@ -205,7 +203,7 @@ struct snd_soc_dai_driver {
int (*resume)(struct snd_soc_dai *dai);
/* ops */
- struct snd_soc_dai_ops *ops;
+ const struct snd_soc_dai_ops *ops;
/* DAI capabilities */
struct snd_soc_pcm_stream capture;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8fd3b41b763f..2f76a51bbaac 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -16,7 +16,6 @@
#include <linux/device.h>
#include <linux/types.h>
#include <sound/control.h>
-#include <sound/soc.h>
/* widget has no PM register bit */
#define SND_SOC_NOPM -1
@@ -72,6 +71,10 @@
wcontrols, wncontrols) \
{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
+ wcontrols, wncontrols) \
+{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols}
#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
wcontrols, wncontrols)\
{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
@@ -116,6 +119,11 @@
{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
+ wncontrols, wevent, wflags) \
+{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
+ .event = wevent, .event_flags = wflags}
#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
wncontrols, wevent, wflags) \
{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
@@ -297,6 +305,7 @@ enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
struct snd_soc_dapm_pin;
struct snd_soc_dapm_route;
+struct snd_soc_dapm_context;
int dapm_reg_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
@@ -324,16 +333,16 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
-int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
-int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num);
/* dapm path setup */
-int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
-void snd_soc_dapm_free(struct snd_soc_codec *codec);
-int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
+void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
/* dapm events */
@@ -343,17 +352,21 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card);
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm);
/* dapm audio pin control and status */
-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_sync(struct snd_soc_codec *codec);
-int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec,
+int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
+int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin);
-int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin);
+int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
+ const char *pin);
/* dapm widget types */
enum snd_soc_dapm_type {
@@ -364,6 +377,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_mixer, /* mixes several analog signals together */
snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */
snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */
+ snd_soc_dapm_out_drv, /* output driver */
snd_soc_dapm_adc, /* analog to digital converter */
snd_soc_dapm_dac, /* digital to analog converter */
snd_soc_dapm_micbias, /* microphone bias (power) */
@@ -425,6 +439,7 @@ struct snd_soc_dapm_widget {
char *sname; /* stream name */
struct snd_soc_codec *codec;
struct list_head list;
+ struct snd_soc_dapm_context *dapm;
/* dapm control */
short reg; /* negative reg = no direct dapm */
@@ -461,4 +476,21 @@ struct snd_soc_dapm_widget {
struct list_head power_list;
};
+/* DAPM context */
+struct snd_soc_dapm_context {
+ struct list_head widgets;
+ struct list_head paths;
+ enum snd_soc_bias_level bias_level;
+ enum snd_soc_bias_level suspend_bias_level;
+ struct delayed_work delayed_work;
+ unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
+
+ struct device *dev; /* from parent - for debug */
+ struct snd_soc_codec *codec; /* parent codec */
+ struct snd_soc_card *card; /* parent card */
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_dapm;
+#endif
+};
+
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 5c3bce83f28a..7e65b015f8dd 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -222,10 +222,8 @@ enum snd_soc_bias_level {
struct snd_jack;
struct snd_soc_card;
-struct snd_soc_device;
struct snd_soc_pcm_stream;
struct snd_soc_ops;
-struct snd_soc_dai_mode;
struct snd_soc_pcm_runtime;
struct snd_soc_dai;
struct snd_soc_dai_driver;
@@ -235,9 +233,10 @@ struct snd_soc_platform_driver;
struct snd_soc_codec;
struct snd_soc_codec_driver;
struct soc_enum;
-struct snd_soc_ac97_ops;
struct snd_soc_jack;
struct snd_soc_jack_pin;
+struct snd_soc_cache_ops;
+#include <sound/soc-dapm.h>
#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio;
@@ -253,17 +252,30 @@ enum snd_soc_control_type {
SND_SOC_SPI,
};
+enum snd_soc_compress_type {
+ SND_SOC_FLAT_COMPRESSION = 1,
+ SND_SOC_LZO_COMPRESSION,
+ SND_SOC_RBTREE_COMPRESSION
+};
+
int snd_soc_register_platform(struct device *dev,
struct snd_soc_platform_driver *platform_drv);
void snd_soc_unregister_platform(struct device *dev);
int snd_soc_register_codec(struct device *dev,
- struct snd_soc_codec_driver *codec_drv,
+ const struct snd_soc_codec_driver *codec_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_codec(struct device *dev);
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
int addr_bits, int data_bits,
enum snd_soc_control_type control);
+int snd_soc_cache_sync(struct snd_soc_codec *codec);
+int snd_soc_cache_init(struct snd_soc_codec *codec);
+int snd_soc_cache_exit(struct snd_soc_codec *codec);
+int snd_soc_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value);
+int snd_soc_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -420,23 +432,37 @@ struct snd_soc_ops {
int (*trigger)(struct snd_pcm_substream *, int);
};
+/* SoC cache ops */
+struct snd_soc_cache_ops {
+ const char *name;
+ enum snd_soc_compress_type id;
+ int (*init)(struct snd_soc_codec *codec);
+ int (*exit)(struct snd_soc_codec *codec);
+ int (*read)(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int *value);
+ int (*write)(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value);
+ int (*sync)(struct snd_soc_codec *codec);
+};
+
/* SoC Audio Codec device */
struct snd_soc_codec {
const char *name;
+ const char *name_prefix;
int id;
struct device *dev;
- struct snd_soc_codec_driver *driver;
+ const struct snd_soc_codec_driver *driver;
struct mutex mutex;
struct snd_soc_card *card;
struct list_head list;
struct list_head card_list;
int num_dai;
+ enum snd_soc_compress_type compress_type;
/* runtime */
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
unsigned int active;
- unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
unsigned int cache_only:1; /* Suppress writes to hardware */
unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
unsigned int suspended:1; /* Codec is in suspend PM state */
@@ -444,25 +470,25 @@ struct snd_soc_codec {
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
+ unsigned int cache_init:1; /* codec cache has been initialized */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
+ unsigned int (*read)(struct snd_soc_codec *, unsigned int);
+ int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
void *reg_cache;
+ const void *reg_def_copy;
+ const struct snd_soc_cache_ops *cache_ops;
+ struct mutex cache_rw_mutex;
/* dapm */
- u32 pop_time;
- struct list_head dapm_widgets;
- struct list_head dapm_paths;
- enum snd_soc_bias_level bias_level;
- enum snd_soc_bias_level suspend_bias_level;
- struct delayed_work delayed_work;
+ struct snd_soc_dapm_context dapm;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root;
struct dentry *debugfs_reg;
- struct dentry *debugfs_pop_time;
struct dentry *debugfs_dapm;
#endif
};
@@ -488,6 +514,7 @@ struct snd_soc_codec_driver {
short reg_cache_step;
short reg_word_size;
const void *reg_cache_default;
+ enum snd_soc_compress_type compress_type;
/* codec bias level */
int (*set_bias_level)(struct snd_soc_codec *,
@@ -554,6 +581,30 @@ struct snd_soc_dai_link {
struct snd_soc_ops *ops;
};
+struct snd_soc_codec_conf {
+ const char *dev_name;
+
+ /*
+ * optional map of kcontrol, widget and path name prefixes that are
+ * associated per device
+ */
+ const char *name_prefix;
+
+ /*
+ * set this to the desired compression type if you want to
+ * override the one supplied in codec->driver->compress_type
+ */
+ enum snd_soc_compress_type compress_type;
+};
+
+struct snd_soc_aux_dev {
+ const char *name; /* Codec name */
+ const char *codec_name; /* for multi-codec */
+
+ /* codec/machine specific init - e.g. add machine controls */
+ int (*init)(struct snd_soc_dapm_context *dapm);
+};
+
/* SoC card */
struct snd_soc_card {
const char *name;
@@ -579,6 +630,8 @@ struct snd_soc_card {
/* callbacks */
int (*set_bias_level)(struct snd_soc_card *,
enum snd_soc_bias_level level);
+ int (*set_bias_level_post)(struct snd_soc_card *,
+ enum snd_soc_bias_level level);
long pmdown_time;
@@ -588,12 +641,31 @@ struct snd_soc_card {
struct snd_soc_pcm_runtime *rtd;
int num_rtd;
+ /* optional codec specific configuration */
+ struct snd_soc_codec_conf *codec_conf;
+ int num_configs;
+
+ /*
+ * optional auxiliary devices such as amplifiers or codecs with DAI
+ * link unused
+ */
+ struct snd_soc_aux_dev *aux_dev;
+ int num_aux_devs;
+ struct snd_soc_pcm_runtime *rtd_aux;
+ int num_aux_rtd;
+
struct work_struct deferred_resume_work;
/* lists of probed devices belonging to this card */
struct list_head codec_dev_list;
struct list_head platform_dev_list;
struct list_head dai_dev_list;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_card_root;
+ struct dentry *debugfs_pop_time;
+#endif
+ u32 pop_time;
};
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
@@ -639,17 +711,9 @@ struct soc_enum {
};
/* codec IO */
-static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return codec->driver->read(codec, reg);
-}
-
-static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val)
-{
- return codec->driver->write(codec, reg, val);
-}
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
+unsigned int snd_soc_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int val);
/* device driver data */
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
new file mode 100644
index 000000000000..186e84db4b54
--- /dev/null
+++ b/include/trace/events/asoc.h
@@ -0,0 +1,235 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM asoc
+
+#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ASOC_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+struct snd_soc_jack;
+struct snd_soc_codec;
+struct snd_soc_card;
+struct snd_soc_dapm_widget;
+
+/*
+ * Log register events
+ */
+DECLARE_EVENT_CLASS(snd_soc_reg,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val),
+
+ TP_STRUCT__entry(
+ __string( name, codec->name )
+ __field( int, id )
+ __field( unsigned int, reg )
+ __field( unsigned int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, codec->name);
+ __entry->id = codec->id;
+ __entry->reg = reg;
+ __entry->val = val;
+ ),
+
+ TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name),
+ (int)__entry->id, (unsigned int)__entry->reg,
+ (unsigned int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val)
+
+);
+
+DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_card,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val),
+
+ TP_STRUCT__entry(
+ __string( name, card->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, card->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val)
+
+);
+
+DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_dapm_basic,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card),
+
+ TP_STRUCT__entry(
+ __string( name, card->name )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, card->name);
+ ),
+
+ TP_printk("card=%s", __get_str(name))
+);
+
+DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_dapm_widget,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val),
+
+ TP_STRUCT__entry(
+ __string( name, w->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, w->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("widget=%s val=%d", __get_str(name),
+ (int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+TRACE_EVENT(snd_soc_jack_irq,
+
+ TP_PROTO(const char *name),
+
+ TP_ARGS(name),
+
+ TP_STRUCT__entry(
+ __string( name, name )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
+
+TRACE_EVENT(snd_soc_jack_report,
+
+ TP_PROTO(struct snd_soc_jack *jack, int mask, int val),
+
+ TP_ARGS(jack, mask, val),
+
+ TP_STRUCT__entry(
+ __string( name, jack->jack->name )
+ __field( int, mask )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, jack->jack->name);
+ __entry->mask = mask;
+ __entry->val = val;
+ ),
+
+ TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val,
+ (int)__entry->mask)
+);
+
+TRACE_EVENT(snd_soc_jack_notify,
+
+ TP_PROTO(struct snd_soc_jack *jack, int val),
+
+ TP_ARGS(jack, val),
+
+ TP_STRUCT__entry(
+ __string( name, jack->jack->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, jack->jack->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("jack=%s %x", __get_str(name), (int)__entry->val)
+);
+
+#endif /* _TRACE_ASOC_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index a351dd0a09c7..2b50cbe6aca9 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -19,8 +19,8 @@
/*
* Let drivers decide whether they want to support given codec from their
- * probe method. Drivers have direct access to the struct snd_ac97 structure and may
- * decide based on the id field amongst other things.
+ * probe method. Drivers have direct access to the struct snd_ac97
+ * structure and may decide based on the id field amongst other things.
*/
static int ac97_bus_match(struct device *dev, struct device_driver *drv)
{
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 91852e49910e..3687a6cc9881 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1114,7 +1114,6 @@ static int onyx_i2c_remove(struct i2c_client *client)
of_node_put(onyx->codec.node);
if (onyx->codec_info)
kfree(onyx->codec_info);
- i2c_set_clientdata(client, onyx);
kfree(onyx);
return 0;
}
diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c
index de8e03afa97b..faa317490545 100644
--- a/sound/aoa/core/gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -287,10 +287,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt)
free_irq(linein_detect_irq, &rt->line_in_notify);
if (rt->line_out_notify.gpio_private)
free_irq(lineout_detect_irq, &rt->line_out_notify);
- cancel_delayed_work(&rt->headphone_notify.work);
- cancel_delayed_work(&rt->line_in_notify.work);
- cancel_delayed_work(&rt->line_out_notify.work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&rt->headphone_notify.work);
+ cancel_delayed_work_sync(&rt->line_in_notify.work);
+ cancel_delayed_work_sync(&rt->line_out_notify.work);
mutex_destroy(&rt->headphone_notify.mutex);
mutex_destroy(&rt->line_in_notify.mutex);
mutex_destroy(&rt->line_out_notify.mutex);
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 7e267c9379bc..c8d8a1a6f964 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -107,10 +107,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt)
/* make sure no work is pending before freeing
* all things */
- cancel_delayed_work(&rt->headphone_notify.work);
- cancel_delayed_work(&rt->line_in_notify.work);
- cancel_delayed_work(&rt->line_out_notify.work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&rt->headphone_notify.work);
+ cancel_delayed_work_sync(&rt->line_in_notify.work);
+ cancel_delayed_work_sync(&rt->line_out_notify.work);
mutex_destroy(&rt->headphone_notify.mutex);
mutex_destroy(&rt->line_in_notify.mutex);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b75db8e9cc0f..fd18c3c6484f 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -373,6 +373,27 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
(unsigned long)new_hw_ptr,
(unsigned long)runtime->hw_ptr_base);
}
+
+ if (runtime->no_period_wakeup) {
+ /*
+ * Without regular period interrupts, we have to check
+ * the elapsed time to detect xruns.
+ */
+ jdelta = jiffies - runtime->hw_ptr_jiffies;
+ if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
+ goto no_delta_check;
+ hdelta = jdelta - delta * HZ / runtime->rate;
+ while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
+ delta += runtime->buffer_size;
+ hw_base += runtime->buffer_size;
+ if (hw_base >= runtime->boundary)
+ hw_base = 0;
+ new_hw_ptr = hw_base + pos;
+ hdelta -= runtime->hw_ptr_buffer_jiffies;
+ }
+ goto no_delta_check;
+ }
+
/* something must be really wrong */
if (delta >= runtime->buffer_size + runtime->period_size) {
hw_ptr_error(substream,
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
(long)old_hw_ptr);
}
+ no_delta_check:
if (runtime->status->hw_ptr == new_hw_ptr)
return 0;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e82c1f97d99e..0db714e87a80 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -422,6 +422,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
runtime->info = params->info;
runtime->rate_num = params->rate_num;
runtime->rate_den = params->rate_den;
+ runtime->no_period_wakeup =
+ (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
+ (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
bits = snd_pcm_format_physical_width(runtime->format);
runtime->sample_bits = bits;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index bf09a5ad1865..119fddb6fc99 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -32,6 +32,7 @@
#include "seq_timer.h"
#include "seq_system.h"
#include "seq_info.h"
+#include <sound/minors.h>
#include <sound/seq_device.h>
#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
@@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe
module_param(seq_default_timer_resolution, int, 0644);
MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
+MODULE_ALIAS("devname:snd/seq");
+
/*
* INIT PART
*/
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 66691fe437e6..1c7a3efe1778 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -188,14 +188,22 @@ static const struct file_operations snd_fops =
};
#ifdef CONFIG_SND_DYNAMIC_MINORS
-static int snd_find_free_minor(void)
+static int snd_find_free_minor(int type)
{
int minor;
+ /* static minors for module auto loading */
+ if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
+ return SNDRV_MINOR_SEQUENCER;
+ if (type == SNDRV_DEVICE_TYPE_TIMER)
+ return SNDRV_MINOR_TIMER;
+
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
- /* skip minors still used statically for autoloading devices */
- if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL ||
- minor == SNDRV_MINOR_SEQUENCER)
+ /* skip static minors still used for module auto loading */
+ if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
+ continue;
+ if (minor == SNDRV_MINOR_SEQUENCER ||
+ minor == SNDRV_MINOR_TIMER)
continue;
if (!snd_minors[minor])
return minor;
@@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
preg->private_data = private_data;
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
- minor = snd_find_free_minor();
+ minor = snd_find_free_minor(type);
#else
minor = snd_kernel_minor(type, card, dev);
if (minor >= 0 && snd_minors[minor])
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 13afb60999b9..ed016329e911 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -34,8 +34,8 @@
#include <sound/initval.h>
#include <linux/kmod.h>
-#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
-#define DEFAULT_TIMER_LIMIT 3
+#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
+#define DEFAULT_TIMER_LIMIT 4
#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
#define DEFAULT_TIMER_LIMIT 2
#else
@@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
module_param(timer_tstamp_monotonic, int, 0444);
MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
+MODULE_ALIAS("devname:snd/timer");
+
struct snd_timer_user {
struct snd_timer_instance *timeri;
int tread; /* enhanced read with timestamps and events */
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index a1282c1c0591..5cfcb908c430 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
(resource->start) + 1);
if (ml403_ac97cr->port == NULL) {
snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to remap memory region (%x to %x)\n",
- resource->start, resource->end);
+ "unable to remap memory region (%pR)\n",
+ resource);
snd_ml403_ac97cr_free(ml403_ac97cr);
return -EBUSY;
}
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index 971a84a4fa77..c424d329f806 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -57,8 +57,7 @@ static void snd_ak4113_free(struct ak4113 *chip)
{
chip->init = 1; /* don't schedule new work */
mb();
- cancel_delayed_work(&chip->work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -141,7 +140,7 @@ void snd_ak4113_reinit(struct ak4113 *chip)
{
chip->init = 1;
mb();
- flush_scheduled_work();
+ flush_delayed_work_sync(&chip->work);
ak4113_init_regs(chip);
/* bring up statistics / event queing */
chip->init = 0;
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 0341451f814c..d9fb537b0b94 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -67,8 +67,7 @@ static void snd_ak4114_free(struct ak4114 *chip)
{
chip->init = 1; /* don't schedule new work */
mb();
- cancel_delayed_work(&chip->work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -154,7 +153,7 @@ void snd_ak4114_reinit(struct ak4114 *chip)
{
chip->init = 1;
mb();
- flush_scheduled_work();
+ flush_delayed_work_sync(&chip->work);
ak4114_init_regs(chip);
/* bring up statistics / event queing */
chip->init = 0;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 12e34653b8a8..7b2678a25ca0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -209,7 +209,7 @@ config SND_OXYGEN_LIB
tristate
config SND_OXYGEN
- tristate "C-Media 8788 (Oxygen)"
+ tristate "C-Media 8787, 8788 (Oxygen)"
select SND_OXYGEN_LIB
select SND_PCM
select SND_MPU401_UART
@@ -222,8 +222,11 @@ config SND_OXYGEN
* Club3D Theatron DTS
* HT-Omega Claro (plus)
* HT-Omega Claro halo (XT)
+ * Kuroutoshikou CMI8787-HG2PCI
* Razer Barracuda AC-1
* Sondigo Inferno
+ * TempoTec/MediaTek HiFier Fantasia
+ * TempoTec/MediaTek HiFier Serenade
To compile this driver as a module, choose M here: the module
will be called snd-oxygen.
@@ -578,18 +581,6 @@ config SND_HDSPM
To compile this driver as a module, choose M here: the module
will be called snd-hdspm.
-config SND_HIFIER
- tristate "TempoTec HiFier Fantasia"
- select SND_OXYGEN_LIB
- select SND_PCM
- select SND_MPU401_UART
- help
- Say Y here to include support for the MediaTek/TempoTec HiFier
- Fantasia sound card.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hifier.
-
config SND_ICE1712
tristate "ICEnsemble ICE1712 (Envy24)"
select SND_MPU401_UART
@@ -826,7 +817,7 @@ config SND_VIRTUOSO
Say Y here to include support for sound cards based on the
Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
Essence ST (Deluxe), and Essence STX.
- Support for the HDAV1.3 (Deluxe) is incomplete; for the
+ Support for the HDAV1.3 (Deluxe) is experimental; for the
HDAV1.3 Slim and Xense, missing.
To compile this driver as a module, choose M here: the module
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index a7630e9edf8a..0fc614ce16c1 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1014,8 +1014,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
{
if (ac97) {
#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work(&ac97->power_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ac97->power_work);
#endif
snd_ac97_proc_done(ac97);
if (ac97->bus)
@@ -2456,8 +2455,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
if (ac97->build_ops->suspend)
ac97->build_ops->suspend(ac97);
#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work(&ac97->power_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ac97->power_work);
#endif
snd_ac97_powerdown(ac97);
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b030c8eba21f..d9e14f14e85e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip,
pos_adj = 0;
} else {
ofs = setup_bdle(substream, azx_dev,
- &bdl, ofs, pos_adj, 1);
+ &bdl, ofs, pos_adj,
+ !substream->runtime->no_period_wakeup);
if (ofs < 0)
goto error;
}
@@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip,
period_bytes - pos_adj, 0);
else
ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
- period_bytes, 1);
+ period_bytes,
+ !substream->runtime->no_period_wakeup);
if (ofs < 0)
goto error;
}
@@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
/* No full-resume yet implemented */
/* SNDRV_PCM_INFO_RESUME |*/
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 76bd58a0e2b6..e584b3dd7aa8 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2111,6 +2111,11 @@ static struct hda_channel_mode cxt5066_modes[1] = {
{ 2, NULL },
};
+#define HP_PRESENT_PORT_A (1 << 0)
+#define HP_PRESENT_PORT_D (1 << 1)
+#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
+#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
+
static void cxt5066_update_speaker(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
@@ -2120,24 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
spec->hp_present, spec->cur_eapd);
/* Port A (HP) */
- pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
+ pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
/* Port D (HP/LO) */
- if (spec->dell_automute) {
- /* DELL AIO Port Rule: PortA> PortD> IntSpk */
- pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
- ? PIN_OUT : 0;
- } else if (spec->thinkpad) {
- if (spec->cur_eapd)
- pinctl = spec->port_d_mode;
- /* Mute dock line-out if Port A (laptop HP) is present */
- if (spec->hp_present& 1)
+ pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
+ if (spec->dell_automute || spec->thinkpad) {
+ /* Mute if Port A is connected */
+ if (hp_port_a_present(spec))
pinctl = 0;
} else {
- pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
- ? spec->port_d_mode : 0;
+ /* Thinkpad/Dell doesn't give pin-D status */
+ if (!hp_port_d_present(spec))
+ pinctl = 0;
}
snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
@@ -2379,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
/* Port D */
portD = snd_hda_jack_detect(codec, 0x1c);
- spec->hp_present = !!(portA);
- spec->hp_present |= portD ? 2 : 0;
+ spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
+ spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
portA, portD, spec->hp_present);
cxt5066_update_speaker(codec);
@@ -3422,6 +3423,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
AC_VERB_SET_PIN_WIDGET_CONTROL,
present ? 0 : PIN_OUT);
}
+ for (i = 0; !present && i < cfg->line_outs; i++)
+ if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
+ present = 1;
for (i = 0; i < cfg->speaker_outs; i++) {
snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 31df7747990d..d1b1b5796c98 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -904,23 +904,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
spec->pin[spec->num_pins] = pin_nid;
spec->num_pins++;
- /*
- * It is assumed that converter nodes come first in the node list and
- * hence have been registered and usable now.
- */
return hdmi_read_pin_conn(codec, pin_nid);
}
static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
{
+ int i, found_pin = 0;
struct hdmi_spec *spec = codec->spec;
- if (spec->num_cvts >= MAX_HDMI_CVTS) {
- snd_printk(KERN_WARNING
- "HDMI: no space for converter %d\n", nid);
- return -E2BIG;
+ for (i = 0; i < spec->num_pins; i++)
+ if (nid == spec->pin_cvt[i]) {
+ found_pin = 1;
+ break;
+ }
+
+ if (!found_pin) {
+ snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
+ return -EINVAL;
}
+ if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
+ return -E2BIG;
+
spec->cvt[spec->num_cvts] = nid;
spec->num_cvts++;
@@ -931,6 +936,8 @@ static int hdmi_parse_codec(struct hda_codec *codec)
{
hda_nid_t nid;
int i, nodes;
+ int num_tmp_cvts = 0;
+ hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
if (!nid || nodes < 0) {
@@ -941,6 +948,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
for (i = 0; i < nodes; i++, nid++) {
unsigned int caps;
unsigned int type;
+ unsigned int config;
caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
type = get_wcaps_type(caps);
@@ -950,17 +958,32 @@ static int hdmi_parse_codec(struct hda_codec *codec)
switch (type) {
case AC_WID_AUD_OUT:
- hdmi_add_cvt(codec, nid);
+ if (num_tmp_cvts >= MAX_HDMI_CVTS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for converter %d\n", nid);
+ continue;
+ }
+ tmp_cvt[num_tmp_cvts] = nid;
+ num_tmp_cvts++;
break;
case AC_WID_PIN:
caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
continue;
+
+ config = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
+ if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
+ continue;
+
hdmi_add_pin(codec, nid);
break;
}
}
+ for (i = 0; i < num_tmp_cvts; i++)
+ hdmi_add_cvt(codec, tmp_cvt[i]);
+
/*
* G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
* can be lost and presence sense verb will become inaccurate if the
@@ -1532,7 +1555,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = {
{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
-{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
+{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 2d7d7de8498a..cd2d3a5efa50 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -231,7 +231,6 @@ enum {
ALC888_ACER_ASPIRE_8930G,
ALC888_ACER_ASPIRE_7730G,
ALC883_MEDION,
- ALC883_MEDION_MD2,
ALC883_MEDION_WIM2160,
ALC883_LAPTOP_EAPD,
ALC883_LENOVO_101E_2ch,
@@ -1678,29 +1677,32 @@ struct alc_pincfg {
u32 val;
};
+struct alc_model_fixup {
+ const int id;
+ const char *name;
+};
+
struct alc_fixup {
unsigned int sku;
const struct alc_pincfg *pins;
const struct hda_verb *verbs;
+ void (*func)(struct hda_codec *codec, const struct alc_fixup *fix,
+ int pre_init);
};
-static void alc_pick_fixup(struct hda_codec *codec,
- const struct snd_pci_quirk *quirk,
- const struct alc_fixup *fix,
- int pre_init)
+static void __alc_pick_fixup(struct hda_codec *codec,
+ const struct alc_fixup *fix,
+ const char *modelname,
+ int pre_init)
{
const struct alc_pincfg *cfg;
struct alc_spec *spec;
- quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (!quirk)
- return;
- fix += quirk->value;
cfg = fix->pins;
if (pre_init && fix->sku) {
#ifdef CONFIG_SND_DEBUG_VERBOSE
snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
- codec->chip_name, quirk->name);
+ codec->chip_name, modelname);
#endif
spec = codec->spec;
spec->cdefine.sku_cfg = fix->sku;
@@ -1709,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
if (pre_init && cfg) {
#ifdef CONFIG_SND_DEBUG_VERBOSE
snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
- codec->chip_name, quirk->name);
+ codec->chip_name, modelname);
#endif
for (; cfg->nid; cfg++)
snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
@@ -1717,10 +1719,53 @@ static void alc_pick_fixup(struct hda_codec *codec,
if (!pre_init && fix->verbs) {
#ifdef CONFIG_SND_DEBUG_VERBOSE
snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
- codec->chip_name, quirk->name);
+ codec->chip_name, modelname);
#endif
add_verb(codec->spec, fix->verbs);
}
+ if (fix->func) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
+ codec->chip_name, modelname);
+#endif
+ fix->func(codec, fix, pre_init);
+ }
+}
+
+static void alc_pick_fixup(struct hda_codec *codec,
+ const struct snd_pci_quirk *quirk,
+ const struct alc_fixup *fix,
+ int pre_init)
+{
+ quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
+ if (quirk) {
+ fix += quirk->value;
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ __alc_pick_fixup(codec, fix, quirk->name, pre_init);
+#else
+ __alc_pick_fixup(codec, fix, NULL, pre_init);
+#endif
+ }
+}
+
+static void alc_pick_fixup_model(struct hda_codec *codec,
+ const struct alc_model_fixup *models,
+ const struct snd_pci_quirk *quirk,
+ const struct alc_fixup *fix,
+ int pre_init)
+{
+ if (codec->modelname && models) {
+ while (models->name) {
+ if (!strcmp(codec->modelname, models->name)) {
+ fix += models->id;
+ break;
+ }
+ models++;
+ }
+ __alc_pick_fixup(codec, fix, codec->modelname, pre_init);
+ } else {
+ alc_pick_fixup(codec, quirk, fix, pre_init);
+ }
}
static int alc_read_coef_idx(struct hda_codec *codec,
@@ -8981,19 +9026,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
{ } /* end */
};
-static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- { } /* end */
-};
-
static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -9435,18 +9467,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
alc888_lenovo_ms7195_rca_automute(codec);
}
-static struct hda_verb alc883_medion_md2_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
/* toggle speaker-output according to the hp-jack state */
-static void alc883_medion_md2_setup(struct hda_codec *codec)
+static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -9731,7 +9753,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
[ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
[ALC883_MEDION] = "medion",
- [ALC883_MEDION_MD2] = "medion-md2",
[ALC883_MEDION_WIM2160] = "medion-wim2160",
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
@@ -10379,19 +10400,6 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source,
},
- [ALC883_MEDION_MD2] = {
- .mixers = { alc883_medion_md2_mixer},
- .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_automute_amp_unsol_event,
- .setup = alc883_medion_md2_setup,
- .init_hook = alc_automute_amp,
- },
[ALC883_MEDION_WIM2160] = {
.mixers = { alc883_medion_wim2160_mixer },
.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
@@ -10468,7 +10476,7 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_nb0763_capture_source,
.unsol_event = alc_automute_amp_unsol_event,
- .setup = alc883_medion_md2_setup,
+ .setup = alc883_lenovo_nb0763_setup,
.init_hook = alc_automute_amp,
},
[ALC888_LENOVO_MS7195_DIG] = {
@@ -19324,9 +19332,21 @@ static void alc662_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
+static void alc272_fixup_mario(struct hda_codec *codec,
+ const struct alc_fixup *fix, int pre_init) {
+ if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
+ (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (0 << AC_AMPCAP_MUTE_SHIFT)))
+ printk(KERN_WARNING
+ "hda_codec: failed to override amp caps for NID 0x2\n");
+}
+
enum {
ALC662_FIXUP_ASPIRE,
ALC662_FIXUP_IDEAPAD,
+ ALC272_FIXUP_MARIO,
};
static const struct alc_fixup alc662_fixups[] = {
@@ -19342,6 +19362,9 @@ static const struct alc_fixup alc662_fixups[] = {
{ }
}
},
+ [ALC272_FIXUP_MARIO] = {
+ .func = alc272_fixup_mario,
+ }
};
static struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -19352,6 +19375,10 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = {
{}
};
+static const struct alc_model_fixup alc662_fixup_models[] = {
+ {.id = ALC272_FIXUP_MARIO, .name = "mario"},
+ {}
+};
static int patch_alc662(struct hda_codec *codec)
@@ -19451,7 +19478,8 @@ static int patch_alc662(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC662_AUTO) {
spec->init_hook = alc662_auto_init;
- alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
+ alc_pick_fixup_model(codec, alc662_fixup_models,
+ alc662_fixup_tbl, alc662_fixups, 0);
}
alc_init_jacks(codec);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index efa4225f5fd6..8e2bb0aad0ae 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -5423,7 +5423,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
codec->no_trigger_sense = 1;
codec->spec = spec;
- spec->linear_tone_beep = 1;
+ spec->linear_tone_beep = 0;
codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
spec->digbeep_nid = 0x21;
spec->dmic_nids = stac92hd83xxx_dmic_nids;
@@ -5471,7 +5471,6 @@ again:
spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
spec->pin_nids = stac92hd88xxx_pin_nids;
spec->mono_nid = 0;
- spec->digbeep_nid = 0;
spec->num_pwrs = 0;
break;
case 0x111d7604:
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index d1c3f8defc48..7f4852a478a1 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -263,8 +263,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
return;
snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
!spec->vt1708_jack_detectect);
- cancel_delayed_work(&spec->vt1708_hp_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&spec->vt1708_hp_work);
}
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 712c1710f9a2..7b62de089fee 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
+ ICE1712_DELTA_66E_CS_CHIP_B;
+ tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
+ break;
case ICE1712_SUBDEVICE_VX442:
tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
tmp &= ~ICE1712_VX442_CS_DIGITAL;
@@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
case ICE1712_SUBDEVICE_DELTA410:
tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ tmp |= ICE1712_DELTA_66E_CS_CS8427;
+ break;
case ICE1712_SUBDEVICE_VX442:
tmp |= ICE1712_VX442_CS_DIGITAL;
break;
@@ -276,6 +284,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
}
/*
+ * AK4524 on Delta66 rev E to choose the chip address
+ */
+static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
+{
+ struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
+ struct snd_ice1712 *ice = ak->private_data[0];
+
+ snd_ice1712_save_gpio_status(ice);
+ priv->cs_mask =
+ priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
+ ICE1712_DELTA_66E_CS_CHIP_B;
+}
+
+/*
* AK4528 on VX442 to choose the chip mask
*/
static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
@@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
.mask_flags = 0,
};
+static struct snd_akm4xxx akm_delta66e __devinitdata = {
+ .type = SND_AK4524,
+ .num_adcs = 4,
+ .num_dacs = 4,
+ .ops = {
+ .lock = delta66e_ak4524_lock,
+ .set_rate_val = delta_ak4524_set_rate_val
+ }
+};
+
+static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
+ .caddr = 2,
+ .cif = 0, /* the default level of the CIF pin from AK4524 */
+ .data_mask = ICE1712_DELTA_66E_DOUT,
+ .clk_mask = ICE1712_DELTA_66E_CCLK,
+ .cs_mask = 0,
+ .cs_addr = 0, /* set later */
+ .cs_none = 0,
+ .add_flags = 0,
+ .mask_flags = 0,
+};
+
+
static struct snd_akm4xxx akm_delta44 __devinitdata = {
.type = SND_AK4524,
.num_adcs = 4,
@@ -644,9 +689,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
break;
case ICE1712_SUBDEVICE_VX442:
- case ICE1712_SUBDEVICE_DELTA66E:
err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
+ break;
default:
snd_BUG();
return -EINVAL;
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 1a0ac6cd6501..11a9c3a76507 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
+/* M-Audio Delta 66 rev. E definitions.
+ * Newer revisions of Delta 66 have CS8427 over SPI for
+ * S/PDIF transceiver instead of CS8404/CS8414. */
+/* 0x01 = DFS */
+#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
+#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
+#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
+#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
+#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
+#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
+
/* Digigram VX442 definitions */
#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
#define ICE1712_VX442_DIN 0x04 /* data input */
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..bd67c0d7779c 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
-snd-hifier-objs := hifier.o
snd-oxygen-objs := oxygen.o
snd-virtuoso-objs := virtuoso.o xonar_lib.o \
xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
-obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * CMI8788:
- *
- * SPI 0 -> AK4396
- */
-
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include "oxygen.h"
-#include "ak4396.h"
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("TempoTec HiFier driver");
-MODULE_LICENSE("GPL v2");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-
-static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
- { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
- { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
- { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
- { }
-};
-MODULE_DEVICE_TABLE(pci, hifier_ids);
-
-struct hifier_data {
- u8 ak4396_regs[5];
-};
-
-static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
-{
- struct hifier_data *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (0 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
- AK4396_WRITE | (reg << 8) | value);
- data->ak4396_regs[reg] = value;
-}
-
-static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
-{
- struct hifier_data *data = chip->model_data;
-
- if (value != data->ak4396_regs[reg])
- ak4396_write(chip, reg, value);
-}
-
-static void hifier_registers_init(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
-
- ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
- ak4396_write(chip, AK4396_CONTROL_2,
- data->ak4396_regs[AK4396_CONTROL_2]);
- ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
- ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
- ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
-}
-
-static void hifier_init(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
-
- data->ak4396_regs[AK4396_CONTROL_2] =
- AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
- hifier_registers_init(chip);
-
- snd_component_add(chip->card, "AK4396");
- snd_component_add(chip->card, "CS5340");
-}
-
-static void hifier_cleanup(struct oxygen *chip)
-{
-}
-
-static void hifier_resume(struct oxygen *chip)
-{
- hifier_registers_init(chip);
-}
-
-static void set_ak4396_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct hifier_data *data = chip->model_data;
- u8 value;
-
- value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
- if (params_rate(params) <= 54000)
- value |= AK4396_DFS_NORMAL;
- else if (params_rate(params) <= 108000)
- value |= AK4396_DFS_DOUBLE;
- else
- value |= AK4396_DFS_QUAD;
-
- msleep(1); /* wait for the new MCLK to become stable */
-
- if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
- ak4396_write(chip, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB);
- ak4396_write(chip, AK4396_CONTROL_2, value);
- ak4396_write(chip, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB | AK4396_RSTN);
- }
-}
-
-static void update_ak4396_volume(struct oxygen *chip)
-{
- ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
- ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
-}
-
-static void update_ak4396_mute(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
- u8 value;
-
- value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
- if (chip->dac_mute)
- value |= AK4396_SMUTE;
- ak4396_write_cached(chip, AK4396_CONTROL_2, value);
-}
-
-static void set_cs5340_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
-}
-
-static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
-
-static const struct oxygen_model model_hifier = {
- .shortname = "C-Media CMI8787",
- .longname = "C-Media Oxygen HD Audio",
- .chip = "CMI8788",
- .init = hifier_init,
- .cleanup = hifier_cleanup,
- .resume = hifier_resume,
- .get_i2s_mclk = oxygen_default_i2s_mclk,
- .set_dac_params = set_ak4396_params,
- .set_adc_params = set_cs5340_params,
- .update_dac_volume = update_ak4396_volume,
- .update_dac_mute = update_ak4396_mute,
- .dac_tlv = ak4396_db_scale,
- .model_data_size = sizeof(struct hifier_data),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1,
- .dac_channels = 2,
- .dac_volume_min = 0,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_SPI,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static int __devinit get_hifier_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- chip->model = model_hifier;
- return 0;
-}
-
-static int __devinit hifier_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- ++dev;
- return -ENOENT;
- }
- err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
- hifier_ids, get_hifier_model);
- if (err >= 0)
- ++dev;
- return err;
-}
-
-static struct pci_driver hifier_driver = {
- .name = "CMI8787HiFier",
- .id_table = hifier_ids,
- .probe = hifier_probe,
- .remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
- .suspend = oxygen_pci_suspend,
- .resume = oxygen_pci_resume,
-#endif
-};
-
-static int __init alsa_card_hifier_init(void)
-{
- return pci_register_driver(&hifier_driver);
-}
-
-static void __exit alsa_card_hifier_exit(void)
-{
- pci_unregister_driver(&hifier_driver);
-}
-
-module_init(alsa_card_hifier_init)
-module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..dc47977becae 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -20,19 +20,25 @@
/*
* CMI8788:
*
- * SPI 0 -> 1st AK4396 (front)
- * SPI 1 -> 2nd AK4396 (surround)
- * SPI 2 -> 3rd AK4396 (center/LFE)
- * SPI 3 -> WM8785
- * SPI 4 -> 4th AK4396 (back)
+ * SPI 0 -> 1st AK4396 (front)
+ * SPI 1 -> 2nd AK4396 (surround)
+ * SPI 2 -> 3rd AK4396 (center/LFE)
+ * SPI 3 -> WM8785
+ * SPI 4 -> 4th AK4396 (back)
*
- * GPIO 0 -> DFS0 of AK5385
- * GPIO 1 -> DFS1 of AK5385
- * GPIO 8 -> enable headphone amplifier on HT-Omega models
+ * GPIO 0 -> DFS0 of AK5385
+ * GPIO 1 -> DFS1 of AK5385
+ * GPIO 8 -> enable headphone amplifier on HT-Omega models
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * CD_IN <- CD
+ * MIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
*/
#include <linux/delay.h>
@@ -41,6 +47,7 @@
#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -66,24 +73,35 @@ module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");
enum {
- MODEL_CMEDIA_REF, /* C-Media's reference design */
- MODEL_MERIDIAN, /* AuzenTech X-Meridian */
- MODEL_CLARO, /* HT-Omega Claro */
- MODEL_CLARO_HALO, /* HT-Omega Claro halo */
+ MODEL_CMEDIA_REF,
+ MODEL_MERIDIAN,
+ MODEL_CLARO,
+ MODEL_CLARO_HALO,
+ MODEL_FANTASIA,
+ MODEL_2CH_OUTPUT,
};
static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
+ /* C-Media's reference design */
{ OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
+ /* Kuroutoshikou CMI8787-HG2PCI */
+ { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT },
+ /* TempoTec HiFier Fantasia */
+ { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
+ /* TempoTec HiFier Serenade */
+ { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT },
+ /* AuzenTech X-Meridian */
{ OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
+ /* HT-Omega Claro */
{ OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
+ /* HT-Omega Claro halo */
{ OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
{ }
};
@@ -98,6 +116,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
#define GPIO_CLARO_HP 0x0100
struct generic_data {
+ unsigned int dacs;
u8 ak4396_regs[4][5];
u16 wm8785_regs[3];
};
@@ -148,7 +167,7 @@ static void ak4396_registers_init(struct oxygen *chip)
struct generic_data *data = chip->model_data;
unsigned int i;
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write(chip, i, AK4396_CONTROL_1,
AK4396_DIF_24_MSB | AK4396_RSTN);
ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +185,7 @@ static void ak4396_init(struct oxygen *chip)
{
struct generic_data *data = chip->model_data;
+ data->dacs = chip->model.dac_channels / 2;
data->ak4396_regs[0][AK4396_CONTROL_2] =
AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
ak4396_registers_init(chip);
@@ -232,6 +252,17 @@ static void claro_halo_init(struct oxygen *chip)
claro_enable_hp(chip);
}
+static void fantasia_init(struct oxygen *chip)
+{
+ ak4396_init(chip);
+ snd_component_add(chip->card, "CS5340");
+}
+
+static void stereo_output_init(struct oxygen *chip)
+{
+ ak4396_init(chip);
+}
+
static void generic_cleanup(struct oxygen *chip)
{
}
@@ -268,6 +299,11 @@ static void claro_resume(struct oxygen *chip)
claro_enable_hp(chip);
}
+static void stereo_resume(struct oxygen *chip)
+{
+ ak4396_registers_init(chip);
+}
+
static void set_ak4396_params(struct oxygen *chip,
struct snd_pcm_hw_params *params)
{
@@ -286,7 +322,7 @@ static void set_ak4396_params(struct oxygen *chip,
msleep(1); /* wait for the new MCLK to become stable */
if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write(chip, i, AK4396_CONTROL_1,
AK4396_DIF_24_MSB);
ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +334,10 @@ static void set_ak4396_params(struct oxygen *chip,
static void update_ak4396_volume(struct oxygen *chip)
{
+ struct generic_data *data = chip->model_data;
unsigned int i;
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write_cached(chip, i, AK4396_LCH_ATT,
chip->dac_volume[i * 2]);
ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +354,7 @@ static void update_ak4396_mute(struct oxygen *chip)
value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
if (chip->dac_mute)
value |= AK4396_SMUTE;
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < data->dacs; ++i)
ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
}
@@ -356,6 +393,10 @@ static void set_ak5385_params(struct oxygen *chip,
value, GPIO_AK5385_DFS_MASK);
}
+static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
+{
+}
+
static int rolloff_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -400,7 +441,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
reg &= ~AK4396_SLOW;
changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
if (changed) {
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < data->dacs; ++i)
ak4396_write(chip, i, AK4396_CONTROL_2, reg);
}
mutex_unlock(&chip->mutex);
@@ -484,6 +525,39 @@ static int generic_wm8785_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_ak4396_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct generic_data *data = chip->model_data;
+ unsigned int dac, i;
+
+ for (dac = 0; dac < data->dacs; ++dac) {
+ snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
+ for (i = 0; i < 5; ++i)
+ snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
+ }
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_wm8785_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct generic_data *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nWM8785:");
+ for (i = 0; i < 3; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_oxygen_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ dump_ak4396_registers(chip, buffer);
+ dump_wm8785_registers(chip, buffer);
+}
+
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
static const struct oxygen_model model_generic = {
@@ -499,6 +573,7 @@ static const struct oxygen_model model_generic = {
.set_adc_params = set_wm8785_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
+ .dump_registers = dump_oxygen_registers,
.dac_tlv = ak4396_db_scale,
.model_data_size = sizeof(struct generic_data),
.device_config = PLAYBACK_0_TO_I2S |
@@ -527,6 +602,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
chip->model.mixer_init = generic_mixer_init;
chip->model.resume = meridian_resume;
chip->model.set_adc_params = set_ak5385_params;
+ chip->model.dump_registers = dump_ak4396_registers;
chip->model.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
CAPTURE_0_FROM_I2S_2 |
@@ -545,11 +621,30 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
chip->model.suspend = claro_suspend;
chip->model.resume = claro_resume;
chip->model.set_adc_params = set_ak5385_params;
+ chip->model.dump_registers = dump_ak4396_registers;
chip->model.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
CAPTURE_0_FROM_I2S_2 |
CAPTURE_1_FROM_SPDIF;
break;
+ case MODEL_FANTASIA:
+ case MODEL_2CH_OUTPUT:
+ chip->model.shortname = "C-Media CMI8787";
+ chip->model.chip = "CMI8787";
+ if (id->driver_data == MODEL_FANTASIA)
+ chip->model.init = fantasia_init;
+ else
+ chip->model.init = stereo_output_init;
+ chip->model.resume = stereo_resume;
+ chip->model.mixer_init = generic_mixer_init;
+ chip->model.set_adc_params = set_no_params;
+ chip->model.dump_registers = dump_ak4396_registers;
+ chip->model.device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF;
+ if (id->driver_data == MODEL_FANTASIA)
+ chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
+ chip->model.dac_channels = 2;
+ break;
}
if (id->driver_data == MODEL_MERIDIAN ||
id->driver_data == MODEL_CLARO_HALO) {
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7d5222caa0a9..b8fbc15b89a3 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -35,6 +35,7 @@
#define MIDI_OUTPUT 0x0800
#define MIDI_INPUT 0x1000
#define AC97_CD_INPUT 0x2000
+#define AC97_FMIC_SWITCH 0x4000
enum {
CONTROL_SPDIF_PCM,
@@ -65,6 +66,7 @@ struct snd_pcm_hardware;
struct snd_pcm_hw_params;
struct snd_kcontrol_new;
struct snd_rawmidi;
+struct snd_info_buffer;
struct oxygen;
struct oxygen_model {
@@ -92,6 +94,8 @@ struct oxygen_model {
void (*uart_input)(struct oxygen *chip);
void (*ac97_switch)(struct oxygen *chip,
unsigned int reg, unsigned int mute);
+ void (*dump_registers)(struct oxygen *chip,
+ struct snd_info_buffer *buffer);
const unsigned int *dac_tlv;
unsigned long private_data;
size_t model_data_size;
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index e5ebe56fb0c5..c44c91e6fb18 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
struct oxygen *chip = entry->private_data;
int i, j;
- snd_iprintf(buffer, "CMI8788\n\n");
+ switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
+ case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
+ case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
+ case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
+ default: i = '?'; break;
+ }
+ snd_iprintf(buffer, "CMI878%c:\n", i);
for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; ++j)
@@ -212,7 +218,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
if (mutex_lock_interruptible(&chip->mutex) < 0)
return;
if (chip->has_ac97_0) {
- snd_iprintf(buffer, "\nAC97\n");
+ snd_iprintf(buffer, "\nAC97:\n");
for (i = 0; i < 0x80; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; j += 2)
@@ -222,7 +228,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
}
}
if (chip->has_ac97_1) {
- snd_iprintf(buffer, "\nAC97 2\n");
+ snd_iprintf(buffer, "\nAC97 2:\n");
for (i = 0; i < 0x80; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; j += 2)
@@ -232,13 +238,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
}
}
mutex_unlock(&chip->mutex);
+ if (chip->model.dump_registers)
+ chip->model.dump_registers(chip, buffer);
}
static void oxygen_proc_init(struct oxygen *chip)
{
struct snd_info_entry *entry;
- if (!snd_card_proc_new(chip->card, "cmi8788", &entry))
+ if (!snd_card_proc_new(chip->card, "oxygen", &entry))
snd_info_set_text_ops(entry, chip, oxygen_proc_read);
}
#else
@@ -262,7 +270,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
*/
subdevice = oxygen_read_eeprom(chip, 2);
/* use default ID if EEPROM is missing */
- if (subdevice == 0xffff)
+ if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
subdevice = 0x8788;
/*
* We use only the subsystem device ID for searching because it is
@@ -557,7 +565,8 @@ static void oxygen_card_free(struct snd_card *card)
oxygen_shutdown(chip);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
- flush_scheduled_work();
+ flush_work_sync(&chip->spdif_input_bits_work);
+ flush_work_sync(&chip->gpio_work);
chip->model.cleanup(chip);
kfree(chip->model_data);
mutex_destroy(&chip->mutex);
@@ -733,7 +742,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
spin_unlock_irq(&chip->reg_lock);
synchronize_irq(chip->irq);
- flush_scheduled_work();
+ flush_work_sync(&chip->spdif_input_bits_work);
+ flush_work_sync(&chip->gpio_work);
chip->interrupt_mask = saved_interrupt_mask;
pci_disable_device(pci);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7e..605e84b9e1ec 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -644,6 +644,51 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
return change;
}
+static int mic_fmic_source_info(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_info *info)
+{
+ static const char *const names[] = { "Mic Jack", "Front Panel" };
+
+ info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ info->count = 1;
+ info->value.enumerated.items = 2;
+ info->value.enumerated.item &= 1;
+ strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
+ return 0;
+}
+
+static int mic_fmic_source_get(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
+{
+ struct oxygen *chip = ctl->private_data;
+
+ mutex_lock(&chip->mutex);
+ value->value.enumerated.item[0] =
+ !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
+ mutex_unlock(&chip->mutex);
+ return 0;
+}
+
+static int mic_fmic_source_put(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
+{
+ struct oxygen *chip = ctl->private_data;
+ u16 oldreg, newreg;
+ int change;
+
+ mutex_lock(&chip->mutex);
+ oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
+ if (value->value.enumerated.item[0])
+ newreg = oldreg | CM9780_FMIC2MIC;
+ else
+ newreg = oldreg & ~CM9780_FMIC2MIC;
+ change = newreg != oldreg;
+ if (change)
+ oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
+ mutex_unlock(&chip->mutex);
+ return change;
+}
+
static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -908,6 +953,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Source Capture Enum",
+ .info = mic_fmic_source_info,
+ .get = mic_fmic_source_get,
+ .put = mic_fmic_source_put,
+ },
AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -972,6 +1024,9 @@ static int add_controls(struct oxygen *chip,
if (!strcmp(template.name, "Stereo Upmixing") &&
chip->model.dac_channels == 2)
continue;
+ if (!strcmp(template.name, "Mic Source Capture Enum") &&
+ !(chip->model.device_config & AC97_FMIC_SWITCH))
+ continue;
if (!strncmp(template.name, "CD Capture ", 11) &&
!(chip->model.device_config & AC97_CD_INPUT))
continue;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 814667442eb0..60e4aa00c042 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.rates = SNDRV_PCM_RATE_32000 |
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.rates = SNDRV_PCM_RATE_32000 |
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
@@ -530,7 +533,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- chip->interrupt_mask |= channel_mask;
+ if (substream->runtime->no_period_wakeup)
+ chip->interrupt_mask &= ~channel_mask;
+ else
+ chip->interrupt_mask |= channel_mask;
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
spin_unlock_irq(&chip->reg_lock);
return 0;
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index b35343b0a9a5..0434c207e811 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip);
void xonar_init_cs53x1(struct oxygen *chip);
void xonar_set_cs53x1_params(struct oxygen *chip,
struct snd_pcm_hw_params *params);
+
+#define XONAR_GPIO_BIT_INVERT (1 << 16)
int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
struct snd_ctl_elem_value *value);
int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index aa27c31049af..de32895b3172 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -22,29 +22,28 @@
*
* CMI8788:
*
- * I²C <-> CS4398 (front)
- * <-> CS4362A (surround, center/LFE, back)
+ * I²C <-> CS4398 (addr 1001111) (front)
+ * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
*
- * GPI 0 <- external power present (DX only)
+ * GPI 0 <- external power present (DX only)
*
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> enable front panel I/O
- * GPIO 2 -> M0 of CS5361
- * GPIO 3 -> M1 of CS5361
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable output to speakers
+ * GPIO 1 -> route output to front panel
+ * GPIO 2 -> M0 of CS5361
+ * GPIO 3 -> M1 of CS5361
+ * GPIO 6 -> ?
+ * GPIO 7 -> ?
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
- * CS4398:
- *
- * AD0 <- 1
- * AD1 <- 1
- *
- * CS4362A:
+ * CM9780:
*
- * AD0 <- 0
+ * LINE_OUT -> input of ADC
*
- * CM9780:
+ * AUX_IN <- aux
+ * MIC_IN <- mic
+ * FMIC_IN <- front mic
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
*/
#include <linux/pci.h>
@@ -63,6 +62,7 @@
#define GPI_EXT_POWER 0x01
#define GPIO_D1_OUTPUT_ENABLE 0x0001
#define GPIO_D1_FRONT_PANEL 0x0002
+#define GPIO_D1_MAGIC 0x00c0
#define GPIO_D1_INPUT_ROUTE 0x0100
#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
@@ -169,12 +169,12 @@ static void xonar_d1_init(struct oxygen *chip)
cs43xx_registers_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
+ GPIO_D1_FRONT_PANEL |
+ GPIO_D1_MAGIC |
+ GPIO_D1_INPUT_ROUTE);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
- oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
-
xonar_init_cs53x1(chip);
xonar_enable_output(chip);
@@ -284,7 +284,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
static const struct snd_kcontrol_new front_panel_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Panel Switch",
+ .name = "Front Panel Playback Switch",
.info = snd_ctl_boolean_mono_info,
.get = xonar_gpio_bit_switch_get,
.put = xonar_gpio_bit_switch_put,
@@ -380,6 +380,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_cs4362a_registers(struct xonar_cs43xx *data,
+ struct snd_info_buffer *buffer)
+{
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nCS4362A:");
+ for (i = 1; i <= 14; ++i)
+ snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_d1_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_cs43xx *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nCS4398: 7?");
+ for (i = 2; i <= 8; ++i)
+ snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
+ snd_iprintf(buffer, "\n");
+ dump_cs4362a_registers(data, buffer);
+}
+
static const struct oxygen_model model_xonar_d1 = {
.longname = "Asus Virtuoso 100",
.chip = "AV200",
@@ -395,11 +419,13 @@ static const struct oxygen_model model_xonar_d1 = {
.update_dac_mute = update_cs43xx_mute,
.update_center_lfe_mix = update_cs43xx_center_lfe_mix,
.ac97_switch = xonar_d1_line_mic_ac97_switch,
+ .dump_registers = dump_d1_registers,
.dac_tlv = cs4362a_db_scale,
.model_data_size = sizeof(struct xonar_cs43xx),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
+ CAPTURE_0_FROM_I2S_2 |
+ AC97_FMIC_SWITCH,
.dac_channels = 8,
.dac_volume_min = 127 - 60,
.dac_volume_max = 127,
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index b3ff71316653..0ebe7f5916f9 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
u16 bit = ctl->private_value;
+ bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
value->value.integer.value[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
+ !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
return 0;
}
@@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
u16 bit = ctl->private_value;
+ bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
u16 old_bits, new_bits;
int changed;
spin_lock_irq(&chip->reg_lock);
old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- if (value->value.integer.value[0])
+ if (!!value->value.integer.value[0] ^ invert)
new_bits = old_bits | bit;
else
new_bits = old_bits & ~bit;
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index d491fd6c0be2..bf357c01afd2 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -22,20 +22,26 @@
*
* CMI8788:
*
- * SPI 0 -> 1st PCM1796 (front)
- * SPI 1 -> 2nd PCM1796 (surround)
- * SPI 2 -> 3rd PCM1796 (center/LFE)
- * SPI 4 -> 4th PCM1796 (back)
+ * SPI 0 -> 1st PCM1796 (front)
+ * SPI 1 -> 2nd PCM1796 (surround)
+ * SPI 2 -> 3rd PCM1796 (center/LFE)
+ * SPI 4 -> 4th PCM1796 (back)
*
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 5 <- external power present (D2X only)
- * GPIO 7 -> ALT
- * GPIO 8 -> enable output to speakers
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 5 <- external power present (D2X only)
+ * GPIO 7 -> ALT
+ * GPIO 8 -> enable output to speakers
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * VIDEO_IN <- CD
+ * FMIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*/
/*
@@ -44,52 +50,53 @@
*
* CMI8788:
*
- * I²C <-> PCM1796 (front)
+ * I²C <-> PCM1796 (addr 1001100) (front)
*
- * GPI 0 <- external power present
+ * GPI 0 <- external power present
*
- * GPIO 0 -> enable output to speakers
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable HDMI (0) or speaker (1) output
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 <- daughterboard detection
+ * GPIO 5 <- daughterboard detection
+ * GPIO 6 -> ?
+ * GPIO 7 -> ?
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
- * TXD -> HDMI controller
- * RXD <- HDMI controller
- *
- * PCM1796 front: AD1,0 <- 0,0
+ * UART <-> HDMI controller
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * CD_IN <- CD
+ * MIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*
* no daughterboard
* ----------------
*
- * GPIO 4 <- 1
+ * GPIO 4 <- 1
*
* H6 daughterboard
* ----------------
*
- * GPIO 4 <- 0
- * GPIO 5 <- 0
+ * GPIO 4 <- 0
+ * GPIO 5 <- 0
*
- * I²C <-> PCM1796 (surround)
- * <-> PCM1796 (center/LFE)
- * <-> PCM1796 (back)
- *
- * PCM1796 surround: AD1,0 <- 0,1
- * PCM1796 center/LFE: AD1,0 <- 1,0
- * PCM1796 back: AD1,0 <- 1,1
+ * I²C <-> PCM1796 (addr 1001101) (surround)
+ * <-> PCM1796 (addr 1001110) (center/LFE)
+ * <-> PCM1796 (addr 1001111) (back)
*
* unknown daughterboard
* ---------------------
*
- * GPIO 4 <- 0
- * GPIO 5 <- 1
- *
- * I²C <-> CS4362A (surround, center/LFE, back)
+ * GPIO 4 <- 0
+ * GPIO 5 <- 1
*
- * CS4362A: AD0 <- 0
+ * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
*/
/*
@@ -98,32 +105,35 @@
*
* CMI8788:
*
- * I²C <-> PCM1792A
- * <-> CS2000 (ST only)
+ * I²C <-> PCM1792A (addr 1001100)
+ * <-> CS2000 (addr 1001110) (ST only)
*
- * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
+ * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
*
- * GPI 0 <- external power present (STX only)
+ * GPI 0 <- external power present (STX only)
*
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> route HP to front panel (0) or rear jack (1)
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 7 -> route output to speaker jacks (0) or HP (1)
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable output to speakers
+ * GPIO 1 -> route HP to front panel (0) or rear jack (1)
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 <- daughterboard detection
+ * GPIO 5 <- daughterboard detection
+ * GPIO 6 -> ?
+ * GPIO 7 -> route output to speaker jacks (0) or HP (1)
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
* PCM1792A:
*
- * AD1,0 <- 0,0
- * SCK <- CLK_OUT of CS2000 (ST only)
+ * SCK <- CLK_OUT of CS2000 (ST only)
*
- * CS2000:
+ * CM9780:
*
- * AD0 <- 0
+ * LINE_OUT -> input of ADC
*
- * CM9780:
+ * AUX_IN <- aux
+ * MIC_IN <- mic
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*
* H6 daughterboard
* ----------------
@@ -133,15 +143,39 @@
*/
/*
- * Xonar HDAV1.3 Slim
- * ------------------
+ * Xonar Xense
+ * -----------
*
* CMI8788:
*
- * GPIO 1 -> enable output
+ * I²C <-> PCM1796 (addr 1001100) (front)
+ * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
+ * <-> CS2000 (addr 1001110)
+ *
+ * ADC1 MCLK -> REF_CLK of CS2000
*
- * TXD -> HDMI controller
- * RXD <- HDMI controller
+ * GPI 0 <- external power present
+ *
+ * GPIO 0 -> enable output
+ * GPIO 1 -> route HP to front panel (0) or rear jack (1)
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 -> enable output
+ * GPIO 5 -> enable output
+ * GPIO 6 -> ?
+ * GPIO 7 -> route output to HP (0) or speaker (1)
+ * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
+ *
+ * CM9780:
+ *
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * VIDEO_IN <- ?
+ * FMIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
*/
#include <linux/pci.h>
@@ -150,6 +184,7 @@
#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
@@ -167,12 +202,14 @@
#define GPIO_INPUT_ROUTE 0x0100
#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
+#define GPIO_HDAV_MAGIC 0x00c0
#define GPIO_DB_MASK 0x0030
#define GPIO_DB_H6 0x0000
#define GPIO_ST_OUTPUT_ENABLE 0x0001
#define GPIO_ST_HP_REAR 0x0002
+#define GPIO_ST_MAGIC 0x0040
#define GPIO_ST_HP 0x0080
#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
@@ -190,7 +227,7 @@ struct xonar_pcm179x {
bool hp_active;
s8 hp_gain_offset;
bool has_cs2000;
- u8 cs2000_fun_cfg_1;
+ u8 cs2000_regs[0x1f];
};
struct xonar_hdav {
@@ -249,16 +286,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
struct xonar_pcm179x *data = chip->model_data;
oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
- if (reg == CS2000_FUN_CFG_1)
- data->cs2000_fun_cfg_1 = value;
+ data->cs2000_regs[reg] = value;
}
static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
{
struct xonar_pcm179x *data = chip->model_data;
- if (reg != CS2000_FUN_CFG_1 ||
- value != data->cs2000_fun_cfg_1)
+ if (value != data->cs2000_regs[reg])
cs2000_write(chip, reg, value);
}
@@ -350,7 +385,8 @@ static void xonar_hdav_init(struct oxygen *chip)
pcm1796_init(chip);
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
+ GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
xonar_init_cs53x1(chip);
@@ -381,7 +417,8 @@ static void xonar_st_init_common(struct oxygen *chip)
pcm1796_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
+ GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
+ GPIO_ST_MAGIC | GPIO_ST_HP);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
@@ -410,7 +447,8 @@ static void cs2000_registers_init(struct oxygen *chip)
cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
- cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1);
+ cs2000_write(chip, CS2000_FUN_CFG_1,
+ data->cs2000_regs[CS2000_FUN_CFG_1]);
cs2000_write(chip, CS2000_FUN_CFG_2, 0);
cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
}
@@ -421,7 +459,7 @@ static void xonar_st_init(struct oxygen *chip)
data->generic.anti_pop_delay = 100;
data->has_cs2000 = 1;
- data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1;
+ data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S |
@@ -772,6 +810,15 @@ static const struct snd_kcontrol_new os_128_control = {
.put = os_128_put,
};
+static const struct snd_kcontrol_new hdav_hdmi_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Playback Switch",
+ .info = snd_ctl_boolean_mono_info,
+ .get = xonar_gpio_bit_switch_get,
+ .put = xonar_gpio_bit_switch_put,
+ .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
+};
+
static int st_output_switch_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -956,7 +1003,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip)
static int xonar_hdav_mixer_init(struct oxygen *chip)
{
- return add_pcm1796_controls(chip);
+ int err;
+
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
+ if (err < 0)
+ return err;
+ err = add_pcm1796_controls(chip);
+ if (err < 0)
+ return err;
+ return 0;
}
static int xonar_st_mixer_init(struct oxygen *chip)
@@ -976,6 +1031,45 @@ static int xonar_st_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_pcm1796_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_pcm179x *data = chip->model_data;
+ unsigned int dac, i;
+
+ for (dac = 0; dac < data->dacs; ++dac) {
+ snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
+ for (i = 0; i < 5; ++i)
+ snd_iprintf(buffer, " %02x",
+ data->pcm1796_regs[dac][i]);
+ }
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_cs2000_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_pcm179x *data = chip->model_data;
+ unsigned int i;
+
+ if (data->has_cs2000) {
+ snd_iprintf(buffer, "\nCS2000:\n00: ");
+ for (i = 1; i < 0x10; ++i)
+ snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
+ snd_iprintf(buffer, "\n10:");
+ for (i = 0x10; i < 0x1f; ++i)
+ snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
+ snd_iprintf(buffer, "\n");
+ }
+}
+
+static void dump_st_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ dump_pcm1796_registers(chip, buffer);
+ dump_cs2000_registers(chip, buffer);
+}
+
static const struct oxygen_model model_xonar_d2 = {
.longname = "Asus Virtuoso 200",
.chip = "AV200",
@@ -990,6 +1084,7 @@ static const struct oxygen_model model_xonar_d2 = {
.set_adc_params = xonar_set_cs53x1_params,
.update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute,
+ .dump_registers = dump_pcm1796_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_pcm179x),
.device_config = PLAYBACK_0_TO_I2S |
@@ -1025,6 +1120,7 @@ static const struct oxygen_model model_xonar_hdav = {
.update_dac_mute = update_pcm1796_mute,
.uart_input = xonar_hdmi_uart_input,
.ac97_switch = xonar_line_mic_ac97_switch,
+ .dump_registers = dump_pcm1796_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_hdav),
.device_config = PLAYBACK_0_TO_I2S |
@@ -1054,11 +1150,13 @@ static const struct oxygen_model model_xonar_st = {
.update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute,
.ac97_switch = xonar_line_mic_ac97_switch,
+ .dump_registers = dump_st_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_pcm179x),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
+ CAPTURE_0_FROM_I2S_2 |
+ AC97_FMIC_SWITCH,
.dac_channels = 2,
.dac_volume_min = 255 - 2*60,
.dac_volume_max = 255,
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 200f7601276f..1705d1e93115 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -22,26 +22,48 @@
*
* CMI8788:
*
- * SPI 0 -> WM8766 (surround, center/LFE, back)
- * SPI 1 -> WM8776 (front, input)
+ * SPI 0 -> WM8766 (surround, center/LFE, back)
+ * SPI 1 -> WM8776 (front, input)
*
- * GPIO 4 <- headphone detect, 0 = plugged
- * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
- * GPIO 7 -> enable output to front L/R speaker channels
- * GPIO 8 -> enable output to other speaker channels and front panel headphone
+ * GPIO 4 <- headphone detect, 0 = plugged
+ * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
+ * GPIO 7 -> enable output to front L/R speaker channels
+ * GPIO 8 -> enable output to other speaker channels and front panel headphone
*
- * WM8766:
+ * WM8776:
*
- * input 1 <- line
- * input 2 <- mic
- * input 3 <- front mic
- * input 4 <- aux
+ * input 1 <- line
+ * input 2 <- mic
+ * input 3 <- front mic
+ * input 4 <- aux
+ */
+
+/*
+ * Xonar HDAV1.3 Slim
+ * ------------------
+ *
+ * CMI8788:
+ *
+ * I²C <-> WM8776 (addr 0011010)
+ *
+ * GPIO 0 -> disable HDMI output
+ * GPIO 1 -> enable HP output
+ * GPIO 6 -> firmware EEPROM I²C clock
+ * GPIO 7 <-> firmware EEPROM I²C data
+ *
+ * UART <-> HDMI controller
+ *
+ * WM8776:
+ *
+ * input 1 <- mic
+ * input 2 <- aux
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -1062,6 +1084,34 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_wm8776_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_wm87x6 *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nWM8776:\n00:");
+ for (i = 0; i < 0x10; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
+ snd_iprintf(buffer, "\n10:");
+ for (i = 0x10; i < 0x17; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_wm87x6_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_wm87x6 *data = chip->model_data;
+ unsigned int i;
+
+ dump_wm8776_registers(chip, buffer);
+ snd_iprintf(buffer, "\nWM8766:\n00:");
+ for (i = 0; i < 0x10; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
static const struct oxygen_model model_xonar_ds = {
.shortname = "Xonar DS",
.longname = "Asus Virtuoso 66",
@@ -1079,6 +1129,7 @@ static const struct oxygen_model model_xonar_ds = {
.update_dac_mute = update_wm87x6_mute,
.update_center_lfe_mix = update_wm8766_center_lfe_mix,
.gpio_changed = xonar_ds_gpio_changed,
+ .dump_registers = dump_wm87x6_registers,
.dac_tlv = wm87x6_dac_db_scale,
.model_data_size = sizeof(struct xonar_wm87x6),
.device_config = PLAYBACK_0_TO_I2S |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0b720cf7783e..2d8332416c83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
"{RME HDSP-9652},"
"{RME HDSP-9632}}");
#ifdef HDSP_FW_LOADER
+MODULE_FIRMWARE("rpm_firmware.bin");
MODULE_FIRMWARE("multiface_firmware.bin");
MODULE_FIRMWARE("multiface_firmware_rev11.bin");
MODULE_FIRMWARE("digiface_firmware.bin");
@@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define H9632_SS_CHANNELS 12
#define H9632_DS_CHANNELS 8
#define H9632_QS_CHANNELS 4
+#define RPM_CHANNELS 6
/* Write registers. These are defined as byte-offsets from the iobase value.
*/
@@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_PhoneGain1 (1<<30)
#define HDSP_QuadSpeed (1<<31)
+/* RPM uses some of the registers for special purposes */
+#define HDSP_RPM_Inp12 0x04A00
+#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
+#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
+#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
+#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
+#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
+
+#define HDSP_RPM_Inp34 0x32000
+#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
+#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
+#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
+#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
+#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
+
+#define HDSP_RPM_Bypass 0x01000
+
+#define HDSP_RPM_Disconnect 0x00001
+
#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
@@ -450,7 +471,7 @@ struct hdsp {
u32 creg_spdif;
u32 creg_spdif_stream;
int clock_source_locked;
- char *card_name; /* digiface/multiface */
+ char *card_name; /* digiface/multiface/rpm */
enum HDSP_IO_Type io_type; /* ditto, but for code use */
unsigned short firmware_rev;
unsigned short state; /* stores state bits */
@@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
switch (hdsp->io_type) {
case Multiface:
case Digiface:
+ case RPM:
default:
if (hdsp->firmware_rev == 0xa)
return (64 * out) + (32 + (in));
@@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
switch (hdsp->io_type) {
case Multiface:
case Digiface:
+ case RPM:
default:
if (hdsp->firmware_rev == 0xa)
return (64 * out) + in;
@@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp)
{
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
- snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n");
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
return -EIO;
}
@@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
}
}
- snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n");
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
return -EIO;
}
@@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) {
- hdsp->io_type = Multiface;
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT);
+ if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
+ hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
+ hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+ if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
+ hdsp->io_type = RPM;
+ else
+ hdsp->io_type = Multiface;
} else {
hdsp->io_type = Digiface;
}
} else {
/* firmware was already loaded, get iobox type */
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
+ hdsp->io_type = RPM;
+ else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
else
hdsp->io_type = Digiface;
@@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
hdsp->channel_map = channel_map_ds;
} else {
switch (hdsp->io_type) {
+ case RPM:
case Multiface:
hdsp->channel_map = channel_map_mf_ss;
break;
@@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0),
HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
};
+
+static int hdsp_rpm_input12(struct hdsp *hdsp)
+{
+ switch (hdsp->control_register & HDSP_RPM_Inp12) {
+ case HDSP_RPM_Inp12_Phon_6dB:
+ return 0;
+ case HDSP_RPM_Inp12_Phon_n6dB:
+ return 2;
+ case HDSP_RPM_Inp12_Line_0dB:
+ return 3;
+ case HDSP_RPM_Inp12_Line_n6dB:
+ return 4;
+ }
+ return 1;
+}
+
+
+static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
+{
+ hdsp->control_register &= ~HDSP_RPM_Inp12;
+ switch (mode) {
+ case 0:
+ hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
+ break;
+ case 1:
+ break;
+ case 2:
+ hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
+ break;
+ case 3:
+ hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
+ break;
+ case 4:
+ hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
+ break;
+ default:
+ return -1;
+ }
+
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.enumerated.item[0];
+ if (val < 0)
+ val = 0;
+ if (val > 4)
+ val = 4;
+ spin_lock_irq(&hdsp->lock);
+ if (val != hdsp_rpm_input12(hdsp))
+ change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
+ else
+ change = 0;
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 5;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+
+static int hdsp_rpm_input34(struct hdsp *hdsp)
+{
+ switch (hdsp->control_register & HDSP_RPM_Inp34) {
+ case HDSP_RPM_Inp34_Phon_6dB:
+ return 0;
+ case HDSP_RPM_Inp34_Phon_n6dB:
+ return 2;
+ case HDSP_RPM_Inp34_Line_0dB:
+ return 3;
+ case HDSP_RPM_Inp34_Line_n6dB:
+ return 4;
+ }
+ return 1;
+}
+
+
+static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
+{
+ hdsp->control_register &= ~HDSP_RPM_Inp34;
+ switch (mode) {
+ case 0:
+ hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
+ break;
+ case 1:
+ break;
+ case 2:
+ hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
+ break;
+ case 3:
+ hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
+ break;
+ case 4:
+ hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
+ break;
+ default:
+ return -1;
+ }
+
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.enumerated.item[0];
+ if (val < 0)
+ val = 0;
+ if (val > 4)
+ val = 4;
+ spin_lock_irq(&hdsp->lock);
+ if (val != hdsp_rpm_input34(hdsp))
+ change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
+ else
+ change = 0;
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+/* RPM Bypass switch */
+static int hdsp_rpm_bypass(struct hdsp *hdsp)
+{
+ return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
+}
+
+
+static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
+{
+ if (on)
+ hdsp->control_register |= HDSP_RPM_Bypass;
+ else
+ hdsp->control_register &= ~HDSP_RPM_Bypass;
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ unsigned int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.integer.value[0] & 1;
+ spin_lock_irq(&hdsp->lock);
+ change = (int)val != hdsp_rpm_bypass(hdsp);
+ hdsp_set_rpm_bypass(hdsp, val);
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"On", "Off"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+
+/* RPM Disconnect switch */
+static int hdsp_rpm_disconnect(struct hdsp *hdsp)
+{
+ return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
+}
+
+
+static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
+{
+ if (on)
+ hdsp->control_register |= HDSP_RPM_Disconnect;
+ else
+ hdsp->control_register &= ~HDSP_RPM_Disconnect;
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ unsigned int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.integer.value[0] & 1;
+ spin_lock_irq(&hdsp->lock);
+ change = (int)val != hdsp_rpm_disconnect(hdsp);
+ hdsp_set_rpm_disconnect(hdsp, val);
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"On", "Off"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "RPM Bypass",
+ .get = snd_hdsp_get_rpm_bypass,
+ .put = snd_hdsp_put_rpm_bypass,
+ .info = snd_hdsp_info_rpm_bypass
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "RPM Disconnect",
+ .get = snd_hdsp_get_rpm_disconnect,
+ .put = snd_hdsp_put_rpm_disconnect,
+ .info = snd_hdsp_info_rpm_disconnect
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Input 1/2",
+ .get = snd_hdsp_get_rpm_input12,
+ .put = snd_hdsp_put_rpm_input12,
+ .info = snd_hdsp_info_rpm_input
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Input 3/4",
+ .get = snd_hdsp_get_rpm_input34,
+ .put = snd_hdsp_put_rpm_input34,
+ .info = snd_hdsp_info_rpm_input
+ },
+ HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
+ HDSP_MIXER("Mixer", 0)
+};
+
static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
@@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
int err;
struct snd_kcontrol *kctl;
+ if (hdsp->io_type == RPM) {
+ /* RPM Bypass, Disconnect and Input switches */
+ for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
+ err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+ }
+
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
return err;
@@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
snd_iprintf(buffer, "\n");
- switch (hdsp_spdif_in(hdsp)) {
- case HDSP_SPDIFIN_OPTICAL:
- snd_iprintf(buffer, "IEC958 input: Optical\n");
- break;
- case HDSP_SPDIFIN_COAXIAL:
- snd_iprintf(buffer, "IEC958 input: Coaxial\n");
- break;
- case HDSP_SPDIFIN_INTERNAL:
- snd_iprintf(buffer, "IEC958 input: Internal\n");
- break;
- case HDSP_SPDIFIN_AES:
- snd_iprintf(buffer, "IEC958 input: AES\n");
- break;
- default:
- snd_iprintf(buffer, "IEC958 input: ???\n");
- break;
+ if (hdsp->io_type != RPM) {
+ switch (hdsp_spdif_in(hdsp)) {
+ case HDSP_SPDIFIN_OPTICAL:
+ snd_iprintf(buffer, "IEC958 input: Optical\n");
+ break;
+ case HDSP_SPDIFIN_COAXIAL:
+ snd_iprintf(buffer, "IEC958 input: Coaxial\n");
+ break;
+ case HDSP_SPDIFIN_INTERNAL:
+ snd_iprintf(buffer, "IEC958 input: Internal\n");
+ break;
+ case HDSP_SPDIFIN_AES:
+ snd_iprintf(buffer, "IEC958 input: AES\n");
+ break;
+ default:
+ snd_iprintf(buffer, "IEC958 input: ???\n");
+ break;
+ }
}
- if (hdsp->control_register & HDSP_SPDIFOpticalOut)
- snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- else
- snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
+ if (RPM == hdsp->io_type) {
+ if (hdsp->control_register & HDSP_RPM_Bypass)
+ snd_iprintf(buffer, "RPM Bypass: disabled\n");
+ else
+ snd_iprintf(buffer, "RPM Bypass: enabled\n");
+ if (hdsp->control_register & HDSP_RPM_Disconnect)
+ snd_iprintf(buffer, "RPM disconnected\n");
+ else
+ snd_iprintf(buffer, "RPM connected\n");
- if (hdsp->control_register & HDSP_SPDIFProfessional)
- snd_iprintf(buffer, "IEC958 quality: Professional\n");
- else
- snd_iprintf(buffer, "IEC958 quality: Consumer\n");
+ switch (hdsp->control_register & HDSP_RPM_Inp12) {
+ case HDSP_RPM_Inp12_Phon_6dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
+ break;
+ case HDSP_RPM_Inp12_Phon_0dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
+ break;
+ case HDSP_RPM_Inp12_Phon_n6dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
+ break;
+ case HDSP_RPM_Inp12_Line_0dB:
+ snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
+ break;
+ case HDSP_RPM_Inp12_Line_n6dB:
+ snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
+ break;
+ default:
+ snd_iprintf(buffer, "Input 1/2: ???\n");
+ }
- if (hdsp->control_register & HDSP_SPDIFEmphasis)
- snd_iprintf(buffer, "IEC958 emphasis: on\n");
- else
- snd_iprintf(buffer, "IEC958 emphasis: off\n");
+ switch (hdsp->control_register & HDSP_RPM_Inp34) {
+ case HDSP_RPM_Inp34_Phon_6dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
+ break;
+ case HDSP_RPM_Inp34_Phon_0dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
+ break;
+ case HDSP_RPM_Inp34_Phon_n6dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
+ break;
+ case HDSP_RPM_Inp34_Line_0dB:
+ snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
+ break;
+ case HDSP_RPM_Inp34_Line_n6dB:
+ snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
+ break;
+ default:
+ snd_iprintf(buffer, "Input 3/4: ???\n");
+ }
- if (hdsp->control_register & HDSP_SPDIFNonAudio)
- snd_iprintf(buffer, "IEC958 NonAudio: on\n");
- else
- snd_iprintf(buffer, "IEC958 NonAudio: off\n");
- if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
- snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
- else
- snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
+ } else {
+ if (hdsp->control_register & HDSP_SPDIFOpticalOut)
+ snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
+ else
+ snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
+
+ if (hdsp->control_register & HDSP_SPDIFProfessional)
+ snd_iprintf(buffer, "IEC958 quality: Professional\n");
+ else
+ snd_iprintf(buffer, "IEC958 quality: Consumer\n");
+
+ if (hdsp->control_register & HDSP_SPDIFEmphasis)
+ snd_iprintf(buffer, "IEC958 emphasis: on\n");
+ else
+ snd_iprintf(buffer, "IEC958 emphasis: off\n");
+ if (hdsp->control_register & HDSP_SPDIFNonAudio)
+ snd_iprintf(buffer, "IEC958 NonAudio: on\n");
+ else
+ snd_iprintf(buffer, "IEC958 NonAudio: off\n");
+ x = hdsp_spdif_sample_rate(hdsp);
+ if (x != 0)
+ snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
+ else
+ snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
+ }
snd_iprintf(buffer, "\n");
/* Sync Check */
@@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
snd_hdsp_midi_input_read (&hdsp->midi[0]);
}
}
- if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) {
+ if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
if (hdsp->use_midi_tasklet) {
/* we disable interrupts for this input until processing is done */
hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
@@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
SNDRV_PCM_RATE_96000),
.rate_min = 32000,
.rate_max = 96000,
- .channels_min = 14,
+ .channels_min = 6,
.channels_max = HDSP_MAX_CHANNELS,
.buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
.period_bytes_min = (64 * 4) * 10,
@@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
SNDRV_PCM_RATE_96000),
.rate_min = 32000,
.rate_max = 96000,
- .channels_min = 14,
+ .channels_min = 5,
.channels_max = HDSP_MAX_CHANNELS,
.buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
.period_bytes_min = (64 * 4) * 10,
@@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
snd_hdsp_hw_rule_rate_out_channels, hdsp,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- hdsp->creg_spdif_stream = hdsp->creg_spdif;
- hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ if (RPM != hdsp->io_type) {
+ hdsp->creg_spdif_stream = hdsp->creg_spdif;
+ hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ }
return 0;
}
@@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
spin_unlock_irq(&hdsp->lock);
- hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ if (RPM != hdsp->io_type) {
+ hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ }
return 0;
}
@@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
if (hdsp->io_type != H9632)
info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
+ for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
@@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
+ } else if (hdsp->io_type == RPM) {
+ info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
+ info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
}
if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
@@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
break;
+ case RPM:
+ hdsp->card_name = "RME Hammerfall DSP + RPM";
+ hdsp->ss_in_channels = RPM_CHANNELS-1;
+ hdsp->ss_out_channels = RPM_CHANNELS;
+ hdsp->ds_in_channels = RPM_CHANNELS-1;
+ hdsp->ds_out_channels = RPM_CHANNELS;
+ break;
+
default:
/* should never get here */
break;
@@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
/* caution: max length of firmware filename is 30! */
switch (hdsp->io_type) {
+ case RPM:
+ fwfile = "rpm_firmware.bin";
+ break;
case Multiface:
if (hdsp->firmware_rev == 0xa)
fwfile = "multiface_firmware.bin";
@@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
return 0;
} else {
snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
+ hdsp->io_type = RPM;
+ else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
else
hdsp->io_type = Digiface;
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3e598e756e54..21a5465ceb65 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -4,6 +4,8 @@
menuconfig SND_SOC
tristate "ALSA for SoC audio support"
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
select SND_PCM
select AC97_BUS if SND_SOC_AC97_BUS
select SND_JACK if INPUT=y || INPUT=SND
@@ -36,7 +38,7 @@ source "sound/soc/nuc900/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/kirkwood/Kconfig"
source "sound/soc/pxa/Kconfig"
-source "sound/soc/s3c24xx/Kconfig"
+source "sound/soc/samsung/Kconfig"
source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/txx9/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index eb183443eee4..ce913bf5213c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
obj-$(CONFIG_SND_SOC) += omap/
obj-$(CONFIG_SND_SOC) += kirkwood/
obj-$(CONFIG_SND_SOC) += pxa/
-obj-$(CONFIG_SND_SOC) += s3c24xx/
+obj-$(CONFIG_SND_SOC) += samsung/
obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 5f4e59f4461c..1aac2f4dbcf6 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -33,7 +33,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/at32ap700x.h>
#include <mach/portmux.h>
@@ -318,27 +317,28 @@ static const struct snd_soc_dapm_route intercon[] = {
static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
/*
* Add DAPM widgets
*/
for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
- snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]);
+ snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]);
/*
* Setup audio path interconnects
*/
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
/* always connected pins */
- snd_soc_dapm_enable_pin(codec, "Int Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_sync(dapm);
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index e521ada80542..af3c73053ee4 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -44,7 +44,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -140,6 +139,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
printk(KERN_DEBUG
@@ -154,25 +154,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
}
/* Add specific widgets */
- snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
/* Set up specific audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
/* not connected */
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
#ifdef ENABLE_MIC_INPUT
- snd_soc_dapm_enable_pin(codec, "Int Mic");
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
#else
- snd_soc_dapm_nc_pin(codec, "Int Mic");
+ snd_soc_dapm_nc_pin(dapm, "Int Mic");
#endif
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 86e0f8586dc3..da2208e06b0d 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -105,19 +104,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add afeb9260 specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up afeb9260 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index b62fcd33e586..cb99f04abe88 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -13,7 +13,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 2394bff2b655..83012da9dfc2 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -20,7 +20,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index e4a625317a1a..d3ccb926b5e4 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -29,7 +29,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 900ced54ac79..732fb8bad076 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -35,7 +35,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 36f2769eb912..e902b24c1856 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -33,7 +33,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/dma.h>
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 01d19e9f53f9..08e15dee9182 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <sound/jack.h>
@@ -1172,7 +1171,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable Audio PLL & Audio section */
data = AUDIO_PLL | AUDIO_SECTION_RESET
| AUDIO_SECTION_ON;
@@ -1185,7 +1184,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1346,6 +1345,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
static int pm860x_probe(struct snd_soc_codec *codec)
{
struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i, ret;
pm860x->codec = codec;
@@ -1358,7 +1358,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
pm860x->name[i], pm860x);
if (ret < 0) {
dev_err(codec->dev, "Failed to request IRQ!\n");
- goto out_irq;
+ goto out;
}
}
@@ -1369,22 +1369,20 @@ static int pm860x_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "Failed to fill register cache: %d\n",
ret);
- goto out_codec;
+ goto out;
}
snd_soc_add_controls(codec, pm860x_snd_controls,
ARRAY_SIZE(pm860x_snd_controls));
- snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
ARRAY_SIZE(pm860x_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
-out_codec:
- i = 3;
-out_irq:
- for (; i >= 0; i--)
+out:
+ while (--i >= 0)
free_irq(pm860x->irq[i], pm860x);
- return -EINVAL;
+ return ret;
}
static int pm860x_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3b5690d28b8b..0f33db2be25a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4535 if I2C
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
+ select SND_SOC_ALC5623 if I2C
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CS42L51 if I2C
select SND_SOC_CS4270 if I2C
@@ -54,9 +55,11 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8727
select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
+ select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
+ select SND_SOC_WM8770 if SPI_MASTER
select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
@@ -130,6 +133,9 @@ config SND_SOC_AK4642
config SND_SOC_AK4671
tristate
+config SND_SOC_ALC5623
+ tristate
+
config SND_SOC_CQ0093VC
tristate
@@ -231,6 +237,9 @@ config SND_SOC_WM8728
config SND_SOC_WM8731
tristate
+config SND_SOC_WM8737
+ tristate
+
config SND_SOC_WM8741
tristate
@@ -240,6 +249,9 @@ config SND_SOC_WM8750
config SND_SOC_WM8753
tristate
+config SND_SOC_WM8770
+ tristate
+
config SND_SOC_WM8776
tristate
@@ -318,3 +330,4 @@ config SND_SOC_WM2000
config SND_SOC_WM9090
tristate
+
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f67a2d6f7a46..10e5e099334a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -17,6 +17,7 @@ snd-soc-da7210-objs := da7210.o
snd-soc-l3-objs := l3.o
snd-soc-max98088-objs := max98088.o
snd-soc-pcm3008-objs := pcm3008.o
+snd-soc-alc5623-objs := alc5623.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
snd-soc-stac9766-objs := stac9766.o
@@ -38,9 +39,11 @@ snd-soc-wm8711-objs := wm8711.o
snd-soc-wm8727-objs := wm8727.o
snd-soc-wm8728-objs := wm8728.o
snd-soc-wm8731-objs := wm8731.o
+snd-soc-wm8737-objs := wm8737.o
snd-soc-wm8741-objs := wm8741.o
snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
+snd-soc-wm8770-objs := wm8770.o
snd-soc-wm8776-objs := wm8776.o
snd-soc-wm8804-objs := wm8804.o
snd-soc-wm8900-objs := wm8900.o
@@ -58,7 +61,7 @@ snd-soc-wm8985-objs := wm8985.o
snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm8993-objs := wm8993.o
-snd-soc-wm8994-objs := wm8994.o
+snd-soc-wm8994-objs := wm8994.o wm8994-tables.o
snd-soc-wm9081-objs := wm9081.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
@@ -92,6 +95,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
+obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
@@ -113,9 +117,11 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
+obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o
obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
+obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index d272534c8f84..ab63d52e36e1 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -27,7 +27,6 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
-#include <sound/soc-dapm.h>
#include <linux/spi/spi.h>
#include "ad1836.h"
@@ -220,6 +219,7 @@ static struct snd_soc_dai_driver ad1836_dai = {
static int ad1836_probe(struct snd_soc_codec *codec)
{
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
codec->control_data = ad1836->control_data;
@@ -227,7 +227,6 @@ static int ad1836_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
- kfree(ad1836);
return ret;
}
@@ -252,9 +251,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, ad1836_snd_controls,
ARRAY_SIZE(ad1836_snd_controls));
- snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
ARRAY_SIZE(ad1836_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index fa2834c91b9f..a007bd7326fd 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -19,7 +19,6 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
-#include <sound/soc-dapm.h>
#include "ad193x.h"
/* codec private data */
@@ -353,6 +352,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
codec->control_data = ad193x->control_data;
@@ -363,7 +363,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
- kfree(ad193x);
return ret;
}
@@ -385,9 +384,9 @@ static int ad193x_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, ad193x_snd_controls,
ARRAY_SIZE(ad193x_snd_controls));
- snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
ARRAY_SIZE(ad193x_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 410ccd5d41cd..34cb51ef2156 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -29,7 +29,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "ad1980.h"
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index cd88c8f32a38..8b38739c88f8 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "ak4535.h"
@@ -290,10 +289,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int ak4535_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets,
- ARRAY_SIZE(ak4535_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
+ ARRAY_SIZE(ak4535_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -366,9 +366,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int ak4535_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
if (!mute)
- ak4535_write(codec, AK4535_DAC, mute_reg);
+ ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
else
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
return 0;
@@ -381,11 +381,11 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
switch (level) {
case SND_SOC_BIAS_ON:
- mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
- ak4535_write(codec, AK4535_DAC, mute_reg);
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
+ ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
break;
case SND_SOC_BIAS_PREPARE:
- mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
break;
case SND_SOC_BIAS_STANDBY:
@@ -399,7 +399,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
ak4535_write(codec, AK4535_PM1, i & (~0x80));
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 90c90b7f4a2e..f00eba313dfd 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -26,7 +26,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 24f5f49bb9d2..4faf10553a30 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -437,10 +436,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int ak4671_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
- ARRAY_SIZE(ak4671_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
+ ARRAY_SIZE(ak4671_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -602,7 +602,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
new file mode 100644
index 000000000000..4f377c9e868d
--- /dev/null
+++ b/sound/soc/codecs/alc5623.c
@@ -0,0 +1,1117 @@
+/*
+ * alc5623.c -- alc562[123] ALSA Soc Audio driver
+ *
+ * Copyright 2008 Realtek Microelectronics
+ * Author: flove <flove@realtek.com> Ethan <eku@marvell.com>
+ *
+ * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * Based on WM8753.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/alc5623.h>
+
+#include "alc5623.h"
+
+static int caps_charge = 2000;
+module_param(caps_charge, int, 0);
+MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
+
+/* codec private data */
+struct alc5623_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
+ struct mutex mutex;
+ u8 id;
+ unsigned int sysclk;
+ u16 reg_cache[ALC5623_VENDOR_ID2+2];
+ unsigned int add_ctrl;
+ unsigned int jack_det_ctrl;
+};
+
+static void alc5623_fill_cache(struct snd_soc_codec *codec)
+{
+ int i, step = codec->driver->reg_cache_step;
+ u16 *cache = codec->reg_cache;
+
+ /* not really efficient ... */
+ for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
+ cache[i] = codec->hw_read(codec, i);
+}
+
+static inline int alc5623_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, ALC5623_RESET, 0);
+}
+
+static int amp_mixer_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ /* to power-on/off class-d amp generators/speaker */
+ /* need to write to 'index-46h' register : */
+ /* so write index num (here 0x46) to reg 0x6a */
+ /* and then 0xffff/0 to reg 0x6c */
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * ALC5623 Controls
+ */
+
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
+static const unsigned int boost_tlv[] = {
+ TLV_DB_RANGE_HEAD(3),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
+};
+static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
+
+static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Speaker Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Speaker Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Headphone Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Headphone Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Speaker Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Speaker Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Line Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Line Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Line Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Line Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Headphone Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Headphone Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_snd_controls[] = {
+ SOC_DOUBLE_TLV("Auxout Playback Volume",
+ ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Auxout Playback Switch",
+ ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("PCM Playback Volume",
+ ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("AuxI Capture Volume",
+ ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("LineIn Capture Volume",
+ ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_SINGLE_TLV("Mic1 Capture Volume",
+ ALC5623_MIC_VOL, 8, 31, 1, vol_tlv),
+ SOC_SINGLE_TLV("Mic2 Capture Volume",
+ ALC5623_MIC_VOL, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("Rec Capture Volume",
+ ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv),
+ SOC_SINGLE_TLV("Mic 1 Boost Volume",
+ ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Mic 2 Boost Volume",
+ ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Digital Boost Volume",
+ ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1),
+SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1),
+SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1),
+SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1),
+SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1),
+SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1),
+};
+
+/* Left Record Mixer */
+static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1),
+SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1),
+SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1),
+SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1),
+};
+
+/* Right Record Mixer */
+static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1),
+SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1),
+SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1),
+SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1),
+};
+
+static const char *alc5623_spk_n_sour_sel[] = {
+ "RN/-R", "RP/+R", "LN/-R", "Vmid" };
+static const char *alc5623_hpl_out_input_sel[] = {
+ "Vmid", "HP Left Mix"};
+static const char *alc5623_hpr_out_input_sel[] = {
+ "Vmid", "HP Right Mix"};
+static const char *alc5623_spkout_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+static const char *alc5623_aux_out_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+
+/* auxout output mux */
+static const struct soc_enum alc5623_aux_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel);
+static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
+
+/* speaker output mux */
+static const struct soc_enum alc5623_spkout_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel);
+static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
+
+/* headphone left output mux */
+static const struct soc_enum alc5623_hpl_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel);
+static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
+
+/* headphone right output mux */
+static const struct soc_enum alc5623_hpr_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel);
+static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
+
+/* speaker output N select */
+static const struct soc_enum alc5623_spk_n_sour_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel);
+static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
+
+static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = {
+/* Muxes */
+SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_auxout_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_spkout_mux_controls),
+SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_hpl_out_mux_controls),
+SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_hpr_out_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_spkoutn_mux_controls),
+
+/* output mixers */
+SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
+ &alc5623_hp_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hp_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0,
+ &alc5623_hpr_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hpr_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0,
+ &alc5623_hpl_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hpl_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0,
+ &alc5623_mono_mixer_controls[0],
+ ARRAY_SIZE(alc5623_mono_mixer_controls)),
+SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0,
+ &alc5623_speaker_mixer_controls[0],
+ ARRAY_SIZE(alc5623_speaker_mixer_controls)),
+
+/* input mixers */
+SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0,
+ &alc5623_captureL_mixer_controls[0],
+ ARRAY_SIZE(alc5623_captureL_mixer_controls)),
+SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0,
+ &alc5623_captureR_mixer_controls[0],
+ ARRAY_SIZE(alc5623_captureR_mixer_controls)),
+
+SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
+ ALC5623_PWR_MANAG_ADD2, 9, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
+ ALC5623_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
+ ALC5623_PWR_MANAG_ADD2, 7, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
+ ALC5623_PWR_MANAG_ADD2, 6, 0),
+SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0),
+SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0),
+
+SND_SOC_DAPM_OUTPUT("AUXOUTL"),
+SND_SOC_DAPM_OUTPUT("AUXOUTR"),
+SND_SOC_DAPM_OUTPUT("HPL"),
+SND_SOC_DAPM_OUTPUT("HPR"),
+SND_SOC_DAPM_OUTPUT("SPKOUT"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+SND_SOC_DAPM_INPUT("LINEINL"),
+SND_SOC_DAPM_INPUT("LINEINR"),
+SND_SOC_DAPM_INPUT("AUXINL"),
+SND_SOC_DAPM_INPUT("AUXINR"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("Vmid"),
+};
+
+static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
+static const struct soc_enum alc5623_amp_enum =
+ SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names);
+static const struct snd_kcontrol_new alc5623_amp_mux_controls =
+ SOC_DAPM_ENUM("Route", alc5623_amp_enum);
+
+static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = {
+SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0,
+ amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0),
+SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_amp_mux_controls),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ /* virtual mixer - mixes left & right channels */
+ {"I2S Mix", NULL, "Left DAC"},
+ {"I2S Mix", NULL, "Right DAC"},
+ {"Line Mix", NULL, "Right LineIn"},
+ {"Line Mix", NULL, "Left LineIn"},
+ {"AuxI Mix", NULL, "Left AuxI"},
+ {"AuxI Mix", NULL, "Right AuxI"},
+ {"AUXOUTL", NULL, "Left AuxOut"},
+ {"AUXOUTR", NULL, "Right AuxOut"},
+
+ /* HP mixer */
+ {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
+ {"HPL Mix", NULL, "HP Mix"},
+ {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
+ {"HPR Mix", NULL, "HP Mix"},
+ {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
+ {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"},
+ {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
+ {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
+ {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"},
+
+ /* speaker mixer */
+ {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
+ {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"},
+ {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
+ {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
+ {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"},
+
+ /* mono mixer */
+ {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
+ {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
+ {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
+ {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"},
+ {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
+ {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
+ {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"},
+
+ /* Left record mixer */
+ {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
+ {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"},
+ {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
+ {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /*Right record mixer */
+ {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
+ {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"},
+ {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
+ {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /* headphone left mux */
+ {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
+ {"Left Headphone Mux", "Vmid", "Vmid"},
+
+ /* headphone right mux */
+ {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
+ {"Right Headphone Mux", "Vmid", "Vmid"},
+
+ /* speaker out mux */
+ {"SpeakerOut Mux", "Vmid", "Vmid"},
+ {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* Mono/Aux Out mux */
+ {"AuxOut Mux", "Vmid", "Vmid"},
+ {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"AuxOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* output pga */
+ {"HPL", NULL, "Left Headphone"},
+ {"Left Headphone", NULL, "Left Headphone Mux"},
+ {"HPR", NULL, "Right Headphone"},
+ {"Right Headphone", NULL, "Right Headphone Mux"},
+ {"Left AuxOut", NULL, "AuxOut Mux"},
+ {"Right AuxOut", NULL, "AuxOut Mux"},
+
+ /* input pga */
+ {"Left LineIn", NULL, "LINEINL"},
+ {"Right LineIn", NULL, "LINEINR"},
+ {"Left AuxI", NULL, "AUXINL"},
+ {"Right AuxI", NULL, "AUXINR"},
+ {"MIC1 Pre Amp", NULL, "MIC1"},
+ {"MIC2 Pre Amp", NULL, "MIC2"},
+ {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
+ {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
+
+ /* left ADC */
+ {"Left ADC", NULL, "Left Capture Mix"},
+
+ /* right ADC */
+ {"Right ADC", NULL, "Right Capture Mix"},
+
+ {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "Vmid", "Vmid"},
+
+ {"SPKOUT", NULL, "SpeakerOut"},
+ {"SPKOUTN", NULL, "SpeakerOut N Mux"},
+};
+
+static const struct snd_soc_dapm_route intercon_spk[] = {
+ {"SpeakerOut", NULL, "SpeakerOut Mux"},
+};
+
+static const struct snd_soc_dapm_route intercon_amp_spk[] = {
+ {"AB Amp", NULL, "SpeakerOut Mux"},
+ {"D Amp", NULL, "SpeakerOut Mux"},
+ {"AB-D Amp Mux", "AB Amp", "AB Amp"},
+ {"AB-D Amp Mux", "D Amp", "D Amp"},
+ {"SpeakerOut", NULL, "AB-D Amp Mux"},
+};
+
+/* PLL divisors */
+struct _pll_div {
+ u32 pll_in;
+ u32 pll_out;
+ u16 regvalue;
+};
+
+/* Note : pll code from original alc5623 driver. Not sure of how good it is */
+/* usefull only for master mode */
+static const struct _pll_div codec_master_pll_div[] = {
+
+ { 2048000, 8192000, 0x0ea0},
+ { 3686400, 8192000, 0x4e27},
+ { 12000000, 8192000, 0x456b},
+ { 13000000, 8192000, 0x495f},
+ { 13100000, 8192000, 0x0320},
+ { 2048000, 11289600, 0xf637},
+ { 3686400, 11289600, 0x2f22},
+ { 12000000, 11289600, 0x3e2f},
+ { 13000000, 11289600, 0x4d5b},
+ { 13100000, 11289600, 0x363b},
+ { 2048000, 16384000, 0x1ea0},
+ { 3686400, 16384000, 0x9e27},
+ { 12000000, 16384000, 0x452b},
+ { 13000000, 16384000, 0x542f},
+ { 13100000, 16384000, 0x03a0},
+ { 2048000, 16934400, 0xe625},
+ { 3686400, 16934400, 0x9126},
+ { 12000000, 16934400, 0x4d2c},
+ { 13000000, 16934400, 0x742f},
+ { 13100000, 16934400, 0x3c27},
+ { 2048000, 22579200, 0x2aa0},
+ { 3686400, 22579200, 0x2f20},
+ { 12000000, 22579200, 0x7e2f},
+ { 13000000, 22579200, 0x742f},
+ { 13100000, 22579200, 0x3c27},
+ { 2048000, 24576000, 0x2ea0},
+ { 3686400, 24576000, 0xee27},
+ { 12000000, 24576000, 0x2915},
+ { 13000000, 24576000, 0x772e},
+ { 13100000, 24576000, 0x0d20},
+};
+
+static const struct _pll_div codec_slave_pll_div[] = {
+
+ { 1024000, 16384000, 0x3ea0},
+ { 1411200, 22579200, 0x3ea0},
+ { 1536000, 24576000, 0x3ea0},
+ { 2048000, 16384000, 0x1ea0},
+ { 2822400, 22579200, 0x1ea0},
+ { 3072000, 24576000, 0x1ea0},
+
+};
+
+static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ int i;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int gbl_clk = 0, pll_div = 0;
+ u16 reg;
+
+ if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK)
+ return -ENODEV;
+
+ /* Disable PLL power */
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_PLL,
+ 0);
+
+ /* pll is not used in slave mode */
+ reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+ if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
+ return 0;
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ switch (pll_id) {
+ case ALC5623_PLL_FR_MCLK:
+ for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
+ if (codec_master_pll_div[i].pll_in == freq_in
+ && codec_master_pll_div[i].pll_out == freq_out) {
+ /* PLL source from MCLK */
+ pll_div = codec_master_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ case ALC5623_PLL_FR_BCK:
+ for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+ if (codec_slave_pll_div[i].pll_in == freq_in
+ && codec_slave_pll_div[i].pll_out == freq_out) {
+ /* PLL source from Bitclk */
+ gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK;
+ pll_div = codec_slave_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!pll_div)
+ return -EINVAL;
+
+ snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+ snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_PLL,
+ ALC5623_PWR_ADD2_PLL);
+ gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
+ snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+
+ return 0;
+}
+
+struct _coeff_div {
+ u16 fs;
+ u16 regvalue;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+/* values inspired from column BCLK=32Fs of Appendix A table */
+static const struct _coeff_div coeff_div[] = {
+ {256*8, 0x3a69},
+ {384*8, 0x3c6b},
+ {256*4, 0x2a69},
+ {384*4, 0x2c6b},
+ {256*2, 0x1a69},
+ {384*2, 0x1c6b},
+ {256*1, 0x0a69},
+ {384*1, 0x0c6b},
+};
+
+static int get_coeff(struct snd_soc_codec *codec, int rate)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].fs * rate == alc5623->sysclk)
+ return i;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+
+ switch (freq) {
+ case 8192000:
+ case 11289600:
+ case 12288000:
+ case 16384000:
+ case 16934400:
+ case 18432000:
+ case 22579200:
+ case 24576000:
+ alc5623->sysclk = freq;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface = ALC5623_DAI_SDP_MASTER_MODE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ iface = ALC5623_DAI_SDP_SLAVE_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= ALC5623_DAI_I2S_DF_I2S;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ iface |= ALC5623_DAI_I2S_DF_RIGHT;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= ALC5623_DAI_I2S_DF_LEFT;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= ALC5623_DAI_I2S_DF_PCM;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+}
+
+static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ int coeff, rate;
+ u16 iface;
+
+ iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+ iface &= ~ALC5623_DAI_I2S_DL_MASK;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= ALC5623_DAI_I2S_DL_16;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= ALC5623_DAI_I2S_DL_20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= ALC5623_DAI_I2S_DL_24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= ALC5623_DAI_I2S_DL_32;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set iface & srate */
+ snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+ rate = params_rate(params);
+ coeff = get_coeff(codec, rate);
+ if (coeff < 0)
+ return -EINVAL;
+
+ coeff = coeff_div[coeff].regvalue;
+ dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
+ __func__, alc5623->sysclk, rate, coeff);
+ snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
+
+ return 0;
+}
+
+static int alc5623_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
+ u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
+
+ if (mute)
+ mute_reg |= hp_mute;
+
+ return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
+}
+
+#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
+ | ALC5623_PWR_ADD2_DAC_REF_CIR)
+
+#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \
+ | ALC5623_PWR_ADD3_MIC1_BOOST_AD)
+
+#define ALC5623_ADD1_POWER_EN \
+ (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \
+ | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \
+ | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP)
+
+#define ALC5623_ADD1_POWER_EN_5622 \
+ (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
+ | ALC5623_PWR_ADD1_HP_OUT_AMP)
+
+static void enable_power_depop(struct snd_soc_codec *codec)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_PWR_ADD1_SOFTGEN_EN,
+ ALC5623_PWR_ADD1_SOFTGEN_EN);
+
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
+
+ snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN);
+
+ msleep(500);
+
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
+
+ /* avoid writing '1' into 5622 reserved bits */
+ if (alc5623->id == 0x22)
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_ADD1_POWER_EN_5622);
+ else
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_ADD1_POWER_EN);
+
+ /* disable HP Depop2 */
+ snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN,
+ 0);
+
+}
+
+static int alc5623_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ enable_power_depop(codec);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* everything off except vref/vmid, */
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_VREF);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
+ ALC5623_PWR_ADD3_MAIN_BIAS);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* everything off, dac mute, inactive */
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
+ | SNDRV_PCM_FMTBIT_S24_LE \
+ | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops alc5623_dai_ops = {
+ .hw_params = alc5623_pcm_hw_params,
+ .digital_mute = alc5623_mute,
+ .set_fmt = alc5623_set_dai_fmt,
+ .set_sysclk = alc5623_set_dai_sysclk,
+ .set_pll = alc5623_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver alc5623_dai = {
+ .name = "alc5623-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5623_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5623_FORMATS,},
+
+ .ops = &alc5623_dai_ops,
+};
+
+static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+{
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int alc5623_resume(struct snd_soc_codec *codec)
+{
+ int i, step = codec->driver->reg_cache_step;
+ u16 *cache = codec->reg_cache;
+
+ /* Sync reg_cache with the hardware */
+ for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
+ snd_soc_write(codec, i, cache[i]);
+
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* charge alc5623 caps */
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ alc5623_set_bias_level(codec, codec->dapm.bias_level);
+ }
+
+ return 0;
+}
+
+static int alc5623_probe(struct snd_soc_codec *codec)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int ret;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ alc5623_reset(codec);
+ alc5623_fill_cache(codec);
+
+ /* power on device */
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ if (alc5623->add_ctrl) {
+ snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
+ alc5623->add_ctrl);
+ }
+
+ if (alc5623->jack_det_ctrl) {
+ snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
+ alc5623->jack_det_ctrl);
+ }
+
+ switch (alc5623->id) {
+ case 0x21:
+ snd_soc_add_controls(codec, rt5621_vol_snd_controls,
+ ARRAY_SIZE(rt5621_vol_snd_controls));
+ break;
+ case 0x22:
+ snd_soc_add_controls(codec, rt5622_vol_snd_controls,
+ ARRAY_SIZE(rt5622_vol_snd_controls));
+ break;
+ case 0x23:
+ snd_soc_add_controls(codec, alc5623_vol_snd_controls,
+ ARRAY_SIZE(alc5623_vol_snd_controls));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_add_controls(codec, alc5623_snd_controls,
+ ARRAY_SIZE(alc5623_snd_controls));
+
+ snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
+ ARRAY_SIZE(alc5623_dapm_widgets));
+
+ /* set up audio path interconnects */
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ switch (alc5623->id) {
+ case 0x21:
+ case 0x22:
+ snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets,
+ ARRAY_SIZE(alc5623_dapm_amp_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon_amp_spk,
+ ARRAY_SIZE(intercon_amp_spk));
+ break;
+ case 0x23:
+ snd_soc_dapm_add_routes(dapm, intercon_spk,
+ ARRAY_SIZE(intercon_spk));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/* power down chip */
+static int alc5623_remove(struct snd_soc_codec *codec)
+{
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
+ .probe = alc5623_probe,
+ .remove = alc5623_remove,
+ .suspend = alc5623_suspend,
+ .resume = alc5623_resume,
+ .set_bias_level = alc5623_set_bias_level,
+ .reg_cache_size = ALC5623_VENDOR_ID2+2,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+};
+
+/*
+ * ALC5623 2 wire address is determined by A1 pin
+ * state during powerup.
+ * low = 0x1a
+ * high = 0x1b
+ */
+static int alc5623_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct alc5623_platform_data *pdata;
+ struct alc5623_priv *alc5623;
+ int ret, vid1, vid2;
+
+ vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
+ if (vid1 < 0) {
+ dev_err(&client->dev, "failed to read I2C\n");
+ return -EIO;
+ }
+ vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
+
+ vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
+ if (vid2 < 0) {
+ dev_err(&client->dev, "failed to read I2C\n");
+ return -EIO;
+ }
+
+ if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
+ dev_err(&client->dev, "unknown or wrong codec\n");
+ dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
+ 0x10ec, id->driver_data,
+ vid1, vid2);
+ return -ENODEV;
+ }
+
+ dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
+
+ alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL);
+ if (alc5623 == NULL)
+ return -ENOMEM;
+
+ pdata = client->dev.platform_data;
+ if (pdata) {
+ alc5623->add_ctrl = pdata->add_ctrl;
+ alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
+ }
+
+ alc5623->id = vid2;
+ switch (alc5623->id) {
+ case 0x21:
+ alc5623_dai.name = "alc5621-hifi";
+ break;
+ case 0x22:
+ alc5623_dai.name = "alc5622-hifi";
+ break;
+ case 0x23:
+ alc5623_dai.name = "alc5623-hifi";
+ break;
+ default:
+ kfree(alc5623);
+ return -EINVAL;
+ }
+
+ i2c_set_clientdata(client, alc5623);
+ alc5623->control_data = client;
+ alc5623->control_type = SND_SOC_I2C;
+ mutex_init(&alc5623->mutex);
+
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_device_alc5623, &alc5623_dai, 1);
+ if (ret != 0) {
+ dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+ kfree(alc5623);
+ }
+
+ return ret;
+}
+
+static int alc5623_i2c_remove(struct i2c_client *client)
+{
+ struct alc5623_priv *alc5623 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+ kfree(alc5623);
+ return 0;
+}
+
+static const struct i2c_device_id alc5623_i2c_table[] = {
+ {"alc5621", 0x21},
+ {"alc5622", 0x22},
+ {"alc5623", 0x23},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
+
+/* i2c codec control layer */
+static struct i2c_driver alc5623_i2c_driver = {
+ .driver = {
+ .name = "alc562x-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = alc5623_i2c_probe,
+ .remove = __devexit_p(alc5623_i2c_remove),
+ .id_table = alc5623_i2c_table,
+};
+
+static int __init alc5623_modinit(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&alc5623_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "%s: can't add i2c driver", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(alc5623_modinit);
+
+static void __exit alc5623_modexit(void)
+{
+ i2c_del_driver(&alc5623_i2c_driver);
+}
+module_exit(alc5623_modexit);
+
+MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h
new file mode 100644
index 000000000000..f3d68260d425
--- /dev/null
+++ b/sound/soc/codecs/alc5623.h
@@ -0,0 +1,161 @@
+/*
+ * alc5623.h -- alc562[123] ALSA Soc Audio driver
+ *
+ * Copyright 2008 Realtek Microelectronics
+ * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Author: flove <flove@realtek.com>
+ * Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ALC5623_H
+#define _ALC5623_H
+
+#define ALC5623_RESET 0x00
+/* 5621 5622 5623 */
+/* speaker output vol 2 2 */
+/* line output vol 4 2 */
+/* HP output vol 4 0 4 */
+#define ALC5623_SPK_OUT_VOL 0x02
+#define ALC5623_HP_OUT_VOL 0x04
+#define ALC5623_MONO_AUX_OUT_VOL 0x06
+#define ALC5623_AUXIN_VOL 0x08
+#define ALC5623_LINE_IN_VOL 0x0A
+#define ALC5623_STEREO_DAC_VOL 0x0C
+#define ALC5623_MIC_VOL 0x0E
+#define ALC5623_MIC_ROUTING_CTRL 0x10
+#define ALC5623_ADC_REC_GAIN 0x12
+#define ALC5623_ADC_REC_MIXER 0x14
+#define ALC5623_SOFT_VOL_CTRL_TIME 0x16
+/* ALC5623_OUTPUT_MIXER_CTRL : */
+/* same remark as for reg 2 line vs speaker */
+#define ALC5623_OUTPUT_MIXER_CTRL 0x1C
+#define ALC5623_MIC_CTRL 0x22
+
+#define ALC5623_DAI_CONTROL 0x34
+#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15)
+#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15)
+#define ALC5623_DAI_I2S_PCM_MODE (1 << 14)
+#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
+#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5)
+#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4)
+#define ALC5623_DAI_I2S_DL_MASK (3 << 2)
+#define ALC5623_DAI_I2S_DL_32 (3 << 2)
+#define ALC5623_DAI_I2S_DL_24 (2 << 2)
+#define ALC5623_DAI_I2S_DL_20 (1 << 2)
+#define ALC5623_DAI_I2S_DL_16 (0 << 2)
+#define ALC5623_DAI_I2S_DF_PCM (3 << 0)
+#define ALC5623_DAI_I2S_DF_LEFT (2 << 0)
+#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0)
+#define ALC5623_DAI_I2S_DF_I2S (0 << 0)
+
+#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36
+#define ALC5623_COMPANDING_CTRL 0x38
+
+#define ALC5623_PWR_MANAG_ADD1 0x3A
+#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15)
+#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14)
+#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11)
+#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10)
+#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5)
+#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2)
+#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1)
+#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */
+
+#define ALC5623_PWR_MANAG_ADD2 0x3C
+#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */
+#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */
+#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */
+#define ALC5623_PWR_ADD2_VREF (1 << 13)
+#define ALC5623_PWR_ADD2_PLL (1 << 12)
+#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10)
+#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9)
+#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8)
+#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
+#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
+#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5)
+#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4)
+#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3)
+#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2)
+#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
+#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
+
+#define ALC5623_PWR_MANAG_ADD3 0x3E
+#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15)
+#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14)
+#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13)
+#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12)
+#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10)
+#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9)
+#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7)
+#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6)
+#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5)
+#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4)
+#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3)
+#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2)
+#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
+#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
+
+#define ALC5623_ADD_CTRL_REG 0x40
+
+#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42
+#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15)
+#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15)
+#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14)
+#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1)
+#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0)
+#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0)
+
+#define ALC5623_PLL_CTRL 0x44
+#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
+#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
+#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf)
+
+#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A
+#define ALC5623_GPIO_PIN_CONFIG 0x4C
+#define ALC5623_GPIO_PIN_POLARITY 0x4E
+#define ALC5623_GPIO_PIN_STICKY 0x50
+#define ALC5623_GPIO_PIN_WAKEUP 0x52
+#define ALC5623_GPIO_PIN_STATUS 0x54
+#define ALC5623_GPIO_PIN_SHARING 0x56
+#define ALC5623_OVER_CURR_STATUS 0x58
+#define ALC5623_JACK_DET_CTRL 0x5A
+
+#define ALC5623_MISC_CTRL 0x5E
+#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15)
+#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */
+#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */
+#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10)
+#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9)
+#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4)
+#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3)
+#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2)
+#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0)
+
+#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60
+#define ALC5623_EQ_CTRL 0x62
+#define ALC5623_EQ_MODE_ENABLE 0x66
+#define ALC5623_AVC_CTRL 0x68
+#define ALC5623_HID_CTRL_INDEX 0x6A
+#define ALC5623_HID_CTRL_DATA 0x6C
+#define ALC5623_VENDOR_ID1 0x7C
+#define ALC5623_VENDOR_ID2 0x7E
+
+#define ALC5623_PLL_FR_MCLK 0
+#define ALC5623_PLL_FR_BCK 1
+#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 823643932dde..46dbfd067f79 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -36,8 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dai.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <mach/dm365.h>
@@ -116,7 +114,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
DAVINCI_VC_REG12_POWER_ALL_OFF);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index cb086eaf4e07..d4e60dc45bf6 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <sound/pcm_params.h>
@@ -519,6 +518,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
static int cs42l51_probe(struct snd_soc_codec *codec)
{
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, reg;
codec->control_data = cs42l51->control_data;
@@ -550,9 +550,9 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, cs42l51_snd_controls,
ARRAY_SIZE(cs42l51_snd_controls));
- snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets,
ARRAY_SIZE(cs42l51_dapm_widgets));
- snd_soc_dapm_add_routes(codec, cs42l51_routes,
+ snd_soc_dapm_add_routes(dapm, cs42l51_routes,
ARRAY_SIZE(cs42l51_routes));
return 0;
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index e8d27c8f9ba3..a9521acad99c 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -18,7 +18,7 @@
#include <sound/core.h>
#include <sound/initval.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include "cx20442.h"
@@ -89,10 +89,11 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
static int cx20442_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
- ARRAY_SIZE(cx20442_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, cx20442_audio_map,
+ snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
+ ARRAY_SIZE(cx20442_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
ARRAY_SIZE(cx20442_audio_map));
return 0;
@@ -263,7 +264,7 @@ static void v253_close(struct tty_struct *tty)
/* Prevent the codec driver from further accessing the modem */
codec->hw_write = NULL;
cx20442->control_data = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
}
/* Line discipline .hangup() */
@@ -291,7 +292,7 @@ static void v253_receive(struct tty_struct *tty,
/* Set up codec driver access to modem controls */
cx20442->control_data = tty;
codec->hw_write = (hw_write_t)tty->ops->write;
- codec->pop_time = 1;
+ codec->card->pop_time = 1;
}
}
@@ -348,7 +349,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
cx20442->control_data = NULL;
codec->hw_write = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
return 0;
}
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 58bb9b994811..92fd9d7a9221 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 16253ec9b022..f7cd346fd727 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -22,7 +22,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
-#include <sound/soc-dapm.h>
#include <sound/soc.h>
#define JZ4740_REG_CODEC_1 0x0
@@ -266,7 +265,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
/* The only way to clear the suspend flag is to reset the codec */
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
jz4740_codec_wakeup(codec);
mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -288,23 +287,25 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
snd_soc_add_controls(codec, jz4740_codec_controls,
ARRAY_SIZE(jz4740_codec_controls));
- snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
ARRAY_SIZE(jz4740_codec_dapm_widgets));
- snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes,
+ snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
ARRAY_SIZE(jz4740_codec_dapm_routes));
snd_soc_dapm_new_widgets(codec);
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index d63e28773eb1..335a002aaf0e 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <linux/slab.h>
@@ -1230,15 +1229,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int max98088_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, max98088_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
ARRAY_SIZE(max98088_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
snd_soc_add_controls(codec, max98088_snd_controls,
ARRAY_SIZE(max98088_snd_controls));
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -1623,7 +1624,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
max98088_sync_cache(codec);
snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
@@ -1636,7 +1637,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
codec->cache_sync = 1;
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 6f38d619bf8a..2727befd158e 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -38,7 +38,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "ssm2602.h"
@@ -207,10 +206,11 @@ static const struct snd_soc_dapm_route audio_conn[] = {
static int ssm2602_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
- ARRAY_SIZE(ssm2602_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
+ snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
+ ARRAY_SIZE(ssm2602_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
return 0;
}
@@ -493,7 +493,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 061f9e5a497b..78b2b50271e2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -236,7 +236,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index e8652b1ae326..54a30ef0ec8b 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
@@ -391,11 +390,12 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
- ARRAY_SIZE(tlv320aic23_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
+ ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -574,7 +574,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 6b7d71ec0004..68f0ae47f608 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "tlv320aic26.h"
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 77b8f9ae29be..fc5abdf0bcb0 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -46,7 +46,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/tlv320aic3x.h>
@@ -61,6 +60,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
"DRVDD", /* ADC Analog and Output Driver Voltage */
};
+static LIST_HEAD(reset_list);
+
struct aic3x_priv;
struct aic3x_disable_nb {
@@ -77,6 +78,7 @@ struct aic3x_priv {
struct aic3x_setup_data *setup;
void *control_data;
unsigned int sysclk;
+ struct list_head list;
int master;
int gpio_reset;
int power;
@@ -183,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -199,7 +201,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
}
if (found)
- snd_soc_dapm_sync(widget->codec);
+ snd_soc_dapm_sync(widget->dapm);
}
ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
@@ -788,17 +790,19 @@ static const struct snd_soc_dapm_route intercon_3007[] = {
static int aic3x_add_widgets(struct snd_soc_codec *codec)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
if (aic3x->model == AIC3X_MODEL_3007) {
- snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
ARRAY_SIZE(aic3007_dapm_widgets));
- snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(intercon_3007));
+ snd_soc_dapm_add_routes(dapm, intercon_3007,
+ ARRAY_SIZE(intercon_3007));
}
return 0;
@@ -1075,7 +1079,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
* Put codec to reset and require cache sync as at least one
* of the supplies was disabled
*/
- if (aic3x->gpio_reset >= 0)
+ if (gpio_is_valid(aic3x->gpio_reset))
gpio_set_value(aic3x->gpio_reset, 0);
aic3x->codec->cache_sync = 1;
}
@@ -1102,7 +1106,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
if (!codec->cache_sync)
goto out;
- if (aic3x->gpio_reset >= 0) {
+ if (gpio_is_valid(aic3x->gpio_reset)) {
udelay(1);
gpio_set_value(aic3x->gpio_reset, 1);
}
@@ -1135,7 +1139,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
aic3x->master) {
/* enable pll */
reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1146,7 +1150,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (!aic3x->power)
aic3x_set_power(codec, 1);
- if (codec->bias_level == SND_SOC_BIAS_PREPARE &&
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
aic3x->master) {
/* disable pll */
reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1159,7 +1163,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
aic3x_set_power(codec, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1344,14 +1348,28 @@ static int aic3x_init(struct snd_soc_codec *codec)
return 0;
}
+static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
+{
+ struct aic3x_priv *a;
+
+ list_for_each_entry(a, &reset_list, list) {
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ aic3x->gpio_reset == a->gpio_reset)
+ return true;
+ }
+
+ return false;
+}
+
static int aic3x_probe(struct snd_soc_codec *codec)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int ret, i;
+ INIT_LIST_HEAD(&aic3x->list);
codec->control_data = aic3x->control_data;
aic3x->codec = codec;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
if (ret != 0) {
@@ -1359,7 +1377,8 @@ static int aic3x_probe(struct snd_soc_codec *codec)
return ret;
}
- if (aic3x->gpio_reset >= 0) {
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x)) {
ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
if (ret != 0)
goto err_gpio;
@@ -1405,6 +1424,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
aic3x_add_widgets(codec);
+ list_add(&aic3x->list, &reset_list);
return 0;
@@ -1414,10 +1434,10 @@ err_notif:
&aic3x->disable_nb[i].nb);
regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
err_get:
- if (aic3x->gpio_reset >= 0)
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x))
gpio_free(aic3x->gpio_reset);
err_gpio:
- kfree(aic3x);
return ret;
}
@@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
int i;
aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (aic3x->gpio_reset >= 0) {
+ list_del(&aic3x->list);
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x)) {
gpio_set_value(aic3x->gpio_reset, 0);
gpio_free(aic3x->gpio_reset);
}
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index c5ab8c805771..ccb267f4e968 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -36,7 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -628,11 +627,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int dac33_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
- ARRAY_SIZE(dac33_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
+ ARRAY_SIZE(dac33_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -649,7 +649,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Coming from OFF, switch on the codec */
ret = dac33_hard_power(codec, 1);
if (ret != 0)
@@ -660,14 +660,14 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
/* Do not power off, when the codec is already off */
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
return 0;
ret = dac33_hard_power(codec, 0);
if (ret != 0)
return ret;
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1415,7 +1415,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
codec->control_data = dac33->control_data;
codec->hw_write = (hw_write_t) i2c_master_send;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
dac33->codec = codec;
/* Read the tlv320dac33 ID registers */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index d2c243095673..9d61a1d6fce0 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -29,7 +29,6 @@
#include <linux/slab.h>
#include <sound/tpa6130a2-plat.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "tpa6130a2.h"
@@ -128,9 +127,6 @@ static int tpa6130a2_power(int power)
mutex_lock(&data->mutex);
if (power && !data->power_state) {
- /* Power on */
- if (data->power_gpio >= 0)
- gpio_set_value(data->power_gpio, 1);
ret = regulator_enable(data->supply);
if (ret != 0) {
@@ -138,6 +134,9 @@ static int tpa6130a2_power(int power)
"Failed to enable supply: %d\n", ret);
goto exit;
}
+ /* Power on */
+ if (data->power_gpio >= 0)
+ gpio_set_value(data->power_gpio, 1);
data->power_state = 1;
ret = tpa6130a2_initialize();
@@ -390,16 +389,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
int tpa6130a2_add_controls(struct snd_soc_codec *codec)
{
struct tpa6130a2_data *data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
if (tpa6130a2_client == NULL)
return -ENODEV;
data = i2c_get_clientdata(tpa6130a2_client);
- snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tpa6130a2_dapm_widgets,
ARRAY_SIZE(tpa6130a2_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (data->id == TPA6140A2)
return snd_soc_add_controls(codec, tpa6140a2_controls,
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index cbebec6ba1ba..c173cf00f5cb 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -32,7 +32,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -233,6 +232,16 @@ static int twl4030_write(struct snd_soc_codec *codec,
return 0;
}
+static inline void twl4030_wait_ms(int time)
+{
+ if (time < 60) {
+ time *= 1000;
+ usleep_range(time, time + 500);
+ } else {
+ msleep(time);
+ }
+}
+
static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -338,10 +347,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
twl4030_write(codec, TWL4030_REG_ANAMICL,
reg | TWL4030_CNCL_OFFSET_START);
- /* wait for offset cancellation to complete */
+ /*
+ * Wait for offset cancellation to complete.
+ * Since this takes a while, do not slam the i2c.
+ * Start polling the status after ~20ms.
+ */
+ msleep(20);
do {
- /* this takes a little while, so don't slam i2c */
- udelay(2000);
+ usleep_range(1000, 2000);
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
TWL4030_REG_ANAMICL);
} while ((i++ < 100) &&
@@ -725,9 +738,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
/* Base values for ramp delay calculation: 2^19 - 2^26 */
unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
8388608, 16777216, 33554432, 67108864};
+ unsigned int delay;
hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
+ delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
+ twl4030->sysclk) + 1;
/* Enable external mute control, this dramatically reduces
* the pop-noise */
@@ -751,16 +767,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
hs_pop |= TWL4030_RAMP_EN;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
/* Wait ramp delay time + 1, so the VMID can settle */
- mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
- twl4030->sysclk) + 1);
+ twl4030_wait_ms(delay);
} else {
/* Headset ramp-down _not_ according to
* the TRM, but in a way that it is working */
hs_pop &= ~TWL4030_RAMP_EN;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
/* Wait ramp delay time + 1, so the VMID can settle */
- mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
- twl4030->sysclk) + 1);
+ twl4030_wait_ms(delay);
/* Bypass the reg_cache to mute the headset */
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
hs_gain & (~0x0f),
@@ -835,7 +849,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
if (twl4030->digimic_delay)
- mdelay(twl4030->digimic_delay);
+ twl4030_wait_ms(twl4030->digimic_delay);
return 0;
}
@@ -1621,10 +1635,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int twl4030_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
- ARRAY_SIZE(twl4030_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
+ ARRAY_SIZE(twl4030_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -1638,14 +1653,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
twl4030_codec_enable(codec, 1);
break;
case SND_SOC_BIAS_OFF:
twl4030_codec_enable(codec, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -2245,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */
twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec);
@@ -2257,9 +2272,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
static int twl4030_soc_remove(struct snd_soc_codec *codec)
{
+ struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+
/* Reset registers to their chip default before leaving */
twl4030_reset_registers(codec);
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ kfree(twl4030);
return 0;
}
@@ -2291,10 +2309,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
static int __devexit twl4030_codec_remove(struct platform_device *pdev)
{
- struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
-
snd_soc_unregister_codec(&pdev->dev);
- kfree(twl4030);
return 0;
}
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 10f6e5214511..b92f2b737e4c 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -34,7 +34,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -641,12 +640,12 @@ static const struct snd_soc_dapm_route intercon[] = {
static int twl6040_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets,
- ARRAY_SIZE(twl6040_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets,
+ ARRAY_SIZE(twl6040_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -739,7 +738,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 464f0cfa4c7a..e76847a9438b 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/uda134x.h>
@@ -389,7 +388,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
pd->power(0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 0c6c725736c6..800980e2e9ab 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -27,7 +27,6 @@
#include <sound/control.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/uda1380.h>
@@ -414,10 +413,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int uda1380_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
- ARRAY_SIZE(uda1380_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
+ ARRAY_SIZE(uda1380_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -603,7 +603,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
int reg;
struct uda1380_platform_data *pdata = codec->dev->platform_data;
- if (codec->bias_level == level)
+ if (codec->dapm.bias_level == level)
return 0;
switch (level) {
@@ -613,7 +613,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
if (gpio_is_valid(pdata->gpio_power)) {
gpio_set_value(pdata->gpio_power, 1);
mdelay(1);
@@ -636,7 +636,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
set_bit(reg - 0x10, &uda1380_cache_dirty);
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 0c47c788ccdf..d3ffa2f0122a 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -25,8 +25,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dai.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include "wl1273.h"
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 4bcd168794e1..80ddf4fd23db 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -36,7 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -705,6 +704,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Called from the machine driver */
int wm2000_add_controls(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
if (!wm2000_i2c) {
@@ -712,12 +712,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec)
return -ENODEV;
}
- ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets,
ARRAY_SIZE(wm2000_dapm_widgets));
if (ret < 0)
return ret;
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret < 0)
return ret;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 7611add7f8c3..07ba7e3f6a8c 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -230,8 +229,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
*/
static void wm8350_pga_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context, delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
struct wm8350_output *out1 = &wm8350_data->out1,
*out2 = &wm8350_data->out2;
@@ -302,8 +302,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out->ramp = WM8350_RAMP_UP;
out->active = 1;
- if (!delayed_work_pending(&codec->delayed_work))
- schedule_delayed_work(&codec->delayed_work,
+ if (!delayed_work_pending(&codec->dapm.delayed_work))
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(1));
break;
@@ -311,8 +311,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out->ramp = WM8350_RAMP_DOWN;
out->active = 0;
- if (!delayed_work_pending(&codec->delayed_work))
- schedule_delayed_work(&codec->delayed_work,
+ if (!delayed_work_pending(&codec->dapm.delayed_work))
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(1));
break;
}
@@ -786,9 +786,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8350_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- ret = snd_soc_dapm_new_controls(codec,
+ ret = snd_soc_dapm_new_controls(dapm,
wm8350_dapm_widgets,
ARRAY_SIZE(wm8350_dapm_widgets));
if (ret != 0) {
@@ -797,7 +798,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
}
/* set up audio paths */
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret != 0) {
dev_err(codec->dev, "DAPM route register failed\n");
return ret;
@@ -1184,7 +1185,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
priv->supplies);
if (ret != 0)
@@ -1317,7 +1318,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
priv->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1550,7 +1551,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
/* Put the codec into reset if it wasn't already */
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
- INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
/* Enable the codec */
wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1626,7 +1627,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
{
struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
- int ret;
wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1641,15 +1641,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
priv->hpr.jack = NULL;
priv->mic.jack = NULL;
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(&codec->delayed_work);
-
/* if there was any work waiting then we run it now and
* wait for its completion */
- if (ret) {
- schedule_delayed_work(&codec->delayed_work, 0);
- flush_scheduled_work();
- }
+ flush_delayed_work_sync(&codec->dapm.delayed_work);
wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 850299786e02..3c3bc079167e 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -911,10 +910,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8400_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets,
- ARRAY_SIZE(wm8400_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets,
+ ARRAY_SIZE(wm8400_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1219,7 +1219,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(power),
&power[0]);
if (ret != 0) {
@@ -1306,7 +1306,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 8f107095760e..db0dced74843 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8510.h"
@@ -216,10 +215,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8510_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets,
- ARRAY_SIZE(wm8510_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets,
+ ARRAY_SIZE(wm8510_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -478,7 +478,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
mdelay(100);
@@ -495,7 +495,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 9a433a5396cb..08f3189f4b3f 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -110,10 +109,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8523_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets,
- ARRAY_SIZE(wm8523_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
+ ARRAY_SIZE(wm8523_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -327,7 +327,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
wm8523->supplies);
if (ret != 0) {
@@ -366,7 +366,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
wm8523->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 879dff2714dd..0ebdecfd27a9 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -31,7 +31,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <asm/div64.h>
@@ -161,7 +160,7 @@
static const u16 wm8580_reg[] = {
0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+ 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -302,10 +301,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8580_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
- ARRAY_SIZE(wm8580_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets,
+ ARRAY_SIZE(wm8580_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -507,13 +507,13 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
}
/* Look up the SYSCLK ratio; accept only exact matches */
- ratio = wm8580->sysclk[dai->id] / params_rate(params);
+ ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);
for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
if (ratio == wm8580_sysclk_ratios[i])
break;
if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
- wm8580->sysclk[dai->id], params_rate(params));
+ wm8580->sysclk[dai->driver->id], params_rate(params));
return -EINVAL;
}
paifa |= i;
@@ -716,7 +716,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
switch (clk_id) {
case WM8580_CLKSRC_ADCMCLK:
- if (dai->id != WM8580_DAI_PAIFTX)
+ if (dai->driver->id != WM8580_DAI_PAIFTX)
return -EINVAL;
sel = 0 << sel_shift;
break;
@@ -735,7 +735,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
}
/* We really should validate PLL settings but not yet */
- wm8580->sysclk[dai->id] = freq;
+ wm8580->sysclk[dai->driver->id] = freq;
return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
}
@@ -767,7 +767,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Power up and get individual control of the DACs */
reg = snd_soc_read(codec, WM8580_PWRDN1);
reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
@@ -785,7 +785,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -905,7 +905,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
.set_bias_level = wm8580_set_bias_level,
.reg_cache_size = ARRAY_SIZE(wm8580_reg),
.reg_word_size = sizeof(u16),
- .reg_cache_default = &wm8580_reg,
+ .reg_cache_default = wm8580_reg,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 54fbd76c8bca..fec37ebfdb34 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
@@ -93,10 +92,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8711_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
- ARRAY_SIZE(wm8711_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
+ ARRAY_SIZE(wm8711_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -318,7 +318,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8711_PWR, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 075f35e4f4cb..736b0352d0a7 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -73,10 +72,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8728_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
- ARRAY_SIZE(wm8728_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
+ ARRAY_SIZE(wm8728_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -180,7 +180,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Power everything up... */
reg = snd_soc_read(codec, WM8728_DACCTL);
snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
@@ -197,7 +197,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e725c09a3e79..71122dc36826 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -47,6 +46,8 @@ struct wm8731_priv {
u16 reg_cache[WM8731_CACHEREGNUM];
unsigned int sysclk;
int sysclk_type;
+ int playback_fs;
+ bool deemph;
};
@@ -65,16 +66,79 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
static const char *wm8731_input_select[] = {"Line In", "Mic"};
-static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const struct soc_enum wm8731_enum[] = {
- SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select),
- SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
-};
+static const struct soc_enum wm8731_insel_enum =
+ SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select);
+
+static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
+
+static int wm8731_set_deemph(struct snd_soc_codec *codec)
+{
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+ int val, i, best;
+
+ /* If we're using deemphasis select the nearest available sample
+ * rate.
+ */
+ if (wm8731->deemph) {
+ best = 1;
+ for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
+ if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
+ abs(wm8731_deemph[best] - wm8731->playback_fs))
+ best = i;
+ }
+
+ val = best << 1;
+ } else {
+ best = 0;
+ val = 0;
+ }
+
+ dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+ best, wm8731_deemph[best]);
+
+ return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
+}
+
+static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8731->deemph;
+
+ return 0;
+}
+
+static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+ int deemph = ucontrol->value.enumerated.item[0];
+ int ret = 0;
+
+ if (deemph > 1)
+ return -EINVAL;
+
+ mutex_lock(&codec->mutex);
+ if (wm8731->deemph != deemph) {
+ wm8731->deemph = deemph;
+
+ wm8731_set_deemph(codec);
+
+ ret = 1;
+ }
+ mutex_unlock(&codec->mutex);
+
+ return ret;
+}
static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
static const struct snd_kcontrol_new wm8731_snd_controls[] = {
@@ -87,7 +151,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
in_tlv),
SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
-SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
+SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
@@ -96,7 +160,8 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
-SOC_ENUM("Playback De-emphasis", wm8731_enum[1]),
+SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
+ wm8731_get_deemph, wm8731_put_deemph),
};
/* Output Mixer */
@@ -108,7 +173,7 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
/* Input mux */
static const struct snd_kcontrol_new wm8731_input_mux_controls =
-SOC_DAPM_ENUM("Input Select", wm8731_enum[0]);
+SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
@@ -165,10 +230,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8731_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
- ARRAY_SIZE(wm8731_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
+ ARRAY_SIZE(wm8731_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -239,6 +305,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
u16 srate = (coeff_div[i].sr << 2) |
(coeff_div[i].bosr << 1) | coeff_div[i].usb;
+ wm8731->playback_fs = params_rate(params);
+
snd_soc_write(codec, WM8731_SRATE, srate);
/* bit size */
@@ -253,6 +321,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
break;
}
+ wm8731_set_deemph(codec);
+
snd_soc_write(codec, WM8731_IFACE, iface);
return 0;
}
@@ -319,7 +389,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
return 0;
}
@@ -399,7 +469,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
wm8731->supplies);
if (ret != 0)
@@ -428,7 +498,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
wm8731->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -542,7 +612,6 @@ err_regulator_enable:
err_regulator_get:
regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
- kfree(wm8731);
return ret;
}
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
new file mode 100644
index 000000000000..30c67d06a904
--- /dev/null
+++ b/sound/soc/codecs/wm8737.c
@@ -0,0 +1,754 @@
+/*
+ * wm8737.c -- WM8737 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8737.h"
+
+#define WM8737_NUM_SUPPLIES 4
+static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
+ "DCVDD",
+ "DBVDD",
+ "AVDD",
+ "MVDD",
+};
+
+/* codec private data */
+struct wm8737_priv {
+ enum snd_soc_control_type control_type;
+ struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
+ unsigned int mclk;
+};
+
+static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
+ 0x00C3, /* R0 - Left PGA volume */
+ 0x00C3, /* R1 - Right PGA volume */
+ 0x0007, /* R2 - AUDIO path L */
+ 0x0007, /* R3 - AUDIO path R */
+ 0x0000, /* R4 - 3D Enhance */
+ 0x0000, /* R5 - ADC Control */
+ 0x0000, /* R6 - Power Management */
+ 0x000A, /* R7 - Audio Format */
+ 0x0000, /* R8 - Clocking */
+ 0x000F, /* R9 - MIC Preamp Control */
+ 0x0003, /* R10 - Misc Bias Control */
+ 0x0000, /* R11 - Noise Gate */
+ 0x007C, /* R12 - ALC1 */
+ 0x0000, /* R13 - ALC2 */
+ 0x0032, /* R14 - ALC3 */
+};
+
+static int wm8737_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, WM8737_RESET, 0);
+}
+
+static const unsigned int micboost_tlv[] = {
+ TLV_DB_RANGE_HEAD(4),
+ 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
+ 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
+};
+static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
+static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
+static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
+
+static const char *micbias_enum_text[] = {
+ "25%",
+ "50%",
+ "75%",
+ "100%",
+};
+
+static const struct soc_enum micbias_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
+
+static const char *low_cutoff_text[] = {
+ "Low", "High"
+};
+
+static const struct soc_enum low_3d =
+ SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
+
+static const char *high_cutoff_text[] = {
+ "High", "Low"
+};
+
+static const struct soc_enum high_3d =
+ SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
+
+static const char *alc_fn_text[] = {
+ "Disabled", "Right", "Left", "Stereo"
+};
+
+static const struct soc_enum alc_fn =
+ SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
+
+static const char *alc_hold_text[] = {
+ "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
+ "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
+ "10.916s", "21.832s", "43.691s"
+};
+
+static const struct soc_enum alc_hold =
+ SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
+
+static const char *alc_atk_text[] = {
+ "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
+ "1.075s", "2.15s", "4.3s", "8.6s"
+};
+
+static const struct soc_enum alc_atk =
+ SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
+
+static const char *alc_dcy_text[] = {
+ "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
+ "4.3s", "8.6s", "17.2s", "34.41s"
+};
+
+static const struct soc_enum alc_dcy =
+ SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
+
+static const struct snd_kcontrol_new wm8737_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 6, 3, 0, micboost_tlv),
+SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 4, 1, 0),
+SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 3, 1, 0),
+
+SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
+ WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
+SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 2, 1, 0),
+
+SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
+
+SOC_ENUM("Mic PGA Bias", micbias_enum),
+SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
+SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
+SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
+
+SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
+SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
+SOC_ENUM("3D Low Cut-off", low_3d),
+SOC_ENUM("3D High Cut-off", low_3d),
+SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
+
+SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
+SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
+ ng_tlv),
+
+SOC_ENUM("ALC", alc_fn),
+SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
+SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
+SOC_ENUM("ALC Hold Time", alc_hold),
+SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
+SOC_ENUM("ALC Attack Time", alc_atk),
+SOC_ENUM("ALC Decay Time", alc_dcy),
+};
+
+static const char *linsel_text[] = {
+ "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
+};
+
+static const struct soc_enum linsel_enum =
+ SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
+
+static const struct snd_kcontrol_new linsel_mux =
+ SOC_DAPM_ENUM("LINSEL", linsel_enum);
+
+
+static const char *rinsel_text[] = {
+ "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
+};
+
+static const struct soc_enum rinsel_enum =
+ SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
+
+static const struct snd_kcontrol_new rinsel_mux =
+ SOC_DAPM_ENUM("RINSEL", rinsel_enum);
+
+static const char *bypass_text[] = {
+ "Direct", "Preamp"
+};
+
+static const struct soc_enum lbypass_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
+
+static const struct snd_kcontrol_new lbypass_mux =
+ SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
+
+
+static const struct soc_enum rbypass_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
+
+static const struct snd_kcontrol_new rbypass_mux =
+ SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
+
+static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("LINPUT1"),
+SND_SOC_DAPM_INPUT("LINPUT2"),
+SND_SOC_DAPM_INPUT("LINPUT3"),
+SND_SOC_DAPM_INPUT("RINPUT1"),
+SND_SOC_DAPM_INPUT("RINPUT2"),
+SND_SOC_DAPM_INPUT("RINPUT3"),
+SND_SOC_DAPM_INPUT("LACIN"),
+SND_SOC_DAPM_INPUT("RACIN"),
+
+SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
+SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
+
+SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
+SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
+
+SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
+
+SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
+SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ { "LINSEL", "LINPUT1", "LINPUT1" },
+ { "LINSEL", "LINPUT2", "LINPUT2" },
+ { "LINSEL", "LINPUT3", "LINPUT3" },
+ { "LINSEL", "LINPUT1 DC", "LINPUT1" },
+
+ { "RINSEL", "RINPUT1", "RINPUT1" },
+ { "RINSEL", "RINPUT2", "RINPUT2" },
+ { "RINSEL", "RINPUT3", "RINPUT3" },
+ { "RINSEL", "RINPUT1 DC", "RINPUT1" },
+
+ { "Left Preamp Mux", "Preamp", "LINSEL" },
+ { "Left Preamp Mux", "Direct", "LACIN" },
+
+ { "Right Preamp Mux", "Preamp", "RINSEL" },
+ { "Right Preamp Mux", "Direct", "RACIN" },
+
+ { "PGAL", NULL, "Left Preamp Mux" },
+ { "PGAR", NULL, "Right Preamp Mux" },
+
+ { "ADCL", NULL, "PGAL" },
+ { "ADCR", NULL, "PGAR" },
+
+ { "AIF", NULL, "ADCL" },
+ { "AIF", NULL, "ADCR" },
+};
+
+static int wm8737_add_widgets(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
+ ARRAY_SIZE(wm8737_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ return 0;
+}
+
+/* codec mclk clock divider coefficients */
+static const struct {
+ u32 mclk;
+ u32 rate;
+ u8 usb;
+ u8 sr;
+} coeff_div[] = {
+ { 12288000, 8000, 0, 0x4 },
+ { 12288000, 12000, 0, 0x8 },
+ { 12288000, 16000, 0, 0xa },
+ { 12288000, 24000, 0, 0x1c },
+ { 12288000, 32000, 0, 0xc },
+ { 12288000, 48000, 0, 0 },
+ { 12288000, 96000, 0, 0xe },
+
+ { 11289600, 8000, 0, 0x14 },
+ { 11289600, 11025, 0, 0x18 },
+ { 11289600, 22050, 0, 0x1a },
+ { 11289600, 44100, 0, 0x10 },
+ { 11289600, 88200, 0, 0x1e },
+
+ { 18432000, 8000, 0, 0x5 },
+ { 18432000, 12000, 0, 0x9 },
+ { 18432000, 16000, 0, 0xb },
+ { 18432000, 24000, 0, 0x1b },
+ { 18432000, 32000, 0, 0xd },
+ { 18432000, 48000, 0, 0x1 },
+ { 18432000, 96000, 0, 0x1f },
+
+ { 16934400, 8000, 0, 0x15 },
+ { 16934400, 11025, 0, 0x19 },
+ { 16934400, 22050, 0, 0x1b },
+ { 16934400, 44100, 0, 0x11 },
+ { 16934400, 88200, 0, 0x1f },
+
+ { 12000000, 8000, 1, 0x4 },
+ { 12000000, 11025, 1, 0x19 },
+ { 12000000, 12000, 1, 0x8 },
+ { 12000000, 16000, 1, 0xa },
+ { 12000000, 22050, 1, 0x1b },
+ { 12000000, 24000, 1, 0x1c },
+ { 12000000, 32000, 1, 0xc },
+ { 12000000, 44100, 1, 0x11 },
+ { 12000000, 48000, 1, 0x0 },
+ { 12000000, 88200, 1, 0x1f },
+ { 12000000, 96000, 1, 0xe },
+};
+
+static int wm8737_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int i;
+ u16 clocking = 0;
+ u16 af = 0;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate != params_rate(params))
+ continue;
+
+ if (coeff_div[i].mclk == wm8737->mclk)
+ break;
+
+ if (coeff_div[i].mclk == wm8737->mclk * 2) {
+ clocking |= WM8737_CLKDIV2;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(coeff_div)) {
+ dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
+ wm8737->mclk, params_rate(params));
+ return -EINVAL;
+ }
+
+ clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ af |= 0x8;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ af |= 0x10;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ af |= 0x18;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
+ snd_soc_update_bits(codec, WM8737_CLOCKING,
+ WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
+ clocking);
+
+ return 0;
+}
+
+static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (freq == coeff_div[i].mclk ||
+ freq == coeff_div[i].mclk * 2) {
+ wm8737->mclk = freq;
+ return 0;
+ }
+ }
+
+ dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
+
+ return -EINVAL;
+}
+
+
+static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 af = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ af |= WM8737_MS;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ af |= 0x2;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ af |= 0x1;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ af |= 0x3;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ af |= 0x13;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ af |= WM8737_LRP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
+ WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
+
+ return 0;
+}
+
+static int wm8737_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ /* VMID at 2*75k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 0);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to enable supplies: %d\n",
+ ret);
+ return ret;
+ }
+
+ snd_soc_cache_sync(codec);
+
+ /* Fast VMID ramp at 2*2.5k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 0x4);
+
+ /* Bring VMID up */
+ snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+ WM8737_VMID_MASK |
+ WM8737_VREF_MASK,
+ WM8737_VMID_MASK |
+ WM8737_VREF_MASK);
+
+ msleep(500);
+ }
+
+ /* VMID at 2*300k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 2);
+
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+ WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
+
+#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8737_dai_ops = {
+ .hw_params = wm8737_hw_params,
+ .set_sysclk = wm8737_set_dai_sysclk,
+ .set_fmt = wm8737_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver wm8737_dai = {
+ .name = "wm8737",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2, /* Mono modes not yet supported */
+ .channels_max = 2,
+ .rates = WM8737_RATES,
+ .formats = WM8737_FORMATS,
+ },
+ .ops = &wm8737_dai_ops,
+};
+
+#ifdef CONFIG_PM
+static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8737_resume(struct snd_soc_codec *codec)
+{
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define wm8737_suspend NULL
+#define wm8737_resume NULL
+#endif
+
+static int wm8737_probe(struct snd_soc_codec *codec)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int ret, i;
+
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+ wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
+
+ ret = wm8737_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ goto err_enable;
+ }
+
+ snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
+ WM8737_LVU);
+ snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
+ WM8737_RVU);
+
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Bias level configuration will have done an extra enable */
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+
+ snd_soc_add_controls(codec, wm8737_snd_controls,
+ ARRAY_SIZE(wm8737_snd_controls));
+ wm8737_add_widgets(codec);
+
+ return 0;
+
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+
+ return ret;
+}
+
+static int wm8737_remove(struct snd_soc_codec *codec)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
+ .probe = wm8737_probe,
+ .remove = wm8737_remove,
+ .suspend = wm8737_suspend,
+ .resume = wm8737_resume,
+ .set_bias_level = wm8737_set_bias_level,
+
+ .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8737_reg,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8737_priv *wm8737;
+ int ret;
+
+ wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ if (wm8737 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8737);
+ wm8737->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8737, &wm8737_dai, 1);
+ if (ret < 0)
+ kfree(wm8737);
+ return ret;
+
+}
+
+static __devexit int wm8737_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id wm8737_i2c_id[] = {
+ { "wm8737", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
+
+static struct i2c_driver wm8737_i2c_driver = {
+ .driver = {
+ .name = "wm8737",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8737_i2c_probe,
+ .remove = __devexit_p(wm8737_i2c_remove),
+ .id_table = wm8737_i2c_id,
+};
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8737_spi_probe(struct spi_device *spi)
+{
+ struct wm8737_priv *wm8737;
+ int ret;
+
+ wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ if (wm8737 == NULL)
+ return -ENOMEM;
+
+ wm8737->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8737);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8737, &wm8737_dai, 1);
+ if (ret < 0)
+ kfree(wm8737);
+ return ret;
+}
+
+static int __devexit wm8737_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8737_spi_driver = {
+ .driver = {
+ .name = "wm8737",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8737_spi_probe,
+ .remove = __devexit_p(wm8737_spi_remove),
+};
+#endif /* CONFIG_SPI_MASTER */
+
+static int __init wm8737_modinit(void)
+{
+ int ret;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8737_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
+ ret);
+ }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8737_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return 0;
+}
+module_init(wm8737_modinit);
+
+static void __exit wm8737_exit(void)
+{
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8737_spi_driver);
+#endif
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8737_i2c_driver);
+#endif
+}
+module_exit(wm8737_exit);
+
+MODULE_DESCRIPTION("ASoC WM8737 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h
new file mode 100644
index 000000000000..23d14c8ff6e7
--- /dev/null
+++ b/sound/soc/codecs/wm8737.h
@@ -0,0 +1,322 @@
+#ifndef _WM8737_H
+#define _WM8737_H
+
+/*
+ * wm8737.c -- WM8523 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Register values.
+ */
+#define WM8737_LEFT_PGA_VOLUME 0x00
+#define WM8737_RIGHT_PGA_VOLUME 0x01
+#define WM8737_AUDIO_PATH_L 0x02
+#define WM8737_AUDIO_PATH_R 0x03
+#define WM8737_3D_ENHANCE 0x04
+#define WM8737_ADC_CONTROL 0x05
+#define WM8737_POWER_MANAGEMENT 0x06
+#define WM8737_AUDIO_FORMAT 0x07
+#define WM8737_CLOCKING 0x08
+#define WM8737_MIC_PREAMP_CONTROL 0x09
+#define WM8737_MISC_BIAS_CONTROL 0x0A
+#define WM8737_NOISE_GATE 0x0B
+#define WM8737_ALC1 0x0C
+#define WM8737_ALC2 0x0D
+#define WM8737_ALC3 0x0E
+#define WM8737_RESET 0x0F
+
+#define WM8737_REGISTER_COUNT 16
+#define WM8737_MAX_REGISTER 0x0F
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Left PGA volume
+ */
+#define WM8737_LVU 0x0100 /* LVU */
+#define WM8737_LVU_MASK 0x0100 /* LVU */
+#define WM8737_LVU_SHIFT 8 /* LVU */
+#define WM8737_LVU_WIDTH 1 /* LVU */
+#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */
+#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */
+#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */
+
+/*
+ * R1 (0x01) - Right PGA volume
+ */
+#define WM8737_RVU 0x0100 /* RVU */
+#define WM8737_RVU_MASK 0x0100 /* RVU */
+#define WM8737_RVU_SHIFT 8 /* RVU */
+#define WM8737_RVU_WIDTH 1 /* RVU */
+#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */
+#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */
+#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */
+
+/*
+ * R2 (0x02) - AUDIO path L
+ */
+#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */
+#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */
+#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */
+#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */
+#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */
+#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */
+#define WM8737_LMBE 0x0010 /* LMBE */
+#define WM8737_LMBE_MASK 0x0010 /* LMBE */
+#define WM8737_LMBE_SHIFT 4 /* LMBE */
+#define WM8737_LMBE_WIDTH 1 /* LMBE */
+#define WM8737_LMZC 0x0008 /* LMZC */
+#define WM8737_LMZC_MASK 0x0008 /* LMZC */
+#define WM8737_LMZC_SHIFT 3 /* LMZC */
+#define WM8737_LMZC_WIDTH 1 /* LMZC */
+#define WM8737_LPZC 0x0004 /* LPZC */
+#define WM8737_LPZC_MASK 0x0004 /* LPZC */
+#define WM8737_LPZC_SHIFT 2 /* LPZC */
+#define WM8737_LPZC_WIDTH 1 /* LPZC */
+#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */
+#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */
+#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */
+
+/*
+ * R3 (0x03) - AUDIO path R
+ */
+#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */
+#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */
+#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */
+#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */
+#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */
+#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */
+#define WM8737_RMBE 0x0010 /* RMBE */
+#define WM8737_RMBE_MASK 0x0010 /* RMBE */
+#define WM8737_RMBE_SHIFT 4 /* RMBE */
+#define WM8737_RMBE_WIDTH 1 /* RMBE */
+#define WM8737_RMZC 0x0008 /* RMZC */
+#define WM8737_RMZC_MASK 0x0008 /* RMZC */
+#define WM8737_RMZC_SHIFT 3 /* RMZC */
+#define WM8737_RMZC_WIDTH 1 /* RMZC */
+#define WM8737_RPZC 0x0004 /* RPZC */
+#define WM8737_RPZC_MASK 0x0004 /* RPZC */
+#define WM8737_RPZC_SHIFT 2 /* RPZC */
+#define WM8737_RPZC_WIDTH 1 /* RPZC */
+#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */
+#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */
+#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */
+
+/*
+ * R4 (0x04) - 3D Enhance
+ */
+#define WM8737_DIV2 0x0080 /* DIV2 */
+#define WM8737_DIV2_MASK 0x0080 /* DIV2 */
+#define WM8737_DIV2_SHIFT 7 /* DIV2 */
+#define WM8737_DIV2_WIDTH 1 /* DIV2 */
+#define WM8737_3DLC 0x0040 /* 3DLC */
+#define WM8737_3DLC_MASK 0x0040 /* 3DLC */
+#define WM8737_3DLC_SHIFT 6 /* 3DLC */
+#define WM8737_3DLC_WIDTH 1 /* 3DLC */
+#define WM8737_3DUC 0x0020 /* 3DUC */
+#define WM8737_3DUC_MASK 0x0020 /* 3DUC */
+#define WM8737_3DUC_SHIFT 5 /* 3DUC */
+#define WM8737_3DUC_WIDTH 1 /* 3DUC */
+#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */
+#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */
+#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */
+#define WM8737_3DE 0x0001 /* 3DE */
+#define WM8737_3DE_MASK 0x0001 /* 3DE */
+#define WM8737_3DE_SHIFT 0 /* 3DE */
+#define WM8737_3DE_WIDTH 1 /* 3DE */
+
+/*
+ * R5 (0x05) - ADC Control
+ */
+#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */
+#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */
+#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */
+#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */
+#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */
+#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */
+#define WM8737_HPOR 0x0010 /* HPOR */
+#define WM8737_HPOR_MASK 0x0010 /* HPOR */
+#define WM8737_HPOR_SHIFT 4 /* HPOR */
+#define WM8737_HPOR_WIDTH 1 /* HPOR */
+#define WM8737_LP 0x0004 /* LP */
+#define WM8737_LP_MASK 0x0004 /* LP */
+#define WM8737_LP_SHIFT 2 /* LP */
+#define WM8737_LP_WIDTH 1 /* LP */
+#define WM8737_MONOUT 0x0002 /* MONOUT */
+#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */
+#define WM8737_MONOUT_SHIFT 1 /* MONOUT */
+#define WM8737_MONOUT_WIDTH 1 /* MONOUT */
+#define WM8737_ADCHPD 0x0001 /* ADCHPD */
+#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */
+#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */
+#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */
+
+/*
+ * R6 (0x06) - Power Management
+ */
+#define WM8737_VMID 0x0100 /* VMID */
+#define WM8737_VMID_MASK 0x0100 /* VMID */
+#define WM8737_VMID_SHIFT 8 /* VMID */
+#define WM8737_VMID_WIDTH 1 /* VMID */
+#define WM8737_VREF 0x0080 /* VREF */
+#define WM8737_VREF_MASK 0x0080 /* VREF */
+#define WM8737_VREF_SHIFT 7 /* VREF */
+#define WM8737_VREF_WIDTH 1 /* VREF */
+#define WM8737_AI 0x0040 /* AI */
+#define WM8737_AI_MASK 0x0040 /* AI */
+#define WM8737_AI_SHIFT 6 /* AI */
+#define WM8737_AI_WIDTH 1 /* AI */
+#define WM8737_PGL 0x0020 /* PGL */
+#define WM8737_PGL_MASK 0x0020 /* PGL */
+#define WM8737_PGL_SHIFT 5 /* PGL */
+#define WM8737_PGL_WIDTH 1 /* PGL */
+#define WM8737_PGR 0x0010 /* PGR */
+#define WM8737_PGR_MASK 0x0010 /* PGR */
+#define WM8737_PGR_SHIFT 4 /* PGR */
+#define WM8737_PGR_WIDTH 1 /* PGR */
+#define WM8737_ADL 0x0008 /* ADL */
+#define WM8737_ADL_MASK 0x0008 /* ADL */
+#define WM8737_ADL_SHIFT 3 /* ADL */
+#define WM8737_ADL_WIDTH 1 /* ADL */
+#define WM8737_ADR 0x0004 /* ADR */
+#define WM8737_ADR_MASK 0x0004 /* ADR */
+#define WM8737_ADR_SHIFT 2 /* ADR */
+#define WM8737_ADR_WIDTH 1 /* ADR */
+#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */
+#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */
+#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */
+
+/*
+ * R7 (0x07) - Audio Format
+ */
+#define WM8737_SDODIS 0x0080 /* SDODIS */
+#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */
+#define WM8737_SDODIS_SHIFT 7 /* SDODIS */
+#define WM8737_SDODIS_WIDTH 1 /* SDODIS */
+#define WM8737_MS 0x0040 /* MS */
+#define WM8737_MS_MASK 0x0040 /* MS */
+#define WM8737_MS_SHIFT 6 /* MS */
+#define WM8737_MS_WIDTH 1 /* MS */
+#define WM8737_LRP 0x0010 /* LRP */
+#define WM8737_LRP_MASK 0x0010 /* LRP */
+#define WM8737_LRP_SHIFT 4 /* LRP */
+#define WM8737_LRP_WIDTH 1 /* LRP */
+#define WM8737_WL_MASK 0x000C /* WL - [3:2] */
+#define WM8737_WL_SHIFT 2 /* WL - [3:2] */
+#define WM8737_WL_WIDTH 2 /* WL - [3:2] */
+#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
+#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
+#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
+
+/*
+ * R8 (0x08) - Clocking
+ */
+#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */
+#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */
+#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */
+#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */
+#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */
+#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */
+#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */
+#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */
+#define WM8737_SR_MASK 0x003E /* SR - [5:1] */
+#define WM8737_SR_SHIFT 1 /* SR - [5:1] */
+#define WM8737_SR_WIDTH 5 /* SR - [5:1] */
+#define WM8737_USB_MODE 0x0001 /* USB MODE */
+#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */
+#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */
+#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */
+
+/*
+ * R9 (0x09) - MIC Preamp Control
+ */
+#define WM8737_RBYPEN 0x0008 /* RBYPEN */
+#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */
+#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */
+#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */
+#define WM8737_LBYPEN 0x0004 /* LBYPEN */
+#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */
+#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */
+#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */
+#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */
+#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */
+#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */
+
+/*
+ * R10 (0x0A) - Misc Bias Control
+ */
+#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */
+#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */
+#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */
+
+/*
+ * R11 (0x0B) - Noise Gate
+ */
+#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */
+#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */
+#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */
+#define WM8737_NGAT 0x0001 /* NGAT */
+#define WM8737_NGAT_MASK 0x0001 /* NGAT */
+#define WM8737_NGAT_SHIFT 0 /* NGAT */
+#define WM8737_NGAT_WIDTH 1 /* NGAT */
+
+/*
+ * R12 (0x0C) - ALC1
+ */
+#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
+#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
+#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
+#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */
+#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */
+#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */
+#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */
+#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */
+#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */
+
+/*
+ * R13 (0x0D) - ALC2
+ */
+#define WM8737_ALCZCE 0x0010 /* ALCZCE */
+#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */
+#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */
+#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */
+#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */
+#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */
+#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */
+
+/*
+ * R14 (0x0E) - ALC3
+ */
+#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */
+#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */
+#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */
+#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */
+#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */
+#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */
+
+/*
+ * R15 (0x0F) - Reset
+ */
+#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */
+#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */
+#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */
+
+#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 90e31e9aa6f7..35789b7dcacf 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -95,10 +94,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8741_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets,
- ARRAY_SIZE(wm8741_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets,
+ ARRAY_SIZE(wm8741_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -455,7 +455,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
.resume = wm8741_resume,
.reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
.reg_word_size = sizeof(u16),
- .reg_cache_default = &wm8741_reg_defaults,
+ .reg_cache_default = wm8741_reg_defaults,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 6c924cd2cfd4..51280e96d721 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8750.h"
@@ -399,10 +398,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8750_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
- ARRAY_SIZE(wm8750_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
+ ARRAY_SIZE(wm8750_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -615,7 +615,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Set VMID to 5k */
snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
@@ -630,7 +630,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8750_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8f679a13f2bc..73507e71cb79 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -45,7 +45,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -670,10 +669,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8753_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
- ARRAY_SIZE(wm8753_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
+ ARRAY_SIZE(wm8753_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1292,7 +1292,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
wm8753_write(codec, WM8753_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1482,9 +1482,11 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
static void wm8753_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
- wm8753_set_bias_level(codec, codec->bias_level);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context,
+ delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
+ wm8753_set_bias_level(codec, dapm->bias_level);
}
static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -1516,41 +1518,22 @@ static int wm8753_resume(struct snd_soc_codec *codec)
wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* charge wm8753 caps */
- if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->bias_level = SND_SOC_BIAS_ON;
- schedule_delayed_work(&codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(caps_charge));
}
return 0;
}
-/*
- * This function forces any delayed work to be queued and run.
- */
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
-
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
-
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
- }
- return ret;
-}
-
static int wm8753_probe(struct snd_soc_codec *codec)
{
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
int ret = 0, reg;
- INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
if (ret < 0) {
@@ -1569,7 +1552,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
/* charge output caps */
wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- schedule_delayed_work(&codec->delayed_work,
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(caps_charge));
/* set the update bits */
@@ -1604,7 +1587,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
/* power down chip */
static int wm8753_remove(struct snd_soc_codec *codec)
{
- run_delayed_work(&codec->delayed_work);
+ flush_delayed_work_sync(&codec->dapm.delayed_work);
wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
new file mode 100644
index 000000000000..19b92baa9e8c
--- /dev/null
+++ b/sound/soc/codecs/wm8770.c
@@ -0,0 +1,749 @@
+/*
+ * wm8770.c -- WM8770 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8770.h"
+
+#define WM8770_NUM_SUPPLIES 3
+static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = {
+ "AVDD1",
+ "AVDD2",
+ "DVDD"
+};
+
+static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
+ 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0, 0x90, 0,
+ 0, 0x22, 0x22, 0x3e,
+ 0xc, 0xc, 0x100, 0x189,
+ 0x189, 0x8770
+};
+
+struct wm8770_priv {
+ enum snd_soc_control_type control_type;
+ struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
+ struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
+ struct snd_soc_codec *codec;
+ int sysclk;
+};
+
+static int vout12supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+static int vout34supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+
+/*
+ * We can't use the same notifier block for more than one supply and
+ * there's no way I can see to get from a callback to the caller
+ * except container_of().
+ */
+#define WM8770_REGULATOR_EVENT(n) \
+static int wm8770_regulator_event_##n(struct notifier_block *nb, \
+ unsigned long event, void *data) \
+{ \
+ struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
+ disable_nb[n]); \
+ if (event & REGULATOR_EVENT_DISABLE) { \
+ wm8770->codec->cache_sync = 1; \
+ } \
+ return 0; \
+}
+
+WM8770_REGULATOR_EVENT(0)
+WM8770_REGULATOR_EVENT(1)
+WM8770_REGULATOR_EVENT(2)
+
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1);
+
+static const char *dac_phase_text[][2] = {
+ { "DAC1 Normal", "DAC1 Inverted" },
+ { "DAC2 Normal", "DAC2 Inverted" },
+ { "DAC3 Normal", "DAC3 Inverted" },
+ { "DAC4 Normal", "DAC4 Inverted" },
+};
+
+static const struct soc_enum dac_phase[] = {
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]),
+};
+
+static const struct snd_kcontrol_new wm8770_snd_controls[] = {
+ /* global DAC playback controls */
+ SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0,
+ dac_dig_tlv),
+ SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1),
+ SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0),
+
+ /* global VOUT playback controls */
+ SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0,
+ dac_alg_tlv),
+ SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0),
+
+ /* VOUT1/2/3/4 specific controls */
+ SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL,
+ WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL,
+ WM8770_VOUT1RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL,
+ WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL,
+ WM8770_VOUT2RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL,
+ WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL,
+ WM8770_VOUT3RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL,
+ WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL,
+ WM8770_VOUT4RVOL, 7, 1, 0),
+
+ /* DAC1/2/3/4 specific controls */
+ SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL,
+ WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0),
+ SOC_ENUM("DAC1 Phase", dac_phase[0]),
+ SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL,
+ WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0),
+ SOC_ENUM("DAC2 Phase", dac_phase[1]),
+ SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL,
+ WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0),
+ SOC_ENUM("DAC3 Phase", dac_phase[2]),
+ SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL,
+ WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0),
+ SOC_ENUM("DAC4 Phase", dac_phase[3]),
+
+ /* ADC specific controls */
+ SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
+ 0, 31, 0, adc_tlv),
+ SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
+ 5, 1, 1),
+
+ /* other controls */
+ SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0),
+ SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1)
+};
+
+static const char *ain_text[] = {
+ "AIN1", "AIN2", "AIN3", "AIN4",
+ "AIN5", "AIN6", "AIN7", "AIN8"
+};
+
+static const struct soc_enum ain_enum =
+ SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
+
+static const struct snd_kcontrol_new ain_mux =
+ SOC_DAPM_ENUM("Capture Mux", ain_enum);
+
+static const struct snd_kcontrol_new vout1_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0),
+ SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout2_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0),
+ SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout3_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0),
+ SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout4_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0)
+};
+
+static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("AUX1"),
+ SND_SOC_DAPM_INPUT("AUX2"),
+ SND_SOC_DAPM_INPUT("AUX3"),
+
+ SND_SOC_DAPM_INPUT("AIN1"),
+ SND_SOC_DAPM_INPUT("AIN2"),
+ SND_SOC_DAPM_INPUT("AIN3"),
+ SND_SOC_DAPM_INPUT("AIN4"),
+ SND_SOC_DAPM_INPUT("AIN5"),
+ SND_SOC_DAPM_INPUT("AIN6"),
+ SND_SOC_DAPM_INPUT("AIN7"),
+ SND_SOC_DAPM_INPUT("AIN8"),
+
+ SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux),
+
+ SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1),
+
+ SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1),
+ SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1),
+ SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1),
+ SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1),
+
+ SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0,
+ vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0,
+ vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0,
+ vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0,
+ vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0,
+ vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0,
+ vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)),
+
+ SND_SOC_DAPM_OUTPUT("VOUT1"),
+ SND_SOC_DAPM_OUTPUT("VOUT2"),
+ SND_SOC_DAPM_OUTPUT("VOUT3"),
+ SND_SOC_DAPM_OUTPUT("VOUT4")
+};
+
+static const struct snd_soc_dapm_route wm8770_intercon[] = {
+ { "Capture Mux", "AIN1", "AIN1" },
+ { "Capture Mux", "AIN2", "AIN2" },
+ { "Capture Mux", "AIN3", "AIN3" },
+ { "Capture Mux", "AIN4", "AIN4" },
+ { "Capture Mux", "AIN5", "AIN5" },
+ { "Capture Mux", "AIN6", "AIN6" },
+ { "Capture Mux", "AIN7", "AIN7" },
+ { "Capture Mux", "AIN8", "AIN8" },
+
+ { "ADC", NULL, "Capture Mux" },
+
+ { "VOUT1 Mixer", NULL, "VOUT12 Supply" },
+ { "VOUT1 Mixer", "DAC1 Switch", "DAC1" },
+ { "VOUT1 Mixer", "AUX1 Switch", "AUX1" },
+ { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT2 Mixer", NULL, "VOUT12 Supply" },
+ { "VOUT2 Mixer", "DAC2 Switch", "DAC2" },
+ { "VOUT2 Mixer", "AUX2 Switch", "AUX2" },
+ { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT3 Mixer", NULL, "VOUT34 Supply" },
+ { "VOUT3 Mixer", "DAC3 Switch", "DAC3" },
+ { "VOUT3 Mixer", "AUX3 Switch", "AUX3" },
+ { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT4 Mixer", NULL, "VOUT34 Supply" },
+ { "VOUT4 Mixer", "DAC4 Switch", "DAC4" },
+ { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT1", NULL, "VOUT1 Mixer" },
+ { "VOUT2", NULL, "VOUT2 Mixer" },
+ { "VOUT3", NULL, "VOUT3 Mixer" },
+ { "VOUT4", NULL, "VOUT4 Mixer" }
+};
+
+static int vout12supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+
+ codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
+ break;
+ }
+
+ return 0;
+}
+
+static int vout34supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+
+ codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8770_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, WM8770_RESET, 0);
+}
+
+static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec;
+ int iface, master;
+
+ codec = dai->codec;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ master = 0x100;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ master = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ iface = 0;
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x2;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0xc;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x8;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
+ snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
+
+ return 0;
+}
+
+static const int mclk_ratios[] = {
+ 128,
+ 192,
+ 256,
+ 384,
+ 512,
+ 768
+};
+
+static int wm8770_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec;
+ struct wm8770_priv *wm8770;
+ int i;
+ int iface;
+ int shift;
+ int ratio;
+
+ codec = dai->codec;
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+
+ iface = 0;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x10;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x20;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x30;
+ break;
+ }
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ i = 0;
+ shift = 4;
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ i = 2;
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Only need to set MCLK/LRCLK ratio if we're master */
+ if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
+ for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
+ ratio = wm8770->sysclk / params_rate(params);
+ if (ratio == mclk_ratios[i])
+ break;
+ }
+
+ if (i == ARRAY_SIZE(mclk_ratios)) {
+ dev_err(codec->dev,
+ "Unable to configure MCLK ratio %d/%d\n",
+ wm8770->sysclk, params_rate(params));
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
+
+ snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
+ i << shift);
+ }
+
+ snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
+
+ return 0;
+}
+
+static int wm8770_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec;
+
+ codec = dai->codec;
+ return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
+ !!mute << 4);
+}
+
+static int wm8770_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec;
+ struct wm8770_priv *wm8770;
+
+ codec = dai->codec;
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770->sysclk = freq;
+ return 0;
+}
+
+static void wm8770_sync_cache(struct snd_soc_codec *codec)
+{
+ int i;
+ u16 *cache;
+
+ if (!codec->cache_sync)
+ return;
+
+ codec->cache_only = 0;
+ cache = codec->reg_cache;
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
+ if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
+ continue;
+ snd_soc_write(codec, i, cache[i]);
+ }
+ codec->cache_sync = 0;
+}
+
+static int wm8770_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ int ret;
+ struct wm8770_priv *wm8770;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to enable supplies: %d\n",
+ ret);
+ return ret;
+ }
+ wm8770_sync_cache(codec);
+ /* global powerup */
+ snd_soc_write(codec, WM8770_PWDNCTRL, 0);
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* global powerdown */
+ snd_soc_write(codec, WM8770_PWDNCTRL, 1);
+ regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8770_dai_ops = {
+ .digital_mute = wm8770_mute,
+ .hw_params = wm8770_hw_params,
+ .set_fmt = wm8770_set_fmt,
+ .set_sysclk = wm8770_set_sysclk,
+};
+
+static struct snd_soc_dai_driver wm8770_dai = {
+ .name = "wm8770-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = WM8770_FORMATS
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = WM8770_FORMATS
+ },
+ .ops = &wm8770_dai_ops,
+ .symmetric_rates = 1
+};
+
+#ifdef CONFIG_PM
+static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8770_resume(struct snd_soc_codec *codec)
+{
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define wm8770_suspend NULL
+#define wm8770_resume NULL
+#endif
+
+static int wm8770_probe(struct snd_soc_codec *codec)
+{
+ struct wm8770_priv *wm8770;
+ int ret;
+ int i;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770->codec = codec;
+
+ codec->dapm.idle_bias_off = 1;
+
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
+ wm8770->supplies[i].supply = wm8770_supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
+ wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
+ wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
+
+ /* This should really be moved into the regulator core */
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
+ ret = regulator_register_notifier(wm8770->supplies[i].consumer,
+ &wm8770->disable_nb[i]);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to register regulator notifier: %d\n",
+ ret);
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_reg_get;
+ }
+
+ ret = wm8770_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+ goto err_reg_enable;
+ }
+
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* latch the volume update bits */
+ snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
+
+ /* mute all DACs */
+ snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
+
+ snd_soc_add_controls(codec, wm8770_snd_controls,
+ ARRAY_SIZE(wm8770_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
+ ARRAY_SIZE(wm8770_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
+ ARRAY_SIZE(wm8770_intercon));
+ return 0;
+
+err_reg_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+err_reg_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+ return ret;
+}
+
+static int wm8770_remove(struct snd_soc_codec *codec)
+{
+ struct wm8770_priv *wm8770;
+ int i;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
+ regulator_unregister_notifier(wm8770->supplies[i].consumer,
+ &wm8770->disable_nb[i]);
+ regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
+ .probe = wm8770_probe,
+ .remove = wm8770_remove,
+ .suspend = wm8770_suspend,
+ .resume = wm8770_resume,
+ .set_bias_level = wm8770_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
+ .reg_word_size = sizeof (u16),
+ .reg_cache_default = wm8770_reg_defs
+};
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8770_spi_probe(struct spi_device *spi)
+{
+ struct wm8770_priv *wm8770;
+ int ret;
+
+ wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL);
+ if (!wm8770)
+ return -ENOMEM;
+
+ wm8770->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8770);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8770, &wm8770_dai, 1);
+ if (ret < 0)
+ kfree(wm8770);
+ return ret;
+}
+
+static int __devexit wm8770_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8770_spi_driver = {
+ .driver = {
+ .name = "wm8770",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8770_spi_probe,
+ .remove = __devexit_p(wm8770_spi_remove)
+};
+#endif
+
+static int __init wm8770_modinit(void)
+{
+ int ret = 0;
+
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8770_spi_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+module_init(wm8770_modinit);
+
+static void __exit wm8770_exit(void)
+{
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8770_spi_driver);
+#endif
+}
+module_exit(wm8770_exit);
+
+MODULE_DESCRIPTION("ASoC WM8770 driver");
+MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h
new file mode 100644
index 000000000000..5f1b3bda6cc8
--- /dev/null
+++ b/sound/soc/codecs/wm8770.h
@@ -0,0 +1,51 @@
+/*
+ * wm8770.h -- WM8770 ASoC driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8770_H
+#define _WM8770_H
+
+/* Registers */
+#define WM8770_VOUT1LVOL 0
+#define WM8770_VOUT1RVOL 0x1
+#define WM8770_VOUT2LVOL 0x2
+#define WM8770_VOUT2RVOL 0x3
+#define WM8770_VOUT3LVOL 0x4
+#define WM8770_VOUT3RVOL 0x5
+#define WM8770_VOUT4LVOL 0x6
+#define WM8770_VOUT4RVOL 0x7
+#define WM8770_MSALGVOL 0x8
+#define WM8770_DAC1LVOL 0x9
+#define WM8770_DAC1RVOL 0xa
+#define WM8770_DAC2LVOL 0xb
+#define WM8770_DAC2RVOL 0xc
+#define WM8770_DAC3LVOL 0xd
+#define WM8770_DAC3RVOL 0xe
+#define WM8770_DAC4LVOL 0xf
+#define WM8770_DAC4RVOL 0x10
+#define WM8770_MSDIGVOL 0x11
+#define WM8770_DACPHASE 0x12
+#define WM8770_DACCTRL1 0x13
+#define WM8770_DACMUTE 0x14
+#define WM8770_DACCTRL2 0x15
+#define WM8770_IFACECTRL 0x16
+#define WM8770_MSTRCTRL 0x17
+#define WM8770_PWDNCTRL 0x18
+#define WM8770_ADCLCTRL 0x19
+#define WM8770_ADCRCTRL 0x1a
+#define WM8770_ADCMUX 0x1b
+#define WM8770_OUTMUX1 0x1c
+#define WM8770_OUTMUX2 0x1d
+#define WM8770_RESET 0x31
+
+#define WM8770_CACHEREGNUM 0x20
+
+#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 0132a27140ae..8e7953b1b790 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -306,7 +305,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Disable the global powerdown; DAPM does the rest */
snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
}
@@ -317,7 +316,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -404,6 +403,7 @@ static int wm8776_resume(struct snd_soc_codec *codec)
static int wm8776_probe(struct snd_soc_codec *codec)
{
struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
@@ -427,9 +427,9 @@ static int wm8776_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8776_snd_controls,
ARRAY_SIZE(wm8776_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
ARRAY_SIZE(wm8776_dapm_widgets));
- snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
+ snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
return ret;
}
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 4599e8e95aa2..6dae1b40c9f7 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -515,7 +514,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
wm8804->supplies);
if (ret) {
@@ -537,7 +536,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -581,7 +580,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
wm8804 = snd_soc_codec_get_drvdata(codec);
wm8804->codec = codec;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
if (ret < 0) {
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index aca4b1ea10bb..cfbaac1a0ead 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -611,10 +610,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8900_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
- ARRAY_SIZE(wm8900_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets,
+ ARRAY_SIZE(wm8900_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1051,7 +1051,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
/* Charge capacitors if initial power up */
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* STARTUP_BIAS_ENA on */
snd_soc_write(codec, WM8900_REG_POWER1,
WM8900_REG_POWER1_STARTUP_BIAS_ENA);
@@ -1119,7 +1119,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
WM8900_REG_POWER2_SYSCLK_ENA);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 622b60238a82..d015745a886b 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -29,7 +29,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/wm8903.h>
@@ -219,10 +218,11 @@ struct wm8903_priv {
int sysclk;
int irq;
- /* Reference counts */
+ int fs;
+ int deemph;
+
+ /* Reference count */
int class_w_users;
- int playback_active;
- int capture_active;
struct completion wseq;
@@ -231,9 +231,6 @@ struct wm8903_priv {
int mic_short;
int mic_last_report;
int mic_delay;
-
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
};
static int wm8903_volatile_register(unsigned int reg)
@@ -463,6 +460,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
+static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
+
+static int wm8903_set_deemph(struct snd_soc_codec *codec)
+{
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+ int val, i, best;
+
+ /* If we're using deemphasis select the nearest available sample
+ * rate.
+ */
+ if (wm8903->deemph) {
+ best = 1;
+ for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
+ if (abs(wm8903_deemph[i] - wm8903->fs) <
+ abs(wm8903_deemph[best] - wm8903->fs))
+ best = i;
+ }
+
+ val = best << WM8903_DEEMPH_SHIFT;
+ } else {
+ best = 0;
+ val = 0;
+ }
+
+ dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+ best, wm8903_deemph[best]);
+
+ return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
+ WM8903_DEEMPH_MASK, val);
+}
+
+static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8903->deemph;
+
+ return 0;
+}
+
+static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+ int deemph = ucontrol->value.enumerated.item[0];
+ int ret = 0;
+
+ if (deemph > 1)
+ return -EINVAL;
+
+ mutex_lock(&codec->mutex);
+ if (wm8903->deemph != deemph) {
+ wm8903->deemph = deemph;
+
+ wm8903_set_deemph(codec);
+
+ ret = 1;
+ }
+ mutex_unlock(&codec->mutex);
+
+ return ret;
+}
+
/* ALSA can only do steps of .01dB */
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
@@ -475,6 +538,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
+static const char *hpf_mode_text[] = {
+ "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
+};
+
+static const struct soc_enum hpf_mode =
+ SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
+
+static const char *osr_text[] = {
+ "Low power", "High performance"
+};
+
+static const struct soc_enum adc_osr =
+ SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
+
+static const struct soc_enum dac_osr =
+ SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
+
static const char *drc_slope_text[] = {
"1", "1/2", "1/4", "1/8", "1/16", "0"
};
@@ -537,13 +617,6 @@ static const char *mute_mode_text[] = {
static const struct soc_enum mute_mode =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
-static const char *dac_deemphasis_text[] = {
- "Disabled", "32kHz", "44.1kHz", "48kHz"
-};
-
-static const struct soc_enum dac_deemphasis =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
-
static const char *companding_text[] = {
"ulaw", "alaw"
};
@@ -613,6 +686,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
6, 1, 0),
/* ADCs */
+SOC_ENUM("ADC OSR", adc_osr),
+SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
+SOC_ENUM("HPF Mode", hpf_mode),
SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
@@ -642,14 +718,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
12, 0, digital_sidetone_tlv),
/* DAC */
+SOC_ENUM("DAC OSR", dac_osr),
SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
SOC_ENUM("DAC Soft Mute Rate", soft_mute),
SOC_ENUM("DAC Mute Mode", mute_mode),
SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
-SOC_ENUM("DAC De-emphasis", dac_deemphasis),
SOC_ENUM("DAC Companding Mode", dac_companding),
SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
+SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
+ wm8903_get_deemph, wm8903_put_deemph),
/* Headphones */
SOC_DOUBLE_R("Headphone Switch",
@@ -923,10 +1001,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8903_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
- ARRAY_SIZE(wm8903_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
+ ARRAY_SIZE(wm8903_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -946,7 +1025,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
snd_soc_write(codec, WM8903_CLOCK_RATES_2,
WM8903_CLK_SYS_ENA);
@@ -991,7 +1070,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1222,58 +1301,6 @@ static struct {
{ 0, 0 },
};
-static int wm8903_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct snd_pcm_runtime *master_runtime;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- wm8903->playback_active++;
- else
- wm8903->capture_active++;
-
- /* The DAI has shared clocks so if we already have a playback or
- * capture going then constrain this substream to match it.
- */
- if (wm8903->master_substream) {
- master_runtime = wm8903->master_substream->runtime;
-
- dev_dbg(codec->dev, "Constraining to %d bits\n",
- master_runtime->sample_bits);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- master_runtime->sample_bits,
- master_runtime->sample_bits);
-
- wm8903->slave_substream = substream;
- } else
- wm8903->master_substream = substream;
-
- return 0;
-}
-
-static void wm8903_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- wm8903->playback_active--;
- else
- wm8903->capture_active--;
-
- if (wm8903->master_substream == substream)
- wm8903->master_substream = wm8903->slave_substream;
-
- wm8903->slave_substream = NULL;
-}
-
static int wm8903_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -1298,11 +1325,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
- if (substream == wm8903->slave_substream) {
- dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
- return 0;
- }
-
/* Enable sloping stopband filter for low sample rates */
if (fs <= 24000)
dac_digital1 |= WM8903_DAC_SB_FILT;
@@ -1320,19 +1342,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
}
}
- /* Constraints should stop us hitting this but let's make sure */
- if (wm8903->capture_active)
- switch (sample_rates[dsp_config].rate) {
- case 88200:
- case 96000:
- dev_err(codec->dev, "%dHz unsupported by ADC\n",
- fs);
- return -EINVAL;
-
- default:
- break;
- }
-
dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
clock1 &= ~WM8903_SAMPLE_RATE_MASK;
clock1 |= sample_rates[dsp_config].value;
@@ -1428,6 +1437,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
aif2 |= bclk_divs[bclk_div].div;
aif3 |= bclk / fs;
+ wm8903->fs = params_rate(params);
+ wm8903_set_deemph(codec);
+
snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
@@ -1571,8 +1583,6 @@ static irqreturn_t wm8903_irq(int irq, void *data)
SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops wm8903_dai_ops = {
- .startup = wm8903_startup,
- .shutdown = wm8903_shutdown,
.hw_params = wm8903_hw_params,
.digital_mute = wm8903_digital_mute,
.set_fmt = wm8903_set_dai_fmt,
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index fca60a0b57b8..8ba142abd8e6 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8904.h>
@@ -818,7 +817,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- return wm8904->deemph;
+ ucontrol->value.enumerated.item[0] = wm8904->deemph;
+ return 0;
}
static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -1428,10 +1428,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
static int wm8904_add_widgets(struct snd_soc_codec *codec)
{
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
ARRAY_SIZE(wm8904_core_dapm_widgets));
- snd_soc_dapm_add_routes(codec, core_intercon,
+ snd_soc_dapm_add_routes(dapm, core_intercon,
ARRAY_SIZE(core_intercon));
switch (wm8904->devtype) {
@@ -1443,20 +1444,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8904_snd_controls,
ARRAY_SIZE(wm8904_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
ARRAY_SIZE(wm8904_adc_dapm_widgets));
- snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
ARRAY_SIZE(wm8904_dac_dapm_widgets));
- snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
ARRAY_SIZE(wm8904_dapm_widgets));
- snd_soc_dapm_add_routes(codec, core_intercon,
+ snd_soc_dapm_add_routes(dapm, core_intercon,
ARRAY_SIZE(core_intercon));
- snd_soc_dapm_add_routes(codec, adc_intercon,
+ snd_soc_dapm_add_routes(dapm, adc_intercon,
ARRAY_SIZE(adc_intercon));
- snd_soc_dapm_add_routes(codec, dac_intercon,
+ snd_soc_dapm_add_routes(dapm, dac_intercon,
ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(codec, wm8904_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8904_intercon,
ARRAY_SIZE(wm8904_intercon));
break;
@@ -1464,17 +1465,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8904_dac_snd_controls,
ARRAY_SIZE(wm8904_dac_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
ARRAY_SIZE(wm8904_dac_dapm_widgets));
- snd_soc_dapm_add_routes(codec, dac_intercon,
+ snd_soc_dapm_add_routes(dapm, dac_intercon,
ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(codec, wm8912_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8912_intercon,
ARRAY_SIZE(wm8912_intercon));
break;
}
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -1590,7 +1591,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
- wm8904->fs);
for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
cur_val = abs((wm8904->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8904->fs);;
+ clk_sys_rates[i].ratio) - wm8904->fs);
if (cur_val < best_val) {
best = i;
best_val = cur_val;
@@ -2139,7 +2140,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
wm8904->supplies);
if (ret != 0) {
@@ -2198,7 +2199,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
wm8904->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -2373,7 +2374,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
int ret, i;
codec->cache_sync = 1;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
switch (wm8904->devtype) {
case WM8904:
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 2cb16f895c46..381934fff4ec 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -35,7 +35,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -291,13 +290,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8940_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
ARRAY_SIZE(wm8940_dapm_widgets));
if (ret)
goto error_ret;
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret)
goto error_ret;
@@ -735,7 +735,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
return ret;
return ret;
-;
}
static int wm8940_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index f89ad6c9a80b..ca0265f008d2 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8955.h>
@@ -380,7 +379,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- return wm8955->deemph;
+ ucontrol->value.enumerated.item[0] = wm8955->deemph;
+ return 0;
}
static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
@@ -577,13 +577,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
static int wm8955_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
snd_soc_add_controls(codec, wm8955_snd_controls,
ARRAY_SIZE(wm8955_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
ARRAY_SIZE(wm8955_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, wm8955_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8955_intercon,
ARRAY_SIZE(wm8955_intercon));
return 0;
@@ -786,7 +787,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
wm8955->supplies);
if (ret != 0) {
@@ -850,7 +851,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
wm8955->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8d5efb333c33..2c5712dce1d5 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8960.h>
@@ -138,7 +137,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- return wm8960->deemph;
+ ucontrol->value.enumerated.item[0] = wm8960->deemph;
+ return 0;
}
static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
@@ -388,27 +388,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
{
struct wm8960_data *pdata = codec->dev->platform_data;
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dapm_widget *w;
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
ARRAY_SIZE(wm8960_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
/* In capless mode OUT3 is used to provide VMID for the
* headphone outputs, otherwise it is used as a mono mixer.
*/
if (pdata && pdata->capless) {
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
ARRAY_SIZE(wm8960_dapm_widgets_capless));
- snd_soc_dapm_add_routes(codec, audio_paths_capless,
+ snd_soc_dapm_add_routes(dapm, audio_paths_capless,
ARRAY_SIZE(audio_paths_capless));
} else {
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
ARRAY_SIZE(wm8960_dapm_widgets_out3));
- snd_soc_dapm_add_routes(codec, audio_paths_out3,
+ snd_soc_dapm_add_routes(dapm, audio_paths_out3,
ARRAY_SIZE(audio_paths_out3));
}
@@ -417,7 +418,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
* list each time to find the desired power state do so now
* and save the result.
*/
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &codec->dapm.widgets, list) {
if (strcmp(w->name, "LOUT1 PGA") == 0)
wm8960->lout1 = w;
if (strcmp(w->name, "ROUT1 PGA") == 0)
@@ -572,7 +573,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable anti-pop features */
snd_soc_write(codec, WM8960_APOP1,
WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -610,7 +611,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -626,7 +627,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_PREPARE:
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
/* Enable anti pop mode */
snd_soc_update_bits(codec, WM8960_APOP1,
@@ -681,7 +682,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_PREPARE:
/* Disable HP discharge */
snd_soc_update_bits(codec, WM8960_APOP2,
@@ -705,7 +706,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 8340485c9851..6b22ef200e20 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -882,7 +881,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_PREPARE:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
/* Enable bias generation */
reg = snd_soc_read(codec, WM8961_ANTI_POP);
reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
@@ -897,7 +896,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_PREPARE) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
/* VREF off */
reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
reg &= ~WM8961_VREF;
@@ -919,7 +918,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -959,6 +958,7 @@ static struct snd_soc_dai_driver wm8961_dai = {
static int wm8961_probe(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
u16 reg;
@@ -1024,9 +1024,9 @@ static int wm8961_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8961_snd_controls,
ARRAY_SIZE(wm8961_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
ARRAY_SIZE(wm8961_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return 0;
}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 1304ca91a11c..f0c9d2691842 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -29,7 +29,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8962.h>
@@ -1958,7 +1957,7 @@ static int wm8962_readable_register(unsigned int reg)
static int wm8962_reset(struct snd_soc_codec *codec)
{
- return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0);
+ return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
}
static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2682,6 +2681,7 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
static int wm8962_add_widgets(struct snd_soc_codec *codec)
{
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
snd_soc_add_controls(codec, wm8962_snd_controls,
ARRAY_SIZE(wm8962_snd_controls));
@@ -2693,26 +2693,26 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
ARRAY_SIZE(wm8962_spk_stereo_controls));
- snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
ARRAY_SIZE(wm8962_dapm_widgets));
if (pdata && pdata->spk_mono)
- snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
else
- snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets,
ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
- snd_soc_dapm_add_routes(codec, wm8962_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_intercon,
ARRAY_SIZE(wm8962_intercon));
if (pdata && pdata->spk_mono)
- snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
ARRAY_SIZE(wm8962_spk_mono_intercon));
else
- snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon,
ARRAY_SIZE(wm8962_spk_stereo_intercon));
- snd_soc_dapm_disable_pin(codec, "Beep");
+ snd_soc_dapm_disable_pin(dapm, "Beep");
return 0;
}
@@ -2819,7 +2819,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
int ret;
- if (level == codec->bias_level)
+ if (level == codec->dapm.bias_level)
return 0;
switch (level) {
@@ -2833,7 +2833,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
if (ret != 0) {
@@ -2883,7 +2883,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
wm8962->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -3353,6 +3353,8 @@ static irqreturn_t wm8962_irq(int irq, void *data)
if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
dev_dbg(codec->dev, "Microphone event detected\n");
+ pm_wakeup_event(codec->dev, 300);
+
schedule_delayed_work(&wm8962->mic_work,
msecs_to_jiffies(250));
}
@@ -3439,6 +3441,7 @@ static void wm8962_beep_work(struct work_struct *work)
struct wm8962_priv *wm8962 =
container_of(work, struct wm8962_priv, beep_work);
struct snd_soc_codec *codec = wm8962->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
int reg = 0;
int best = 0;
@@ -3455,16 +3458,16 @@ static void wm8962_beep_work(struct work_struct *work)
reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
- snd_soc_dapm_enable_pin(codec, "Beep");
+ snd_soc_dapm_enable_pin(dapm, "Beep");
} else {
dev_dbg(codec->dev, "Disabling beep\n");
- snd_soc_dapm_disable_pin(codec, "Beep");
+ snd_soc_dapm_disable_pin(dapm, "Beep");
}
snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
/* For usability define a way of injecting beep events for the device -
@@ -3711,7 +3714,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
codec->cache_sync = 1;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
if (ret != 0) {
@@ -3870,7 +3873,6 @@ err_enable:
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
err:
- kfree(wm8962);
return ret;
}
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 63f6dbf5d070..8805636bda53 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8971.h"
@@ -333,10 +332,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8971_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets,
- ARRAY_SIZE(wm8971_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
+ ARRAY_SIZE(wm8971_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -553,7 +553,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8971_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -590,9 +590,11 @@ static struct snd_soc_dai_driver wm8971_dai = {
static void wm8971_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
- wm8971_set_bias_level(codec, codec->bias_level);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context,
+ delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
+ wm8971_set_bias_level(codec, codec->dapm.bias_level);
}
static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -620,11 +622,11 @@ static int wm8971_resume(struct snd_soc_codec *codec)
wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* charge wm8971 caps */
- if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->bias_level = SND_SOC_BIAS_ON;
- queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
msecs_to_jiffies(1000));
}
@@ -643,7 +645,7 @@ static int wm8971_probe(struct snd_soc_codec *codec)
return ret;
}
- INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
wm8971_workq = create_workqueue("wm8971");
if (wm8971_workq == NULL)
return -ENOMEM;
@@ -653,8 +655,8 @@ static int wm8971_probe(struct snd_soc_codec *codec)
/* charge output caps - set vmid to 5k for quick power up */
reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->bias_level = SND_SOC_BIAS_STANDBY;
- queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
+ queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
msecs_to_jiffies(1000));
/* set the update bits */
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index b4363f6d19b3..5d286427532a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -274,10 +273,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8974_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets,
- ARRAY_SIZE(wm8974_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
+ ARRAY_SIZE(wm8974_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -530,7 +530,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
mdelay(100);
@@ -547,7 +547,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 13b979a71a7c..a195af92b425 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -355,11 +354,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8978_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
- ARRAY_SIZE(wm8978_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
+ ARRAY_SIZE(wm8978_dapm_widgets));
/* set up the WM8978 audio map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -837,7 +837,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
/* bit 3: enable bias, bit 2: enable I/O tie off buffer */
power1 |= 0xc;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
power1 | 0x3);
@@ -857,7 +857,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index fd2e7cca1228..bae510acdec8 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -533,10 +532,11 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
static int wm8985_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets,
- ARRAY_SIZE(wm8985_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map,
+ snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
+ ARRAY_SIZE(wm8985_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map,
ARRAY_SIZE(audio_map));
return 0;
}
@@ -879,7 +879,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
1 << WM8985_VMIDSEL_SHIFT);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
wm8985->supplies);
if (ret) {
@@ -939,7 +939,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index d7f259711970..65807b15a2cc 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -25,7 +25,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8988.h"
@@ -677,7 +676,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* VREF, VMID=2x5k */
snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -693,7 +692,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8988_PWR1, 0x0000);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -759,6 +758,7 @@ static int wm8988_resume(struct snd_soc_codec *codec)
static int wm8988_probe(struct snd_soc_codec *codec)
{
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
u16 reg;
@@ -790,9 +790,9 @@ static int wm8988_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8988_snd_controls,
ARRAY_SIZE(wm8988_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
ARRAY_SIZE(wm8988_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 264828e4e67c..5c87a634fc04 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -914,11 +913,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8990_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets,
- ARRAY_SIZE(wm8990_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
+ ARRAY_SIZE(wm8990_dapm_widgets));
/* set up the WM8990 audio map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1170,7 +1170,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable all output discharge bits */
snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1266,7 +1266,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 589e3fa24734..15f34a26debf 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -24,7 +24,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/wm8993.h>
@@ -735,6 +734,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
0);
}
wm8993->class_w_users++;
+ wm8993->hubs_data.class_w = true;
}
/* Implement the change */
@@ -751,6 +751,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
WM8993_CP_DYN_V);
}
wm8993->class_w_users--;
+ wm8993->hubs_data.class_w = false;
}
dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
@@ -968,7 +969,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
wm8993->supplies);
if (ret != 0)
@@ -1029,6 +1030,12 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
0);
+ snd_soc_update_bits(codec, WM8993_ANTIPOP2,
+ WM8993_STARTUP_BIAS_ENA |
+ WM8993_VMID_BUF_ENA |
+ WM8993_VMID_RAMP_MASK |
+ WM8993_BIAS_SRC, 0);
+
#ifdef CONFIG_REGULATOR
/* Post 2.6.34 we will be able to get a callback when
* the regulators are disabled which we can use but
@@ -1043,7 +1050,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1225,7 +1232,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
- wm8993->fs);
for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
cur_val = abs((wm8993->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8993->fs);;
+ clk_sys_rates[i].ratio) - wm8993->fs);
if (cur_val < best_val) {
best = i;
best_val = cur_val;
@@ -1422,6 +1429,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
static int wm8993_probe(struct snd_soc_codec *codec)
{
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i, val;
wm8993->hubs_data.hp_startup_mode = 1;
@@ -1503,11 +1511,11 @@ static int wm8993_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(wm8993_eq_controls));
}
- snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
ARRAY_SIZE(wm8993_dapm_widgets));
wm_hubs_add_analogue_controls(codec);
- snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
+ snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
wm8993->pdata.lineout2_diff);
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
new file mode 100644
index 000000000000..68e9b024dd48
--- /dev/null
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -0,0 +1,3147 @@
+#include "wm8994.h"
+
+const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
+ { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
+ { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
+ { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
+ { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
+ { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
+ { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
+ { 0x003F, 0x003F }, /* R6 - Power Management (6) */
+ { 0x0000, 0x0000 }, /* R7 */
+ { 0x0000, 0x0000 }, /* R8 */
+ { 0x0000, 0x0000 }, /* R9 */
+ { 0x0000, 0x0000 }, /* R10 */
+ { 0x0000, 0x0000 }, /* R11 */
+ { 0x0000, 0x0000 }, /* R12 */
+ { 0x0000, 0x0000 }, /* R13 */
+ { 0x0000, 0x0000 }, /* R14 */
+ { 0x0000, 0x0000 }, /* R15 */
+ { 0x0000, 0x0000 }, /* R16 */
+ { 0x0000, 0x0000 }, /* R17 */
+ { 0x0000, 0x0000 }, /* R18 */
+ { 0x0000, 0x0000 }, /* R19 */
+ { 0x0000, 0x0000 }, /* R20 */
+ { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
+ { 0x0000, 0x0000 }, /* R22 */
+ { 0x0000, 0x0000 }, /* R23 */
+ { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
+ { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
+ { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
+ { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
+ { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
+ { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
+ { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
+ { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
+ { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
+ { 0x003F, 0x003F }, /* R37 - ClassD */
+ { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
+ { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
+ { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
+ { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
+ { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
+ { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
+ { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
+ { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
+ { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
+ { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
+ { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
+ { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
+ { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
+ { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
+ { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
+ { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
+ { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
+ { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
+ { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
+ { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
+ { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
+ { 0x000F, 0x000F }, /* R59 - LDO 1 */
+ { 0x0007, 0x0007 }, /* R60 - LDO 2 */
+ { 0x0000, 0x0000 }, /* R61 */
+ { 0x0000, 0x0000 }, /* R62 */
+ { 0x0000, 0x0000 }, /* R63 */
+ { 0x0000, 0x0000 }, /* R64 */
+ { 0x0000, 0x0000 }, /* R65 */
+ { 0x0000, 0x0000 }, /* R66 */
+ { 0x0000, 0x0000 }, /* R67 */
+ { 0x0000, 0x0000 }, /* R68 */
+ { 0x0000, 0x0000 }, /* R69 */
+ { 0x0000, 0x0000 }, /* R70 */
+ { 0x0000, 0x0000 }, /* R71 */
+ { 0x0000, 0x0000 }, /* R72 */
+ { 0x0000, 0x0000 }, /* R73 */
+ { 0x0000, 0x0000 }, /* R74 */
+ { 0x0000, 0x0000 }, /* R75 */
+ { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
+ { 0x0000, 0x0000 }, /* R77 */
+ { 0x0000, 0x0000 }, /* R78 */
+ { 0x0000, 0x0000 }, /* R79 */
+ { 0x0000, 0x0000 }, /* R80 */
+ { 0x0301, 0x0301 }, /* R81 - Class W (1) */
+ { 0x0000, 0x0000 }, /* R82 */
+ { 0x0000, 0x0000 }, /* R83 */
+ { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
+ { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
+ { 0x0000, 0x0000 }, /* R86 */
+ { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
+ { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
+ { 0x0000, 0x0000 }, /* R89 */
+ { 0x0000, 0x0000 }, /* R90 */
+ { 0x0000, 0x0000 }, /* R91 */
+ { 0x0000, 0x0000 }, /* R92 */
+ { 0x0000, 0x0000 }, /* R93 */
+ { 0x0000, 0x0000 }, /* R94 */
+ { 0x0000, 0x0000 }, /* R95 */
+ { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
+ { 0x0000, 0x0000 }, /* R97 */
+ { 0x0000, 0x0000 }, /* R98 */
+ { 0x0000, 0x0000 }, /* R99 */
+ { 0x0000, 0x0000 }, /* R100 */
+ { 0x0000, 0x0000 }, /* R101 */
+ { 0x0000, 0x0000 }, /* R102 */
+ { 0x0000, 0x0000 }, /* R103 */
+ { 0x0000, 0x0000 }, /* R104 */
+ { 0x0000, 0x0000 }, /* R105 */
+ { 0x0000, 0x0000 }, /* R106 */
+ { 0x0000, 0x0000 }, /* R107 */
+ { 0x0000, 0x0000 }, /* R108 */
+ { 0x0000, 0x0000 }, /* R109 */
+ { 0x0000, 0x0000 }, /* R110 */
+ { 0x0000, 0x0000 }, /* R111 */
+ { 0x0000, 0x0000 }, /* R112 */
+ { 0x0000, 0x0000 }, /* R113 */
+ { 0x0000, 0x0000 }, /* R114 */
+ { 0x0000, 0x0000 }, /* R115 */
+ { 0x0000, 0x0000 }, /* R116 */
+ { 0x0000, 0x0000 }, /* R117 */
+ { 0x0000, 0x0000 }, /* R118 */
+ { 0x0000, 0x0000 }, /* R119 */
+ { 0x0000, 0x0000 }, /* R120 */
+ { 0x0000, 0x0000 }, /* R121 */
+ { 0x0000, 0x0000 }, /* R122 */
+ { 0x0000, 0x0000 }, /* R123 */
+ { 0x0000, 0x0000 }, /* R124 */
+ { 0x0000, 0x0000 }, /* R125 */
+ { 0x0000, 0x0000 }, /* R126 */
+ { 0x0000, 0x0000 }, /* R127 */
+ { 0x0000, 0x0000 }, /* R128 */
+ { 0x0000, 0x0000 }, /* R129 */
+ { 0x0000, 0x0000 }, /* R130 */
+ { 0x0000, 0x0000 }, /* R131 */
+ { 0x0000, 0x0000 }, /* R132 */
+ { 0x0000, 0x0000 }, /* R133 */
+ { 0x0000, 0x0000 }, /* R134 */
+ { 0x0000, 0x0000 }, /* R135 */
+ { 0x0000, 0x0000 }, /* R136 */
+ { 0x0000, 0x0000 }, /* R137 */
+ { 0x0000, 0x0000 }, /* R138 */
+ { 0x0000, 0x0000 }, /* R139 */
+ { 0x0000, 0x0000 }, /* R140 */
+ { 0x0000, 0x0000 }, /* R141 */
+ { 0x0000, 0x0000 }, /* R142 */
+ { 0x0000, 0x0000 }, /* R143 */
+ { 0x0000, 0x0000 }, /* R144 */
+ { 0x0000, 0x0000 }, /* R145 */
+ { 0x0000, 0x0000 }, /* R146 */
+ { 0x0000, 0x0000 }, /* R147 */
+ { 0x0000, 0x0000 }, /* R148 */
+ { 0x0000, 0x0000 }, /* R149 */
+ { 0x0000, 0x0000 }, /* R150 */
+ { 0x0000, 0x0000 }, /* R151 */
+ { 0x0000, 0x0000 }, /* R152 */
+ { 0x0000, 0x0000 }, /* R153 */
+ { 0x0000, 0x0000 }, /* R154 */
+ { 0x0000, 0x0000 }, /* R155 */
+ { 0x0000, 0x0000 }, /* R156 */
+ { 0x0000, 0x0000 }, /* R157 */
+ { 0x0000, 0x0000 }, /* R158 */
+ { 0x0000, 0x0000 }, /* R159 */
+ { 0x0000, 0x0000 }, /* R160 */
+ { 0x0000, 0x0000 }, /* R161 */
+ { 0x0000, 0x0000 }, /* R162 */
+ { 0x0000, 0x0000 }, /* R163 */
+ { 0x0000, 0x0000 }, /* R164 */
+ { 0x0000, 0x0000 }, /* R165 */
+ { 0x0000, 0x0000 }, /* R166 */
+ { 0x0000, 0x0000 }, /* R167 */
+ { 0x0000, 0x0000 }, /* R168 */
+ { 0x0000, 0x0000 }, /* R169 */
+ { 0x0000, 0x0000 }, /* R170 */
+ { 0x0000, 0x0000 }, /* R171 */
+ { 0x0000, 0x0000 }, /* R172 */
+ { 0x0000, 0x0000 }, /* R173 */
+ { 0x0000, 0x0000 }, /* R174 */
+ { 0x0000, 0x0000 }, /* R175 */
+ { 0x0000, 0x0000 }, /* R176 */
+ { 0x0000, 0x0000 }, /* R177 */
+ { 0x0000, 0x0000 }, /* R178 */
+ { 0x0000, 0x0000 }, /* R179 */
+ { 0x0000, 0x0000 }, /* R180 */
+ { 0x0000, 0x0000 }, /* R181 */
+ { 0x0000, 0x0000 }, /* R182 */
+ { 0x0000, 0x0000 }, /* R183 */
+ { 0x0000, 0x0000 }, /* R184 */
+ { 0x0000, 0x0000 }, /* R185 */
+ { 0x0000, 0x0000 }, /* R186 */
+ { 0x0000, 0x0000 }, /* R187 */
+ { 0x0000, 0x0000 }, /* R188 */
+ { 0x0000, 0x0000 }, /* R189 */
+ { 0x0000, 0x0000 }, /* R190 */
+ { 0x0000, 0x0000 }, /* R191 */
+ { 0x0000, 0x0000 }, /* R192 */
+ { 0x0000, 0x0000 }, /* R193 */
+ { 0x0000, 0x0000 }, /* R194 */
+ { 0x0000, 0x0000 }, /* R195 */
+ { 0x0000, 0x0000 }, /* R196 */
+ { 0x0000, 0x0000 }, /* R197 */
+ { 0x0000, 0x0000 }, /* R198 */
+ { 0x0000, 0x0000 }, /* R199 */
+ { 0x0000, 0x0000 }, /* R200 */
+ { 0x0000, 0x0000 }, /* R201 */
+ { 0x0000, 0x0000 }, /* R202 */
+ { 0x0000, 0x0000 }, /* R203 */
+ { 0x0000, 0x0000 }, /* R204 */
+ { 0x0000, 0x0000 }, /* R205 */
+ { 0x0000, 0x0000 }, /* R206 */
+ { 0x0000, 0x0000 }, /* R207 */
+ { 0x0000, 0x0000 }, /* R208 */
+ { 0x0000, 0x0000 }, /* R209 */
+ { 0x0000, 0x0000 }, /* R210 */
+ { 0x0000, 0x0000 }, /* R211 */
+ { 0x0000, 0x0000 }, /* R212 */
+ { 0x0000, 0x0000 }, /* R213 */
+ { 0x0000, 0x0000 }, /* R214 */
+ { 0x0000, 0x0000 }, /* R215 */
+ { 0x0000, 0x0000 }, /* R216 */
+ { 0x0000, 0x0000 }, /* R217 */
+ { 0x0000, 0x0000 }, /* R218 */
+ { 0x0000, 0x0000 }, /* R219 */
+ { 0x0000, 0x0000 }, /* R220 */
+ { 0x0000, 0x0000 }, /* R221 */
+ { 0x0000, 0x0000 }, /* R222 */
+ { 0x0000, 0x0000 }, /* R223 */
+ { 0x0000, 0x0000 }, /* R224 */
+ { 0x0000, 0x0000 }, /* R225 */
+ { 0x0000, 0x0000 }, /* R226 */
+ { 0x0000, 0x0000 }, /* R227 */
+ { 0x0000, 0x0000 }, /* R228 */
+ { 0x0000, 0x0000 }, /* R229 */
+ { 0x0000, 0x0000 }, /* R230 */
+ { 0x0000, 0x0000 }, /* R231 */
+ { 0x0000, 0x0000 }, /* R232 */
+ { 0x0000, 0x0000 }, /* R233 */
+ { 0x0000, 0x0000 }, /* R234 */
+ { 0x0000, 0x0000 }, /* R235 */
+ { 0x0000, 0x0000 }, /* R236 */
+ { 0x0000, 0x0000 }, /* R237 */
+ { 0x0000, 0x0000 }, /* R238 */
+ { 0x0000, 0x0000 }, /* R239 */
+ { 0x0000, 0x0000 }, /* R240 */
+ { 0x0000, 0x0000 }, /* R241 */
+ { 0x0000, 0x0000 }, /* R242 */
+ { 0x0000, 0x0000 }, /* R243 */
+ { 0x0000, 0x0000 }, /* R244 */
+ { 0x0000, 0x0000 }, /* R245 */
+ { 0x0000, 0x0000 }, /* R246 */
+ { 0x0000, 0x0000 }, /* R247 */
+ { 0x0000, 0x0000 }, /* R248 */
+ { 0x0000, 0x0000 }, /* R249 */
+ { 0x0000, 0x0000 }, /* R250 */
+ { 0x0000, 0x0000 }, /* R251 */
+ { 0x0000, 0x0000 }, /* R252 */
+ { 0x0000, 0x0000 }, /* R253 */
+ { 0x0000, 0x0000 }, /* R254 */
+ { 0x0000, 0x0000 }, /* R255 */
+ { 0x000F, 0x0000 }, /* R256 - Chip Revision */
+ { 0x0074, 0x0074 }, /* R257 - Control Interface */
+ { 0x0000, 0x0000 }, /* R258 */
+ { 0x0000, 0x0000 }, /* R259 */
+ { 0x0000, 0x0000 }, /* R260 */
+ { 0x0000, 0x0000 }, /* R261 */
+ { 0x0000, 0x0000 }, /* R262 */
+ { 0x0000, 0x0000 }, /* R263 */
+ { 0x0000, 0x0000 }, /* R264 */
+ { 0x0000, 0x0000 }, /* R265 */
+ { 0x0000, 0x0000 }, /* R266 */
+ { 0x0000, 0x0000 }, /* R267 */
+ { 0x0000, 0x0000 }, /* R268 */
+ { 0x0000, 0x0000 }, /* R269 */
+ { 0x0000, 0x0000 }, /* R270 */
+ { 0x0000, 0x0000 }, /* R271 */
+ { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
+ { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
+ { 0x0000, 0x0000 }, /* R274 */
+ { 0x0000, 0x0000 }, /* R275 */
+ { 0x0000, 0x0000 }, /* R276 */
+ { 0x0000, 0x0000 }, /* R277 */
+ { 0x0000, 0x0000 }, /* R278 */
+ { 0x0000, 0x0000 }, /* R279 */
+ { 0x0000, 0x0000 }, /* R280 */
+ { 0x0000, 0x0000 }, /* R281 */
+ { 0x0000, 0x0000 }, /* R282 */
+ { 0x0000, 0x0000 }, /* R283 */
+ { 0x0000, 0x0000 }, /* R284 */
+ { 0x0000, 0x0000 }, /* R285 */
+ { 0x0000, 0x0000 }, /* R286 */
+ { 0x0000, 0x0000 }, /* R287 */
+ { 0x0000, 0x0000 }, /* R288 */
+ { 0x0000, 0x0000 }, /* R289 */
+ { 0x0000, 0x0000 }, /* R290 */
+ { 0x0000, 0x0000 }, /* R291 */
+ { 0x0000, 0x0000 }, /* R292 */
+ { 0x0000, 0x0000 }, /* R293 */
+ { 0x0000, 0x0000 }, /* R294 */
+ { 0x0000, 0x0000 }, /* R295 */
+ { 0x0000, 0x0000 }, /* R296 */
+ { 0x0000, 0x0000 }, /* R297 */
+ { 0x0000, 0x0000 }, /* R298 */
+ { 0x0000, 0x0000 }, /* R299 */
+ { 0x0000, 0x0000 }, /* R300 */
+ { 0x0000, 0x0000 }, /* R301 */
+ { 0x0000, 0x0000 }, /* R302 */
+ { 0x0000, 0x0000 }, /* R303 */
+ { 0x0000, 0x0000 }, /* R304 */
+ { 0x0000, 0x0000 }, /* R305 */
+ { 0x0000, 0x0000 }, /* R306 */
+ { 0x0000, 0x0000 }, /* R307 */
+ { 0x0000, 0x0000 }, /* R308 */
+ { 0x0000, 0x0000 }, /* R309 */
+ { 0x0000, 0x0000 }, /* R310 */
+ { 0x0000, 0x0000 }, /* R311 */
+ { 0x0000, 0x0000 }, /* R312 */
+ { 0x0000, 0x0000 }, /* R313 */
+ { 0x0000, 0x0000 }, /* R314 */
+ { 0x0000, 0x0000 }, /* R315 */
+ { 0x0000, 0x0000 }, /* R316 */
+ { 0x0000, 0x0000 }, /* R317 */
+ { 0x0000, 0x0000 }, /* R318 */
+ { 0x0000, 0x0000 }, /* R319 */
+ { 0x0000, 0x0000 }, /* R320 */
+ { 0x0000, 0x0000 }, /* R321 */
+ { 0x0000, 0x0000 }, /* R322 */
+ { 0x0000, 0x0000 }, /* R323 */
+ { 0x0000, 0x0000 }, /* R324 */
+ { 0x0000, 0x0000 }, /* R325 */
+ { 0x0000, 0x0000 }, /* R326 */
+ { 0x0000, 0x0000 }, /* R327 */
+ { 0x0000, 0x0000 }, /* R328 */
+ { 0x0000, 0x0000 }, /* R329 */
+ { 0x0000, 0x0000 }, /* R330 */
+ { 0x0000, 0x0000 }, /* R331 */
+ { 0x0000, 0x0000 }, /* R332 */
+ { 0x0000, 0x0000 }, /* R333 */
+ { 0x0000, 0x0000 }, /* R334 */
+ { 0x0000, 0x0000 }, /* R335 */
+ { 0x0000, 0x0000 }, /* R336 */
+ { 0x0000, 0x0000 }, /* R337 */
+ { 0x0000, 0x0000 }, /* R338 */
+ { 0x0000, 0x0000 }, /* R339 */
+ { 0x0000, 0x0000 }, /* R340 */
+ { 0x0000, 0x0000 }, /* R341 */
+ { 0x0000, 0x0000 }, /* R342 */
+ { 0x0000, 0x0000 }, /* R343 */
+ { 0x0000, 0x0000 }, /* R344 */
+ { 0x0000, 0x0000 }, /* R345 */
+ { 0x0000, 0x0000 }, /* R346 */
+ { 0x0000, 0x0000 }, /* R347 */
+ { 0x0000, 0x0000 }, /* R348 */
+ { 0x0000, 0x0000 }, /* R349 */
+ { 0x0000, 0x0000 }, /* R350 */
+ { 0x0000, 0x0000 }, /* R351 */
+ { 0x0000, 0x0000 }, /* R352 */
+ { 0x0000, 0x0000 }, /* R353 */
+ { 0x0000, 0x0000 }, /* R354 */
+ { 0x0000, 0x0000 }, /* R355 */
+ { 0x0000, 0x0000 }, /* R356 */
+ { 0x0000, 0x0000 }, /* R357 */
+ { 0x0000, 0x0000 }, /* R358 */
+ { 0x0000, 0x0000 }, /* R359 */
+ { 0x0000, 0x0000 }, /* R360 */
+ { 0x0000, 0x0000 }, /* R361 */
+ { 0x0000, 0x0000 }, /* R362 */
+ { 0x0000, 0x0000 }, /* R363 */
+ { 0x0000, 0x0000 }, /* R364 */
+ { 0x0000, 0x0000 }, /* R365 */
+ { 0x0000, 0x0000 }, /* R366 */
+ { 0x0000, 0x0000 }, /* R367 */
+ { 0x0000, 0x0000 }, /* R368 */
+ { 0x0000, 0x0000 }, /* R369 */
+ { 0x0000, 0x0000 }, /* R370 */
+ { 0x0000, 0x0000 }, /* R371 */
+ { 0x0000, 0x0000 }, /* R372 */
+ { 0x0000, 0x0000 }, /* R373 */
+ { 0x0000, 0x0000 }, /* R374 */
+ { 0x0000, 0x0000 }, /* R375 */
+ { 0x0000, 0x0000 }, /* R376 */
+ { 0x0000, 0x0000 }, /* R377 */
+ { 0x0000, 0x0000 }, /* R378 */
+ { 0x0000, 0x0000 }, /* R379 */
+ { 0x0000, 0x0000 }, /* R380 */
+ { 0x0000, 0x0000 }, /* R381 */
+ { 0x0000, 0x0000 }, /* R382 */
+ { 0x0000, 0x0000 }, /* R383 */
+ { 0x0000, 0x0000 }, /* R384 */
+ { 0x0000, 0x0000 }, /* R385 */
+ { 0x0000, 0x0000 }, /* R386 */
+ { 0x0000, 0x0000 }, /* R387 */
+ { 0x0000, 0x0000 }, /* R388 */
+ { 0x0000, 0x0000 }, /* R389 */
+ { 0x0000, 0x0000 }, /* R390 */
+ { 0x0000, 0x0000 }, /* R391 */
+ { 0x0000, 0x0000 }, /* R392 */
+ { 0x0000, 0x0000 }, /* R393 */
+ { 0x0000, 0x0000 }, /* R394 */
+ { 0x0000, 0x0000 }, /* R395 */
+ { 0x0000, 0x0000 }, /* R396 */
+ { 0x0000, 0x0000 }, /* R397 */
+ { 0x0000, 0x0000 }, /* R398 */
+ { 0x0000, 0x0000 }, /* R399 */
+ { 0x0000, 0x0000 }, /* R400 */
+ { 0x0000, 0x0000 }, /* R401 */
+ { 0x0000, 0x0000 }, /* R402 */
+ { 0x0000, 0x0000 }, /* R403 */
+ { 0x0000, 0x0000 }, /* R404 */
+ { 0x0000, 0x0000 }, /* R405 */
+ { 0x0000, 0x0000 }, /* R406 */
+ { 0x0000, 0x0000 }, /* R407 */
+ { 0x0000, 0x0000 }, /* R408 */
+ { 0x0000, 0x0000 }, /* R409 */
+ { 0x0000, 0x0000 }, /* R410 */
+ { 0x0000, 0x0000 }, /* R411 */
+ { 0x0000, 0x0000 }, /* R412 */
+ { 0x0000, 0x0000 }, /* R413 */
+ { 0x0000, 0x0000 }, /* R414 */
+ { 0x0000, 0x0000 }, /* R415 */
+ { 0x0000, 0x0000 }, /* R416 */
+ { 0x0000, 0x0000 }, /* R417 */
+ { 0x0000, 0x0000 }, /* R418 */
+ { 0x0000, 0x0000 }, /* R419 */
+ { 0x0000, 0x0000 }, /* R420 */
+ { 0x0000, 0x0000 }, /* R421 */
+ { 0x0000, 0x0000 }, /* R422 */
+ { 0x0000, 0x0000 }, /* R423 */
+ { 0x0000, 0x0000 }, /* R424 */
+ { 0x0000, 0x0000 }, /* R425 */
+ { 0x0000, 0x0000 }, /* R426 */
+ { 0x0000, 0x0000 }, /* R427 */
+ { 0x0000, 0x0000 }, /* R428 */
+ { 0x0000, 0x0000 }, /* R429 */
+ { 0x0000, 0x0000 }, /* R430 */
+ { 0x0000, 0x0000 }, /* R431 */
+ { 0x0000, 0x0000 }, /* R432 */
+ { 0x0000, 0x0000 }, /* R433 */
+ { 0x0000, 0x0000 }, /* R434 */
+ { 0x0000, 0x0000 }, /* R435 */
+ { 0x0000, 0x0000 }, /* R436 */
+ { 0x0000, 0x0000 }, /* R437 */
+ { 0x0000, 0x0000 }, /* R438 */
+ { 0x0000, 0x0000 }, /* R439 */
+ { 0x0000, 0x0000 }, /* R440 */
+ { 0x0000, 0x0000 }, /* R441 */
+ { 0x0000, 0x0000 }, /* R442 */
+ { 0x0000, 0x0000 }, /* R443 */
+ { 0x0000, 0x0000 }, /* R444 */
+ { 0x0000, 0x0000 }, /* R445 */
+ { 0x0000, 0x0000 }, /* R446 */
+ { 0x0000, 0x0000 }, /* R447 */
+ { 0x0000, 0x0000 }, /* R448 */
+ { 0x0000, 0x0000 }, /* R449 */
+ { 0x0000, 0x0000 }, /* R450 */
+ { 0x0000, 0x0000 }, /* R451 */
+ { 0x0000, 0x0000 }, /* R452 */
+ { 0x0000, 0x0000 }, /* R453 */
+ { 0x0000, 0x0000 }, /* R454 */
+ { 0x0000, 0x0000 }, /* R455 */
+ { 0x0000, 0x0000 }, /* R456 */
+ { 0x0000, 0x0000 }, /* R457 */
+ { 0x0000, 0x0000 }, /* R458 */
+ { 0x0000, 0x0000 }, /* R459 */
+ { 0x0000, 0x0000 }, /* R460 */
+ { 0x0000, 0x0000 }, /* R461 */
+ { 0x0000, 0x0000 }, /* R462 */
+ { 0x0000, 0x0000 }, /* R463 */
+ { 0x0000, 0x0000 }, /* R464 */
+ { 0x0000, 0x0000 }, /* R465 */
+ { 0x0000, 0x0000 }, /* R466 */
+ { 0x0000, 0x0000 }, /* R467 */
+ { 0x0000, 0x0000 }, /* R468 */
+ { 0x0000, 0x0000 }, /* R469 */
+ { 0x0000, 0x0000 }, /* R470 */
+ { 0x0000, 0x0000 }, /* R471 */
+ { 0x0000, 0x0000 }, /* R472 */
+ { 0x0000, 0x0000 }, /* R473 */
+ { 0x0000, 0x0000 }, /* R474 */
+ { 0x0000, 0x0000 }, /* R475 */
+ { 0x0000, 0x0000 }, /* R476 */
+ { 0x0000, 0x0000 }, /* R477 */
+ { 0x0000, 0x0000 }, /* R478 */
+ { 0x0000, 0x0000 }, /* R479 */
+ { 0x0000, 0x0000 }, /* R480 */
+ { 0x0000, 0x0000 }, /* R481 */
+ { 0x0000, 0x0000 }, /* R482 */
+ { 0x0000, 0x0000 }, /* R483 */
+ { 0x0000, 0x0000 }, /* R484 */
+ { 0x0000, 0x0000 }, /* R485 */
+ { 0x0000, 0x0000 }, /* R486 */
+ { 0x0000, 0x0000 }, /* R487 */
+ { 0x0000, 0x0000 }, /* R488 */
+ { 0x0000, 0x0000 }, /* R489 */
+ { 0x0000, 0x0000 }, /* R490 */
+ { 0x0000, 0x0000 }, /* R491 */
+ { 0x0000, 0x0000 }, /* R492 */
+ { 0x0000, 0x0000 }, /* R493 */
+ { 0x0000, 0x0000 }, /* R494 */
+ { 0x0000, 0x0000 }, /* R495 */
+ { 0x0000, 0x0000 }, /* R496 */
+ { 0x0000, 0x0000 }, /* R497 */
+ { 0x0000, 0x0000 }, /* R498 */
+ { 0x0000, 0x0000 }, /* R499 */
+ { 0x0000, 0x0000 }, /* R500 */
+ { 0x0000, 0x0000 }, /* R501 */
+ { 0x0000, 0x0000 }, /* R502 */
+ { 0x0000, 0x0000 }, /* R503 */
+ { 0x0000, 0x0000 }, /* R504 */
+ { 0x0000, 0x0000 }, /* R505 */
+ { 0x0000, 0x0000 }, /* R506 */
+ { 0x0000, 0x0000 }, /* R507 */
+ { 0x0000, 0x0000 }, /* R508 */
+ { 0x0000, 0x0000 }, /* R509 */
+ { 0x0000, 0x0000 }, /* R510 */
+ { 0x0000, 0x0000 }, /* R511 */
+ { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
+ { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R514 */
+ { 0x0000, 0x0000 }, /* R515 */
+ { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
+ { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R518 */
+ { 0x0000, 0x0000 }, /* R519 */
+ { 0x001F, 0x001F }, /* R520 - Clocking (1) */
+ { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
+ { 0x0000, 0x0000 }, /* R522 */
+ { 0x0000, 0x0000 }, /* R523 */
+ { 0x0000, 0x0000 }, /* R524 */
+ { 0x0000, 0x0000 }, /* R525 */
+ { 0x0000, 0x0000 }, /* R526 */
+ { 0x0000, 0x0000 }, /* R527 */
+ { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
+ { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
+ { 0x000F, 0x0000 }, /* R530 - Rate Status */
+ { 0x0000, 0x0000 }, /* R531 */
+ { 0x0000, 0x0000 }, /* R532 */
+ { 0x0000, 0x0000 }, /* R533 */
+ { 0x0000, 0x0000 }, /* R534 */
+ { 0x0000, 0x0000 }, /* R535 */
+ { 0x0000, 0x0000 }, /* R536 */
+ { 0x0000, 0x0000 }, /* R537 */
+ { 0x0000, 0x0000 }, /* R538 */
+ { 0x0000, 0x0000 }, /* R539 */
+ { 0x0000, 0x0000 }, /* R540 */
+ { 0x0000, 0x0000 }, /* R541 */
+ { 0x0000, 0x0000 }, /* R542 */
+ { 0x0000, 0x0000 }, /* R543 */
+ { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
+ { 0x0000, 0x0000 }, /* R549 */
+ { 0x0000, 0x0000 }, /* R550 */
+ { 0x0000, 0x0000 }, /* R551 */
+ { 0x0000, 0x0000 }, /* R552 */
+ { 0x0000, 0x0000 }, /* R553 */
+ { 0x0000, 0x0000 }, /* R554 */
+ { 0x0000, 0x0000 }, /* R555 */
+ { 0x0000, 0x0000 }, /* R556 */
+ { 0x0000, 0x0000 }, /* R557 */
+ { 0x0000, 0x0000 }, /* R558 */
+ { 0x0000, 0x0000 }, /* R559 */
+ { 0x0000, 0x0000 }, /* R560 */
+ { 0x0000, 0x0000 }, /* R561 */
+ { 0x0000, 0x0000 }, /* R562 */
+ { 0x0000, 0x0000 }, /* R563 */
+ { 0x0000, 0x0000 }, /* R564 */
+ { 0x0000, 0x0000 }, /* R565 */
+ { 0x0000, 0x0000 }, /* R566 */
+ { 0x0000, 0x0000 }, /* R567 */
+ { 0x0000, 0x0000 }, /* R568 */
+ { 0x0000, 0x0000 }, /* R569 */
+ { 0x0000, 0x0000 }, /* R570 */
+ { 0x0000, 0x0000 }, /* R571 */
+ { 0x0000, 0x0000 }, /* R572 */
+ { 0x0000, 0x0000 }, /* R573 */
+ { 0x0000, 0x0000 }, /* R574 */
+ { 0x0000, 0x0000 }, /* R575 */
+ { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
+ { 0x0000, 0x0000 }, /* R581 */
+ { 0x0000, 0x0000 }, /* R582 */
+ { 0x0000, 0x0000 }, /* R583 */
+ { 0x0000, 0x0000 }, /* R584 */
+ { 0x0000, 0x0000 }, /* R585 */
+ { 0x0000, 0x0000 }, /* R586 */
+ { 0x0000, 0x0000 }, /* R587 */
+ { 0x0000, 0x0000 }, /* R588 */
+ { 0x0000, 0x0000 }, /* R589 */
+ { 0x0000, 0x0000 }, /* R590 */
+ { 0x0000, 0x0000 }, /* R591 */
+ { 0x0000, 0x0000 }, /* R592 */
+ { 0x0000, 0x0000 }, /* R593 */
+ { 0x0000, 0x0000 }, /* R594 */
+ { 0x0000, 0x0000 }, /* R595 */
+ { 0x0000, 0x0000 }, /* R596 */
+ { 0x0000, 0x0000 }, /* R597 */
+ { 0x0000, 0x0000 }, /* R598 */
+ { 0x0000, 0x0000 }, /* R599 */
+ { 0x0000, 0x0000 }, /* R600 */
+ { 0x0000, 0x0000 }, /* R601 */
+ { 0x0000, 0x0000 }, /* R602 */
+ { 0x0000, 0x0000 }, /* R603 */
+ { 0x0000, 0x0000 }, /* R604 */
+ { 0x0000, 0x0000 }, /* R605 */
+ { 0x0000, 0x0000 }, /* R606 */
+ { 0x0000, 0x0000 }, /* R607 */
+ { 0x0000, 0x0000 }, /* R608 */
+ { 0x0000, 0x0000 }, /* R609 */
+ { 0x0000, 0x0000 }, /* R610 */
+ { 0x0000, 0x0000 }, /* R611 */
+ { 0x0000, 0x0000 }, /* R612 */
+ { 0x0000, 0x0000 }, /* R613 */
+ { 0x0000, 0x0000 }, /* R614 */
+ { 0x0000, 0x0000 }, /* R615 */
+ { 0x0000, 0x0000 }, /* R616 */
+ { 0x0000, 0x0000 }, /* R617 */
+ { 0x0000, 0x0000 }, /* R618 */
+ { 0x0000, 0x0000 }, /* R619 */
+ { 0x0000, 0x0000 }, /* R620 */
+ { 0x0000, 0x0000 }, /* R621 */
+ { 0x0000, 0x0000 }, /* R622 */
+ { 0x0000, 0x0000 }, /* R623 */
+ { 0x0000, 0x0000 }, /* R624 */
+ { 0x0000, 0x0000 }, /* R625 */
+ { 0x0000, 0x0000 }, /* R626 */
+ { 0x0000, 0x0000 }, /* R627 */
+ { 0x0000, 0x0000 }, /* R628 */
+ { 0x0000, 0x0000 }, /* R629 */
+ { 0x0000, 0x0000 }, /* R630 */
+ { 0x0000, 0x0000 }, /* R631 */
+ { 0x0000, 0x0000 }, /* R632 */
+ { 0x0000, 0x0000 }, /* R633 */
+ { 0x0000, 0x0000 }, /* R634 */
+ { 0x0000, 0x0000 }, /* R635 */
+ { 0x0000, 0x0000 }, /* R636 */
+ { 0x0000, 0x0000 }, /* R637 */
+ { 0x0000, 0x0000 }, /* R638 */
+ { 0x0000, 0x0000 }, /* R639 */
+ { 0x0000, 0x0000 }, /* R640 */
+ { 0x0000, 0x0000 }, /* R641 */
+ { 0x0000, 0x0000 }, /* R642 */
+ { 0x0000, 0x0000 }, /* R643 */
+ { 0x0000, 0x0000 }, /* R644 */
+ { 0x0000, 0x0000 }, /* R645 */
+ { 0x0000, 0x0000 }, /* R646 */
+ { 0x0000, 0x0000 }, /* R647 */
+ { 0x0000, 0x0000 }, /* R648 */
+ { 0x0000, 0x0000 }, /* R649 */
+ { 0x0000, 0x0000 }, /* R650 */
+ { 0x0000, 0x0000 }, /* R651 */
+ { 0x0000, 0x0000 }, /* R652 */
+ { 0x0000, 0x0000 }, /* R653 */
+ { 0x0000, 0x0000 }, /* R654 */
+ { 0x0000, 0x0000 }, /* R655 */
+ { 0x0000, 0x0000 }, /* R656 */
+ { 0x0000, 0x0000 }, /* R657 */
+ { 0x0000, 0x0000 }, /* R658 */
+ { 0x0000, 0x0000 }, /* R659 */
+ { 0x0000, 0x0000 }, /* R660 */
+ { 0x0000, 0x0000 }, /* R661 */
+ { 0x0000, 0x0000 }, /* R662 */
+ { 0x0000, 0x0000 }, /* R663 */
+ { 0x0000, 0x0000 }, /* R664 */
+ { 0x0000, 0x0000 }, /* R665 */
+ { 0x0000, 0x0000 }, /* R666 */
+ { 0x0000, 0x0000 }, /* R667 */
+ { 0x0000, 0x0000 }, /* R668 */
+ { 0x0000, 0x0000 }, /* R669 */
+ { 0x0000, 0x0000 }, /* R670 */
+ { 0x0000, 0x0000 }, /* R671 */
+ { 0x0000, 0x0000 }, /* R672 */
+ { 0x0000, 0x0000 }, /* R673 */
+ { 0x0000, 0x0000 }, /* R674 */
+ { 0x0000, 0x0000 }, /* R675 */
+ { 0x0000, 0x0000 }, /* R676 */
+ { 0x0000, 0x0000 }, /* R677 */
+ { 0x0000, 0x0000 }, /* R678 */
+ { 0x0000, 0x0000 }, /* R679 */
+ { 0x0000, 0x0000 }, /* R680 */
+ { 0x0000, 0x0000 }, /* R681 */
+ { 0x0000, 0x0000 }, /* R682 */
+ { 0x0000, 0x0000 }, /* R683 */
+ { 0x0000, 0x0000 }, /* R684 */
+ { 0x0000, 0x0000 }, /* R685 */
+ { 0x0000, 0x0000 }, /* R686 */
+ { 0x0000, 0x0000 }, /* R687 */
+ { 0x0000, 0x0000 }, /* R688 */
+ { 0x0000, 0x0000 }, /* R689 */
+ { 0x0000, 0x0000 }, /* R690 */
+ { 0x0000, 0x0000 }, /* R691 */
+ { 0x0000, 0x0000 }, /* R692 */
+ { 0x0000, 0x0000 }, /* R693 */
+ { 0x0000, 0x0000 }, /* R694 */
+ { 0x0000, 0x0000 }, /* R695 */
+ { 0x0000, 0x0000 }, /* R696 */
+ { 0x0000, 0x0000 }, /* R697 */
+ { 0x0000, 0x0000 }, /* R698 */
+ { 0x0000, 0x0000 }, /* R699 */
+ { 0x0000, 0x0000 }, /* R700 */
+ { 0x0000, 0x0000 }, /* R701 */
+ { 0x0000, 0x0000 }, /* R702 */
+ { 0x0000, 0x0000 }, /* R703 */
+ { 0x0000, 0x0000 }, /* R704 */
+ { 0x0000, 0x0000 }, /* R705 */
+ { 0x0000, 0x0000 }, /* R706 */
+ { 0x0000, 0x0000 }, /* R707 */
+ { 0x0000, 0x0000 }, /* R708 */
+ { 0x0000, 0x0000 }, /* R709 */
+ { 0x0000, 0x0000 }, /* R710 */
+ { 0x0000, 0x0000 }, /* R711 */
+ { 0x0000, 0x0000 }, /* R712 */
+ { 0x0000, 0x0000 }, /* R713 */
+ { 0x0000, 0x0000 }, /* R714 */
+ { 0x0000, 0x0000 }, /* R715 */
+ { 0x0000, 0x0000 }, /* R716 */
+ { 0x0000, 0x0000 }, /* R717 */
+ { 0x0000, 0x0000 }, /* R718 */
+ { 0x0000, 0x0000 }, /* R719 */
+ { 0x0000, 0x0000 }, /* R720 */
+ { 0x0000, 0x0000 }, /* R721 */
+ { 0x0000, 0x0000 }, /* R722 */
+ { 0x0000, 0x0000 }, /* R723 */
+ { 0x0000, 0x0000 }, /* R724 */
+ { 0x0000, 0x0000 }, /* R725 */
+ { 0x0000, 0x0000 }, /* R726 */
+ { 0x0000, 0x0000 }, /* R727 */
+ { 0x0000, 0x0000 }, /* R728 */
+ { 0x0000, 0x0000 }, /* R729 */
+ { 0x0000, 0x0000 }, /* R730 */
+ { 0x0000, 0x0000 }, /* R731 */
+ { 0x0000, 0x0000 }, /* R732 */
+ { 0x0000, 0x0000 }, /* R733 */
+ { 0x0000, 0x0000 }, /* R734 */
+ { 0x0000, 0x0000 }, /* R735 */
+ { 0x0000, 0x0000 }, /* R736 */
+ { 0x0000, 0x0000 }, /* R737 */
+ { 0x0000, 0x0000 }, /* R738 */
+ { 0x0000, 0x0000 }, /* R739 */
+ { 0x0000, 0x0000 }, /* R740 */
+ { 0x0000, 0x0000 }, /* R741 */
+ { 0x0000, 0x0000 }, /* R742 */
+ { 0x0000, 0x0000 }, /* R743 */
+ { 0x0000, 0x0000 }, /* R744 */
+ { 0x0000, 0x0000 }, /* R745 */
+ { 0x0000, 0x0000 }, /* R746 */
+ { 0x0000, 0x0000 }, /* R747 */
+ { 0x0000, 0x0000 }, /* R748 */
+ { 0x0000, 0x0000 }, /* R749 */
+ { 0x0000, 0x0000 }, /* R750 */
+ { 0x0000, 0x0000 }, /* R751 */
+ { 0x0000, 0x0000 }, /* R752 */
+ { 0x0000, 0x0000 }, /* R753 */
+ { 0x0000, 0x0000 }, /* R754 */
+ { 0x0000, 0x0000 }, /* R755 */
+ { 0x0000, 0x0000 }, /* R756 */
+ { 0x0000, 0x0000 }, /* R757 */
+ { 0x0000, 0x0000 }, /* R758 */
+ { 0x0000, 0x0000 }, /* R759 */
+ { 0x0000, 0x0000 }, /* R760 */
+ { 0x0000, 0x0000 }, /* R761 */
+ { 0x0000, 0x0000 }, /* R762 */
+ { 0x0000, 0x0000 }, /* R763 */
+ { 0x0000, 0x0000 }, /* R764 */
+ { 0x0000, 0x0000 }, /* R765 */
+ { 0x0000, 0x0000 }, /* R766 */
+ { 0x0000, 0x0000 }, /* R767 */
+ { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
+ { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
+ { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
+ { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
+ { 0x0000, 0x0000 }, /* R776 */
+ { 0x0000, 0x0000 }, /* R777 */
+ { 0x0000, 0x0000 }, /* R778 */
+ { 0x0000, 0x0000 }, /* R779 */
+ { 0x0000, 0x0000 }, /* R780 */
+ { 0x0000, 0x0000 }, /* R781 */
+ { 0x0000, 0x0000 }, /* R782 */
+ { 0x0000, 0x0000 }, /* R783 */
+ { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
+ { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
+ { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
+ { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
+ { 0x0000, 0x0000 }, /* R792 */
+ { 0x0000, 0x0000 }, /* R793 */
+ { 0x0000, 0x0000 }, /* R794 */
+ { 0x0000, 0x0000 }, /* R795 */
+ { 0x0000, 0x0000 }, /* R796 */
+ { 0x0000, 0x0000 }, /* R797 */
+ { 0x0000, 0x0000 }, /* R798 */
+ { 0x0000, 0x0000 }, /* R799 */
+ { 0x0000, 0x0000 }, /* R800 */
+ { 0x0000, 0x0000 }, /* R801 */
+ { 0x0000, 0x0000 }, /* R802 */
+ { 0x0000, 0x0000 }, /* R803 */
+ { 0x0000, 0x0000 }, /* R804 */
+ { 0x0000, 0x0000 }, /* R805 */
+ { 0x0000, 0x0000 }, /* R806 */
+ { 0x0000, 0x0000 }, /* R807 */
+ { 0x0000, 0x0000 }, /* R808 */
+ { 0x0000, 0x0000 }, /* R809 */
+ { 0x0000, 0x0000 }, /* R810 */
+ { 0x0000, 0x0000 }, /* R811 */
+ { 0x0000, 0x0000 }, /* R812 */
+ { 0x0000, 0x0000 }, /* R813 */
+ { 0x0000, 0x0000 }, /* R814 */
+ { 0x0000, 0x0000 }, /* R815 */
+ { 0x0000, 0x0000 }, /* R816 */
+ { 0x0000, 0x0000 }, /* R817 */
+ { 0x0000, 0x0000 }, /* R818 */
+ { 0x0000, 0x0000 }, /* R819 */
+ { 0x0000, 0x0000 }, /* R820 */
+ { 0x0000, 0x0000 }, /* R821 */
+ { 0x0000, 0x0000 }, /* R822 */
+ { 0x0000, 0x0000 }, /* R823 */
+ { 0x0000, 0x0000 }, /* R824 */
+ { 0x0000, 0x0000 }, /* R825 */
+ { 0x0000, 0x0000 }, /* R826 */
+ { 0x0000, 0x0000 }, /* R827 */
+ { 0x0000, 0x0000 }, /* R828 */
+ { 0x0000, 0x0000 }, /* R829 */
+ { 0x0000, 0x0000 }, /* R830 */
+ { 0x0000, 0x0000 }, /* R831 */
+ { 0x0000, 0x0000 }, /* R832 */
+ { 0x0000, 0x0000 }, /* R833 */
+ { 0x0000, 0x0000 }, /* R834 */
+ { 0x0000, 0x0000 }, /* R835 */
+ { 0x0000, 0x0000 }, /* R836 */
+ { 0x0000, 0x0000 }, /* R837 */
+ { 0x0000, 0x0000 }, /* R838 */
+ { 0x0000, 0x0000 }, /* R839 */
+ { 0x0000, 0x0000 }, /* R840 */
+ { 0x0000, 0x0000 }, /* R841 */
+ { 0x0000, 0x0000 }, /* R842 */
+ { 0x0000, 0x0000 }, /* R843 */
+ { 0x0000, 0x0000 }, /* R844 */
+ { 0x0000, 0x0000 }, /* R845 */
+ { 0x0000, 0x0000 }, /* R846 */
+ { 0x0000, 0x0000 }, /* R847 */
+ { 0x0000, 0x0000 }, /* R848 */
+ { 0x0000, 0x0000 }, /* R849 */
+ { 0x0000, 0x0000 }, /* R850 */
+ { 0x0000, 0x0000 }, /* R851 */
+ { 0x0000, 0x0000 }, /* R852 */
+ { 0x0000, 0x0000 }, /* R853 */
+ { 0x0000, 0x0000 }, /* R854 */
+ { 0x0000, 0x0000 }, /* R855 */
+ { 0x0000, 0x0000 }, /* R856 */
+ { 0x0000, 0x0000 }, /* R857 */
+ { 0x0000, 0x0000 }, /* R858 */
+ { 0x0000, 0x0000 }, /* R859 */
+ { 0x0000, 0x0000 }, /* R860 */
+ { 0x0000, 0x0000 }, /* R861 */
+ { 0x0000, 0x0000 }, /* R862 */
+ { 0x0000, 0x0000 }, /* R863 */
+ { 0x0000, 0x0000 }, /* R864 */
+ { 0x0000, 0x0000 }, /* R865 */
+ { 0x0000, 0x0000 }, /* R866 */
+ { 0x0000, 0x0000 }, /* R867 */
+ { 0x0000, 0x0000 }, /* R868 */
+ { 0x0000, 0x0000 }, /* R869 */
+ { 0x0000, 0x0000 }, /* R870 */
+ { 0x0000, 0x0000 }, /* R871 */
+ { 0x0000, 0x0000 }, /* R872 */
+ { 0x0000, 0x0000 }, /* R873 */
+ { 0x0000, 0x0000 }, /* R874 */
+ { 0x0000, 0x0000 }, /* R875 */
+ { 0x0000, 0x0000 }, /* R876 */
+ { 0x0000, 0x0000 }, /* R877 */
+ { 0x0000, 0x0000 }, /* R878 */
+ { 0x0000, 0x0000 }, /* R879 */
+ { 0x0000, 0x0000 }, /* R880 */
+ { 0x0000, 0x0000 }, /* R881 */
+ { 0x0000, 0x0000 }, /* R882 */
+ { 0x0000, 0x0000 }, /* R883 */
+ { 0x0000, 0x0000 }, /* R884 */
+ { 0x0000, 0x0000 }, /* R885 */
+ { 0x0000, 0x0000 }, /* R886 */
+ { 0x0000, 0x0000 }, /* R887 */
+ { 0x0000, 0x0000 }, /* R888 */
+ { 0x0000, 0x0000 }, /* R889 */
+ { 0x0000, 0x0000 }, /* R890 */
+ { 0x0000, 0x0000 }, /* R891 */
+ { 0x0000, 0x0000 }, /* R892 */
+ { 0x0000, 0x0000 }, /* R893 */
+ { 0x0000, 0x0000 }, /* R894 */
+ { 0x0000, 0x0000 }, /* R895 */
+ { 0x0000, 0x0000 }, /* R896 */
+ { 0x0000, 0x0000 }, /* R897 */
+ { 0x0000, 0x0000 }, /* R898 */
+ { 0x0000, 0x0000 }, /* R899 */
+ { 0x0000, 0x0000 }, /* R900 */
+ { 0x0000, 0x0000 }, /* R901 */
+ { 0x0000, 0x0000 }, /* R902 */
+ { 0x0000, 0x0000 }, /* R903 */
+ { 0x0000, 0x0000 }, /* R904 */
+ { 0x0000, 0x0000 }, /* R905 */
+ { 0x0000, 0x0000 }, /* R906 */
+ { 0x0000, 0x0000 }, /* R907 */
+ { 0x0000, 0x0000 }, /* R908 */
+ { 0x0000, 0x0000 }, /* R909 */
+ { 0x0000, 0x0000 }, /* R910 */
+ { 0x0000, 0x0000 }, /* R911 */
+ { 0x0000, 0x0000 }, /* R912 */
+ { 0x0000, 0x0000 }, /* R913 */
+ { 0x0000, 0x0000 }, /* R914 */
+ { 0x0000, 0x0000 }, /* R915 */
+ { 0x0000, 0x0000 }, /* R916 */
+ { 0x0000, 0x0000 }, /* R917 */
+ { 0x0000, 0x0000 }, /* R918 */
+ { 0x0000, 0x0000 }, /* R919 */
+ { 0x0000, 0x0000 }, /* R920 */
+ { 0x0000, 0x0000 }, /* R921 */
+ { 0x0000, 0x0000 }, /* R922 */
+ { 0x0000, 0x0000 }, /* R923 */
+ { 0x0000, 0x0000 }, /* R924 */
+ { 0x0000, 0x0000 }, /* R925 */
+ { 0x0000, 0x0000 }, /* R926 */
+ { 0x0000, 0x0000 }, /* R927 */
+ { 0x0000, 0x0000 }, /* R928 */
+ { 0x0000, 0x0000 }, /* R929 */
+ { 0x0000, 0x0000 }, /* R930 */
+ { 0x0000, 0x0000 }, /* R931 */
+ { 0x0000, 0x0000 }, /* R932 */
+ { 0x0000, 0x0000 }, /* R933 */
+ { 0x0000, 0x0000 }, /* R934 */
+ { 0x0000, 0x0000 }, /* R935 */
+ { 0x0000, 0x0000 }, /* R936 */
+ { 0x0000, 0x0000 }, /* R937 */
+ { 0x0000, 0x0000 }, /* R938 */
+ { 0x0000, 0x0000 }, /* R939 */
+ { 0x0000, 0x0000 }, /* R940 */
+ { 0x0000, 0x0000 }, /* R941 */
+ { 0x0000, 0x0000 }, /* R942 */
+ { 0x0000, 0x0000 }, /* R943 */
+ { 0x0000, 0x0000 }, /* R944 */
+ { 0x0000, 0x0000 }, /* R945 */
+ { 0x0000, 0x0000 }, /* R946 */
+ { 0x0000, 0x0000 }, /* R947 */
+ { 0x0000, 0x0000 }, /* R948 */
+ { 0x0000, 0x0000 }, /* R949 */
+ { 0x0000, 0x0000 }, /* R950 */
+ { 0x0000, 0x0000 }, /* R951 */
+ { 0x0000, 0x0000 }, /* R952 */
+ { 0x0000, 0x0000 }, /* R953 */
+ { 0x0000, 0x0000 }, /* R954 */
+ { 0x0000, 0x0000 }, /* R955 */
+ { 0x0000, 0x0000 }, /* R956 */
+ { 0x0000, 0x0000 }, /* R957 */
+ { 0x0000, 0x0000 }, /* R958 */
+ { 0x0000, 0x0000 }, /* R959 */
+ { 0x0000, 0x0000 }, /* R960 */
+ { 0x0000, 0x0000 }, /* R961 */
+ { 0x0000, 0x0000 }, /* R962 */
+ { 0x0000, 0x0000 }, /* R963 */
+ { 0x0000, 0x0000 }, /* R964 */
+ { 0x0000, 0x0000 }, /* R965 */
+ { 0x0000, 0x0000 }, /* R966 */
+ { 0x0000, 0x0000 }, /* R967 */
+ { 0x0000, 0x0000 }, /* R968 */
+ { 0x0000, 0x0000 }, /* R969 */
+ { 0x0000, 0x0000 }, /* R970 */
+ { 0x0000, 0x0000 }, /* R971 */
+ { 0x0000, 0x0000 }, /* R972 */
+ { 0x0000, 0x0000 }, /* R973 */
+ { 0x0000, 0x0000 }, /* R974 */
+ { 0x0000, 0x0000 }, /* R975 */
+ { 0x0000, 0x0000 }, /* R976 */
+ { 0x0000, 0x0000 }, /* R977 */
+ { 0x0000, 0x0000 }, /* R978 */
+ { 0x0000, 0x0000 }, /* R979 */
+ { 0x0000, 0x0000 }, /* R980 */
+ { 0x0000, 0x0000 }, /* R981 */
+ { 0x0000, 0x0000 }, /* R982 */
+ { 0x0000, 0x0000 }, /* R983 */
+ { 0x0000, 0x0000 }, /* R984 */
+ { 0x0000, 0x0000 }, /* R985 */
+ { 0x0000, 0x0000 }, /* R986 */
+ { 0x0000, 0x0000 }, /* R987 */
+ { 0x0000, 0x0000 }, /* R988 */
+ { 0x0000, 0x0000 }, /* R989 */
+ { 0x0000, 0x0000 }, /* R990 */
+ { 0x0000, 0x0000 }, /* R991 */
+ { 0x0000, 0x0000 }, /* R992 */
+ { 0x0000, 0x0000 }, /* R993 */
+ { 0x0000, 0x0000 }, /* R994 */
+ { 0x0000, 0x0000 }, /* R995 */
+ { 0x0000, 0x0000 }, /* R996 */
+ { 0x0000, 0x0000 }, /* R997 */
+ { 0x0000, 0x0000 }, /* R998 */
+ { 0x0000, 0x0000 }, /* R999 */
+ { 0x0000, 0x0000 }, /* R1000 */
+ { 0x0000, 0x0000 }, /* R1001 */
+ { 0x0000, 0x0000 }, /* R1002 */
+ { 0x0000, 0x0000 }, /* R1003 */
+ { 0x0000, 0x0000 }, /* R1004 */
+ { 0x0000, 0x0000 }, /* R1005 */
+ { 0x0000, 0x0000 }, /* R1006 */
+ { 0x0000, 0x0000 }, /* R1007 */
+ { 0x0000, 0x0000 }, /* R1008 */
+ { 0x0000, 0x0000 }, /* R1009 */
+ { 0x0000, 0x0000 }, /* R1010 */
+ { 0x0000, 0x0000 }, /* R1011 */
+ { 0x0000, 0x0000 }, /* R1012 */
+ { 0x0000, 0x0000 }, /* R1013 */
+ { 0x0000, 0x0000 }, /* R1014 */
+ { 0x0000, 0x0000 }, /* R1015 */
+ { 0x0000, 0x0000 }, /* R1016 */
+ { 0x0000, 0x0000 }, /* R1017 */
+ { 0x0000, 0x0000 }, /* R1018 */
+ { 0x0000, 0x0000 }, /* R1019 */
+ { 0x0000, 0x0000 }, /* R1020 */
+ { 0x0000, 0x0000 }, /* R1021 */
+ { 0x0000, 0x0000 }, /* R1022 */
+ { 0x0000, 0x0000 }, /* R1023 */
+ { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
+ { 0x0000, 0x0000 }, /* R1032 */
+ { 0x0000, 0x0000 }, /* R1033 */
+ { 0x0000, 0x0000 }, /* R1034 */
+ { 0x0000, 0x0000 }, /* R1035 */
+ { 0x0000, 0x0000 }, /* R1036 */
+ { 0x0000, 0x0000 }, /* R1037 */
+ { 0x0000, 0x0000 }, /* R1038 */
+ { 0x0000, 0x0000 }, /* R1039 */
+ { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
+ { 0x0000, 0x0000 }, /* R1042 */
+ { 0x0000, 0x0000 }, /* R1043 */
+ { 0x0000, 0x0000 }, /* R1044 */
+ { 0x0000, 0x0000 }, /* R1045 */
+ { 0x0000, 0x0000 }, /* R1046 */
+ { 0x0000, 0x0000 }, /* R1047 */
+ { 0x0000, 0x0000 }, /* R1048 */
+ { 0x0000, 0x0000 }, /* R1049 */
+ { 0x0000, 0x0000 }, /* R1050 */
+ { 0x0000, 0x0000 }, /* R1051 */
+ { 0x0000, 0x0000 }, /* R1052 */
+ { 0x0000, 0x0000 }, /* R1053 */
+ { 0x0000, 0x0000 }, /* R1054 */
+ { 0x0000, 0x0000 }, /* R1055 */
+ { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
+ { 0x0000, 0x0000 }, /* R1060 */
+ { 0x0000, 0x0000 }, /* R1061 */
+ { 0x0000, 0x0000 }, /* R1062 */
+ { 0x0000, 0x0000 }, /* R1063 */
+ { 0x0000, 0x0000 }, /* R1064 */
+ { 0x0000, 0x0000 }, /* R1065 */
+ { 0x0000, 0x0000 }, /* R1066 */
+ { 0x0000, 0x0000 }, /* R1067 */
+ { 0x0000, 0x0000 }, /* R1068 */
+ { 0x0000, 0x0000 }, /* R1069 */
+ { 0x0000, 0x0000 }, /* R1070 */
+ { 0x0000, 0x0000 }, /* R1071 */
+ { 0x0000, 0x0000 }, /* R1072 */
+ { 0x0000, 0x0000 }, /* R1073 */
+ { 0x0000, 0x0000 }, /* R1074 */
+ { 0x0000, 0x0000 }, /* R1075 */
+ { 0x0000, 0x0000 }, /* R1076 */
+ { 0x0000, 0x0000 }, /* R1077 */
+ { 0x0000, 0x0000 }, /* R1078 */
+ { 0x0000, 0x0000 }, /* R1079 */
+ { 0x0000, 0x0000 }, /* R1080 */
+ { 0x0000, 0x0000 }, /* R1081 */
+ { 0x0000, 0x0000 }, /* R1082 */
+ { 0x0000, 0x0000 }, /* R1083 */
+ { 0x0000, 0x0000 }, /* R1084 */
+ { 0x0000, 0x0000 }, /* R1085 */
+ { 0x0000, 0x0000 }, /* R1086 */
+ { 0x0000, 0x0000 }, /* R1087 */
+ { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0000, 0x0000 }, /* R1093 */
+ { 0x0000, 0x0000 }, /* R1094 */
+ { 0x0000, 0x0000 }, /* R1095 */
+ { 0x0000, 0x0000 }, /* R1096 */
+ { 0x0000, 0x0000 }, /* R1097 */
+ { 0x0000, 0x0000 }, /* R1098 */
+ { 0x0000, 0x0000 }, /* R1099 */
+ { 0x0000, 0x0000 }, /* R1100 */
+ { 0x0000, 0x0000 }, /* R1101 */
+ { 0x0000, 0x0000 }, /* R1102 */
+ { 0x0000, 0x0000 }, /* R1103 */
+ { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
+ { 0x0000, 0x0000 }, /* R1109 */
+ { 0x0000, 0x0000 }, /* R1110 */
+ { 0x0000, 0x0000 }, /* R1111 */
+ { 0x0000, 0x0000 }, /* R1112 */
+ { 0x0000, 0x0000 }, /* R1113 */
+ { 0x0000, 0x0000 }, /* R1114 */
+ { 0x0000, 0x0000 }, /* R1115 */
+ { 0x0000, 0x0000 }, /* R1116 */
+ { 0x0000, 0x0000 }, /* R1117 */
+ { 0x0000, 0x0000 }, /* R1118 */
+ { 0x0000, 0x0000 }, /* R1119 */
+ { 0x0000, 0x0000 }, /* R1120 */
+ { 0x0000, 0x0000 }, /* R1121 */
+ { 0x0000, 0x0000 }, /* R1122 */
+ { 0x0000, 0x0000 }, /* R1123 */
+ { 0x0000, 0x0000 }, /* R1124 */
+ { 0x0000, 0x0000 }, /* R1125 */
+ { 0x0000, 0x0000 }, /* R1126 */
+ { 0x0000, 0x0000 }, /* R1127 */
+ { 0x0000, 0x0000 }, /* R1128 */
+ { 0x0000, 0x0000 }, /* R1129 */
+ { 0x0000, 0x0000 }, /* R1130 */
+ { 0x0000, 0x0000 }, /* R1131 */
+ { 0x0000, 0x0000 }, /* R1132 */
+ { 0x0000, 0x0000 }, /* R1133 */
+ { 0x0000, 0x0000 }, /* R1134 */
+ { 0x0000, 0x0000 }, /* R1135 */
+ { 0x0000, 0x0000 }, /* R1136 */
+ { 0x0000, 0x0000 }, /* R1137 */
+ { 0x0000, 0x0000 }, /* R1138 */
+ { 0x0000, 0x0000 }, /* R1139 */
+ { 0x0000, 0x0000 }, /* R1140 */
+ { 0x0000, 0x0000 }, /* R1141 */
+ { 0x0000, 0x0000 }, /* R1142 */
+ { 0x0000, 0x0000 }, /* R1143 */
+ { 0x0000, 0x0000 }, /* R1144 */
+ { 0x0000, 0x0000 }, /* R1145 */
+ { 0x0000, 0x0000 }, /* R1146 */
+ { 0x0000, 0x0000 }, /* R1147 */
+ { 0x0000, 0x0000 }, /* R1148 */
+ { 0x0000, 0x0000 }, /* R1149 */
+ { 0x0000, 0x0000 }, /* R1150 */
+ { 0x0000, 0x0000 }, /* R1151 */
+ { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1172 */
+ { 0x0000, 0x0000 }, /* R1173 */
+ { 0x0000, 0x0000 }, /* R1174 */
+ { 0x0000, 0x0000 }, /* R1175 */
+ { 0x0000, 0x0000 }, /* R1176 */
+ { 0x0000, 0x0000 }, /* R1177 */
+ { 0x0000, 0x0000 }, /* R1178 */
+ { 0x0000, 0x0000 }, /* R1179 */
+ { 0x0000, 0x0000 }, /* R1180 */
+ { 0x0000, 0x0000 }, /* R1181 */
+ { 0x0000, 0x0000 }, /* R1182 */
+ { 0x0000, 0x0000 }, /* R1183 */
+ { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1204 */
+ { 0x0000, 0x0000 }, /* R1205 */
+ { 0x0000, 0x0000 }, /* R1206 */
+ { 0x0000, 0x0000 }, /* R1207 */
+ { 0x0000, 0x0000 }, /* R1208 */
+ { 0x0000, 0x0000 }, /* R1209 */
+ { 0x0000, 0x0000 }, /* R1210 */
+ { 0x0000, 0x0000 }, /* R1211 */
+ { 0x0000, 0x0000 }, /* R1212 */
+ { 0x0000, 0x0000 }, /* R1213 */
+ { 0x0000, 0x0000 }, /* R1214 */
+ { 0x0000, 0x0000 }, /* R1215 */
+ { 0x0000, 0x0000 }, /* R1216 */
+ { 0x0000, 0x0000 }, /* R1217 */
+ { 0x0000, 0x0000 }, /* R1218 */
+ { 0x0000, 0x0000 }, /* R1219 */
+ { 0x0000, 0x0000 }, /* R1220 */
+ { 0x0000, 0x0000 }, /* R1221 */
+ { 0x0000, 0x0000 }, /* R1222 */
+ { 0x0000, 0x0000 }, /* R1223 */
+ { 0x0000, 0x0000 }, /* R1224 */
+ { 0x0000, 0x0000 }, /* R1225 */
+ { 0x0000, 0x0000 }, /* R1226 */
+ { 0x0000, 0x0000 }, /* R1227 */
+ { 0x0000, 0x0000 }, /* R1228 */
+ { 0x0000, 0x0000 }, /* R1229 */
+ { 0x0000, 0x0000 }, /* R1230 */
+ { 0x0000, 0x0000 }, /* R1231 */
+ { 0x0000, 0x0000 }, /* R1232 */
+ { 0x0000, 0x0000 }, /* R1233 */
+ { 0x0000, 0x0000 }, /* R1234 */
+ { 0x0000, 0x0000 }, /* R1235 */
+ { 0x0000, 0x0000 }, /* R1236 */
+ { 0x0000, 0x0000 }, /* R1237 */
+ { 0x0000, 0x0000 }, /* R1238 */
+ { 0x0000, 0x0000 }, /* R1239 */
+ { 0x0000, 0x0000 }, /* R1240 */
+ { 0x0000, 0x0000 }, /* R1241 */
+ { 0x0000, 0x0000 }, /* R1242 */
+ { 0x0000, 0x0000 }, /* R1243 */
+ { 0x0000, 0x0000 }, /* R1244 */
+ { 0x0000, 0x0000 }, /* R1245 */
+ { 0x0000, 0x0000 }, /* R1246 */
+ { 0x0000, 0x0000 }, /* R1247 */
+ { 0x0000, 0x0000 }, /* R1248 */
+ { 0x0000, 0x0000 }, /* R1249 */
+ { 0x0000, 0x0000 }, /* R1250 */
+ { 0x0000, 0x0000 }, /* R1251 */
+ { 0x0000, 0x0000 }, /* R1252 */
+ { 0x0000, 0x0000 }, /* R1253 */
+ { 0x0000, 0x0000 }, /* R1254 */
+ { 0x0000, 0x0000 }, /* R1255 */
+ { 0x0000, 0x0000 }, /* R1256 */
+ { 0x0000, 0x0000 }, /* R1257 */
+ { 0x0000, 0x0000 }, /* R1258 */
+ { 0x0000, 0x0000 }, /* R1259 */
+ { 0x0000, 0x0000 }, /* R1260 */
+ { 0x0000, 0x0000 }, /* R1261 */
+ { 0x0000, 0x0000 }, /* R1262 */
+ { 0x0000, 0x0000 }, /* R1263 */
+ { 0x0000, 0x0000 }, /* R1264 */
+ { 0x0000, 0x0000 }, /* R1265 */
+ { 0x0000, 0x0000 }, /* R1266 */
+ { 0x0000, 0x0000 }, /* R1267 */
+ { 0x0000, 0x0000 }, /* R1268 */
+ { 0x0000, 0x0000 }, /* R1269 */
+ { 0x0000, 0x0000 }, /* R1270 */
+ { 0x0000, 0x0000 }, /* R1271 */
+ { 0x0000, 0x0000 }, /* R1272 */
+ { 0x0000, 0x0000 }, /* R1273 */
+ { 0x0000, 0x0000 }, /* R1274 */
+ { 0x0000, 0x0000 }, /* R1275 */
+ { 0x0000, 0x0000 }, /* R1276 */
+ { 0x0000, 0x0000 }, /* R1277 */
+ { 0x0000, 0x0000 }, /* R1278 */
+ { 0x0000, 0x0000 }, /* R1279 */
+ { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0000, 0x0000 }, /* R1284 */
+ { 0x0000, 0x0000 }, /* R1285 */
+ { 0x0000, 0x0000 }, /* R1286 */
+ { 0x0000, 0x0000 }, /* R1287 */
+ { 0x0000, 0x0000 }, /* R1288 */
+ { 0x0000, 0x0000 }, /* R1289 */
+ { 0x0000, 0x0000 }, /* R1290 */
+ { 0x0000, 0x0000 }, /* R1291 */
+ { 0x0000, 0x0000 }, /* R1292 */
+ { 0x0000, 0x0000 }, /* R1293 */
+ { 0x0000, 0x0000 }, /* R1294 */
+ { 0x0000, 0x0000 }, /* R1295 */
+ { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0000, 0x0000 }, /* R1297 */
+ { 0x0000, 0x0000 }, /* R1298 */
+ { 0x0000, 0x0000 }, /* R1299 */
+ { 0x0000, 0x0000 }, /* R1300 */
+ { 0x0000, 0x0000 }, /* R1301 */
+ { 0x0000, 0x0000 }, /* R1302 */
+ { 0x0000, 0x0000 }, /* R1303 */
+ { 0x0000, 0x0000 }, /* R1304 */
+ { 0x0000, 0x0000 }, /* R1305 */
+ { 0x0000, 0x0000 }, /* R1306 */
+ { 0x0000, 0x0000 }, /* R1307 */
+ { 0x0000, 0x0000 }, /* R1308 */
+ { 0x0000, 0x0000 }, /* R1309 */
+ { 0x0000, 0x0000 }, /* R1310 */
+ { 0x0000, 0x0000 }, /* R1311 */
+ { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0000, 0x0000 }, /* R1314 */
+ { 0x0000, 0x0000 }, /* R1315 */
+ { 0x0000, 0x0000 }, /* R1316 */
+ { 0x0000, 0x0000 }, /* R1317 */
+ { 0x0000, 0x0000 }, /* R1318 */
+ { 0x0000, 0x0000 }, /* R1319 */
+ { 0x0000, 0x0000 }, /* R1320 */
+ { 0x0000, 0x0000 }, /* R1321 */
+ { 0x0000, 0x0000 }, /* R1322 */
+ { 0x0000, 0x0000 }, /* R1323 */
+ { 0x0000, 0x0000 }, /* R1324 */
+ { 0x0000, 0x0000 }, /* R1325 */
+ { 0x0000, 0x0000 }, /* R1326 */
+ { 0x0000, 0x0000 }, /* R1327 */
+ { 0x0000, 0x0000 }, /* R1328 */
+ { 0x0000, 0x0000 }, /* R1329 */
+ { 0x0000, 0x0000 }, /* R1330 */
+ { 0x0000, 0x0000 }, /* R1331 */
+ { 0x0000, 0x0000 }, /* R1332 */
+ { 0x0000, 0x0000 }, /* R1333 */
+ { 0x0000, 0x0000 }, /* R1334 */
+ { 0x0000, 0x0000 }, /* R1335 */
+ { 0x0000, 0x0000 }, /* R1336 */
+ { 0x0000, 0x0000 }, /* R1337 */
+ { 0x0000, 0x0000 }, /* R1338 */
+ { 0x0000, 0x0000 }, /* R1339 */
+ { 0x0000, 0x0000 }, /* R1340 */
+ { 0x0000, 0x0000 }, /* R1341 */
+ { 0x0000, 0x0000 }, /* R1342 */
+ { 0x0000, 0x0000 }, /* R1343 */
+ { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
+ { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
+ { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
+ { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
+ { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
+ { 0x0000, 0x0000 }, /* R1349 */
+ { 0x0000, 0x0000 }, /* R1350 */
+ { 0x0000, 0x0000 }, /* R1351 */
+ { 0x0000, 0x0000 }, /* R1352 */
+ { 0x0000, 0x0000 }, /* R1353 */
+ { 0x0000, 0x0000 }, /* R1354 */
+ { 0x0000, 0x0000 }, /* R1355 */
+ { 0x0000, 0x0000 }, /* R1356 */
+ { 0x0000, 0x0000 }, /* R1357 */
+ { 0x0000, 0x0000 }, /* R1358 */
+ { 0x0000, 0x0000 }, /* R1359 */
+ { 0x0000, 0x0000 }, /* R1360 */
+ { 0x0000, 0x0000 }, /* R1361 */
+ { 0x0000, 0x0000 }, /* R1362 */
+ { 0x0000, 0x0000 }, /* R1363 */
+ { 0x0000, 0x0000 }, /* R1364 */
+ { 0x0000, 0x0000 }, /* R1365 */
+ { 0x0000, 0x0000 }, /* R1366 */
+ { 0x0000, 0x0000 }, /* R1367 */
+ { 0x0000, 0x0000 }, /* R1368 */
+ { 0x0000, 0x0000 }, /* R1369 */
+ { 0x0000, 0x0000 }, /* R1370 */
+ { 0x0000, 0x0000 }, /* R1371 */
+ { 0x0000, 0x0000 }, /* R1372 */
+ { 0x0000, 0x0000 }, /* R1373 */
+ { 0x0000, 0x0000 }, /* R1374 */
+ { 0x0000, 0x0000 }, /* R1375 */
+ { 0x0000, 0x0000 }, /* R1376 */
+ { 0x0000, 0x0000 }, /* R1377 */
+ { 0x0000, 0x0000 }, /* R1378 */
+ { 0x0000, 0x0000 }, /* R1379 */
+ { 0x0000, 0x0000 }, /* R1380 */
+ { 0x0000, 0x0000 }, /* R1381 */
+ { 0x0000, 0x0000 }, /* R1382 */
+ { 0x0000, 0x0000 }, /* R1383 */
+ { 0x0000, 0x0000 }, /* R1384 */
+ { 0x0000, 0x0000 }, /* R1385 */
+ { 0x0000, 0x0000 }, /* R1386 */
+ { 0x0000, 0x0000 }, /* R1387 */
+ { 0x0000, 0x0000 }, /* R1388 */
+ { 0x0000, 0x0000 }, /* R1389 */
+ { 0x0000, 0x0000 }, /* R1390 */
+ { 0x0000, 0x0000 }, /* R1391 */
+ { 0x0000, 0x0000 }, /* R1392 */
+ { 0x0000, 0x0000 }, /* R1393 */
+ { 0x0000, 0x0000 }, /* R1394 */
+ { 0x0000, 0x0000 }, /* R1395 */
+ { 0x0000, 0x0000 }, /* R1396 */
+ { 0x0000, 0x0000 }, /* R1397 */
+ { 0x0000, 0x0000 }, /* R1398 */
+ { 0x0000, 0x0000 }, /* R1399 */
+ { 0x0000, 0x0000 }, /* R1400 */
+ { 0x0000, 0x0000 }, /* R1401 */
+ { 0x0000, 0x0000 }, /* R1402 */
+ { 0x0000, 0x0000 }, /* R1403 */
+ { 0x0000, 0x0000 }, /* R1404 */
+ { 0x0000, 0x0000 }, /* R1405 */
+ { 0x0000, 0x0000 }, /* R1406 */
+ { 0x0000, 0x0000 }, /* R1407 */
+ { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1428 */
+ { 0x0000, 0x0000 }, /* R1429 */
+ { 0x0000, 0x0000 }, /* R1430 */
+ { 0x0000, 0x0000 }, /* R1431 */
+ { 0x0000, 0x0000 }, /* R1432 */
+ { 0x0000, 0x0000 }, /* R1433 */
+ { 0x0000, 0x0000 }, /* R1434 */
+ { 0x0000, 0x0000 }, /* R1435 */
+ { 0x0000, 0x0000 }, /* R1436 */
+ { 0x0000, 0x0000 }, /* R1437 */
+ { 0x0000, 0x0000 }, /* R1438 */
+ { 0x0000, 0x0000 }, /* R1439 */
+ { 0x0000, 0x0000 }, /* R1440 */
+ { 0x0000, 0x0000 }, /* R1441 */
+ { 0x0000, 0x0000 }, /* R1442 */
+ { 0x0000, 0x0000 }, /* R1443 */
+ { 0x0000, 0x0000 }, /* R1444 */
+ { 0x0000, 0x0000 }, /* R1445 */
+ { 0x0000, 0x0000 }, /* R1446 */
+ { 0x0000, 0x0000 }, /* R1447 */
+ { 0x0000, 0x0000 }, /* R1448 */
+ { 0x0000, 0x0000 }, /* R1449 */
+ { 0x0000, 0x0000 }, /* R1450 */
+ { 0x0000, 0x0000 }, /* R1451 */
+ { 0x0000, 0x0000 }, /* R1452 */
+ { 0x0000, 0x0000 }, /* R1453 */
+ { 0x0000, 0x0000 }, /* R1454 */
+ { 0x0000, 0x0000 }, /* R1455 */
+ { 0x0000, 0x0000 }, /* R1456 */
+ { 0x0000, 0x0000 }, /* R1457 */
+ { 0x0000, 0x0000 }, /* R1458 */
+ { 0x0000, 0x0000 }, /* R1459 */
+ { 0x0000, 0x0000 }, /* R1460 */
+ { 0x0000, 0x0000 }, /* R1461 */
+ { 0x0000, 0x0000 }, /* R1462 */
+ { 0x0000, 0x0000 }, /* R1463 */
+ { 0x0000, 0x0000 }, /* R1464 */
+ { 0x0000, 0x0000 }, /* R1465 */
+ { 0x0000, 0x0000 }, /* R1466 */
+ { 0x0000, 0x0000 }, /* R1467 */
+ { 0x0000, 0x0000 }, /* R1468 */
+ { 0x0000, 0x0000 }, /* R1469 */
+ { 0x0000, 0x0000 }, /* R1470 */
+ { 0x0000, 0x0000 }, /* R1471 */
+ { 0x0000, 0x0000 }, /* R1472 */
+ { 0x0000, 0x0000 }, /* R1473 */
+ { 0x0000, 0x0000 }, /* R1474 */
+ { 0x0000, 0x0000 }, /* R1475 */
+ { 0x0000, 0x0000 }, /* R1476 */
+ { 0x0000, 0x0000 }, /* R1477 */
+ { 0x0000, 0x0000 }, /* R1478 */
+ { 0x0000, 0x0000 }, /* R1479 */
+ { 0x0000, 0x0000 }, /* R1480 */
+ { 0x0000, 0x0000 }, /* R1481 */
+ { 0x0000, 0x0000 }, /* R1482 */
+ { 0x0000, 0x0000 }, /* R1483 */
+ { 0x0000, 0x0000 }, /* R1484 */
+ { 0x0000, 0x0000 }, /* R1485 */
+ { 0x0000, 0x0000 }, /* R1486 */
+ { 0x0000, 0x0000 }, /* R1487 */
+ { 0x0000, 0x0000 }, /* R1488 */
+ { 0x0000, 0x0000 }, /* R1489 */
+ { 0x0000, 0x0000 }, /* R1490 */
+ { 0x0000, 0x0000 }, /* R1491 */
+ { 0x0000, 0x0000 }, /* R1492 */
+ { 0x0000, 0x0000 }, /* R1493 */
+ { 0x0000, 0x0000 }, /* R1494 */
+ { 0x0000, 0x0000 }, /* R1495 */
+ { 0x0000, 0x0000 }, /* R1496 */
+ { 0x0000, 0x0000 }, /* R1497 */
+ { 0x0000, 0x0000 }, /* R1498 */
+ { 0x0000, 0x0000 }, /* R1499 */
+ { 0x0000, 0x0000 }, /* R1500 */
+ { 0x0000, 0x0000 }, /* R1501 */
+ { 0x0000, 0x0000 }, /* R1502 */
+ { 0x0000, 0x0000 }, /* R1503 */
+ { 0x0000, 0x0000 }, /* R1504 */
+ { 0x0000, 0x0000 }, /* R1505 */
+ { 0x0000, 0x0000 }, /* R1506 */
+ { 0x0000, 0x0000 }, /* R1507 */
+ { 0x0000, 0x0000 }, /* R1508 */
+ { 0x0000, 0x0000 }, /* R1509 */
+ { 0x0000, 0x0000 }, /* R1510 */
+ { 0x0000, 0x0000 }, /* R1511 */
+ { 0x0000, 0x0000 }, /* R1512 */
+ { 0x0000, 0x0000 }, /* R1513 */
+ { 0x0000, 0x0000 }, /* R1514 */
+ { 0x0000, 0x0000 }, /* R1515 */
+ { 0x0000, 0x0000 }, /* R1516 */
+ { 0x0000, 0x0000 }, /* R1517 */
+ { 0x0000, 0x0000 }, /* R1518 */
+ { 0x0000, 0x0000 }, /* R1519 */
+ { 0x0000, 0x0000 }, /* R1520 */
+ { 0x0000, 0x0000 }, /* R1521 */
+ { 0x0000, 0x0000 }, /* R1522 */
+ { 0x0000, 0x0000 }, /* R1523 */
+ { 0x0000, 0x0000 }, /* R1524 */
+ { 0x0000, 0x0000 }, /* R1525 */
+ { 0x0000, 0x0000 }, /* R1526 */
+ { 0x0000, 0x0000 }, /* R1527 */
+ { 0x0000, 0x0000 }, /* R1528 */
+ { 0x0000, 0x0000 }, /* R1529 */
+ { 0x0000, 0x0000 }, /* R1530 */
+ { 0x0000, 0x0000 }, /* R1531 */
+ { 0x0000, 0x0000 }, /* R1532 */
+ { 0x0000, 0x0000 }, /* R1533 */
+ { 0x0000, 0x0000 }, /* R1534 */
+ { 0x0000, 0x0000 }, /* R1535 */
+ { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ { 0x0000, 0x0000 }, /* R1546 */
+ { 0x0000, 0x0000 }, /* R1547 */
+ { 0x0000, 0x0000 }, /* R1548 */
+ { 0x0000, 0x0000 }, /* R1549 */
+ { 0x0000, 0x0000 }, /* R1550 */
+ { 0x0000, 0x0000 }, /* R1551 */
+ { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
+ { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
+ { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
+ { 0x0000, 0x0000 }, /* R1557 */
+ { 0x0000, 0x0000 }, /* R1558 */
+ { 0x0000, 0x0000 }, /* R1559 */
+ { 0x0000, 0x0000 }, /* R1560 */
+ { 0x0000, 0x0000 }, /* R1561 */
+ { 0x0000, 0x0000 }, /* R1562 */
+ { 0x0000, 0x0000 }, /* R1563 */
+ { 0x0000, 0x0000 }, /* R1564 */
+ { 0x0000, 0x0000 }, /* R1565 */
+ { 0x0000, 0x0000 }, /* R1566 */
+ { 0x0000, 0x0000 }, /* R1567 */
+ { 0x0003, 0x0003 }, /* R1568 - Oversampling */
+ { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
+};
+
+const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
+ 0x8994, /* R0 - Software Reset */
+ 0x0000, /* R1 - Power Management (1) */
+ 0x6000, /* R2 - Power Management (2) */
+ 0x0000, /* R3 - Power Management (3) */
+ 0x0000, /* R4 - Power Management (4) */
+ 0x0000, /* R5 - Power Management (5) */
+ 0x0000, /* R6 - Power Management (6) */
+ 0x0000, /* R7 */
+ 0x0000, /* R8 */
+ 0x0000, /* R9 */
+ 0x0000, /* R10 */
+ 0x0000, /* R11 */
+ 0x0000, /* R12 */
+ 0x0000, /* R13 */
+ 0x0000, /* R14 */
+ 0x0000, /* R15 */
+ 0x0000, /* R16 */
+ 0x0000, /* R17 */
+ 0x0000, /* R18 */
+ 0x0000, /* R19 */
+ 0x0000, /* R20 */
+ 0x0000, /* R21 - Input Mixer (1) */
+ 0x0000, /* R22 */
+ 0x0000, /* R23 */
+ 0x008B, /* R24 - Left Line Input 1&2 Volume */
+ 0x008B, /* R25 - Left Line Input 3&4 Volume */
+ 0x008B, /* R26 - Right Line Input 1&2 Volume */
+ 0x008B, /* R27 - Right Line Input 3&4 Volume */
+ 0x006D, /* R28 - Left Output Volume */
+ 0x006D, /* R29 - Right Output Volume */
+ 0x0066, /* R30 - Line Outputs Volume */
+ 0x0020, /* R31 - HPOUT2 Volume */
+ 0x0079, /* R32 - Left OPGA Volume */
+ 0x0079, /* R33 - Right OPGA Volume */
+ 0x0003, /* R34 - SPKMIXL Attenuation */
+ 0x0003, /* R35 - SPKMIXR Attenuation */
+ 0x0011, /* R36 - SPKOUT Mixers */
+ 0x0140, /* R37 - ClassD */
+ 0x0079, /* R38 - Speaker Volume Left */
+ 0x0079, /* R39 - Speaker Volume Right */
+ 0x0000, /* R40 - Input Mixer (2) */
+ 0x0000, /* R41 - Input Mixer (3) */
+ 0x0000, /* R42 - Input Mixer (4) */
+ 0x0000, /* R43 - Input Mixer (5) */
+ 0x0000, /* R44 - Input Mixer (6) */
+ 0x0000, /* R45 - Output Mixer (1) */
+ 0x0000, /* R46 - Output Mixer (2) */
+ 0x0000, /* R47 - Output Mixer (3) */
+ 0x0000, /* R48 - Output Mixer (4) */
+ 0x0000, /* R49 - Output Mixer (5) */
+ 0x0000, /* R50 - Output Mixer (6) */
+ 0x0000, /* R51 - HPOUT2 Mixer */
+ 0x0000, /* R52 - Line Mixer (1) */
+ 0x0000, /* R53 - Line Mixer (2) */
+ 0x0000, /* R54 - Speaker Mixer */
+ 0x0000, /* R55 - Additional Control */
+ 0x0000, /* R56 - AntiPOP (1) */
+ 0x0000, /* R57 - AntiPOP (2) */
+ 0x0000, /* R58 - MICBIAS */
+ 0x000D, /* R59 - LDO 1 */
+ 0x0003, /* R60 - LDO 2 */
+ 0x0000, /* R61 */
+ 0x0000, /* R62 */
+ 0x0000, /* R63 */
+ 0x0000, /* R64 */
+ 0x0000, /* R65 */
+ 0x0000, /* R66 */
+ 0x0000, /* R67 */
+ 0x0000, /* R68 */
+ 0x0000, /* R69 */
+ 0x0000, /* R70 */
+ 0x0000, /* R71 */
+ 0x0000, /* R72 */
+ 0x0000, /* R73 */
+ 0x0000, /* R74 */
+ 0x0000, /* R75 */
+ 0x1F25, /* R76 - Charge Pump (1) */
+ 0x0000, /* R77 */
+ 0x0000, /* R78 */
+ 0x0000, /* R79 */
+ 0x0000, /* R80 */
+ 0x0004, /* R81 - Class W (1) */
+ 0x0000, /* R82 */
+ 0x0000, /* R83 */
+ 0x0000, /* R84 - DC Servo (1) */
+ 0x054A, /* R85 - DC Servo (2) */
+ 0x0000, /* R86 */
+ 0x0000, /* R87 - DC Servo (4) */
+ 0x0000, /* R88 - DC Servo Readback */
+ 0x0000, /* R89 */
+ 0x0000, /* R90 */
+ 0x0000, /* R91 */
+ 0x0000, /* R92 */
+ 0x0000, /* R93 */
+ 0x0000, /* R94 */
+ 0x0000, /* R95 */
+ 0x0000, /* R96 - Analogue HP (1) */
+ 0x0000, /* R97 */
+ 0x0000, /* R98 */
+ 0x0000, /* R99 */
+ 0x0000, /* R100 */
+ 0x0000, /* R101 */
+ 0x0000, /* R102 */
+ 0x0000, /* R103 */
+ 0x0000, /* R104 */
+ 0x0000, /* R105 */
+ 0x0000, /* R106 */
+ 0x0000, /* R107 */
+ 0x0000, /* R108 */
+ 0x0000, /* R109 */
+ 0x0000, /* R110 */
+ 0x0000, /* R111 */
+ 0x0000, /* R112 */
+ 0x0000, /* R113 */
+ 0x0000, /* R114 */
+ 0x0000, /* R115 */
+ 0x0000, /* R116 */
+ 0x0000, /* R117 */
+ 0x0000, /* R118 */
+ 0x0000, /* R119 */
+ 0x0000, /* R120 */
+ 0x0000, /* R121 */
+ 0x0000, /* R122 */
+ 0x0000, /* R123 */
+ 0x0000, /* R124 */
+ 0x0000, /* R125 */
+ 0x0000, /* R126 */
+ 0x0000, /* R127 */
+ 0x0000, /* R128 */
+ 0x0000, /* R129 */
+ 0x0000, /* R130 */
+ 0x0000, /* R131 */
+ 0x0000, /* R132 */
+ 0x0000, /* R133 */
+ 0x0000, /* R134 */
+ 0x0000, /* R135 */
+ 0x0000, /* R136 */
+ 0x0000, /* R137 */
+ 0x0000, /* R138 */
+ 0x0000, /* R139 */
+ 0x0000, /* R140 */
+ 0x0000, /* R141 */
+ 0x0000, /* R142 */
+ 0x0000, /* R143 */
+ 0x0000, /* R144 */
+ 0x0000, /* R145 */
+ 0x0000, /* R146 */
+ 0x0000, /* R147 */
+ 0x0000, /* R148 */
+ 0x0000, /* R149 */
+ 0x0000, /* R150 */
+ 0x0000, /* R151 */
+ 0x0000, /* R152 */
+ 0x0000, /* R153 */
+ 0x0000, /* R154 */
+ 0x0000, /* R155 */
+ 0x0000, /* R156 */
+ 0x0000, /* R157 */
+ 0x0000, /* R158 */
+ 0x0000, /* R159 */
+ 0x0000, /* R160 */
+ 0x0000, /* R161 */
+ 0x0000, /* R162 */
+ 0x0000, /* R163 */
+ 0x0000, /* R164 */
+ 0x0000, /* R165 */
+ 0x0000, /* R166 */
+ 0x0000, /* R167 */
+ 0x0000, /* R168 */
+ 0x0000, /* R169 */
+ 0x0000, /* R170 */
+ 0x0000, /* R171 */
+ 0x0000, /* R172 */
+ 0x0000, /* R173 */
+ 0x0000, /* R174 */
+ 0x0000, /* R175 */
+ 0x0000, /* R176 */
+ 0x0000, /* R177 */
+ 0x0000, /* R178 */
+ 0x0000, /* R179 */
+ 0x0000, /* R180 */
+ 0x0000, /* R181 */
+ 0x0000, /* R182 */
+ 0x0000, /* R183 */
+ 0x0000, /* R184 */
+ 0x0000, /* R185 */
+ 0x0000, /* R186 */
+ 0x0000, /* R187 */
+ 0x0000, /* R188 */
+ 0x0000, /* R189 */
+ 0x0000, /* R190 */
+ 0x0000, /* R191 */
+ 0x0000, /* R192 */
+ 0x0000, /* R193 */
+ 0x0000, /* R194 */
+ 0x0000, /* R195 */
+ 0x0000, /* R196 */
+ 0x0000, /* R197 */
+ 0x0000, /* R198 */
+ 0x0000, /* R199 */
+ 0x0000, /* R200 */
+ 0x0000, /* R201 */
+ 0x0000, /* R202 */
+ 0x0000, /* R203 */
+ 0x0000, /* R204 */
+ 0x0000, /* R205 */
+ 0x0000, /* R206 */
+ 0x0000, /* R207 */
+ 0x0000, /* R208 */
+ 0x0000, /* R209 */
+ 0x0000, /* R210 */
+ 0x0000, /* R211 */
+ 0x0000, /* R212 */
+ 0x0000, /* R213 */
+ 0x0000, /* R214 */
+ 0x0000, /* R215 */
+ 0x0000, /* R216 */
+ 0x0000, /* R217 */
+ 0x0000, /* R218 */
+ 0x0000, /* R219 */
+ 0x0000, /* R220 */
+ 0x0000, /* R221 */
+ 0x0000, /* R222 */
+ 0x0000, /* R223 */
+ 0x0000, /* R224 */
+ 0x0000, /* R225 */
+ 0x0000, /* R226 */
+ 0x0000, /* R227 */
+ 0x0000, /* R228 */
+ 0x0000, /* R229 */
+ 0x0000, /* R230 */
+ 0x0000, /* R231 */
+ 0x0000, /* R232 */
+ 0x0000, /* R233 */
+ 0x0000, /* R234 */
+ 0x0000, /* R235 */
+ 0x0000, /* R236 */
+ 0x0000, /* R237 */
+ 0x0000, /* R238 */
+ 0x0000, /* R239 */
+ 0x0000, /* R240 */
+ 0x0000, /* R241 */
+ 0x0000, /* R242 */
+ 0x0000, /* R243 */
+ 0x0000, /* R244 */
+ 0x0000, /* R245 */
+ 0x0000, /* R246 */
+ 0x0000, /* R247 */
+ 0x0000, /* R248 */
+ 0x0000, /* R249 */
+ 0x0000, /* R250 */
+ 0x0000, /* R251 */
+ 0x0000, /* R252 */
+ 0x0000, /* R253 */
+ 0x0000, /* R254 */
+ 0x0000, /* R255 */
+ 0x0003, /* R256 - Chip Revision */
+ 0x8004, /* R257 - Control Interface */
+ 0x0000, /* R258 */
+ 0x0000, /* R259 */
+ 0x0000, /* R260 */
+ 0x0000, /* R261 */
+ 0x0000, /* R262 */
+ 0x0000, /* R263 */
+ 0x0000, /* R264 */
+ 0x0000, /* R265 */
+ 0x0000, /* R266 */
+ 0x0000, /* R267 */
+ 0x0000, /* R268 */
+ 0x0000, /* R269 */
+ 0x0000, /* R270 */
+ 0x0000, /* R271 */
+ 0x0000, /* R272 - Write Sequencer Ctrl (1) */
+ 0x0000, /* R273 - Write Sequencer Ctrl (2) */
+ 0x0000, /* R274 */
+ 0x0000, /* R275 */
+ 0x0000, /* R276 */
+ 0x0000, /* R277 */
+ 0x0000, /* R278 */
+ 0x0000, /* R279 */
+ 0x0000, /* R280 */
+ 0x0000, /* R281 */
+ 0x0000, /* R282 */
+ 0x0000, /* R283 */
+ 0x0000, /* R284 */
+ 0x0000, /* R285 */
+ 0x0000, /* R286 */
+ 0x0000, /* R287 */
+ 0x0000, /* R288 */
+ 0x0000, /* R289 */
+ 0x0000, /* R290 */
+ 0x0000, /* R291 */
+ 0x0000, /* R292 */
+ 0x0000, /* R293 */
+ 0x0000, /* R294 */
+ 0x0000, /* R295 */
+ 0x0000, /* R296 */
+ 0x0000, /* R297 */
+ 0x0000, /* R298 */
+ 0x0000, /* R299 */
+ 0x0000, /* R300 */
+ 0x0000, /* R301 */
+ 0x0000, /* R302 */
+ 0x0000, /* R303 */
+ 0x0000, /* R304 */
+ 0x0000, /* R305 */
+ 0x0000, /* R306 */
+ 0x0000, /* R307 */
+ 0x0000, /* R308 */
+ 0x0000, /* R309 */
+ 0x0000, /* R310 */
+ 0x0000, /* R311 */
+ 0x0000, /* R312 */
+ 0x0000, /* R313 */
+ 0x0000, /* R314 */
+ 0x0000, /* R315 */
+ 0x0000, /* R316 */
+ 0x0000, /* R317 */
+ 0x0000, /* R318 */
+ 0x0000, /* R319 */
+ 0x0000, /* R320 */
+ 0x0000, /* R321 */
+ 0x0000, /* R322 */
+ 0x0000, /* R323 */
+ 0x0000, /* R324 */
+ 0x0000, /* R325 */
+ 0x0000, /* R326 */
+ 0x0000, /* R327 */
+ 0x0000, /* R328 */
+ 0x0000, /* R329 */
+ 0x0000, /* R330 */
+ 0x0000, /* R331 */
+ 0x0000, /* R332 */
+ 0x0000, /* R333 */
+ 0x0000, /* R334 */
+ 0x0000, /* R335 */
+ 0x0000, /* R336 */
+ 0x0000, /* R337 */
+ 0x0000, /* R338 */
+ 0x0000, /* R339 */
+ 0x0000, /* R340 */
+ 0x0000, /* R341 */
+ 0x0000, /* R342 */
+ 0x0000, /* R343 */
+ 0x0000, /* R344 */
+ 0x0000, /* R345 */
+ 0x0000, /* R346 */
+ 0x0000, /* R347 */
+ 0x0000, /* R348 */
+ 0x0000, /* R349 */
+ 0x0000, /* R350 */
+ 0x0000, /* R351 */
+ 0x0000, /* R352 */
+ 0x0000, /* R353 */
+ 0x0000, /* R354 */
+ 0x0000, /* R355 */
+ 0x0000, /* R356 */
+ 0x0000, /* R357 */
+ 0x0000, /* R358 */
+ 0x0000, /* R359 */
+ 0x0000, /* R360 */
+ 0x0000, /* R361 */
+ 0x0000, /* R362 */
+ 0x0000, /* R363 */
+ 0x0000, /* R364 */
+ 0x0000, /* R365 */
+ 0x0000, /* R366 */
+ 0x0000, /* R367 */
+ 0x0000, /* R368 */
+ 0x0000, /* R369 */
+ 0x0000, /* R370 */
+ 0x0000, /* R371 */
+ 0x0000, /* R372 */
+ 0x0000, /* R373 */
+ 0x0000, /* R374 */
+ 0x0000, /* R375 */
+ 0x0000, /* R376 */
+ 0x0000, /* R377 */
+ 0x0000, /* R378 */
+ 0x0000, /* R379 */
+ 0x0000, /* R380 */
+ 0x0000, /* R381 */
+ 0x0000, /* R382 */
+ 0x0000, /* R383 */
+ 0x0000, /* R384 */
+ 0x0000, /* R385 */
+ 0x0000, /* R386 */
+ 0x0000, /* R387 */
+ 0x0000, /* R388 */
+ 0x0000, /* R389 */
+ 0x0000, /* R390 */
+ 0x0000, /* R391 */
+ 0x0000, /* R392 */
+ 0x0000, /* R393 */
+ 0x0000, /* R394 */
+ 0x0000, /* R395 */
+ 0x0000, /* R396 */
+ 0x0000, /* R397 */
+ 0x0000, /* R398 */
+ 0x0000, /* R399 */
+ 0x0000, /* R400 */
+ 0x0000, /* R401 */
+ 0x0000, /* R402 */
+ 0x0000, /* R403 */
+ 0x0000, /* R404 */
+ 0x0000, /* R405 */
+ 0x0000, /* R406 */
+ 0x0000, /* R407 */
+ 0x0000, /* R408 */
+ 0x0000, /* R409 */
+ 0x0000, /* R410 */
+ 0x0000, /* R411 */
+ 0x0000, /* R412 */
+ 0x0000, /* R413 */
+ 0x0000, /* R414 */
+ 0x0000, /* R415 */
+ 0x0000, /* R416 */
+ 0x0000, /* R417 */
+ 0x0000, /* R418 */
+ 0x0000, /* R419 */
+ 0x0000, /* R420 */
+ 0x0000, /* R421 */
+ 0x0000, /* R422 */
+ 0x0000, /* R423 */
+ 0x0000, /* R424 */
+ 0x0000, /* R425 */
+ 0x0000, /* R426 */
+ 0x0000, /* R427 */
+ 0x0000, /* R428 */
+ 0x0000, /* R429 */
+ 0x0000, /* R430 */
+ 0x0000, /* R431 */
+ 0x0000, /* R432 */
+ 0x0000, /* R433 */
+ 0x0000, /* R434 */
+ 0x0000, /* R435 */
+ 0x0000, /* R436 */
+ 0x0000, /* R437 */
+ 0x0000, /* R438 */
+ 0x0000, /* R439 */
+ 0x0000, /* R440 */
+ 0x0000, /* R441 */
+ 0x0000, /* R442 */
+ 0x0000, /* R443 */
+ 0x0000, /* R444 */
+ 0x0000, /* R445 */
+ 0x0000, /* R446 */
+ 0x0000, /* R447 */
+ 0x0000, /* R448 */
+ 0x0000, /* R449 */
+ 0x0000, /* R450 */
+ 0x0000, /* R451 */
+ 0x0000, /* R452 */
+ 0x0000, /* R453 */
+ 0x0000, /* R454 */
+ 0x0000, /* R455 */
+ 0x0000, /* R456 */
+ 0x0000, /* R457 */
+ 0x0000, /* R458 */
+ 0x0000, /* R459 */
+ 0x0000, /* R460 */
+ 0x0000, /* R461 */
+ 0x0000, /* R462 */
+ 0x0000, /* R463 */
+ 0x0000, /* R464 */
+ 0x0000, /* R465 */
+ 0x0000, /* R466 */
+ 0x0000, /* R467 */
+ 0x0000, /* R468 */
+ 0x0000, /* R469 */
+ 0x0000, /* R470 */
+ 0x0000, /* R471 */
+ 0x0000, /* R472 */
+ 0x0000, /* R473 */
+ 0x0000, /* R474 */
+ 0x0000, /* R475 */
+ 0x0000, /* R476 */
+ 0x0000, /* R477 */
+ 0x0000, /* R478 */
+ 0x0000, /* R479 */
+ 0x0000, /* R480 */
+ 0x0000, /* R481 */
+ 0x0000, /* R482 */
+ 0x0000, /* R483 */
+ 0x0000, /* R484 */
+ 0x0000, /* R485 */
+ 0x0000, /* R486 */
+ 0x0000, /* R487 */
+ 0x0000, /* R488 */
+ 0x0000, /* R489 */
+ 0x0000, /* R490 */
+ 0x0000, /* R491 */
+ 0x0000, /* R492 */
+ 0x0000, /* R493 */
+ 0x0000, /* R494 */
+ 0x0000, /* R495 */
+ 0x0000, /* R496 */
+ 0x0000, /* R497 */
+ 0x0000, /* R498 */
+ 0x0000, /* R499 */
+ 0x0000, /* R500 */
+ 0x0000, /* R501 */
+ 0x0000, /* R502 */
+ 0x0000, /* R503 */
+ 0x0000, /* R504 */
+ 0x0000, /* R505 */
+ 0x0000, /* R506 */
+ 0x0000, /* R507 */
+ 0x0000, /* R508 */
+ 0x0000, /* R509 */
+ 0x0000, /* R510 */
+ 0x0000, /* R511 */
+ 0x0000, /* R512 - AIF1 Clocking (1) */
+ 0x0000, /* R513 - AIF1 Clocking (2) */
+ 0x0000, /* R514 */
+ 0x0000, /* R515 */
+ 0x0000, /* R516 - AIF2 Clocking (1) */
+ 0x0000, /* R517 - AIF2 Clocking (2) */
+ 0x0000, /* R518 */
+ 0x0000, /* R519 */
+ 0x0000, /* R520 - Clocking (1) */
+ 0x0000, /* R521 - Clocking (2) */
+ 0x0000, /* R522 */
+ 0x0000, /* R523 */
+ 0x0000, /* R524 */
+ 0x0000, /* R525 */
+ 0x0000, /* R526 */
+ 0x0000, /* R527 */
+ 0x0083, /* R528 - AIF1 Rate */
+ 0x0083, /* R529 - AIF2 Rate */
+ 0x0000, /* R530 - Rate Status */
+ 0x0000, /* R531 */
+ 0x0000, /* R532 */
+ 0x0000, /* R533 */
+ 0x0000, /* R534 */
+ 0x0000, /* R535 */
+ 0x0000, /* R536 */
+ 0x0000, /* R537 */
+ 0x0000, /* R538 */
+ 0x0000, /* R539 */
+ 0x0000, /* R540 */
+ 0x0000, /* R541 */
+ 0x0000, /* R542 */
+ 0x0000, /* R543 */
+ 0x0000, /* R544 - FLL1 Control (1) */
+ 0x0000, /* R545 - FLL1 Control (2) */
+ 0x0000, /* R546 - FLL1 Control (3) */
+ 0x0000, /* R547 - FLL1 Control (4) */
+ 0x0C80, /* R548 - FLL1 Control (5) */
+ 0x0000, /* R549 */
+ 0x0000, /* R550 */
+ 0x0000, /* R551 */
+ 0x0000, /* R552 */
+ 0x0000, /* R553 */
+ 0x0000, /* R554 */
+ 0x0000, /* R555 */
+ 0x0000, /* R556 */
+ 0x0000, /* R557 */
+ 0x0000, /* R558 */
+ 0x0000, /* R559 */
+ 0x0000, /* R560 */
+ 0x0000, /* R561 */
+ 0x0000, /* R562 */
+ 0x0000, /* R563 */
+ 0x0000, /* R564 */
+ 0x0000, /* R565 */
+ 0x0000, /* R566 */
+ 0x0000, /* R567 */
+ 0x0000, /* R568 */
+ 0x0000, /* R569 */
+ 0x0000, /* R570 */
+ 0x0000, /* R571 */
+ 0x0000, /* R572 */
+ 0x0000, /* R573 */
+ 0x0000, /* R574 */
+ 0x0000, /* R575 */
+ 0x0000, /* R576 - FLL2 Control (1) */
+ 0x0000, /* R577 - FLL2 Control (2) */
+ 0x0000, /* R578 - FLL2 Control (3) */
+ 0x0000, /* R579 - FLL2 Control (4) */
+ 0x0C80, /* R580 - FLL2 Control (5) */
+ 0x0000, /* R581 */
+ 0x0000, /* R582 */
+ 0x0000, /* R583 */
+ 0x0000, /* R584 */
+ 0x0000, /* R585 */
+ 0x0000, /* R586 */
+ 0x0000, /* R587 */
+ 0x0000, /* R588 */
+ 0x0000, /* R589 */
+ 0x0000, /* R590 */
+ 0x0000, /* R591 */
+ 0x0000, /* R592 */
+ 0x0000, /* R593 */
+ 0x0000, /* R594 */
+ 0x0000, /* R595 */
+ 0x0000, /* R596 */
+ 0x0000, /* R597 */
+ 0x0000, /* R598 */
+ 0x0000, /* R599 */
+ 0x0000, /* R600 */
+ 0x0000, /* R601 */
+ 0x0000, /* R602 */
+ 0x0000, /* R603 */
+ 0x0000, /* R604 */
+ 0x0000, /* R605 */
+ 0x0000, /* R606 */
+ 0x0000, /* R607 */
+ 0x0000, /* R608 */
+ 0x0000, /* R609 */
+ 0x0000, /* R610 */
+ 0x0000, /* R611 */
+ 0x0000, /* R612 */
+ 0x0000, /* R613 */
+ 0x0000, /* R614 */
+ 0x0000, /* R615 */
+ 0x0000, /* R616 */
+ 0x0000, /* R617 */
+ 0x0000, /* R618 */
+ 0x0000, /* R619 */
+ 0x0000, /* R620 */
+ 0x0000, /* R621 */
+ 0x0000, /* R622 */
+ 0x0000, /* R623 */
+ 0x0000, /* R624 */
+ 0x0000, /* R625 */
+ 0x0000, /* R626 */
+ 0x0000, /* R627 */
+ 0x0000, /* R628 */
+ 0x0000, /* R629 */
+ 0x0000, /* R630 */
+ 0x0000, /* R631 */
+ 0x0000, /* R632 */
+ 0x0000, /* R633 */
+ 0x0000, /* R634 */
+ 0x0000, /* R635 */
+ 0x0000, /* R636 */
+ 0x0000, /* R637 */
+ 0x0000, /* R638 */
+ 0x0000, /* R639 */
+ 0x0000, /* R640 */
+ 0x0000, /* R641 */
+ 0x0000, /* R642 */
+ 0x0000, /* R643 */
+ 0x0000, /* R644 */
+ 0x0000, /* R645 */
+ 0x0000, /* R646 */
+ 0x0000, /* R647 */
+ 0x0000, /* R648 */
+ 0x0000, /* R649 */
+ 0x0000, /* R650 */
+ 0x0000, /* R651 */
+ 0x0000, /* R652 */
+ 0x0000, /* R653 */
+ 0x0000, /* R654 */
+ 0x0000, /* R655 */
+ 0x0000, /* R656 */
+ 0x0000, /* R657 */
+ 0x0000, /* R658 */
+ 0x0000, /* R659 */
+ 0x0000, /* R660 */
+ 0x0000, /* R661 */
+ 0x0000, /* R662 */
+ 0x0000, /* R663 */
+ 0x0000, /* R664 */
+ 0x0000, /* R665 */
+ 0x0000, /* R666 */
+ 0x0000, /* R667 */
+ 0x0000, /* R668 */
+ 0x0000, /* R669 */
+ 0x0000, /* R670 */
+ 0x0000, /* R671 */
+ 0x0000, /* R672 */
+ 0x0000, /* R673 */
+ 0x0000, /* R674 */
+ 0x0000, /* R675 */
+ 0x0000, /* R676 */
+ 0x0000, /* R677 */
+ 0x0000, /* R678 */
+ 0x0000, /* R679 */
+ 0x0000, /* R680 */
+ 0x0000, /* R681 */
+ 0x0000, /* R682 */
+ 0x0000, /* R683 */
+ 0x0000, /* R684 */
+ 0x0000, /* R685 */
+ 0x0000, /* R686 */
+ 0x0000, /* R687 */
+ 0x0000, /* R688 */
+ 0x0000, /* R689 */
+ 0x0000, /* R690 */
+ 0x0000, /* R691 */
+ 0x0000, /* R692 */
+ 0x0000, /* R693 */
+ 0x0000, /* R694 */
+ 0x0000, /* R695 */
+ 0x0000, /* R696 */
+ 0x0000, /* R697 */
+ 0x0000, /* R698 */
+ 0x0000, /* R699 */
+ 0x0000, /* R700 */
+ 0x0000, /* R701 */
+ 0x0000, /* R702 */
+ 0x0000, /* R703 */
+ 0x0000, /* R704 */
+ 0x0000, /* R705 */
+ 0x0000, /* R706 */
+ 0x0000, /* R707 */
+ 0x0000, /* R708 */
+ 0x0000, /* R709 */
+ 0x0000, /* R710 */
+ 0x0000, /* R711 */
+ 0x0000, /* R712 */
+ 0x0000, /* R713 */
+ 0x0000, /* R714 */
+ 0x0000, /* R715 */
+ 0x0000, /* R716 */
+ 0x0000, /* R717 */
+ 0x0000, /* R718 */
+ 0x0000, /* R719 */
+ 0x0000, /* R720 */
+ 0x0000, /* R721 */
+ 0x0000, /* R722 */
+ 0x0000, /* R723 */
+ 0x0000, /* R724 */
+ 0x0000, /* R725 */
+ 0x0000, /* R726 */
+ 0x0000, /* R727 */
+ 0x0000, /* R728 */
+ 0x0000, /* R729 */
+ 0x0000, /* R730 */
+ 0x0000, /* R731 */
+ 0x0000, /* R732 */
+ 0x0000, /* R733 */
+ 0x0000, /* R734 */
+ 0x0000, /* R735 */
+ 0x0000, /* R736 */
+ 0x0000, /* R737 */
+ 0x0000, /* R738 */
+ 0x0000, /* R739 */
+ 0x0000, /* R740 */
+ 0x0000, /* R741 */
+ 0x0000, /* R742 */
+ 0x0000, /* R743 */
+ 0x0000, /* R744 */
+ 0x0000, /* R745 */
+ 0x0000, /* R746 */
+ 0x0000, /* R747 */
+ 0x0000, /* R748 */
+ 0x0000, /* R749 */
+ 0x0000, /* R750 */
+ 0x0000, /* R751 */
+ 0x0000, /* R752 */
+ 0x0000, /* R753 */
+ 0x0000, /* R754 */
+ 0x0000, /* R755 */
+ 0x0000, /* R756 */
+ 0x0000, /* R757 */
+ 0x0000, /* R758 */
+ 0x0000, /* R759 */
+ 0x0000, /* R760 */
+ 0x0000, /* R761 */
+ 0x0000, /* R762 */
+ 0x0000, /* R763 */
+ 0x0000, /* R764 */
+ 0x0000, /* R765 */
+ 0x0000, /* R766 */
+ 0x0000, /* R767 */
+ 0x4050, /* R768 - AIF1 Control (1) */
+ 0x4000, /* R769 - AIF1 Control (2) */
+ 0x0000, /* R770 - AIF1 Master/Slave */
+ 0x0040, /* R771 - AIF1 BCLK */
+ 0x0040, /* R772 - AIF1ADC LRCLK */
+ 0x0040, /* R773 - AIF1DAC LRCLK */
+ 0x0004, /* R774 - AIF1DAC Data */
+ 0x0100, /* R775 - AIF1ADC Data */
+ 0x0000, /* R776 */
+ 0x0000, /* R777 */
+ 0x0000, /* R778 */
+ 0x0000, /* R779 */
+ 0x0000, /* R780 */
+ 0x0000, /* R781 */
+ 0x0000, /* R782 */
+ 0x0000, /* R783 */
+ 0x4050, /* R784 - AIF2 Control (1) */
+ 0x4000, /* R785 - AIF2 Control (2) */
+ 0x0000, /* R786 - AIF2 Master/Slave */
+ 0x0040, /* R787 - AIF2 BCLK */
+ 0x0040, /* R788 - AIF2ADC LRCLK */
+ 0x0040, /* R789 - AIF2DAC LRCLK */
+ 0x0000, /* R790 - AIF2DAC Data */
+ 0x0000, /* R791 - AIF2ADC Data */
+ 0x0000, /* R792 */
+ 0x0000, /* R793 */
+ 0x0000, /* R794 */
+ 0x0000, /* R795 */
+ 0x0000, /* R796 */
+ 0x0000, /* R797 */
+ 0x0000, /* R798 */
+ 0x0000, /* R799 */
+ 0x0000, /* R800 */
+ 0x0000, /* R801 */
+ 0x0000, /* R802 */
+ 0x0000, /* R803 */
+ 0x0000, /* R804 */
+ 0x0000, /* R805 */
+ 0x0000, /* R806 */
+ 0x0000, /* R807 */
+ 0x0000, /* R808 */
+ 0x0000, /* R809 */
+ 0x0000, /* R810 */
+ 0x0000, /* R811 */
+ 0x0000, /* R812 */
+ 0x0000, /* R813 */
+ 0x0000, /* R814 */
+ 0x0000, /* R815 */
+ 0x0000, /* R816 */
+ 0x0000, /* R817 */
+ 0x0000, /* R818 */
+ 0x0000, /* R819 */
+ 0x0000, /* R820 */
+ 0x0000, /* R821 */
+ 0x0000, /* R822 */
+ 0x0000, /* R823 */
+ 0x0000, /* R824 */
+ 0x0000, /* R825 */
+ 0x0000, /* R826 */
+ 0x0000, /* R827 */
+ 0x0000, /* R828 */
+ 0x0000, /* R829 */
+ 0x0000, /* R830 */
+ 0x0000, /* R831 */
+ 0x0000, /* R832 */
+ 0x0000, /* R833 */
+ 0x0000, /* R834 */
+ 0x0000, /* R835 */
+ 0x0000, /* R836 */
+ 0x0000, /* R837 */
+ 0x0000, /* R838 */
+ 0x0000, /* R839 */
+ 0x0000, /* R840 */
+ 0x0000, /* R841 */
+ 0x0000, /* R842 */
+ 0x0000, /* R843 */
+ 0x0000, /* R844 */
+ 0x0000, /* R845 */
+ 0x0000, /* R846 */
+ 0x0000, /* R847 */
+ 0x0000, /* R848 */
+ 0x0000, /* R849 */
+ 0x0000, /* R850 */
+ 0x0000, /* R851 */
+ 0x0000, /* R852 */
+ 0x0000, /* R853 */
+ 0x0000, /* R854 */
+ 0x0000, /* R855 */
+ 0x0000, /* R856 */
+ 0x0000, /* R857 */
+ 0x0000, /* R858 */
+ 0x0000, /* R859 */
+ 0x0000, /* R860 */
+ 0x0000, /* R861 */
+ 0x0000, /* R862 */
+ 0x0000, /* R863 */
+ 0x0000, /* R864 */
+ 0x0000, /* R865 */
+ 0x0000, /* R866 */
+ 0x0000, /* R867 */
+ 0x0000, /* R868 */
+ 0x0000, /* R869 */
+ 0x0000, /* R870 */
+ 0x0000, /* R871 */
+ 0x0000, /* R872 */
+ 0x0000, /* R873 */
+ 0x0000, /* R874 */
+ 0x0000, /* R875 */
+ 0x0000, /* R876 */
+ 0x0000, /* R877 */
+ 0x0000, /* R878 */
+ 0x0000, /* R879 */
+ 0x0000, /* R880 */
+ 0x0000, /* R881 */
+ 0x0000, /* R882 */
+ 0x0000, /* R883 */
+ 0x0000, /* R884 */
+ 0x0000, /* R885 */
+ 0x0000, /* R886 */
+ 0x0000, /* R887 */
+ 0x0000, /* R888 */
+ 0x0000, /* R889 */
+ 0x0000, /* R890 */
+ 0x0000, /* R891 */
+ 0x0000, /* R892 */
+ 0x0000, /* R893 */
+ 0x0000, /* R894 */
+ 0x0000, /* R895 */
+ 0x0000, /* R896 */
+ 0x0000, /* R897 */
+ 0x0000, /* R898 */
+ 0x0000, /* R899 */
+ 0x0000, /* R900 */
+ 0x0000, /* R901 */
+ 0x0000, /* R902 */
+ 0x0000, /* R903 */
+ 0x0000, /* R904 */
+ 0x0000, /* R905 */
+ 0x0000, /* R906 */
+ 0x0000, /* R907 */
+ 0x0000, /* R908 */
+ 0x0000, /* R909 */
+ 0x0000, /* R910 */
+ 0x0000, /* R911 */
+ 0x0000, /* R912 */
+ 0x0000, /* R913 */
+ 0x0000, /* R914 */
+ 0x0000, /* R915 */
+ 0x0000, /* R916 */
+ 0x0000, /* R917 */
+ 0x0000, /* R918 */
+ 0x0000, /* R919 */
+ 0x0000, /* R920 */
+ 0x0000, /* R921 */
+ 0x0000, /* R922 */
+ 0x0000, /* R923 */
+ 0x0000, /* R924 */
+ 0x0000, /* R925 */
+ 0x0000, /* R926 */
+ 0x0000, /* R927 */
+ 0x0000, /* R928 */
+ 0x0000, /* R929 */
+ 0x0000, /* R930 */
+ 0x0000, /* R931 */
+ 0x0000, /* R932 */
+ 0x0000, /* R933 */
+ 0x0000, /* R934 */
+ 0x0000, /* R935 */
+ 0x0000, /* R936 */
+ 0x0000, /* R937 */
+ 0x0000, /* R938 */
+ 0x0000, /* R939 */
+ 0x0000, /* R940 */
+ 0x0000, /* R941 */
+ 0x0000, /* R942 */
+ 0x0000, /* R943 */
+ 0x0000, /* R944 */
+ 0x0000, /* R945 */
+ 0x0000, /* R946 */
+ 0x0000, /* R947 */
+ 0x0000, /* R948 */
+ 0x0000, /* R949 */
+ 0x0000, /* R950 */
+ 0x0000, /* R951 */
+ 0x0000, /* R952 */
+ 0x0000, /* R953 */
+ 0x0000, /* R954 */
+ 0x0000, /* R955 */
+ 0x0000, /* R956 */
+ 0x0000, /* R957 */
+ 0x0000, /* R958 */
+ 0x0000, /* R959 */
+ 0x0000, /* R960 */
+ 0x0000, /* R961 */
+ 0x0000, /* R962 */
+ 0x0000, /* R963 */
+ 0x0000, /* R964 */
+ 0x0000, /* R965 */
+ 0x0000, /* R966 */
+ 0x0000, /* R967 */
+ 0x0000, /* R968 */
+ 0x0000, /* R969 */
+ 0x0000, /* R970 */
+ 0x0000, /* R971 */
+ 0x0000, /* R972 */
+ 0x0000, /* R973 */
+ 0x0000, /* R974 */
+ 0x0000, /* R975 */
+ 0x0000, /* R976 */
+ 0x0000, /* R977 */
+ 0x0000, /* R978 */
+ 0x0000, /* R979 */
+ 0x0000, /* R980 */
+ 0x0000, /* R981 */
+ 0x0000, /* R982 */
+ 0x0000, /* R983 */
+ 0x0000, /* R984 */
+ 0x0000, /* R985 */
+ 0x0000, /* R986 */
+ 0x0000, /* R987 */
+ 0x0000, /* R988 */
+ 0x0000, /* R989 */
+ 0x0000, /* R990 */
+ 0x0000, /* R991 */
+ 0x0000, /* R992 */
+ 0x0000, /* R993 */
+ 0x0000, /* R994 */
+ 0x0000, /* R995 */
+ 0x0000, /* R996 */
+ 0x0000, /* R997 */
+ 0x0000, /* R998 */
+ 0x0000, /* R999 */
+ 0x0000, /* R1000 */
+ 0x0000, /* R1001 */
+ 0x0000, /* R1002 */
+ 0x0000, /* R1003 */
+ 0x0000, /* R1004 */
+ 0x0000, /* R1005 */
+ 0x0000, /* R1006 */
+ 0x0000, /* R1007 */
+ 0x0000, /* R1008 */
+ 0x0000, /* R1009 */
+ 0x0000, /* R1010 */
+ 0x0000, /* R1011 */
+ 0x0000, /* R1012 */
+ 0x0000, /* R1013 */
+ 0x0000, /* R1014 */
+ 0x0000, /* R1015 */
+ 0x0000, /* R1016 */
+ 0x0000, /* R1017 */
+ 0x0000, /* R1018 */
+ 0x0000, /* R1019 */
+ 0x0000, /* R1020 */
+ 0x0000, /* R1021 */
+ 0x0000, /* R1022 */
+ 0x0000, /* R1023 */
+ 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */
+ 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */
+ 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */
+ 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */
+ 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */
+ 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */
+ 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */
+ 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */
+ 0x0000, /* R1032 */
+ 0x0000, /* R1033 */
+ 0x0000, /* R1034 */
+ 0x0000, /* R1035 */
+ 0x0000, /* R1036 */
+ 0x0000, /* R1037 */
+ 0x0000, /* R1038 */
+ 0x0000, /* R1039 */
+ 0x0000, /* R1040 - AIF1 ADC1 Filters */
+ 0x0000, /* R1041 - AIF1 ADC2 Filters */
+ 0x0000, /* R1042 */
+ 0x0000, /* R1043 */
+ 0x0000, /* R1044 */
+ 0x0000, /* R1045 */
+ 0x0000, /* R1046 */
+ 0x0000, /* R1047 */
+ 0x0000, /* R1048 */
+ 0x0000, /* R1049 */
+ 0x0000, /* R1050 */
+ 0x0000, /* R1051 */
+ 0x0000, /* R1052 */
+ 0x0000, /* R1053 */
+ 0x0000, /* R1054 */
+ 0x0000, /* R1055 */
+ 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */
+ 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */
+ 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */
+ 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */
+ 0x0000, /* R1060 */
+ 0x0000, /* R1061 */
+ 0x0000, /* R1062 */
+ 0x0000, /* R1063 */
+ 0x0000, /* R1064 */
+ 0x0000, /* R1065 */
+ 0x0000, /* R1066 */
+ 0x0000, /* R1067 */
+ 0x0000, /* R1068 */
+ 0x0000, /* R1069 */
+ 0x0000, /* R1070 */
+ 0x0000, /* R1071 */
+ 0x0000, /* R1072 */
+ 0x0000, /* R1073 */
+ 0x0000, /* R1074 */
+ 0x0000, /* R1075 */
+ 0x0000, /* R1076 */
+ 0x0000, /* R1077 */
+ 0x0000, /* R1078 */
+ 0x0000, /* R1079 */
+ 0x0000, /* R1080 */
+ 0x0000, /* R1081 */
+ 0x0000, /* R1082 */
+ 0x0000, /* R1083 */
+ 0x0000, /* R1084 */
+ 0x0000, /* R1085 */
+ 0x0000, /* R1086 */
+ 0x0000, /* R1087 */
+ 0x0098, /* R1088 - AIF1 DRC1 (1) */
+ 0x0845, /* R1089 - AIF1 DRC1 (2) */
+ 0x0000, /* R1090 - AIF1 DRC1 (3) */
+ 0x0000, /* R1091 - AIF1 DRC1 (4) */
+ 0x0000, /* R1092 - AIF1 DRC1 (5) */
+ 0x0000, /* R1093 */
+ 0x0000, /* R1094 */
+ 0x0000, /* R1095 */
+ 0x0000, /* R1096 */
+ 0x0000, /* R1097 */
+ 0x0000, /* R1098 */
+ 0x0000, /* R1099 */
+ 0x0000, /* R1100 */
+ 0x0000, /* R1101 */
+ 0x0000, /* R1102 */
+ 0x0000, /* R1103 */
+ 0x0098, /* R1104 - AIF1 DRC2 (1) */
+ 0x0845, /* R1105 - AIF1 DRC2 (2) */
+ 0x0000, /* R1106 - AIF1 DRC2 (3) */
+ 0x0000, /* R1107 - AIF1 DRC2 (4) */
+ 0x0000, /* R1108 - AIF1 DRC2 (5) */
+ 0x0000, /* R1109 */
+ 0x0000, /* R1110 */
+ 0x0000, /* R1111 */
+ 0x0000, /* R1112 */
+ 0x0000, /* R1113 */
+ 0x0000, /* R1114 */
+ 0x0000, /* R1115 */
+ 0x0000, /* R1116 */
+ 0x0000, /* R1117 */
+ 0x0000, /* R1118 */
+ 0x0000, /* R1119 */
+ 0x0000, /* R1120 */
+ 0x0000, /* R1121 */
+ 0x0000, /* R1122 */
+ 0x0000, /* R1123 */
+ 0x0000, /* R1124 */
+ 0x0000, /* R1125 */
+ 0x0000, /* R1126 */
+ 0x0000, /* R1127 */
+ 0x0000, /* R1128 */
+ 0x0000, /* R1129 */
+ 0x0000, /* R1130 */
+ 0x0000, /* R1131 */
+ 0x0000, /* R1132 */
+ 0x0000, /* R1133 */
+ 0x0000, /* R1134 */
+ 0x0000, /* R1135 */
+ 0x0000, /* R1136 */
+ 0x0000, /* R1137 */
+ 0x0000, /* R1138 */
+ 0x0000, /* R1139 */
+ 0x0000, /* R1140 */
+ 0x0000, /* R1141 */
+ 0x0000, /* R1142 */
+ 0x0000, /* R1143 */
+ 0x0000, /* R1144 */
+ 0x0000, /* R1145 */
+ 0x0000, /* R1146 */
+ 0x0000, /* R1147 */
+ 0x0000, /* R1148 */
+ 0x0000, /* R1149 */
+ 0x0000, /* R1150 */
+ 0x0000, /* R1151 */
+ 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ 0x0000, /* R1172 */
+ 0x0000, /* R1173 */
+ 0x0000, /* R1174 */
+ 0x0000, /* R1175 */
+ 0x0000, /* R1176 */
+ 0x0000, /* R1177 */
+ 0x0000, /* R1178 */
+ 0x0000, /* R1179 */
+ 0x0000, /* R1180 */
+ 0x0000, /* R1181 */
+ 0x0000, /* R1182 */
+ 0x0000, /* R1183 */
+ 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ 0x0000, /* R1204 */
+ 0x0000, /* R1205 */
+ 0x0000, /* R1206 */
+ 0x0000, /* R1207 */
+ 0x0000, /* R1208 */
+ 0x0000, /* R1209 */
+ 0x0000, /* R1210 */
+ 0x0000, /* R1211 */
+ 0x0000, /* R1212 */
+ 0x0000, /* R1213 */
+ 0x0000, /* R1214 */
+ 0x0000, /* R1215 */
+ 0x0000, /* R1216 */
+ 0x0000, /* R1217 */
+ 0x0000, /* R1218 */
+ 0x0000, /* R1219 */
+ 0x0000, /* R1220 */
+ 0x0000, /* R1221 */
+ 0x0000, /* R1222 */
+ 0x0000, /* R1223 */
+ 0x0000, /* R1224 */
+ 0x0000, /* R1225 */
+ 0x0000, /* R1226 */
+ 0x0000, /* R1227 */
+ 0x0000, /* R1228 */
+ 0x0000, /* R1229 */
+ 0x0000, /* R1230 */
+ 0x0000, /* R1231 */
+ 0x0000, /* R1232 */
+ 0x0000, /* R1233 */
+ 0x0000, /* R1234 */
+ 0x0000, /* R1235 */
+ 0x0000, /* R1236 */
+ 0x0000, /* R1237 */
+ 0x0000, /* R1238 */
+ 0x0000, /* R1239 */
+ 0x0000, /* R1240 */
+ 0x0000, /* R1241 */
+ 0x0000, /* R1242 */
+ 0x0000, /* R1243 */
+ 0x0000, /* R1244 */
+ 0x0000, /* R1245 */
+ 0x0000, /* R1246 */
+ 0x0000, /* R1247 */
+ 0x0000, /* R1248 */
+ 0x0000, /* R1249 */
+ 0x0000, /* R1250 */
+ 0x0000, /* R1251 */
+ 0x0000, /* R1252 */
+ 0x0000, /* R1253 */
+ 0x0000, /* R1254 */
+ 0x0000, /* R1255 */
+ 0x0000, /* R1256 */
+ 0x0000, /* R1257 */
+ 0x0000, /* R1258 */
+ 0x0000, /* R1259 */
+ 0x0000, /* R1260 */
+ 0x0000, /* R1261 */
+ 0x0000, /* R1262 */
+ 0x0000, /* R1263 */
+ 0x0000, /* R1264 */
+ 0x0000, /* R1265 */
+ 0x0000, /* R1266 */
+ 0x0000, /* R1267 */
+ 0x0000, /* R1268 */
+ 0x0000, /* R1269 */
+ 0x0000, /* R1270 */
+ 0x0000, /* R1271 */
+ 0x0000, /* R1272 */
+ 0x0000, /* R1273 */
+ 0x0000, /* R1274 */
+ 0x0000, /* R1275 */
+ 0x0000, /* R1276 */
+ 0x0000, /* R1277 */
+ 0x0000, /* R1278 */
+ 0x0000, /* R1279 */
+ 0x00C0, /* R1280 - AIF2 ADC Left Volume */
+ 0x00C0, /* R1281 - AIF2 ADC Right Volume */
+ 0x00C0, /* R1282 - AIF2 DAC Left Volume */
+ 0x00C0, /* R1283 - AIF2 DAC Right Volume */
+ 0x0000, /* R1284 */
+ 0x0000, /* R1285 */
+ 0x0000, /* R1286 */
+ 0x0000, /* R1287 */
+ 0x0000, /* R1288 */
+ 0x0000, /* R1289 */
+ 0x0000, /* R1290 */
+ 0x0000, /* R1291 */
+ 0x0000, /* R1292 */
+ 0x0000, /* R1293 */
+ 0x0000, /* R1294 */
+ 0x0000, /* R1295 */
+ 0x0000, /* R1296 - AIF2 ADC Filters */
+ 0x0000, /* R1297 */
+ 0x0000, /* R1298 */
+ 0x0000, /* R1299 */
+ 0x0000, /* R1300 */
+ 0x0000, /* R1301 */
+ 0x0000, /* R1302 */
+ 0x0000, /* R1303 */
+ 0x0000, /* R1304 */
+ 0x0000, /* R1305 */
+ 0x0000, /* R1306 */
+ 0x0000, /* R1307 */
+ 0x0000, /* R1308 */
+ 0x0000, /* R1309 */
+ 0x0000, /* R1310 */
+ 0x0000, /* R1311 */
+ 0x0200, /* R1312 - AIF2 DAC Filters (1) */
+ 0x0010, /* R1313 - AIF2 DAC Filters (2) */
+ 0x0000, /* R1314 */
+ 0x0000, /* R1315 */
+ 0x0000, /* R1316 */
+ 0x0000, /* R1317 */
+ 0x0000, /* R1318 */
+ 0x0000, /* R1319 */
+ 0x0000, /* R1320 */
+ 0x0000, /* R1321 */
+ 0x0000, /* R1322 */
+ 0x0000, /* R1323 */
+ 0x0000, /* R1324 */
+ 0x0000, /* R1325 */
+ 0x0000, /* R1326 */
+ 0x0000, /* R1327 */
+ 0x0000, /* R1328 */
+ 0x0000, /* R1329 */
+ 0x0000, /* R1330 */
+ 0x0000, /* R1331 */
+ 0x0000, /* R1332 */
+ 0x0000, /* R1333 */
+ 0x0000, /* R1334 */
+ 0x0000, /* R1335 */
+ 0x0000, /* R1336 */
+ 0x0000, /* R1337 */
+ 0x0000, /* R1338 */
+ 0x0000, /* R1339 */
+ 0x0000, /* R1340 */
+ 0x0000, /* R1341 */
+ 0x0000, /* R1342 */
+ 0x0000, /* R1343 */
+ 0x0098, /* R1344 - AIF2 DRC (1) */
+ 0x0845, /* R1345 - AIF2 DRC (2) */
+ 0x0000, /* R1346 - AIF2 DRC (3) */
+ 0x0000, /* R1347 - AIF2 DRC (4) */
+ 0x0000, /* R1348 - AIF2 DRC (5) */
+ 0x0000, /* R1349 */
+ 0x0000, /* R1350 */
+ 0x0000, /* R1351 */
+ 0x0000, /* R1352 */
+ 0x0000, /* R1353 */
+ 0x0000, /* R1354 */
+ 0x0000, /* R1355 */
+ 0x0000, /* R1356 */
+ 0x0000, /* R1357 */
+ 0x0000, /* R1358 */
+ 0x0000, /* R1359 */
+ 0x0000, /* R1360 */
+ 0x0000, /* R1361 */
+ 0x0000, /* R1362 */
+ 0x0000, /* R1363 */
+ 0x0000, /* R1364 */
+ 0x0000, /* R1365 */
+ 0x0000, /* R1366 */
+ 0x0000, /* R1367 */
+ 0x0000, /* R1368 */
+ 0x0000, /* R1369 */
+ 0x0000, /* R1370 */
+ 0x0000, /* R1371 */
+ 0x0000, /* R1372 */
+ 0x0000, /* R1373 */
+ 0x0000, /* R1374 */
+ 0x0000, /* R1375 */
+ 0x0000, /* R1376 */
+ 0x0000, /* R1377 */
+ 0x0000, /* R1378 */
+ 0x0000, /* R1379 */
+ 0x0000, /* R1380 */
+ 0x0000, /* R1381 */
+ 0x0000, /* R1382 */
+ 0x0000, /* R1383 */
+ 0x0000, /* R1384 */
+ 0x0000, /* R1385 */
+ 0x0000, /* R1386 */
+ 0x0000, /* R1387 */
+ 0x0000, /* R1388 */
+ 0x0000, /* R1389 */
+ 0x0000, /* R1390 */
+ 0x0000, /* R1391 */
+ 0x0000, /* R1392 */
+ 0x0000, /* R1393 */
+ 0x0000, /* R1394 */
+ 0x0000, /* R1395 */
+ 0x0000, /* R1396 */
+ 0x0000, /* R1397 */
+ 0x0000, /* R1398 */
+ 0x0000, /* R1399 */
+ 0x0000, /* R1400 */
+ 0x0000, /* R1401 */
+ 0x0000, /* R1402 */
+ 0x0000, /* R1403 */
+ 0x0000, /* R1404 */
+ 0x0000, /* R1405 */
+ 0x0000, /* R1406 */
+ 0x0000, /* R1407 */
+ 0x6318, /* R1408 - AIF2 EQ Gains (1) */
+ 0x6300, /* R1409 - AIF2 EQ Gains (2) */
+ 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */
+ 0x0400, /* R1411 - AIF2 EQ Band 1 B */
+ 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */
+ 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */
+ 0xF145, /* R1414 - AIF2 EQ Band 2 B */
+ 0x0B75, /* R1415 - AIF2 EQ Band 2 C */
+ 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */
+ 0x1C58, /* R1417 - AIF2 EQ Band 3 A */
+ 0xF373, /* R1418 - AIF2 EQ Band 3 B */
+ 0x0A54, /* R1419 - AIF2 EQ Band 3 C */
+ 0x0558, /* R1420 - AIF2 EQ Band 3 PG */
+ 0x168E, /* R1421 - AIF2 EQ Band 4 A */
+ 0xF829, /* R1422 - AIF2 EQ Band 4 B */
+ 0x07AD, /* R1423 - AIF2 EQ Band 4 C */
+ 0x1103, /* R1424 - AIF2 EQ Band 4 PG */
+ 0x0564, /* R1425 - AIF2 EQ Band 5 A */
+ 0x0559, /* R1426 - AIF2 EQ Band 5 B */
+ 0x4000, /* R1427 - AIF2 EQ Band 5 PG */
+ 0x0000, /* R1428 */
+ 0x0000, /* R1429 */
+ 0x0000, /* R1430 */
+ 0x0000, /* R1431 */
+ 0x0000, /* R1432 */
+ 0x0000, /* R1433 */
+ 0x0000, /* R1434 */
+ 0x0000, /* R1435 */
+ 0x0000, /* R1436 */
+ 0x0000, /* R1437 */
+ 0x0000, /* R1438 */
+ 0x0000, /* R1439 */
+ 0x0000, /* R1440 */
+ 0x0000, /* R1441 */
+ 0x0000, /* R1442 */
+ 0x0000, /* R1443 */
+ 0x0000, /* R1444 */
+ 0x0000, /* R1445 */
+ 0x0000, /* R1446 */
+ 0x0000, /* R1447 */
+ 0x0000, /* R1448 */
+ 0x0000, /* R1449 */
+ 0x0000, /* R1450 */
+ 0x0000, /* R1451 */
+ 0x0000, /* R1452 */
+ 0x0000, /* R1453 */
+ 0x0000, /* R1454 */
+ 0x0000, /* R1455 */
+ 0x0000, /* R1456 */
+ 0x0000, /* R1457 */
+ 0x0000, /* R1458 */
+ 0x0000, /* R1459 */
+ 0x0000, /* R1460 */
+ 0x0000, /* R1461 */
+ 0x0000, /* R1462 */
+ 0x0000, /* R1463 */
+ 0x0000, /* R1464 */
+ 0x0000, /* R1465 */
+ 0x0000, /* R1466 */
+ 0x0000, /* R1467 */
+ 0x0000, /* R1468 */
+ 0x0000, /* R1469 */
+ 0x0000, /* R1470 */
+ 0x0000, /* R1471 */
+ 0x0000, /* R1472 */
+ 0x0000, /* R1473 */
+ 0x0000, /* R1474 */
+ 0x0000, /* R1475 */
+ 0x0000, /* R1476 */
+ 0x0000, /* R1477 */
+ 0x0000, /* R1478 */
+ 0x0000, /* R1479 */
+ 0x0000, /* R1480 */
+ 0x0000, /* R1481 */
+ 0x0000, /* R1482 */
+ 0x0000, /* R1483 */
+ 0x0000, /* R1484 */
+ 0x0000, /* R1485 */
+ 0x0000, /* R1486 */
+ 0x0000, /* R1487 */
+ 0x0000, /* R1488 */
+ 0x0000, /* R1489 */
+ 0x0000, /* R1490 */
+ 0x0000, /* R1491 */
+ 0x0000, /* R1492 */
+ 0x0000, /* R1493 */
+ 0x0000, /* R1494 */
+ 0x0000, /* R1495 */
+ 0x0000, /* R1496 */
+ 0x0000, /* R1497 */
+ 0x0000, /* R1498 */
+ 0x0000, /* R1499 */
+ 0x0000, /* R1500 */
+ 0x0000, /* R1501 */
+ 0x0000, /* R1502 */
+ 0x0000, /* R1503 */
+ 0x0000, /* R1504 */
+ 0x0000, /* R1505 */
+ 0x0000, /* R1506 */
+ 0x0000, /* R1507 */
+ 0x0000, /* R1508 */
+ 0x0000, /* R1509 */
+ 0x0000, /* R1510 */
+ 0x0000, /* R1511 */
+ 0x0000, /* R1512 */
+ 0x0000, /* R1513 */
+ 0x0000, /* R1514 */
+ 0x0000, /* R1515 */
+ 0x0000, /* R1516 */
+ 0x0000, /* R1517 */
+ 0x0000, /* R1518 */
+ 0x0000, /* R1519 */
+ 0x0000, /* R1520 */
+ 0x0000, /* R1521 */
+ 0x0000, /* R1522 */
+ 0x0000, /* R1523 */
+ 0x0000, /* R1524 */
+ 0x0000, /* R1525 */
+ 0x0000, /* R1526 */
+ 0x0000, /* R1527 */
+ 0x0000, /* R1528 */
+ 0x0000, /* R1529 */
+ 0x0000, /* R1530 */
+ 0x0000, /* R1531 */
+ 0x0000, /* R1532 */
+ 0x0000, /* R1533 */
+ 0x0000, /* R1534 */
+ 0x0000, /* R1535 */
+ 0x0000, /* R1536 - DAC1 Mixer Volumes */
+ 0x0000, /* R1537 - DAC1 Left Mixer Routing */
+ 0x0000, /* R1538 - DAC1 Right Mixer Routing */
+ 0x0000, /* R1539 - DAC2 Mixer Volumes */
+ 0x0000, /* R1540 - DAC2 Left Mixer Routing */
+ 0x0000, /* R1541 - DAC2 Right Mixer Routing */
+ 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ 0x0000, /* R1546 */
+ 0x0000, /* R1547 */
+ 0x0000, /* R1548 */
+ 0x0000, /* R1549 */
+ 0x0000, /* R1550 */
+ 0x0000, /* R1551 */
+ 0x02C0, /* R1552 - DAC1 Left Volume */
+ 0x02C0, /* R1553 - DAC1 Right Volume */
+ 0x02C0, /* R1554 - DAC2 Left Volume */
+ 0x02C0, /* R1555 - DAC2 Right Volume */
+ 0x0000, /* R1556 - DAC Softmute */
+ 0x0000, /* R1557 */
+ 0x0000, /* R1558 */
+ 0x0000, /* R1559 */
+ 0x0000, /* R1560 */
+ 0x0000, /* R1561 */
+ 0x0000, /* R1562 */
+ 0x0000, /* R1563 */
+ 0x0000, /* R1564 */
+ 0x0000, /* R1565 */
+ 0x0000, /* R1566 */
+ 0x0000, /* R1567 */
+ 0x0002, /* R1568 - Oversampling */
+ 0x0000, /* R1569 - Sidetone */
+};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 4d3e6f1ac584..af104acd75f8 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -18,13 +18,14 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
+#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -57,8 +58,6 @@ static int wm8994_retune_mobile_base[] = {
WM8994_AIF2_EQ_GAINS_1,
};
-#define WM8994_REG_CACHE_SIZE 0x621
-
struct wm8994_micdet {
struct snd_soc_jack *jack;
int det;
@@ -71,7 +70,6 @@ struct wm8994_priv {
enum snd_soc_control_type control_type;
void *control_data;
struct snd_soc_codec *codec;
- u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
int sysclk[2];
int sysclk_rate[2];
int mclk[2];
@@ -81,6 +79,8 @@ struct wm8994_priv {
int dac_rates[2];
int lrclk_shared[2];
+ int mbc_ena[3];
+
/* Platform dependant DRC configuration */
const char **drc_texts;
int drc_cfg[WM8994_NUM_DRC];
@@ -92,1588 +92,22 @@ struct wm8994_priv {
int retune_mobile_cfg[WM8994_NUM_EQ];
struct soc_enum retune_mobile_enum;
+ /* Platform dependant MBC configuration */
+ int mbc_cfg;
+ const char **mbc_texts;
+ struct soc_enum mbc_enum;
+
struct wm8994_micdet micdet[2];
+ wm8958_micdet_cb jack_cb;
+ void *jack_cb_data;
+ bool jack_is_mic;
+ bool jack_is_video;
+
int revision;
struct wm8994_pdata *pdata;
};
-static const struct {
- unsigned short readable; /* Mask of readable bits */
- unsigned short writable; /* Mask of writable bits */
-} access_masks[] = {
- { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
- { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
- { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
- { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
- { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
- { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
- { 0x003F, 0x003F }, /* R6 - Power Management (6) */
- { 0x0000, 0x0000 }, /* R7 */
- { 0x0000, 0x0000 }, /* R8 */
- { 0x0000, 0x0000 }, /* R9 */
- { 0x0000, 0x0000 }, /* R10 */
- { 0x0000, 0x0000 }, /* R11 */
- { 0x0000, 0x0000 }, /* R12 */
- { 0x0000, 0x0000 }, /* R13 */
- { 0x0000, 0x0000 }, /* R14 */
- { 0x0000, 0x0000 }, /* R15 */
- { 0x0000, 0x0000 }, /* R16 */
- { 0x0000, 0x0000 }, /* R17 */
- { 0x0000, 0x0000 }, /* R18 */
- { 0x0000, 0x0000 }, /* R19 */
- { 0x0000, 0x0000 }, /* R20 */
- { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
- { 0x0000, 0x0000 }, /* R22 */
- { 0x0000, 0x0000 }, /* R23 */
- { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
- { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
- { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
- { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
- { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
- { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
- { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
- { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
- { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
- { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
- { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
- { 0x003F, 0x003F }, /* R37 - ClassD */
- { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
- { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
- { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
- { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
- { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
- { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
- { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
- { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
- { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
- { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
- { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
- { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
- { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
- { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
- { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
- { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
- { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
- { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
- { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
- { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
- { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
- { 0x000F, 0x000F }, /* R59 - LDO 1 */
- { 0x0007, 0x0007 }, /* R60 - LDO 2 */
- { 0x0000, 0x0000 }, /* R61 */
- { 0x0000, 0x0000 }, /* R62 */
- { 0x0000, 0x0000 }, /* R63 */
- { 0x0000, 0x0000 }, /* R64 */
- { 0x0000, 0x0000 }, /* R65 */
- { 0x0000, 0x0000 }, /* R66 */
- { 0x0000, 0x0000 }, /* R67 */
- { 0x0000, 0x0000 }, /* R68 */
- { 0x0000, 0x0000 }, /* R69 */
- { 0x0000, 0x0000 }, /* R70 */
- { 0x0000, 0x0000 }, /* R71 */
- { 0x0000, 0x0000 }, /* R72 */
- { 0x0000, 0x0000 }, /* R73 */
- { 0x0000, 0x0000 }, /* R74 */
- { 0x0000, 0x0000 }, /* R75 */
- { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
- { 0x0000, 0x0000 }, /* R77 */
- { 0x0000, 0x0000 }, /* R78 */
- { 0x0000, 0x0000 }, /* R79 */
- { 0x0000, 0x0000 }, /* R80 */
- { 0x0301, 0x0301 }, /* R81 - Class W (1) */
- { 0x0000, 0x0000 }, /* R82 */
- { 0x0000, 0x0000 }, /* R83 */
- { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
- { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
- { 0x0000, 0x0000 }, /* R86 */
- { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
- { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
- { 0x0000, 0x0000 }, /* R89 */
- { 0x0000, 0x0000 }, /* R90 */
- { 0x0000, 0x0000 }, /* R91 */
- { 0x0000, 0x0000 }, /* R92 */
- { 0x0000, 0x0000 }, /* R93 */
- { 0x0000, 0x0000 }, /* R94 */
- { 0x0000, 0x0000 }, /* R95 */
- { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
- { 0x0000, 0x0000 }, /* R97 */
- { 0x0000, 0x0000 }, /* R98 */
- { 0x0000, 0x0000 }, /* R99 */
- { 0x0000, 0x0000 }, /* R100 */
- { 0x0000, 0x0000 }, /* R101 */
- { 0x0000, 0x0000 }, /* R102 */
- { 0x0000, 0x0000 }, /* R103 */
- { 0x0000, 0x0000 }, /* R104 */
- { 0x0000, 0x0000 }, /* R105 */
- { 0x0000, 0x0000 }, /* R106 */
- { 0x0000, 0x0000 }, /* R107 */
- { 0x0000, 0x0000 }, /* R108 */
- { 0x0000, 0x0000 }, /* R109 */
- { 0x0000, 0x0000 }, /* R110 */
- { 0x0000, 0x0000 }, /* R111 */
- { 0x0000, 0x0000 }, /* R112 */
- { 0x0000, 0x0000 }, /* R113 */
- { 0x0000, 0x0000 }, /* R114 */
- { 0x0000, 0x0000 }, /* R115 */
- { 0x0000, 0x0000 }, /* R116 */
- { 0x0000, 0x0000 }, /* R117 */
- { 0x0000, 0x0000 }, /* R118 */
- { 0x0000, 0x0000 }, /* R119 */
- { 0x0000, 0x0000 }, /* R120 */
- { 0x0000, 0x0000 }, /* R121 */
- { 0x0000, 0x0000 }, /* R122 */
- { 0x0000, 0x0000 }, /* R123 */
- { 0x0000, 0x0000 }, /* R124 */
- { 0x0000, 0x0000 }, /* R125 */
- { 0x0000, 0x0000 }, /* R126 */
- { 0x0000, 0x0000 }, /* R127 */
- { 0x0000, 0x0000 }, /* R128 */
- { 0x0000, 0x0000 }, /* R129 */
- { 0x0000, 0x0000 }, /* R130 */
- { 0x0000, 0x0000 }, /* R131 */
- { 0x0000, 0x0000 }, /* R132 */
- { 0x0000, 0x0000 }, /* R133 */
- { 0x0000, 0x0000 }, /* R134 */
- { 0x0000, 0x0000 }, /* R135 */
- { 0x0000, 0x0000 }, /* R136 */
- { 0x0000, 0x0000 }, /* R137 */
- { 0x0000, 0x0000 }, /* R138 */
- { 0x0000, 0x0000 }, /* R139 */
- { 0x0000, 0x0000 }, /* R140 */
- { 0x0000, 0x0000 }, /* R141 */
- { 0x0000, 0x0000 }, /* R142 */
- { 0x0000, 0x0000 }, /* R143 */
- { 0x0000, 0x0000 }, /* R144 */
- { 0x0000, 0x0000 }, /* R145 */
- { 0x0000, 0x0000 }, /* R146 */
- { 0x0000, 0x0000 }, /* R147 */
- { 0x0000, 0x0000 }, /* R148 */
- { 0x0000, 0x0000 }, /* R149 */
- { 0x0000, 0x0000 }, /* R150 */
- { 0x0000, 0x0000 }, /* R151 */
- { 0x0000, 0x0000 }, /* R152 */
- { 0x0000, 0x0000 }, /* R153 */
- { 0x0000, 0x0000 }, /* R154 */
- { 0x0000, 0x0000 }, /* R155 */
- { 0x0000, 0x0000 }, /* R156 */
- { 0x0000, 0x0000 }, /* R157 */
- { 0x0000, 0x0000 }, /* R158 */
- { 0x0000, 0x0000 }, /* R159 */
- { 0x0000, 0x0000 }, /* R160 */
- { 0x0000, 0x0000 }, /* R161 */
- { 0x0000, 0x0000 }, /* R162 */
- { 0x0000, 0x0000 }, /* R163 */
- { 0x0000, 0x0000 }, /* R164 */
- { 0x0000, 0x0000 }, /* R165 */
- { 0x0000, 0x0000 }, /* R166 */
- { 0x0000, 0x0000 }, /* R167 */
- { 0x0000, 0x0000 }, /* R168 */
- { 0x0000, 0x0000 }, /* R169 */
- { 0x0000, 0x0000 }, /* R170 */
- { 0x0000, 0x0000 }, /* R171 */
- { 0x0000, 0x0000 }, /* R172 */
- { 0x0000, 0x0000 }, /* R173 */
- { 0x0000, 0x0000 }, /* R174 */
- { 0x0000, 0x0000 }, /* R175 */
- { 0x0000, 0x0000 }, /* R176 */
- { 0x0000, 0x0000 }, /* R177 */
- { 0x0000, 0x0000 }, /* R178 */
- { 0x0000, 0x0000 }, /* R179 */
- { 0x0000, 0x0000 }, /* R180 */
- { 0x0000, 0x0000 }, /* R181 */
- { 0x0000, 0x0000 }, /* R182 */
- { 0x0000, 0x0000 }, /* R183 */
- { 0x0000, 0x0000 }, /* R184 */
- { 0x0000, 0x0000 }, /* R185 */
- { 0x0000, 0x0000 }, /* R186 */
- { 0x0000, 0x0000 }, /* R187 */
- { 0x0000, 0x0000 }, /* R188 */
- { 0x0000, 0x0000 }, /* R189 */
- { 0x0000, 0x0000 }, /* R190 */
- { 0x0000, 0x0000 }, /* R191 */
- { 0x0000, 0x0000 }, /* R192 */
- { 0x0000, 0x0000 }, /* R193 */
- { 0x0000, 0x0000 }, /* R194 */
- { 0x0000, 0x0000 }, /* R195 */
- { 0x0000, 0x0000 }, /* R196 */
- { 0x0000, 0x0000 }, /* R197 */
- { 0x0000, 0x0000 }, /* R198 */
- { 0x0000, 0x0000 }, /* R199 */
- { 0x0000, 0x0000 }, /* R200 */
- { 0x0000, 0x0000 }, /* R201 */
- { 0x0000, 0x0000 }, /* R202 */
- { 0x0000, 0x0000 }, /* R203 */
- { 0x0000, 0x0000 }, /* R204 */
- { 0x0000, 0x0000 }, /* R205 */
- { 0x0000, 0x0000 }, /* R206 */
- { 0x0000, 0x0000 }, /* R207 */
- { 0x0000, 0x0000 }, /* R208 */
- { 0x0000, 0x0000 }, /* R209 */
- { 0x0000, 0x0000 }, /* R210 */
- { 0x0000, 0x0000 }, /* R211 */
- { 0x0000, 0x0000 }, /* R212 */
- { 0x0000, 0x0000 }, /* R213 */
- { 0x0000, 0x0000 }, /* R214 */
- { 0x0000, 0x0000 }, /* R215 */
- { 0x0000, 0x0000 }, /* R216 */
- { 0x0000, 0x0000 }, /* R217 */
- { 0x0000, 0x0000 }, /* R218 */
- { 0x0000, 0x0000 }, /* R219 */
- { 0x0000, 0x0000 }, /* R220 */
- { 0x0000, 0x0000 }, /* R221 */
- { 0x0000, 0x0000 }, /* R222 */
- { 0x0000, 0x0000 }, /* R223 */
- { 0x0000, 0x0000 }, /* R224 */
- { 0x0000, 0x0000 }, /* R225 */
- { 0x0000, 0x0000 }, /* R226 */
- { 0x0000, 0x0000 }, /* R227 */
- { 0x0000, 0x0000 }, /* R228 */
- { 0x0000, 0x0000 }, /* R229 */
- { 0x0000, 0x0000 }, /* R230 */
- { 0x0000, 0x0000 }, /* R231 */
- { 0x0000, 0x0000 }, /* R232 */
- { 0x0000, 0x0000 }, /* R233 */
- { 0x0000, 0x0000 }, /* R234 */
- { 0x0000, 0x0000 }, /* R235 */
- { 0x0000, 0x0000 }, /* R236 */
- { 0x0000, 0x0000 }, /* R237 */
- { 0x0000, 0x0000 }, /* R238 */
- { 0x0000, 0x0000 }, /* R239 */
- { 0x0000, 0x0000 }, /* R240 */
- { 0x0000, 0x0000 }, /* R241 */
- { 0x0000, 0x0000 }, /* R242 */
- { 0x0000, 0x0000 }, /* R243 */
- { 0x0000, 0x0000 }, /* R244 */
- { 0x0000, 0x0000 }, /* R245 */
- { 0x0000, 0x0000 }, /* R246 */
- { 0x0000, 0x0000 }, /* R247 */
- { 0x0000, 0x0000 }, /* R248 */
- { 0x0000, 0x0000 }, /* R249 */
- { 0x0000, 0x0000 }, /* R250 */
- { 0x0000, 0x0000 }, /* R251 */
- { 0x0000, 0x0000 }, /* R252 */
- { 0x0000, 0x0000 }, /* R253 */
- { 0x0000, 0x0000 }, /* R254 */
- { 0x0000, 0x0000 }, /* R255 */
- { 0x000F, 0x0000 }, /* R256 - Chip Revision */
- { 0x0074, 0x0074 }, /* R257 - Control Interface */
- { 0x0000, 0x0000 }, /* R258 */
- { 0x0000, 0x0000 }, /* R259 */
- { 0x0000, 0x0000 }, /* R260 */
- { 0x0000, 0x0000 }, /* R261 */
- { 0x0000, 0x0000 }, /* R262 */
- { 0x0000, 0x0000 }, /* R263 */
- { 0x0000, 0x0000 }, /* R264 */
- { 0x0000, 0x0000 }, /* R265 */
- { 0x0000, 0x0000 }, /* R266 */
- { 0x0000, 0x0000 }, /* R267 */
- { 0x0000, 0x0000 }, /* R268 */
- { 0x0000, 0x0000 }, /* R269 */
- { 0x0000, 0x0000 }, /* R270 */
- { 0x0000, 0x0000 }, /* R271 */
- { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
- { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
- { 0x0000, 0x0000 }, /* R274 */
- { 0x0000, 0x0000 }, /* R275 */
- { 0x0000, 0x0000 }, /* R276 */
- { 0x0000, 0x0000 }, /* R277 */
- { 0x0000, 0x0000 }, /* R278 */
- { 0x0000, 0x0000 }, /* R279 */
- { 0x0000, 0x0000 }, /* R280 */
- { 0x0000, 0x0000 }, /* R281 */
- { 0x0000, 0x0000 }, /* R282 */
- { 0x0000, 0x0000 }, /* R283 */
- { 0x0000, 0x0000 }, /* R284 */
- { 0x0000, 0x0000 }, /* R285 */
- { 0x0000, 0x0000 }, /* R286 */
- { 0x0000, 0x0000 }, /* R287 */
- { 0x0000, 0x0000 }, /* R288 */
- { 0x0000, 0x0000 }, /* R289 */
- { 0x0000, 0x0000 }, /* R290 */
- { 0x0000, 0x0000 }, /* R291 */
- { 0x0000, 0x0000 }, /* R292 */
- { 0x0000, 0x0000 }, /* R293 */
- { 0x0000, 0x0000 }, /* R294 */
- { 0x0000, 0x0000 }, /* R295 */
- { 0x0000, 0x0000 }, /* R296 */
- { 0x0000, 0x0000 }, /* R297 */
- { 0x0000, 0x0000 }, /* R298 */
- { 0x0000, 0x0000 }, /* R299 */
- { 0x0000, 0x0000 }, /* R300 */
- { 0x0000, 0x0000 }, /* R301 */
- { 0x0000, 0x0000 }, /* R302 */
- { 0x0000, 0x0000 }, /* R303 */
- { 0x0000, 0x0000 }, /* R304 */
- { 0x0000, 0x0000 }, /* R305 */
- { 0x0000, 0x0000 }, /* R306 */
- { 0x0000, 0x0000 }, /* R307 */
- { 0x0000, 0x0000 }, /* R308 */
- { 0x0000, 0x0000 }, /* R309 */
- { 0x0000, 0x0000 }, /* R310 */
- { 0x0000, 0x0000 }, /* R311 */
- { 0x0000, 0x0000 }, /* R312 */
- { 0x0000, 0x0000 }, /* R313 */
- { 0x0000, 0x0000 }, /* R314 */
- { 0x0000, 0x0000 }, /* R315 */
- { 0x0000, 0x0000 }, /* R316 */
- { 0x0000, 0x0000 }, /* R317 */
- { 0x0000, 0x0000 }, /* R318 */
- { 0x0000, 0x0000 }, /* R319 */
- { 0x0000, 0x0000 }, /* R320 */
- { 0x0000, 0x0000 }, /* R321 */
- { 0x0000, 0x0000 }, /* R322 */
- { 0x0000, 0x0000 }, /* R323 */
- { 0x0000, 0x0000 }, /* R324 */
- { 0x0000, 0x0000 }, /* R325 */
- { 0x0000, 0x0000 }, /* R326 */
- { 0x0000, 0x0000 }, /* R327 */
- { 0x0000, 0x0000 }, /* R328 */
- { 0x0000, 0x0000 }, /* R329 */
- { 0x0000, 0x0000 }, /* R330 */
- { 0x0000, 0x0000 }, /* R331 */
- { 0x0000, 0x0000 }, /* R332 */
- { 0x0000, 0x0000 }, /* R333 */
- { 0x0000, 0x0000 }, /* R334 */
- { 0x0000, 0x0000 }, /* R335 */
- { 0x0000, 0x0000 }, /* R336 */
- { 0x0000, 0x0000 }, /* R337 */
- { 0x0000, 0x0000 }, /* R338 */
- { 0x0000, 0x0000 }, /* R339 */
- { 0x0000, 0x0000 }, /* R340 */
- { 0x0000, 0x0000 }, /* R341 */
- { 0x0000, 0x0000 }, /* R342 */
- { 0x0000, 0x0000 }, /* R343 */
- { 0x0000, 0x0000 }, /* R344 */
- { 0x0000, 0x0000 }, /* R345 */
- { 0x0000, 0x0000 }, /* R346 */
- { 0x0000, 0x0000 }, /* R347 */
- { 0x0000, 0x0000 }, /* R348 */
- { 0x0000, 0x0000 }, /* R349 */
- { 0x0000, 0x0000 }, /* R350 */
- { 0x0000, 0x0000 }, /* R351 */
- { 0x0000, 0x0000 }, /* R352 */
- { 0x0000, 0x0000 }, /* R353 */
- { 0x0000, 0x0000 }, /* R354 */
- { 0x0000, 0x0000 }, /* R355 */
- { 0x0000, 0x0000 }, /* R356 */
- { 0x0000, 0x0000 }, /* R357 */
- { 0x0000, 0x0000 }, /* R358 */
- { 0x0000, 0x0000 }, /* R359 */
- { 0x0000, 0x0000 }, /* R360 */
- { 0x0000, 0x0000 }, /* R361 */
- { 0x0000, 0x0000 }, /* R362 */
- { 0x0000, 0x0000 }, /* R363 */
- { 0x0000, 0x0000 }, /* R364 */
- { 0x0000, 0x0000 }, /* R365 */
- { 0x0000, 0x0000 }, /* R366 */
- { 0x0000, 0x0000 }, /* R367 */
- { 0x0000, 0x0000 }, /* R368 */
- { 0x0000, 0x0000 }, /* R369 */
- { 0x0000, 0x0000 }, /* R370 */
- { 0x0000, 0x0000 }, /* R371 */
- { 0x0000, 0x0000 }, /* R372 */
- { 0x0000, 0x0000 }, /* R373 */
- { 0x0000, 0x0000 }, /* R374 */
- { 0x0000, 0x0000 }, /* R375 */
- { 0x0000, 0x0000 }, /* R376 */
- { 0x0000, 0x0000 }, /* R377 */
- { 0x0000, 0x0000 }, /* R378 */
- { 0x0000, 0x0000 }, /* R379 */
- { 0x0000, 0x0000 }, /* R380 */
- { 0x0000, 0x0000 }, /* R381 */
- { 0x0000, 0x0000 }, /* R382 */
- { 0x0000, 0x0000 }, /* R383 */
- { 0x0000, 0x0000 }, /* R384 */
- { 0x0000, 0x0000 }, /* R385 */
- { 0x0000, 0x0000 }, /* R386 */
- { 0x0000, 0x0000 }, /* R387 */
- { 0x0000, 0x0000 }, /* R388 */
- { 0x0000, 0x0000 }, /* R389 */
- { 0x0000, 0x0000 }, /* R390 */
- { 0x0000, 0x0000 }, /* R391 */
- { 0x0000, 0x0000 }, /* R392 */
- { 0x0000, 0x0000 }, /* R393 */
- { 0x0000, 0x0000 }, /* R394 */
- { 0x0000, 0x0000 }, /* R395 */
- { 0x0000, 0x0000 }, /* R396 */
- { 0x0000, 0x0000 }, /* R397 */
- { 0x0000, 0x0000 }, /* R398 */
- { 0x0000, 0x0000 }, /* R399 */
- { 0x0000, 0x0000 }, /* R400 */
- { 0x0000, 0x0000 }, /* R401 */
- { 0x0000, 0x0000 }, /* R402 */
- { 0x0000, 0x0000 }, /* R403 */
- { 0x0000, 0x0000 }, /* R404 */
- { 0x0000, 0x0000 }, /* R405 */
- { 0x0000, 0x0000 }, /* R406 */
- { 0x0000, 0x0000 }, /* R407 */
- { 0x0000, 0x0000 }, /* R408 */
- { 0x0000, 0x0000 }, /* R409 */
- { 0x0000, 0x0000 }, /* R410 */
- { 0x0000, 0x0000 }, /* R411 */
- { 0x0000, 0x0000 }, /* R412 */
- { 0x0000, 0x0000 }, /* R413 */
- { 0x0000, 0x0000 }, /* R414 */
- { 0x0000, 0x0000 }, /* R415 */
- { 0x0000, 0x0000 }, /* R416 */
- { 0x0000, 0x0000 }, /* R417 */
- { 0x0000, 0x0000 }, /* R418 */
- { 0x0000, 0x0000 }, /* R419 */
- { 0x0000, 0x0000 }, /* R420 */
- { 0x0000, 0x0000 }, /* R421 */
- { 0x0000, 0x0000 }, /* R422 */
- { 0x0000, 0x0000 }, /* R423 */
- { 0x0000, 0x0000 }, /* R424 */
- { 0x0000, 0x0000 }, /* R425 */
- { 0x0000, 0x0000 }, /* R426 */
- { 0x0000, 0x0000 }, /* R427 */
- { 0x0000, 0x0000 }, /* R428 */
- { 0x0000, 0x0000 }, /* R429 */
- { 0x0000, 0x0000 }, /* R430 */
- { 0x0000, 0x0000 }, /* R431 */
- { 0x0000, 0x0000 }, /* R432 */
- { 0x0000, 0x0000 }, /* R433 */
- { 0x0000, 0x0000 }, /* R434 */
- { 0x0000, 0x0000 }, /* R435 */
- { 0x0000, 0x0000 }, /* R436 */
- { 0x0000, 0x0000 }, /* R437 */
- { 0x0000, 0x0000 }, /* R438 */
- { 0x0000, 0x0000 }, /* R439 */
- { 0x0000, 0x0000 }, /* R440 */
- { 0x0000, 0x0000 }, /* R441 */
- { 0x0000, 0x0000 }, /* R442 */
- { 0x0000, 0x0000 }, /* R443 */
- { 0x0000, 0x0000 }, /* R444 */
- { 0x0000, 0x0000 }, /* R445 */
- { 0x0000, 0x0000 }, /* R446 */
- { 0x0000, 0x0000 }, /* R447 */
- { 0x0000, 0x0000 }, /* R448 */
- { 0x0000, 0x0000 }, /* R449 */
- { 0x0000, 0x0000 }, /* R450 */
- { 0x0000, 0x0000 }, /* R451 */
- { 0x0000, 0x0000 }, /* R452 */
- { 0x0000, 0x0000 }, /* R453 */
- { 0x0000, 0x0000 }, /* R454 */
- { 0x0000, 0x0000 }, /* R455 */
- { 0x0000, 0x0000 }, /* R456 */
- { 0x0000, 0x0000 }, /* R457 */
- { 0x0000, 0x0000 }, /* R458 */
- { 0x0000, 0x0000 }, /* R459 */
- { 0x0000, 0x0000 }, /* R460 */
- { 0x0000, 0x0000 }, /* R461 */
- { 0x0000, 0x0000 }, /* R462 */
- { 0x0000, 0x0000 }, /* R463 */
- { 0x0000, 0x0000 }, /* R464 */
- { 0x0000, 0x0000 }, /* R465 */
- { 0x0000, 0x0000 }, /* R466 */
- { 0x0000, 0x0000 }, /* R467 */
- { 0x0000, 0x0000 }, /* R468 */
- { 0x0000, 0x0000 }, /* R469 */
- { 0x0000, 0x0000 }, /* R470 */
- { 0x0000, 0x0000 }, /* R471 */
- { 0x0000, 0x0000 }, /* R472 */
- { 0x0000, 0x0000 }, /* R473 */
- { 0x0000, 0x0000 }, /* R474 */
- { 0x0000, 0x0000 }, /* R475 */
- { 0x0000, 0x0000 }, /* R476 */
- { 0x0000, 0x0000 }, /* R477 */
- { 0x0000, 0x0000 }, /* R478 */
- { 0x0000, 0x0000 }, /* R479 */
- { 0x0000, 0x0000 }, /* R480 */
- { 0x0000, 0x0000 }, /* R481 */
- { 0x0000, 0x0000 }, /* R482 */
- { 0x0000, 0x0000 }, /* R483 */
- { 0x0000, 0x0000 }, /* R484 */
- { 0x0000, 0x0000 }, /* R485 */
- { 0x0000, 0x0000 }, /* R486 */
- { 0x0000, 0x0000 }, /* R487 */
- { 0x0000, 0x0000 }, /* R488 */
- { 0x0000, 0x0000 }, /* R489 */
- { 0x0000, 0x0000 }, /* R490 */
- { 0x0000, 0x0000 }, /* R491 */
- { 0x0000, 0x0000 }, /* R492 */
- { 0x0000, 0x0000 }, /* R493 */
- { 0x0000, 0x0000 }, /* R494 */
- { 0x0000, 0x0000 }, /* R495 */
- { 0x0000, 0x0000 }, /* R496 */
- { 0x0000, 0x0000 }, /* R497 */
- { 0x0000, 0x0000 }, /* R498 */
- { 0x0000, 0x0000 }, /* R499 */
- { 0x0000, 0x0000 }, /* R500 */
- { 0x0000, 0x0000 }, /* R501 */
- { 0x0000, 0x0000 }, /* R502 */
- { 0x0000, 0x0000 }, /* R503 */
- { 0x0000, 0x0000 }, /* R504 */
- { 0x0000, 0x0000 }, /* R505 */
- { 0x0000, 0x0000 }, /* R506 */
- { 0x0000, 0x0000 }, /* R507 */
- { 0x0000, 0x0000 }, /* R508 */
- { 0x0000, 0x0000 }, /* R509 */
- { 0x0000, 0x0000 }, /* R510 */
- { 0x0000, 0x0000 }, /* R511 */
- { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
- { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
- { 0x0000, 0x0000 }, /* R514 */
- { 0x0000, 0x0000 }, /* R515 */
- { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
- { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
- { 0x0000, 0x0000 }, /* R518 */
- { 0x0000, 0x0000 }, /* R519 */
- { 0x001F, 0x001F }, /* R520 - Clocking (1) */
- { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
- { 0x0000, 0x0000 }, /* R522 */
- { 0x0000, 0x0000 }, /* R523 */
- { 0x0000, 0x0000 }, /* R524 */
- { 0x0000, 0x0000 }, /* R525 */
- { 0x0000, 0x0000 }, /* R526 */
- { 0x0000, 0x0000 }, /* R527 */
- { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
- { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
- { 0x000F, 0x0000 }, /* R530 - Rate Status */
- { 0x0000, 0x0000 }, /* R531 */
- { 0x0000, 0x0000 }, /* R532 */
- { 0x0000, 0x0000 }, /* R533 */
- { 0x0000, 0x0000 }, /* R534 */
- { 0x0000, 0x0000 }, /* R535 */
- { 0x0000, 0x0000 }, /* R536 */
- { 0x0000, 0x0000 }, /* R537 */
- { 0x0000, 0x0000 }, /* R538 */
- { 0x0000, 0x0000 }, /* R539 */
- { 0x0000, 0x0000 }, /* R540 */
- { 0x0000, 0x0000 }, /* R541 */
- { 0x0000, 0x0000 }, /* R542 */
- { 0x0000, 0x0000 }, /* R543 */
- { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
- { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
- { 0x0000, 0x0000 }, /* R549 */
- { 0x0000, 0x0000 }, /* R550 */
- { 0x0000, 0x0000 }, /* R551 */
- { 0x0000, 0x0000 }, /* R552 */
- { 0x0000, 0x0000 }, /* R553 */
- { 0x0000, 0x0000 }, /* R554 */
- { 0x0000, 0x0000 }, /* R555 */
- { 0x0000, 0x0000 }, /* R556 */
- { 0x0000, 0x0000 }, /* R557 */
- { 0x0000, 0x0000 }, /* R558 */
- { 0x0000, 0x0000 }, /* R559 */
- { 0x0000, 0x0000 }, /* R560 */
- { 0x0000, 0x0000 }, /* R561 */
- { 0x0000, 0x0000 }, /* R562 */
- { 0x0000, 0x0000 }, /* R563 */
- { 0x0000, 0x0000 }, /* R564 */
- { 0x0000, 0x0000 }, /* R565 */
- { 0x0000, 0x0000 }, /* R566 */
- { 0x0000, 0x0000 }, /* R567 */
- { 0x0000, 0x0000 }, /* R568 */
- { 0x0000, 0x0000 }, /* R569 */
- { 0x0000, 0x0000 }, /* R570 */
- { 0x0000, 0x0000 }, /* R571 */
- { 0x0000, 0x0000 }, /* R572 */
- { 0x0000, 0x0000 }, /* R573 */
- { 0x0000, 0x0000 }, /* R574 */
- { 0x0000, 0x0000 }, /* R575 */
- { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
- { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
- { 0x0000, 0x0000 }, /* R581 */
- { 0x0000, 0x0000 }, /* R582 */
- { 0x0000, 0x0000 }, /* R583 */
- { 0x0000, 0x0000 }, /* R584 */
- { 0x0000, 0x0000 }, /* R585 */
- { 0x0000, 0x0000 }, /* R586 */
- { 0x0000, 0x0000 }, /* R587 */
- { 0x0000, 0x0000 }, /* R588 */
- { 0x0000, 0x0000 }, /* R589 */
- { 0x0000, 0x0000 }, /* R590 */
- { 0x0000, 0x0000 }, /* R591 */
- { 0x0000, 0x0000 }, /* R592 */
- { 0x0000, 0x0000 }, /* R593 */
- { 0x0000, 0x0000 }, /* R594 */
- { 0x0000, 0x0000 }, /* R595 */
- { 0x0000, 0x0000 }, /* R596 */
- { 0x0000, 0x0000 }, /* R597 */
- { 0x0000, 0x0000 }, /* R598 */
- { 0x0000, 0x0000 }, /* R599 */
- { 0x0000, 0x0000 }, /* R600 */
- { 0x0000, 0x0000 }, /* R601 */
- { 0x0000, 0x0000 }, /* R602 */
- { 0x0000, 0x0000 }, /* R603 */
- { 0x0000, 0x0000 }, /* R604 */
- { 0x0000, 0x0000 }, /* R605 */
- { 0x0000, 0x0000 }, /* R606 */
- { 0x0000, 0x0000 }, /* R607 */
- { 0x0000, 0x0000 }, /* R608 */
- { 0x0000, 0x0000 }, /* R609 */
- { 0x0000, 0x0000 }, /* R610 */
- { 0x0000, 0x0000 }, /* R611 */
- { 0x0000, 0x0000 }, /* R612 */
- { 0x0000, 0x0000 }, /* R613 */
- { 0x0000, 0x0000 }, /* R614 */
- { 0x0000, 0x0000 }, /* R615 */
- { 0x0000, 0x0000 }, /* R616 */
- { 0x0000, 0x0000 }, /* R617 */
- { 0x0000, 0x0000 }, /* R618 */
- { 0x0000, 0x0000 }, /* R619 */
- { 0x0000, 0x0000 }, /* R620 */
- { 0x0000, 0x0000 }, /* R621 */
- { 0x0000, 0x0000 }, /* R622 */
- { 0x0000, 0x0000 }, /* R623 */
- { 0x0000, 0x0000 }, /* R624 */
- { 0x0000, 0x0000 }, /* R625 */
- { 0x0000, 0x0000 }, /* R626 */
- { 0x0000, 0x0000 }, /* R627 */
- { 0x0000, 0x0000 }, /* R628 */
- { 0x0000, 0x0000 }, /* R629 */
- { 0x0000, 0x0000 }, /* R630 */
- { 0x0000, 0x0000 }, /* R631 */
- { 0x0000, 0x0000 }, /* R632 */
- { 0x0000, 0x0000 }, /* R633 */
- { 0x0000, 0x0000 }, /* R634 */
- { 0x0000, 0x0000 }, /* R635 */
- { 0x0000, 0x0000 }, /* R636 */
- { 0x0000, 0x0000 }, /* R637 */
- { 0x0000, 0x0000 }, /* R638 */
- { 0x0000, 0x0000 }, /* R639 */
- { 0x0000, 0x0000 }, /* R640 */
- { 0x0000, 0x0000 }, /* R641 */
- { 0x0000, 0x0000 }, /* R642 */
- { 0x0000, 0x0000 }, /* R643 */
- { 0x0000, 0x0000 }, /* R644 */
- { 0x0000, 0x0000 }, /* R645 */
- { 0x0000, 0x0000 }, /* R646 */
- { 0x0000, 0x0000 }, /* R647 */
- { 0x0000, 0x0000 }, /* R648 */
- { 0x0000, 0x0000 }, /* R649 */
- { 0x0000, 0x0000 }, /* R650 */
- { 0x0000, 0x0000 }, /* R651 */
- { 0x0000, 0x0000 }, /* R652 */
- { 0x0000, 0x0000 }, /* R653 */
- { 0x0000, 0x0000 }, /* R654 */
- { 0x0000, 0x0000 }, /* R655 */
- { 0x0000, 0x0000 }, /* R656 */
- { 0x0000, 0x0000 }, /* R657 */
- { 0x0000, 0x0000 }, /* R658 */
- { 0x0000, 0x0000 }, /* R659 */
- { 0x0000, 0x0000 }, /* R660 */
- { 0x0000, 0x0000 }, /* R661 */
- { 0x0000, 0x0000 }, /* R662 */
- { 0x0000, 0x0000 }, /* R663 */
- { 0x0000, 0x0000 }, /* R664 */
- { 0x0000, 0x0000 }, /* R665 */
- { 0x0000, 0x0000 }, /* R666 */
- { 0x0000, 0x0000 }, /* R667 */
- { 0x0000, 0x0000 }, /* R668 */
- { 0x0000, 0x0000 }, /* R669 */
- { 0x0000, 0x0000 }, /* R670 */
- { 0x0000, 0x0000 }, /* R671 */
- { 0x0000, 0x0000 }, /* R672 */
- { 0x0000, 0x0000 }, /* R673 */
- { 0x0000, 0x0000 }, /* R674 */
- { 0x0000, 0x0000 }, /* R675 */
- { 0x0000, 0x0000 }, /* R676 */
- { 0x0000, 0x0000 }, /* R677 */
- { 0x0000, 0x0000 }, /* R678 */
- { 0x0000, 0x0000 }, /* R679 */
- { 0x0000, 0x0000 }, /* R680 */
- { 0x0000, 0x0000 }, /* R681 */
- { 0x0000, 0x0000 }, /* R682 */
- { 0x0000, 0x0000 }, /* R683 */
- { 0x0000, 0x0000 }, /* R684 */
- { 0x0000, 0x0000 }, /* R685 */
- { 0x0000, 0x0000 }, /* R686 */
- { 0x0000, 0x0000 }, /* R687 */
- { 0x0000, 0x0000 }, /* R688 */
- { 0x0000, 0x0000 }, /* R689 */
- { 0x0000, 0x0000 }, /* R690 */
- { 0x0000, 0x0000 }, /* R691 */
- { 0x0000, 0x0000 }, /* R692 */
- { 0x0000, 0x0000 }, /* R693 */
- { 0x0000, 0x0000 }, /* R694 */
- { 0x0000, 0x0000 }, /* R695 */
- { 0x0000, 0x0000 }, /* R696 */
- { 0x0000, 0x0000 }, /* R697 */
- { 0x0000, 0x0000 }, /* R698 */
- { 0x0000, 0x0000 }, /* R699 */
- { 0x0000, 0x0000 }, /* R700 */
- { 0x0000, 0x0000 }, /* R701 */
- { 0x0000, 0x0000 }, /* R702 */
- { 0x0000, 0x0000 }, /* R703 */
- { 0x0000, 0x0000 }, /* R704 */
- { 0x0000, 0x0000 }, /* R705 */
- { 0x0000, 0x0000 }, /* R706 */
- { 0x0000, 0x0000 }, /* R707 */
- { 0x0000, 0x0000 }, /* R708 */
- { 0x0000, 0x0000 }, /* R709 */
- { 0x0000, 0x0000 }, /* R710 */
- { 0x0000, 0x0000 }, /* R711 */
- { 0x0000, 0x0000 }, /* R712 */
- { 0x0000, 0x0000 }, /* R713 */
- { 0x0000, 0x0000 }, /* R714 */
- { 0x0000, 0x0000 }, /* R715 */
- { 0x0000, 0x0000 }, /* R716 */
- { 0x0000, 0x0000 }, /* R717 */
- { 0x0000, 0x0000 }, /* R718 */
- { 0x0000, 0x0000 }, /* R719 */
- { 0x0000, 0x0000 }, /* R720 */
- { 0x0000, 0x0000 }, /* R721 */
- { 0x0000, 0x0000 }, /* R722 */
- { 0x0000, 0x0000 }, /* R723 */
- { 0x0000, 0x0000 }, /* R724 */
- { 0x0000, 0x0000 }, /* R725 */
- { 0x0000, 0x0000 }, /* R726 */
- { 0x0000, 0x0000 }, /* R727 */
- { 0x0000, 0x0000 }, /* R728 */
- { 0x0000, 0x0000 }, /* R729 */
- { 0x0000, 0x0000 }, /* R730 */
- { 0x0000, 0x0000 }, /* R731 */
- { 0x0000, 0x0000 }, /* R732 */
- { 0x0000, 0x0000 }, /* R733 */
- { 0x0000, 0x0000 }, /* R734 */
- { 0x0000, 0x0000 }, /* R735 */
- { 0x0000, 0x0000 }, /* R736 */
- { 0x0000, 0x0000 }, /* R737 */
- { 0x0000, 0x0000 }, /* R738 */
- { 0x0000, 0x0000 }, /* R739 */
- { 0x0000, 0x0000 }, /* R740 */
- { 0x0000, 0x0000 }, /* R741 */
- { 0x0000, 0x0000 }, /* R742 */
- { 0x0000, 0x0000 }, /* R743 */
- { 0x0000, 0x0000 }, /* R744 */
- { 0x0000, 0x0000 }, /* R745 */
- { 0x0000, 0x0000 }, /* R746 */
- { 0x0000, 0x0000 }, /* R747 */
- { 0x0000, 0x0000 }, /* R748 */
- { 0x0000, 0x0000 }, /* R749 */
- { 0x0000, 0x0000 }, /* R750 */
- { 0x0000, 0x0000 }, /* R751 */
- { 0x0000, 0x0000 }, /* R752 */
- { 0x0000, 0x0000 }, /* R753 */
- { 0x0000, 0x0000 }, /* R754 */
- { 0x0000, 0x0000 }, /* R755 */
- { 0x0000, 0x0000 }, /* R756 */
- { 0x0000, 0x0000 }, /* R757 */
- { 0x0000, 0x0000 }, /* R758 */
- { 0x0000, 0x0000 }, /* R759 */
- { 0x0000, 0x0000 }, /* R760 */
- { 0x0000, 0x0000 }, /* R761 */
- { 0x0000, 0x0000 }, /* R762 */
- { 0x0000, 0x0000 }, /* R763 */
- { 0x0000, 0x0000 }, /* R764 */
- { 0x0000, 0x0000 }, /* R765 */
- { 0x0000, 0x0000 }, /* R766 */
- { 0x0000, 0x0000 }, /* R767 */
- { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
- { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
- { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
- { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
- { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
- { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
- { 0x0000, 0x0000 }, /* R776 */
- { 0x0000, 0x0000 }, /* R777 */
- { 0x0000, 0x0000 }, /* R778 */
- { 0x0000, 0x0000 }, /* R779 */
- { 0x0000, 0x0000 }, /* R780 */
- { 0x0000, 0x0000 }, /* R781 */
- { 0x0000, 0x0000 }, /* R782 */
- { 0x0000, 0x0000 }, /* R783 */
- { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
- { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
- { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
- { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
- { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
- { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
- { 0x0000, 0x0000 }, /* R792 */
- { 0x0000, 0x0000 }, /* R793 */
- { 0x0000, 0x0000 }, /* R794 */
- { 0x0000, 0x0000 }, /* R795 */
- { 0x0000, 0x0000 }, /* R796 */
- { 0x0000, 0x0000 }, /* R797 */
- { 0x0000, 0x0000 }, /* R798 */
- { 0x0000, 0x0000 }, /* R799 */
- { 0x0000, 0x0000 }, /* R800 */
- { 0x0000, 0x0000 }, /* R801 */
- { 0x0000, 0x0000 }, /* R802 */
- { 0x0000, 0x0000 }, /* R803 */
- { 0x0000, 0x0000 }, /* R804 */
- { 0x0000, 0x0000 }, /* R805 */
- { 0x0000, 0x0000 }, /* R806 */
- { 0x0000, 0x0000 }, /* R807 */
- { 0x0000, 0x0000 }, /* R808 */
- { 0x0000, 0x0000 }, /* R809 */
- { 0x0000, 0x0000 }, /* R810 */
- { 0x0000, 0x0000 }, /* R811 */
- { 0x0000, 0x0000 }, /* R812 */
- { 0x0000, 0x0000 }, /* R813 */
- { 0x0000, 0x0000 }, /* R814 */
- { 0x0000, 0x0000 }, /* R815 */
- { 0x0000, 0x0000 }, /* R816 */
- { 0x0000, 0x0000 }, /* R817 */
- { 0x0000, 0x0000 }, /* R818 */
- { 0x0000, 0x0000 }, /* R819 */
- { 0x0000, 0x0000 }, /* R820 */
- { 0x0000, 0x0000 }, /* R821 */
- { 0x0000, 0x0000 }, /* R822 */
- { 0x0000, 0x0000 }, /* R823 */
- { 0x0000, 0x0000 }, /* R824 */
- { 0x0000, 0x0000 }, /* R825 */
- { 0x0000, 0x0000 }, /* R826 */
- { 0x0000, 0x0000 }, /* R827 */
- { 0x0000, 0x0000 }, /* R828 */
- { 0x0000, 0x0000 }, /* R829 */
- { 0x0000, 0x0000 }, /* R830 */
- { 0x0000, 0x0000 }, /* R831 */
- { 0x0000, 0x0000 }, /* R832 */
- { 0x0000, 0x0000 }, /* R833 */
- { 0x0000, 0x0000 }, /* R834 */
- { 0x0000, 0x0000 }, /* R835 */
- { 0x0000, 0x0000 }, /* R836 */
- { 0x0000, 0x0000 }, /* R837 */
- { 0x0000, 0x0000 }, /* R838 */
- { 0x0000, 0x0000 }, /* R839 */
- { 0x0000, 0x0000 }, /* R840 */
- { 0x0000, 0x0000 }, /* R841 */
- { 0x0000, 0x0000 }, /* R842 */
- { 0x0000, 0x0000 }, /* R843 */
- { 0x0000, 0x0000 }, /* R844 */
- { 0x0000, 0x0000 }, /* R845 */
- { 0x0000, 0x0000 }, /* R846 */
- { 0x0000, 0x0000 }, /* R847 */
- { 0x0000, 0x0000 }, /* R848 */
- { 0x0000, 0x0000 }, /* R849 */
- { 0x0000, 0x0000 }, /* R850 */
- { 0x0000, 0x0000 }, /* R851 */
- { 0x0000, 0x0000 }, /* R852 */
- { 0x0000, 0x0000 }, /* R853 */
- { 0x0000, 0x0000 }, /* R854 */
- { 0x0000, 0x0000 }, /* R855 */
- { 0x0000, 0x0000 }, /* R856 */
- { 0x0000, 0x0000 }, /* R857 */
- { 0x0000, 0x0000 }, /* R858 */
- { 0x0000, 0x0000 }, /* R859 */
- { 0x0000, 0x0000 }, /* R860 */
- { 0x0000, 0x0000 }, /* R861 */
- { 0x0000, 0x0000 }, /* R862 */
- { 0x0000, 0x0000 }, /* R863 */
- { 0x0000, 0x0000 }, /* R864 */
- { 0x0000, 0x0000 }, /* R865 */
- { 0x0000, 0x0000 }, /* R866 */
- { 0x0000, 0x0000 }, /* R867 */
- { 0x0000, 0x0000 }, /* R868 */
- { 0x0000, 0x0000 }, /* R869 */
- { 0x0000, 0x0000 }, /* R870 */
- { 0x0000, 0x0000 }, /* R871 */
- { 0x0000, 0x0000 }, /* R872 */
- { 0x0000, 0x0000 }, /* R873 */
- { 0x0000, 0x0000 }, /* R874 */
- { 0x0000, 0x0000 }, /* R875 */
- { 0x0000, 0x0000 }, /* R876 */
- { 0x0000, 0x0000 }, /* R877 */
- { 0x0000, 0x0000 }, /* R878 */
- { 0x0000, 0x0000 }, /* R879 */
- { 0x0000, 0x0000 }, /* R880 */
- { 0x0000, 0x0000 }, /* R881 */
- { 0x0000, 0x0000 }, /* R882 */
- { 0x0000, 0x0000 }, /* R883 */
- { 0x0000, 0x0000 }, /* R884 */
- { 0x0000, 0x0000 }, /* R885 */
- { 0x0000, 0x0000 }, /* R886 */
- { 0x0000, 0x0000 }, /* R887 */
- { 0x0000, 0x0000 }, /* R888 */
- { 0x0000, 0x0000 }, /* R889 */
- { 0x0000, 0x0000 }, /* R890 */
- { 0x0000, 0x0000 }, /* R891 */
- { 0x0000, 0x0000 }, /* R892 */
- { 0x0000, 0x0000 }, /* R893 */
- { 0x0000, 0x0000 }, /* R894 */
- { 0x0000, 0x0000 }, /* R895 */
- { 0x0000, 0x0000 }, /* R896 */
- { 0x0000, 0x0000 }, /* R897 */
- { 0x0000, 0x0000 }, /* R898 */
- { 0x0000, 0x0000 }, /* R899 */
- { 0x0000, 0x0000 }, /* R900 */
- { 0x0000, 0x0000 }, /* R901 */
- { 0x0000, 0x0000 }, /* R902 */
- { 0x0000, 0x0000 }, /* R903 */
- { 0x0000, 0x0000 }, /* R904 */
- { 0x0000, 0x0000 }, /* R905 */
- { 0x0000, 0x0000 }, /* R906 */
- { 0x0000, 0x0000 }, /* R907 */
- { 0x0000, 0x0000 }, /* R908 */
- { 0x0000, 0x0000 }, /* R909 */
- { 0x0000, 0x0000 }, /* R910 */
- { 0x0000, 0x0000 }, /* R911 */
- { 0x0000, 0x0000 }, /* R912 */
- { 0x0000, 0x0000 }, /* R913 */
- { 0x0000, 0x0000 }, /* R914 */
- { 0x0000, 0x0000 }, /* R915 */
- { 0x0000, 0x0000 }, /* R916 */
- { 0x0000, 0x0000 }, /* R917 */
- { 0x0000, 0x0000 }, /* R918 */
- { 0x0000, 0x0000 }, /* R919 */
- { 0x0000, 0x0000 }, /* R920 */
- { 0x0000, 0x0000 }, /* R921 */
- { 0x0000, 0x0000 }, /* R922 */
- { 0x0000, 0x0000 }, /* R923 */
- { 0x0000, 0x0000 }, /* R924 */
- { 0x0000, 0x0000 }, /* R925 */
- { 0x0000, 0x0000 }, /* R926 */
- { 0x0000, 0x0000 }, /* R927 */
- { 0x0000, 0x0000 }, /* R928 */
- { 0x0000, 0x0000 }, /* R929 */
- { 0x0000, 0x0000 }, /* R930 */
- { 0x0000, 0x0000 }, /* R931 */
- { 0x0000, 0x0000 }, /* R932 */
- { 0x0000, 0x0000 }, /* R933 */
- { 0x0000, 0x0000 }, /* R934 */
- { 0x0000, 0x0000 }, /* R935 */
- { 0x0000, 0x0000 }, /* R936 */
- { 0x0000, 0x0000 }, /* R937 */
- { 0x0000, 0x0000 }, /* R938 */
- { 0x0000, 0x0000 }, /* R939 */
- { 0x0000, 0x0000 }, /* R940 */
- { 0x0000, 0x0000 }, /* R941 */
- { 0x0000, 0x0000 }, /* R942 */
- { 0x0000, 0x0000 }, /* R943 */
- { 0x0000, 0x0000 }, /* R944 */
- { 0x0000, 0x0000 }, /* R945 */
- { 0x0000, 0x0000 }, /* R946 */
- { 0x0000, 0x0000 }, /* R947 */
- { 0x0000, 0x0000 }, /* R948 */
- { 0x0000, 0x0000 }, /* R949 */
- { 0x0000, 0x0000 }, /* R950 */
- { 0x0000, 0x0000 }, /* R951 */
- { 0x0000, 0x0000 }, /* R952 */
- { 0x0000, 0x0000 }, /* R953 */
- { 0x0000, 0x0000 }, /* R954 */
- { 0x0000, 0x0000 }, /* R955 */
- { 0x0000, 0x0000 }, /* R956 */
- { 0x0000, 0x0000 }, /* R957 */
- { 0x0000, 0x0000 }, /* R958 */
- { 0x0000, 0x0000 }, /* R959 */
- { 0x0000, 0x0000 }, /* R960 */
- { 0x0000, 0x0000 }, /* R961 */
- { 0x0000, 0x0000 }, /* R962 */
- { 0x0000, 0x0000 }, /* R963 */
- { 0x0000, 0x0000 }, /* R964 */
- { 0x0000, 0x0000 }, /* R965 */
- { 0x0000, 0x0000 }, /* R966 */
- { 0x0000, 0x0000 }, /* R967 */
- { 0x0000, 0x0000 }, /* R968 */
- { 0x0000, 0x0000 }, /* R969 */
- { 0x0000, 0x0000 }, /* R970 */
- { 0x0000, 0x0000 }, /* R971 */
- { 0x0000, 0x0000 }, /* R972 */
- { 0x0000, 0x0000 }, /* R973 */
- { 0x0000, 0x0000 }, /* R974 */
- { 0x0000, 0x0000 }, /* R975 */
- { 0x0000, 0x0000 }, /* R976 */
- { 0x0000, 0x0000 }, /* R977 */
- { 0x0000, 0x0000 }, /* R978 */
- { 0x0000, 0x0000 }, /* R979 */
- { 0x0000, 0x0000 }, /* R980 */
- { 0x0000, 0x0000 }, /* R981 */
- { 0x0000, 0x0000 }, /* R982 */
- { 0x0000, 0x0000 }, /* R983 */
- { 0x0000, 0x0000 }, /* R984 */
- { 0x0000, 0x0000 }, /* R985 */
- { 0x0000, 0x0000 }, /* R986 */
- { 0x0000, 0x0000 }, /* R987 */
- { 0x0000, 0x0000 }, /* R988 */
- { 0x0000, 0x0000 }, /* R989 */
- { 0x0000, 0x0000 }, /* R990 */
- { 0x0000, 0x0000 }, /* R991 */
- { 0x0000, 0x0000 }, /* R992 */
- { 0x0000, 0x0000 }, /* R993 */
- { 0x0000, 0x0000 }, /* R994 */
- { 0x0000, 0x0000 }, /* R995 */
- { 0x0000, 0x0000 }, /* R996 */
- { 0x0000, 0x0000 }, /* R997 */
- { 0x0000, 0x0000 }, /* R998 */
- { 0x0000, 0x0000 }, /* R999 */
- { 0x0000, 0x0000 }, /* R1000 */
- { 0x0000, 0x0000 }, /* R1001 */
- { 0x0000, 0x0000 }, /* R1002 */
- { 0x0000, 0x0000 }, /* R1003 */
- { 0x0000, 0x0000 }, /* R1004 */
- { 0x0000, 0x0000 }, /* R1005 */
- { 0x0000, 0x0000 }, /* R1006 */
- { 0x0000, 0x0000 }, /* R1007 */
- { 0x0000, 0x0000 }, /* R1008 */
- { 0x0000, 0x0000 }, /* R1009 */
- { 0x0000, 0x0000 }, /* R1010 */
- { 0x0000, 0x0000 }, /* R1011 */
- { 0x0000, 0x0000 }, /* R1012 */
- { 0x0000, 0x0000 }, /* R1013 */
- { 0x0000, 0x0000 }, /* R1014 */
- { 0x0000, 0x0000 }, /* R1015 */
- { 0x0000, 0x0000 }, /* R1016 */
- { 0x0000, 0x0000 }, /* R1017 */
- { 0x0000, 0x0000 }, /* R1018 */
- { 0x0000, 0x0000 }, /* R1019 */
- { 0x0000, 0x0000 }, /* R1020 */
- { 0x0000, 0x0000 }, /* R1021 */
- { 0x0000, 0x0000 }, /* R1022 */
- { 0x0000, 0x0000 }, /* R1023 */
- { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
- { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
- { 0x0000, 0x0000 }, /* R1032 */
- { 0x0000, 0x0000 }, /* R1033 */
- { 0x0000, 0x0000 }, /* R1034 */
- { 0x0000, 0x0000 }, /* R1035 */
- { 0x0000, 0x0000 }, /* R1036 */
- { 0x0000, 0x0000 }, /* R1037 */
- { 0x0000, 0x0000 }, /* R1038 */
- { 0x0000, 0x0000 }, /* R1039 */
- { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
- { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
- { 0x0000, 0x0000 }, /* R1042 */
- { 0x0000, 0x0000 }, /* R1043 */
- { 0x0000, 0x0000 }, /* R1044 */
- { 0x0000, 0x0000 }, /* R1045 */
- { 0x0000, 0x0000 }, /* R1046 */
- { 0x0000, 0x0000 }, /* R1047 */
- { 0x0000, 0x0000 }, /* R1048 */
- { 0x0000, 0x0000 }, /* R1049 */
- { 0x0000, 0x0000 }, /* R1050 */
- { 0x0000, 0x0000 }, /* R1051 */
- { 0x0000, 0x0000 }, /* R1052 */
- { 0x0000, 0x0000 }, /* R1053 */
- { 0x0000, 0x0000 }, /* R1054 */
- { 0x0000, 0x0000 }, /* R1055 */
- { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
- { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
- { 0x0000, 0x0000 }, /* R1060 */
- { 0x0000, 0x0000 }, /* R1061 */
- { 0x0000, 0x0000 }, /* R1062 */
- { 0x0000, 0x0000 }, /* R1063 */
- { 0x0000, 0x0000 }, /* R1064 */
- { 0x0000, 0x0000 }, /* R1065 */
- { 0x0000, 0x0000 }, /* R1066 */
- { 0x0000, 0x0000 }, /* R1067 */
- { 0x0000, 0x0000 }, /* R1068 */
- { 0x0000, 0x0000 }, /* R1069 */
- { 0x0000, 0x0000 }, /* R1070 */
- { 0x0000, 0x0000 }, /* R1071 */
- { 0x0000, 0x0000 }, /* R1072 */
- { 0x0000, 0x0000 }, /* R1073 */
- { 0x0000, 0x0000 }, /* R1074 */
- { 0x0000, 0x0000 }, /* R1075 */
- { 0x0000, 0x0000 }, /* R1076 */
- { 0x0000, 0x0000 }, /* R1077 */
- { 0x0000, 0x0000 }, /* R1078 */
- { 0x0000, 0x0000 }, /* R1079 */
- { 0x0000, 0x0000 }, /* R1080 */
- { 0x0000, 0x0000 }, /* R1081 */
- { 0x0000, 0x0000 }, /* R1082 */
- { 0x0000, 0x0000 }, /* R1083 */
- { 0x0000, 0x0000 }, /* R1084 */
- { 0x0000, 0x0000 }, /* R1085 */
- { 0x0000, 0x0000 }, /* R1086 */
- { 0x0000, 0x0000 }, /* R1087 */
- { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
- { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
- { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
- { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
- { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
- { 0x0000, 0x0000 }, /* R1093 */
- { 0x0000, 0x0000 }, /* R1094 */
- { 0x0000, 0x0000 }, /* R1095 */
- { 0x0000, 0x0000 }, /* R1096 */
- { 0x0000, 0x0000 }, /* R1097 */
- { 0x0000, 0x0000 }, /* R1098 */
- { 0x0000, 0x0000 }, /* R1099 */
- { 0x0000, 0x0000 }, /* R1100 */
- { 0x0000, 0x0000 }, /* R1101 */
- { 0x0000, 0x0000 }, /* R1102 */
- { 0x0000, 0x0000 }, /* R1103 */
- { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
- { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
- { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
- { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
- { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
- { 0x0000, 0x0000 }, /* R1109 */
- { 0x0000, 0x0000 }, /* R1110 */
- { 0x0000, 0x0000 }, /* R1111 */
- { 0x0000, 0x0000 }, /* R1112 */
- { 0x0000, 0x0000 }, /* R1113 */
- { 0x0000, 0x0000 }, /* R1114 */
- { 0x0000, 0x0000 }, /* R1115 */
- { 0x0000, 0x0000 }, /* R1116 */
- { 0x0000, 0x0000 }, /* R1117 */
- { 0x0000, 0x0000 }, /* R1118 */
- { 0x0000, 0x0000 }, /* R1119 */
- { 0x0000, 0x0000 }, /* R1120 */
- { 0x0000, 0x0000 }, /* R1121 */
- { 0x0000, 0x0000 }, /* R1122 */
- { 0x0000, 0x0000 }, /* R1123 */
- { 0x0000, 0x0000 }, /* R1124 */
- { 0x0000, 0x0000 }, /* R1125 */
- { 0x0000, 0x0000 }, /* R1126 */
- { 0x0000, 0x0000 }, /* R1127 */
- { 0x0000, 0x0000 }, /* R1128 */
- { 0x0000, 0x0000 }, /* R1129 */
- { 0x0000, 0x0000 }, /* R1130 */
- { 0x0000, 0x0000 }, /* R1131 */
- { 0x0000, 0x0000 }, /* R1132 */
- { 0x0000, 0x0000 }, /* R1133 */
- { 0x0000, 0x0000 }, /* R1134 */
- { 0x0000, 0x0000 }, /* R1135 */
- { 0x0000, 0x0000 }, /* R1136 */
- { 0x0000, 0x0000 }, /* R1137 */
- { 0x0000, 0x0000 }, /* R1138 */
- { 0x0000, 0x0000 }, /* R1139 */
- { 0x0000, 0x0000 }, /* R1140 */
- { 0x0000, 0x0000 }, /* R1141 */
- { 0x0000, 0x0000 }, /* R1142 */
- { 0x0000, 0x0000 }, /* R1143 */
- { 0x0000, 0x0000 }, /* R1144 */
- { 0x0000, 0x0000 }, /* R1145 */
- { 0x0000, 0x0000 }, /* R1146 */
- { 0x0000, 0x0000 }, /* R1147 */
- { 0x0000, 0x0000 }, /* R1148 */
- { 0x0000, 0x0000 }, /* R1149 */
- { 0x0000, 0x0000 }, /* R1150 */
- { 0x0000, 0x0000 }, /* R1151 */
- { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1172 */
- { 0x0000, 0x0000 }, /* R1173 */
- { 0x0000, 0x0000 }, /* R1174 */
- { 0x0000, 0x0000 }, /* R1175 */
- { 0x0000, 0x0000 }, /* R1176 */
- { 0x0000, 0x0000 }, /* R1177 */
- { 0x0000, 0x0000 }, /* R1178 */
- { 0x0000, 0x0000 }, /* R1179 */
- { 0x0000, 0x0000 }, /* R1180 */
- { 0x0000, 0x0000 }, /* R1181 */
- { 0x0000, 0x0000 }, /* R1182 */
- { 0x0000, 0x0000 }, /* R1183 */
- { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1204 */
- { 0x0000, 0x0000 }, /* R1205 */
- { 0x0000, 0x0000 }, /* R1206 */
- { 0x0000, 0x0000 }, /* R1207 */
- { 0x0000, 0x0000 }, /* R1208 */
- { 0x0000, 0x0000 }, /* R1209 */
- { 0x0000, 0x0000 }, /* R1210 */
- { 0x0000, 0x0000 }, /* R1211 */
- { 0x0000, 0x0000 }, /* R1212 */
- { 0x0000, 0x0000 }, /* R1213 */
- { 0x0000, 0x0000 }, /* R1214 */
- { 0x0000, 0x0000 }, /* R1215 */
- { 0x0000, 0x0000 }, /* R1216 */
- { 0x0000, 0x0000 }, /* R1217 */
- { 0x0000, 0x0000 }, /* R1218 */
- { 0x0000, 0x0000 }, /* R1219 */
- { 0x0000, 0x0000 }, /* R1220 */
- { 0x0000, 0x0000 }, /* R1221 */
- { 0x0000, 0x0000 }, /* R1222 */
- { 0x0000, 0x0000 }, /* R1223 */
- { 0x0000, 0x0000 }, /* R1224 */
- { 0x0000, 0x0000 }, /* R1225 */
- { 0x0000, 0x0000 }, /* R1226 */
- { 0x0000, 0x0000 }, /* R1227 */
- { 0x0000, 0x0000 }, /* R1228 */
- { 0x0000, 0x0000 }, /* R1229 */
- { 0x0000, 0x0000 }, /* R1230 */
- { 0x0000, 0x0000 }, /* R1231 */
- { 0x0000, 0x0000 }, /* R1232 */
- { 0x0000, 0x0000 }, /* R1233 */
- { 0x0000, 0x0000 }, /* R1234 */
- { 0x0000, 0x0000 }, /* R1235 */
- { 0x0000, 0x0000 }, /* R1236 */
- { 0x0000, 0x0000 }, /* R1237 */
- { 0x0000, 0x0000 }, /* R1238 */
- { 0x0000, 0x0000 }, /* R1239 */
- { 0x0000, 0x0000 }, /* R1240 */
- { 0x0000, 0x0000 }, /* R1241 */
- { 0x0000, 0x0000 }, /* R1242 */
- { 0x0000, 0x0000 }, /* R1243 */
- { 0x0000, 0x0000 }, /* R1244 */
- { 0x0000, 0x0000 }, /* R1245 */
- { 0x0000, 0x0000 }, /* R1246 */
- { 0x0000, 0x0000 }, /* R1247 */
- { 0x0000, 0x0000 }, /* R1248 */
- { 0x0000, 0x0000 }, /* R1249 */
- { 0x0000, 0x0000 }, /* R1250 */
- { 0x0000, 0x0000 }, /* R1251 */
- { 0x0000, 0x0000 }, /* R1252 */
- { 0x0000, 0x0000 }, /* R1253 */
- { 0x0000, 0x0000 }, /* R1254 */
- { 0x0000, 0x0000 }, /* R1255 */
- { 0x0000, 0x0000 }, /* R1256 */
- { 0x0000, 0x0000 }, /* R1257 */
- { 0x0000, 0x0000 }, /* R1258 */
- { 0x0000, 0x0000 }, /* R1259 */
- { 0x0000, 0x0000 }, /* R1260 */
- { 0x0000, 0x0000 }, /* R1261 */
- { 0x0000, 0x0000 }, /* R1262 */
- { 0x0000, 0x0000 }, /* R1263 */
- { 0x0000, 0x0000 }, /* R1264 */
- { 0x0000, 0x0000 }, /* R1265 */
- { 0x0000, 0x0000 }, /* R1266 */
- { 0x0000, 0x0000 }, /* R1267 */
- { 0x0000, 0x0000 }, /* R1268 */
- { 0x0000, 0x0000 }, /* R1269 */
- { 0x0000, 0x0000 }, /* R1270 */
- { 0x0000, 0x0000 }, /* R1271 */
- { 0x0000, 0x0000 }, /* R1272 */
- { 0x0000, 0x0000 }, /* R1273 */
- { 0x0000, 0x0000 }, /* R1274 */
- { 0x0000, 0x0000 }, /* R1275 */
- { 0x0000, 0x0000 }, /* R1276 */
- { 0x0000, 0x0000 }, /* R1277 */
- { 0x0000, 0x0000 }, /* R1278 */
- { 0x0000, 0x0000 }, /* R1279 */
- { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
- { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
- { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
- { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
- { 0x0000, 0x0000 }, /* R1284 */
- { 0x0000, 0x0000 }, /* R1285 */
- { 0x0000, 0x0000 }, /* R1286 */
- { 0x0000, 0x0000 }, /* R1287 */
- { 0x0000, 0x0000 }, /* R1288 */
- { 0x0000, 0x0000 }, /* R1289 */
- { 0x0000, 0x0000 }, /* R1290 */
- { 0x0000, 0x0000 }, /* R1291 */
- { 0x0000, 0x0000 }, /* R1292 */
- { 0x0000, 0x0000 }, /* R1293 */
- { 0x0000, 0x0000 }, /* R1294 */
- { 0x0000, 0x0000 }, /* R1295 */
- { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
- { 0x0000, 0x0000 }, /* R1297 */
- { 0x0000, 0x0000 }, /* R1298 */
- { 0x0000, 0x0000 }, /* R1299 */
- { 0x0000, 0x0000 }, /* R1300 */
- { 0x0000, 0x0000 }, /* R1301 */
- { 0x0000, 0x0000 }, /* R1302 */
- { 0x0000, 0x0000 }, /* R1303 */
- { 0x0000, 0x0000 }, /* R1304 */
- { 0x0000, 0x0000 }, /* R1305 */
- { 0x0000, 0x0000 }, /* R1306 */
- { 0x0000, 0x0000 }, /* R1307 */
- { 0x0000, 0x0000 }, /* R1308 */
- { 0x0000, 0x0000 }, /* R1309 */
- { 0x0000, 0x0000 }, /* R1310 */
- { 0x0000, 0x0000 }, /* R1311 */
- { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
- { 0x0000, 0x0000 }, /* R1314 */
- { 0x0000, 0x0000 }, /* R1315 */
- { 0x0000, 0x0000 }, /* R1316 */
- { 0x0000, 0x0000 }, /* R1317 */
- { 0x0000, 0x0000 }, /* R1318 */
- { 0x0000, 0x0000 }, /* R1319 */
- { 0x0000, 0x0000 }, /* R1320 */
- { 0x0000, 0x0000 }, /* R1321 */
- { 0x0000, 0x0000 }, /* R1322 */
- { 0x0000, 0x0000 }, /* R1323 */
- { 0x0000, 0x0000 }, /* R1324 */
- { 0x0000, 0x0000 }, /* R1325 */
- { 0x0000, 0x0000 }, /* R1326 */
- { 0x0000, 0x0000 }, /* R1327 */
- { 0x0000, 0x0000 }, /* R1328 */
- { 0x0000, 0x0000 }, /* R1329 */
- { 0x0000, 0x0000 }, /* R1330 */
- { 0x0000, 0x0000 }, /* R1331 */
- { 0x0000, 0x0000 }, /* R1332 */
- { 0x0000, 0x0000 }, /* R1333 */
- { 0x0000, 0x0000 }, /* R1334 */
- { 0x0000, 0x0000 }, /* R1335 */
- { 0x0000, 0x0000 }, /* R1336 */
- { 0x0000, 0x0000 }, /* R1337 */
- { 0x0000, 0x0000 }, /* R1338 */
- { 0x0000, 0x0000 }, /* R1339 */
- { 0x0000, 0x0000 }, /* R1340 */
- { 0x0000, 0x0000 }, /* R1341 */
- { 0x0000, 0x0000 }, /* R1342 */
- { 0x0000, 0x0000 }, /* R1343 */
- { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
- { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
- { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
- { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
- { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
- { 0x0000, 0x0000 }, /* R1349 */
- { 0x0000, 0x0000 }, /* R1350 */
- { 0x0000, 0x0000 }, /* R1351 */
- { 0x0000, 0x0000 }, /* R1352 */
- { 0x0000, 0x0000 }, /* R1353 */
- { 0x0000, 0x0000 }, /* R1354 */
- { 0x0000, 0x0000 }, /* R1355 */
- { 0x0000, 0x0000 }, /* R1356 */
- { 0x0000, 0x0000 }, /* R1357 */
- { 0x0000, 0x0000 }, /* R1358 */
- { 0x0000, 0x0000 }, /* R1359 */
- { 0x0000, 0x0000 }, /* R1360 */
- { 0x0000, 0x0000 }, /* R1361 */
- { 0x0000, 0x0000 }, /* R1362 */
- { 0x0000, 0x0000 }, /* R1363 */
- { 0x0000, 0x0000 }, /* R1364 */
- { 0x0000, 0x0000 }, /* R1365 */
- { 0x0000, 0x0000 }, /* R1366 */
- { 0x0000, 0x0000 }, /* R1367 */
- { 0x0000, 0x0000 }, /* R1368 */
- { 0x0000, 0x0000 }, /* R1369 */
- { 0x0000, 0x0000 }, /* R1370 */
- { 0x0000, 0x0000 }, /* R1371 */
- { 0x0000, 0x0000 }, /* R1372 */
- { 0x0000, 0x0000 }, /* R1373 */
- { 0x0000, 0x0000 }, /* R1374 */
- { 0x0000, 0x0000 }, /* R1375 */
- { 0x0000, 0x0000 }, /* R1376 */
- { 0x0000, 0x0000 }, /* R1377 */
- { 0x0000, 0x0000 }, /* R1378 */
- { 0x0000, 0x0000 }, /* R1379 */
- { 0x0000, 0x0000 }, /* R1380 */
- { 0x0000, 0x0000 }, /* R1381 */
- { 0x0000, 0x0000 }, /* R1382 */
- { 0x0000, 0x0000 }, /* R1383 */
- { 0x0000, 0x0000 }, /* R1384 */
- { 0x0000, 0x0000 }, /* R1385 */
- { 0x0000, 0x0000 }, /* R1386 */
- { 0x0000, 0x0000 }, /* R1387 */
- { 0x0000, 0x0000 }, /* R1388 */
- { 0x0000, 0x0000 }, /* R1389 */
- { 0x0000, 0x0000 }, /* R1390 */
- { 0x0000, 0x0000 }, /* R1391 */
- { 0x0000, 0x0000 }, /* R1392 */
- { 0x0000, 0x0000 }, /* R1393 */
- { 0x0000, 0x0000 }, /* R1394 */
- { 0x0000, 0x0000 }, /* R1395 */
- { 0x0000, 0x0000 }, /* R1396 */
- { 0x0000, 0x0000 }, /* R1397 */
- { 0x0000, 0x0000 }, /* R1398 */
- { 0x0000, 0x0000 }, /* R1399 */
- { 0x0000, 0x0000 }, /* R1400 */
- { 0x0000, 0x0000 }, /* R1401 */
- { 0x0000, 0x0000 }, /* R1402 */
- { 0x0000, 0x0000 }, /* R1403 */
- { 0x0000, 0x0000 }, /* R1404 */
- { 0x0000, 0x0000 }, /* R1405 */
- { 0x0000, 0x0000 }, /* R1406 */
- { 0x0000, 0x0000 }, /* R1407 */
- { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1428 */
- { 0x0000, 0x0000 }, /* R1429 */
- { 0x0000, 0x0000 }, /* R1430 */
- { 0x0000, 0x0000 }, /* R1431 */
- { 0x0000, 0x0000 }, /* R1432 */
- { 0x0000, 0x0000 }, /* R1433 */
- { 0x0000, 0x0000 }, /* R1434 */
- { 0x0000, 0x0000 }, /* R1435 */
- { 0x0000, 0x0000 }, /* R1436 */
- { 0x0000, 0x0000 }, /* R1437 */
- { 0x0000, 0x0000 }, /* R1438 */
- { 0x0000, 0x0000 }, /* R1439 */
- { 0x0000, 0x0000 }, /* R1440 */
- { 0x0000, 0x0000 }, /* R1441 */
- { 0x0000, 0x0000 }, /* R1442 */
- { 0x0000, 0x0000 }, /* R1443 */
- { 0x0000, 0x0000 }, /* R1444 */
- { 0x0000, 0x0000 }, /* R1445 */
- { 0x0000, 0x0000 }, /* R1446 */
- { 0x0000, 0x0000 }, /* R1447 */
- { 0x0000, 0x0000 }, /* R1448 */
- { 0x0000, 0x0000 }, /* R1449 */
- { 0x0000, 0x0000 }, /* R1450 */
- { 0x0000, 0x0000 }, /* R1451 */
- { 0x0000, 0x0000 }, /* R1452 */
- { 0x0000, 0x0000 }, /* R1453 */
- { 0x0000, 0x0000 }, /* R1454 */
- { 0x0000, 0x0000 }, /* R1455 */
- { 0x0000, 0x0000 }, /* R1456 */
- { 0x0000, 0x0000 }, /* R1457 */
- { 0x0000, 0x0000 }, /* R1458 */
- { 0x0000, 0x0000 }, /* R1459 */
- { 0x0000, 0x0000 }, /* R1460 */
- { 0x0000, 0x0000 }, /* R1461 */
- { 0x0000, 0x0000 }, /* R1462 */
- { 0x0000, 0x0000 }, /* R1463 */
- { 0x0000, 0x0000 }, /* R1464 */
- { 0x0000, 0x0000 }, /* R1465 */
- { 0x0000, 0x0000 }, /* R1466 */
- { 0x0000, 0x0000 }, /* R1467 */
- { 0x0000, 0x0000 }, /* R1468 */
- { 0x0000, 0x0000 }, /* R1469 */
- { 0x0000, 0x0000 }, /* R1470 */
- { 0x0000, 0x0000 }, /* R1471 */
- { 0x0000, 0x0000 }, /* R1472 */
- { 0x0000, 0x0000 }, /* R1473 */
- { 0x0000, 0x0000 }, /* R1474 */
- { 0x0000, 0x0000 }, /* R1475 */
- { 0x0000, 0x0000 }, /* R1476 */
- { 0x0000, 0x0000 }, /* R1477 */
- { 0x0000, 0x0000 }, /* R1478 */
- { 0x0000, 0x0000 }, /* R1479 */
- { 0x0000, 0x0000 }, /* R1480 */
- { 0x0000, 0x0000 }, /* R1481 */
- { 0x0000, 0x0000 }, /* R1482 */
- { 0x0000, 0x0000 }, /* R1483 */
- { 0x0000, 0x0000 }, /* R1484 */
- { 0x0000, 0x0000 }, /* R1485 */
- { 0x0000, 0x0000 }, /* R1486 */
- { 0x0000, 0x0000 }, /* R1487 */
- { 0x0000, 0x0000 }, /* R1488 */
- { 0x0000, 0x0000 }, /* R1489 */
- { 0x0000, 0x0000 }, /* R1490 */
- { 0x0000, 0x0000 }, /* R1491 */
- { 0x0000, 0x0000 }, /* R1492 */
- { 0x0000, 0x0000 }, /* R1493 */
- { 0x0000, 0x0000 }, /* R1494 */
- { 0x0000, 0x0000 }, /* R1495 */
- { 0x0000, 0x0000 }, /* R1496 */
- { 0x0000, 0x0000 }, /* R1497 */
- { 0x0000, 0x0000 }, /* R1498 */
- { 0x0000, 0x0000 }, /* R1499 */
- { 0x0000, 0x0000 }, /* R1500 */
- { 0x0000, 0x0000 }, /* R1501 */
- { 0x0000, 0x0000 }, /* R1502 */
- { 0x0000, 0x0000 }, /* R1503 */
- { 0x0000, 0x0000 }, /* R1504 */
- { 0x0000, 0x0000 }, /* R1505 */
- { 0x0000, 0x0000 }, /* R1506 */
- { 0x0000, 0x0000 }, /* R1507 */
- { 0x0000, 0x0000 }, /* R1508 */
- { 0x0000, 0x0000 }, /* R1509 */
- { 0x0000, 0x0000 }, /* R1510 */
- { 0x0000, 0x0000 }, /* R1511 */
- { 0x0000, 0x0000 }, /* R1512 */
- { 0x0000, 0x0000 }, /* R1513 */
- { 0x0000, 0x0000 }, /* R1514 */
- { 0x0000, 0x0000 }, /* R1515 */
- { 0x0000, 0x0000 }, /* R1516 */
- { 0x0000, 0x0000 }, /* R1517 */
- { 0x0000, 0x0000 }, /* R1518 */
- { 0x0000, 0x0000 }, /* R1519 */
- { 0x0000, 0x0000 }, /* R1520 */
- { 0x0000, 0x0000 }, /* R1521 */
- { 0x0000, 0x0000 }, /* R1522 */
- { 0x0000, 0x0000 }, /* R1523 */
- { 0x0000, 0x0000 }, /* R1524 */
- { 0x0000, 0x0000 }, /* R1525 */
- { 0x0000, 0x0000 }, /* R1526 */
- { 0x0000, 0x0000 }, /* R1527 */
- { 0x0000, 0x0000 }, /* R1528 */
- { 0x0000, 0x0000 }, /* R1529 */
- { 0x0000, 0x0000 }, /* R1530 */
- { 0x0000, 0x0000 }, /* R1531 */
- { 0x0000, 0x0000 }, /* R1532 */
- { 0x0000, 0x0000 }, /* R1533 */
- { 0x0000, 0x0000 }, /* R1534 */
- { 0x0000, 0x0000 }, /* R1535 */
- { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
- { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
- { 0x0000, 0x0000 }, /* R1546 */
- { 0x0000, 0x0000 }, /* R1547 */
- { 0x0000, 0x0000 }, /* R1548 */
- { 0x0000, 0x0000 }, /* R1549 */
- { 0x0000, 0x0000 }, /* R1550 */
- { 0x0000, 0x0000 }, /* R1551 */
- { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
- { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
- { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
- { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
- { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
- { 0x0000, 0x0000 }, /* R1557 */
- { 0x0000, 0x0000 }, /* R1558 */
- { 0x0000, 0x0000 }, /* R1559 */
- { 0x0000, 0x0000 }, /* R1560 */
- { 0x0000, 0x0000 }, /* R1561 */
- { 0x0000, 0x0000 }, /* R1562 */
- { 0x0000, 0x0000 }, /* R1563 */
- { 0x0000, 0x0000 }, /* R1564 */
- { 0x0000, 0x0000 }, /* R1565 */
- { 0x0000, 0x0000 }, /* R1566 */
- { 0x0000, 0x0000 }, /* R1567 */
- { 0x0003, 0x0003 }, /* R1568 - Oversampling */
- { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
-};
-
static int wm8994_readable(unsigned int reg)
{
switch (reg) {
@@ -1696,14 +130,14 @@ static int wm8994_readable(unsigned int reg)
break;
}
- if (reg >= ARRAY_SIZE(access_masks))
+ if (reg >= WM8994_CACHE_SIZE)
return 0;
- return access_masks[reg].readable != 0;
+ return wm8994_access_masks[reg].readable != 0;
}
static int wm8994_volatile(unsigned int reg)
{
- if (reg >= WM8994_REG_CACHE_SIZE)
+ if (reg >= WM8994_CACHE_SIZE)
return 1;
switch (reg) {
@@ -1714,6 +148,8 @@ static int wm8994_volatile(unsigned int reg)
case WM8994_RATE_STATUS:
case WM8994_LDO_1:
case WM8994_LDO_2:
+ case WM8958_DSP2_EXECCONTROL:
+ case WM8958_MIC_DETECT_3:
return 1;
default:
return 0;
@@ -1723,14 +159,16 @@ static int wm8994_volatile(unsigned int reg)
static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int ret;
BUG_ON(reg > WM8994_MAX_REGISTER);
- if (!wm8994_volatile(reg))
- wm8994->reg_cache[reg] = value;
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
+ if (!wm8994_volatile(reg)) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret != 0)
+ dev_err(codec->dev, "Cache write to %x failed: %d\n",
+ reg, ret);
+ }
return wm8994_reg_write(codec->control_data, reg, value);
}
@@ -1738,14 +176,22 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int wm8994_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *reg_cache = codec->reg_cache;
+ unsigned int val;
+ int ret;
BUG_ON(reg > WM8994_MAX_REGISTER);
- if (wm8994_volatile(reg))
- return wm8994_reg_read(codec->control_data, reg);
- else
- return reg_cache[reg];
+ if (!wm8994_volatile(reg) && wm8994_readable(reg) &&
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret >= 0)
+ return val;
+ else
+ dev_err(codec->dev, "Cache read from %x failed: %d\n",
+ reg, ret);
+ }
+
+ return wm8994_reg_read(codec->control_data, reg);
}
static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -1837,7 +283,7 @@ static int configure_clock(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
return 0;
}
@@ -1864,6 +310,19 @@ static const char *sidetone_hpf_text[] = {
static const struct soc_enum sidetone_hpf =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
+static const char *adc_hpf_text[] = {
+ "HiFi", "Voice 1", "Voice 2", "Voice 3"
+};
+
+static const struct soc_enum aif1adc1_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
+
+static const struct soc_enum aif1adc2_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
+
+static const struct soc_enum aif2adc_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
+
static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
@@ -2071,21 +530,252 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
return 0;
}
-static const char *aifdac_src_text[] = {
+static const char *aif_chan_src_text[] = {
"Left", "Right"
};
+static const struct soc_enum aif1adcl_src =
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
+
+static const struct soc_enum aif1adcr_src =
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
+
+static const struct soc_enum aif2adcl_src =
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
+
+static const struct soc_enum aif2adcr_src =
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
+
static const struct soc_enum aif1dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
static const struct soc_enum aif1dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
static const struct soc_enum aif2dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
static const struct soc_enum aif2dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
+
+static const char *osr_text[] = {
+ "Low Power", "High Performance",
+};
+
+static const struct soc_enum dac_osr =
+ SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
+
+static const struct soc_enum adc_osr =
+ SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
+
+static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_pdata *pdata = wm8994->pdata;
+ int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
+ int ena, reg, aif, i;
+
+ switch (mbc) {
+ case 0:
+ pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
+ aif = 0;
+ break;
+ case 1:
+ pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
+ aif = 0;
+ break;
+ case 2:
+ pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
+ aif = 1;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ /* We can only enable the MBC if the AIF is enabled and we
+ * want it to be enabled. */
+ ena = pwr_reg && wm8994->mbc_ena[mbc];
+
+ reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
+
+ dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
+ mbc, start, pwr_reg, reg);
+
+ if (start && ena) {
+ /* If the DSP is already running then noop */
+ if (reg & WM8958_DSP2_ENA)
+ return;
+
+ /* Switch the clock over to the appropriate AIF */
+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+ WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
+ aif << WM8958_DSP2CLK_SRC_SHIFT |
+ WM8958_DSP2CLK_ENA);
+
+ snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+ WM8958_DSP2_ENA, WM8958_DSP2_ENA);
+
+ /* If we've got user supplied MBC settings use them */
+ if (pdata && pdata->num_mbc_cfgs) {
+ struct wm8958_mbc_cfg *cfg
+ = &pdata->mbc_cfgs[wm8994->mbc_cfg];
+
+ for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
+ snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
+ cfg->coeff_regs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
+ snd_soc_write(codec,
+ i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
+ cfg->cutoff_regs[i]);
+ }
+
+ /* Run the DSP */
+ snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+ WM8958_DSP2_RUNR);
+
+ /* And we're off! */
+ snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+ WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
+ mbc << WM8958_MBC_SEL_SHIFT |
+ WM8958_MBC_ENA);
+ } else {
+ /* If the DSP is already stopped then noop */
+ if (!(reg & WM8958_DSP2_ENA))
+ return;
+
+ snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+ WM8958_MBC_ENA, 0);
+ snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+ WM8958_DSP2_ENA, 0);
+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+ WM8958_DSP2CLK_ENA, 0);
+ }
+}
+
+static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ int mbc;
+
+ switch (w->shift) {
+ case 13:
+ case 12:
+ mbc = 2;
+ break;
+ case 11:
+ case 10:
+ mbc = 1;
+ break;
+ case 9:
+ case 8:
+ mbc = 0;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ wm8958_mbc_apply(codec, mbc, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ wm8958_mbc_apply(codec, mbc, 0);
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_pdata *pdata = wm8994->pdata;
+ int value = ucontrol->value.integer.value[0];
+ int reg;
+
+ /* Don't allow on the fly reconfiguration */
+ reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+ if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
+ return -EBUSY;
+
+ if (value >= pdata->num_mbc_cfgs)
+ return -EINVAL;
+
+ wm8994->mbc_cfg = value;
+
+ return 0;
+}
+
+static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
+
+ return 0;
+}
+
+static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mbc = kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
+
+ return 0;
+}
+
+static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mbc = kcontrol->private_value;
+ int i;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (ucontrol->value.integer.value[0] > 1)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
+ if (mbc != i && wm8994->mbc_ena[i]) {
+ dev_dbg(codec->dev, "MBC %d active already\n", mbc);
+ return -EBUSY;
+ }
+ }
+
+ wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
+
+ wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
+
+ return 0;
+}
+
+#define WM8958_MBC_SWITCH(xname, xval) {\
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+ .info = wm8958_mbc_info, \
+ .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
+ .private_value = xval }
static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
@@ -2098,10 +788,15 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
WM8994_AIF2_ADC_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
+SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
+SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
+SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
+SOC_ENUM("AIF2ADCR Source", aif2adcr_src),
+
SOC_ENUM("AIF1DACL Source", aif1dacl_src),
SOC_ENUM("AIF1DACR Source", aif1dacr_src),
-SOC_ENUM("AIF2DACL Source", aif1dacl_src),
-SOC_ENUM("AIF2DACR Source", aif1dacr_src),
+SOC_ENUM("AIF2DACL Source", aif2dacl_src),
+SOC_ENUM("AIF2DACR Source", aif2dacr_src),
SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
@@ -2140,6 +835,18 @@ SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
+SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
+SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
+SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
+SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("ADC OSR", adc_osr),
+SOC_ENUM("DAC OSR", dac_osr),
+
SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
@@ -2209,6 +916,13 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
};
+static const struct snd_kcontrol_new wm8958_snd_controls[] = {
+SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
+WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
+WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
+WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
+};
+
static int clk_sys_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -2228,6 +942,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
static void wm8994_update_class_w(struct snd_soc_codec *codec)
{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int enable = 1;
int source = 0; /* GCC flow analysis can't track enable */
int reg, reg_r;
@@ -2278,11 +993,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
WM8994_CP_DYN_PWR |
WM8994_CP_DYN_SRC_SEL_MASK,
source | WM8994_CP_DYN_PWR);
+ wm8994->hubs.class_w = true;
} else {
dev_dbg(codec->dev, "Class W disabled\n");
snd_soc_update_bits(codec, WM8994_CLASS_W_1,
WM8994_CP_DYN_PWR, 0);
+ wm8994->hubs.class_w = false;
}
}
@@ -2512,14 +1229,47 @@ static const struct snd_kcontrol_new aif2adc_mux =
SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
static const char *aif3adc_text[] = {
- "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
+ "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
};
-static const struct soc_enum aif3adc_enum =
+static const struct soc_enum wm8994_aif3adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
-static const struct snd_kcontrol_new aif3adc_mux =
- SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
+static const struct snd_kcontrol_new wm8994_aif3adc_mux =
+ SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
+
+static const struct soc_enum wm8958_aif3adc_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
+
+static const struct snd_kcontrol_new wm8958_aif3adc_mux =
+ SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
+
+static const char *mono_pcm_out_text[] = {
+ "None", "AIF2ADCL", "AIF2ADCR",
+};
+
+static const struct soc_enum mono_pcm_out_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
+
+static const struct snd_kcontrol_new mono_pcm_out_mux =
+ SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
+
+static const char *aif2dac_src_text[] = {
+ "AIF2", "AIF3",
+};
+
+/* Note that these two control shouldn't be simultaneously switched to AIF3 */
+static const struct soc_enum aif2dacl_src_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
+
+static const struct snd_kcontrol_new aif2dacl_src_mux =
+ SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
+
+static const struct soc_enum aif2dacr_src_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
+
+static const struct snd_kcontrol_new aif2dacr_src_mux =
+ SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("DMIC1DAT"),
@@ -2540,19 +1290,23 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 9, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 8, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 9, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 8, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 11, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 10, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 11, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 10, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
@@ -2581,10 +1335,12 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 13, 0),
SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 12, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 13, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 12, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
@@ -2593,7 +1349,6 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
-SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -2631,8 +1386,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
SND_SOC_DAPM_POST("Debug log", post_ev),
};
-static const struct snd_soc_dapm_route intercon[] = {
+static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
+};
+
+static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
+SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
+SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
+SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
+};
+static const struct snd_soc_dapm_route intercon[] = {
{ "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
{ "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
@@ -2740,9 +1505,6 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "AIF1DAC2L", NULL, "AIF1DAC Mux" },
{ "AIF1DAC2R", NULL, "AIF1DAC Mux" },
- { "AIF2DACL", NULL, "AIF2DAC Mux" },
- { "AIF2DACR", NULL, "AIF2DAC Mux" },
-
{ "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
{ "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
{ "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
@@ -2815,6 +1577,26 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "Right Headphone Mux", "DAC", "DAC1R" },
};
+static const struct snd_soc_dapm_route wm8994_intercon[] = {
+ { "AIF2DACL", NULL, "AIF2DAC Mux" },
+ { "AIF2DACR", NULL, "AIF2DAC Mux" },
+};
+
+static const struct snd_soc_dapm_route wm8958_intercon[] = {
+ { "AIF2DACL", NULL, "AIF2DACL Mux" },
+ { "AIF2DACR", NULL, "AIF2DACR Mux" },
+
+ { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
+ { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
+ { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
+ { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
+
+ { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
+ { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
+
+ { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
+};
+
/* The size in bits of the FLL divide multiplied by 10
* to allow rounding later */
#define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2930,6 +1712,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
/* Allow no source specification when stopping */
if (freq_out)
return -EINVAL;
+ src = wm8994->fll[id].src;
break;
case WM8994_FLL_SRC_MCLK1:
case WM8994_FLL_SRC_MCLK2:
@@ -3094,6 +1877,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
switch (level) {
@@ -3107,16 +1891,36 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
- /* Tweak DC servo and DSP configuration for
- * improved performance. */
- if (wm8994->revision < 4) {
- /* Tweak DC servo and DSP configuration for
- * improved performance. */
- snd_soc_write(codec, 0x102, 0x3);
- snd_soc_write(codec, 0x56, 0x3);
- snd_soc_write(codec, 0x817, 0);
- snd_soc_write(codec, 0x102, 0);
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ pm_runtime_get_sync(codec->dev);
+
+ switch (control->type) {
+ case WM8994:
+ if (wm8994->revision < 4) {
+ /* Tweak DC servo and DSP
+ * configuration for improved
+ * performance. */
+ snd_soc_write(codec, 0x102, 0x3);
+ snd_soc_write(codec, 0x56, 0x3);
+ snd_soc_write(codec, 0x817, 0);
+ snd_soc_write(codec, 0x102, 0);
+ }
+ break;
+
+ case WM8958:
+ if (wm8994->revision == 0) {
+ /* Optimise performance for rev A */
+ snd_soc_write(codec, 0x102, 0x3);
+ snd_soc_write(codec, 0xcb, 0x81);
+ snd_soc_write(codec, 0x817, 0);
+ snd_soc_write(codec, 0x102, 0);
+
+ snd_soc_update_bits(codec,
+ WM8958_CHARGE_PUMP_2,
+ WM8958_CP_DISCH,
+ WM8958_CP_DISCH);
+ }
+ break;
}
/* Discharge LINEOUT1 & 2 */
@@ -3151,7 +1955,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
/* Switch over to startup biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC |
@@ -3183,16 +1987,19 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0);
+
+ pm_runtime_put(codec->dev);
}
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
int ms_reg;
int aif1_reg;
int ms = 0;
@@ -3277,6 +2084,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
+ /* The AIF2 format configuration needs to be mirrored to AIF3
+ * on WM8958 if it's in use so just do it all the time. */
+ if (control->type == WM8958 && dai->id == 2)
+ snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
+ WM8994_AIF1_LRCLK_INV |
+ WM8958_AIF3_FMT_MASK, aif1);
+
snd_soc_update_bits(codec, aif1_reg,
WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
WM8994_AIF1_FMT_MASK,
@@ -3317,12 +2131,15 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int aif1_reg;
+ int aif2_reg;
int bclk_reg;
int lrclk_reg;
int rate_reg;
int aif1 = 0;
+ int aif2 = 0;
int bclk = 0;
int lrclk = 0;
int rate_val = 0;
@@ -3333,6 +2150,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
switch (dai->id) {
case 1:
aif1_reg = WM8994_AIF1_CONTROL_1;
+ aif2_reg = WM8994_AIF1_CONTROL_2;
bclk_reg = WM8994_AIF1_BCLK;
rate_reg = WM8994_AIF1_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3345,6 +2163,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
break;
case 2:
aif1_reg = WM8994_AIF2_CONTROL_1;
+ aif2_reg = WM8994_AIF2_CONTROL_2;
bclk_reg = WM8994_AIF2_BCLK;
rate_reg = WM8994_AIF2_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3355,6 +2174,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
}
break;
+ case 3:
+ switch (control->type) {
+ case WM8958:
+ aif1_reg = WM8958_AIF3_CONTROL_1;
+ break;
+ default:
+ return 0;
+ }
default:
return -EINVAL;
}
@@ -3392,6 +2219,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
dai->id, wm8994->aifclk[id], bclk_rate);
+ if (params_channels(params) == 1 &&
+ (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
+ aif2 |= WM8994_AIF1_MONO;
+
if (wm8994->aifclk[id] == 0) {
dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
return -EINVAL;
@@ -3435,6 +2266,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
lrclk, bclk_rate / lrclk);
snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+ snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
lrclk);
@@ -3458,6 +2290,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
return 0;
}
+static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
+ int aif1_reg;
+ int aif1 = 0;
+
+ switch (dai->id) {
+ case 3:
+ switch (control->type) {
+ case WM8958:
+ aif1_reg = WM8958_AIF3_CONTROL_1;
+ break;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ aif1 |= 0x20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ aif1 |= 0x40;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ aif1 |= 0x60;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+}
+
static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
{
struct snd_soc_codec *codec = codec_dai->codec;
@@ -3539,6 +2412,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
};
static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
+ .hw_params = wm8994_aif3_hw_params,
.set_tristate = wm8994_set_tristate,
};
@@ -3548,14 +2422,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 1,
.playback = {
.stream_name = "AIF1 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF1 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3567,14 +2441,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 2,
.playback = {
.stream_name = "AIF2 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF2 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3586,14 +2460,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 3,
.playback = {
.stream_name = "AIF3 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF3 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3625,26 +2499,12 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int wm8994_resume(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = codec->reg_cache;
int i, ret;
/* Restore the registers */
- for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
- switch (i) {
- case WM8994_LDO_1:
- case WM8994_LDO_2:
- case WM8994_SOFTWARE_RESET:
- /* Handled by other MFD drivers */
- continue;
- default:
- break;
- }
-
- if (!access_masks[i].writable)
- continue;
-
- wm8994_reg_write(codec->control_data, i, reg_cache[i]);
- }
+ ret = snd_soc_cache_sync(codec);
+ if (ret != 0)
+ dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -3794,6 +2654,34 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
pdata->num_retune_mobile_cfgs);
+ if (pdata->num_mbc_cfgs) {
+ struct snd_kcontrol_new control[] = {
+ SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
+ wm8958_get_mbc_enum, wm8958_put_mbc_enum),
+ };
+
+ /* We need an array of texts for the enum API */
+ wm8994->mbc_texts = kmalloc(sizeof(char *)
+ * pdata->num_mbc_cfgs, GFP_KERNEL);
+ if (!wm8994->mbc_texts) {
+ dev_err(wm8994->codec->dev,
+ "Failed to allocate %d MBC config texts\n",
+ pdata->num_mbc_cfgs);
+ return;
+ }
+
+ for (i = 0; i < pdata->num_mbc_cfgs; i++)
+ wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
+
+ wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
+ wm8994->mbc_enum.texts = wm8994->mbc_texts;
+
+ ret = snd_soc_add_controls(wm8994->codec, control, 1);
+ if (ret != 0)
+ dev_err(wm8994->codec->dev,
+ "Failed to add MBC mode controls: %d\n", ret);
+ }
+
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994);
else
@@ -3823,8 +2711,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
+ struct wm8994 *control = codec->control_data;
int reg;
+ if (control->type != WM8994)
+ return -EINVAL;
+
switch (micbias) {
case 1:
micdet = &wm8994->micdet[0];
@@ -3891,77 +2783,247 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
return IRQ_HANDLED;
}
+/* Default microphone detection handler for WM8958 - the user can
+ * override this if they wish.
+ */
+static void wm8958_default_micdet(u16 status, void *data)
+{
+ struct snd_soc_codec *codec = data;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int report = 0;
+
+ /* If nothing present then clear our statuses */
+ if (!(status & WM8958_MICD_STS)) {
+ wm8994->jack_is_video = false;
+ wm8994->jack_is_mic = false;
+ goto done;
+ }
+
+ /* Assume anything over 475 ohms is a microphone and remember
+ * that we've seen one (since buttons override it) */
+ if (status & 0x600)
+ wm8994->jack_is_mic = true;
+ if (wm8994->jack_is_mic)
+ report |= SND_JACK_MICROPHONE;
+
+ /* Video has an impedence of approximately 75 ohms; assume
+ * this isn't used as a button and remember it since buttons
+ * override it. */
+ if (status & 0x40)
+ wm8994->jack_is_video = true;
+ if (wm8994->jack_is_video)
+ report |= SND_JACK_VIDEOOUT;
+
+ /* Everything else is buttons; just assign slots */
+ if (status & 0x4)
+ report |= SND_JACK_BTN_0;
+ if (status & 0x8)
+ report |= SND_JACK_BTN_1;
+ if (status & 0x10)
+ report |= SND_JACK_BTN_2;
+ if (status & 0x20)
+ report |= SND_JACK_BTN_3;
+ if (status & 0x80)
+ report |= SND_JACK_BTN_4;
+ if (status & 0x100)
+ report |= SND_JACK_BTN_5;
+
+done:
+ snd_soc_jack_report(wm8994->micdet[0].jack,
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+ SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
+ SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT,
+ report);
+}
+
+/**
+ * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
+ *
+ * @codec: WM8958 codec
+ * @jack: jack to report detection events on
+ *
+ * Enable microphone detection functionality for the WM8958. By
+ * default simple detection which supports the detection of up to 6
+ * buttons plus video and microphone functionality is supported.
+ *
+ * The WM8958 has an advanced jack detection facility which is able to
+ * support complex accessory detection, especially when used in
+ * conjunction with external circuitry. In order to provide maximum
+ * flexiblity a callback is provided which allows a completely custom
+ * detection algorithm.
+ */
+int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8958_micdet_cb cb, void *cb_data)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = codec->control_data;
+
+ if (control->type != WM8958)
+ return -EINVAL;
+
+ if (jack) {
+ if (!cb) {
+ dev_dbg(codec->dev, "Using default micdet callback\n");
+ cb = wm8958_default_micdet;
+ cb_data = codec;
+ }
+
+ wm8994->micdet[0].jack = jack;
+ wm8994->jack_cb = cb;
+ wm8994->jack_cb_data = cb_data;
+
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, WM8958_MICD_ENA);
+ } else {
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, 0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wm8958_mic_detect);
+
+static irqreturn_t wm8958_mic_irq(int irq, void *data)
+{
+ struct wm8994_priv *wm8994 = data;
+ struct snd_soc_codec *codec = wm8994->codec;
+ int reg;
+
+ reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
+ if (reg < 0) {
+ dev_err(codec->dev, "Failed to read mic detect status: %d\n",
+ reg);
+ return IRQ_NONE;
+ }
+
+ if (!(reg & WM8958_MICD_VALID)) {
+ dev_dbg(codec->dev, "Mic detect data not valid\n");
+ goto out;
+ }
+
+ if (wm8994->jack_cb)
+ wm8994->jack_cb(reg, wm8994->jack_cb_data);
+ else
+ dev_warn(codec->dev, "Accessory detection with no callback\n");
+
+out:
+ return IRQ_HANDLED;
+}
+
static int wm8994_codec_probe(struct snd_soc_codec *codec)
{
+ struct wm8994 *control;
struct wm8994_priv *wm8994;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i;
codec->control_data = dev_get_drvdata(codec->dev->parent);
+ control = codec->control_data;
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
if (wm8994 == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm8994);
- codec->reg_cache = &wm8994->reg_cache;
-
wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec;
- /* Fill the cache with physical values we inherited; don't reset */
- ret = wm8994_bulk_read(codec->control_data, 0,
- ARRAY_SIZE(wm8994->reg_cache) - 1,
- codec->reg_cache);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to fill register cache: %d\n",
- ret);
- goto err;
- }
+ pm_runtime_enable(codec->dev);
+ pm_runtime_resume(codec->dev);
- /* Clear the cached values for unreadable/volatile registers to
- * avoid potential confusion.
- */
- for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
- if (wm8994_volatile(i) || !wm8994_readable(i))
- wm8994->reg_cache[i] = 0;
+ /* Read our current status back from the chip - we don't want to
+ * reset as this may interfere with the GPIO or LDO operation. */
+ for (i = 0; i < WM8994_CACHE_SIZE; i++) {
+ if (!wm8994_readable(i) || wm8994_volatile(i))
+ continue;
+
+ ret = wm8994_reg_read(codec->control_data, i);
+ if (ret <= 0)
+ continue;
+
+ ret = snd_soc_cache_write(codec, i, ret);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to initialise cache for 0x%x: %d\n",
+ i, ret);
+ goto err;
+ }
+ }
/* Set revision-specific configuration */
wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
- switch (wm8994->revision) {
- case 2:
- case 3:
- wm8994->hubs.dcs_codes = -5;
- wm8994->hubs.hp_startup_mode = 1;
+ switch (control->type) {
+ case WM8994:
+ switch (wm8994->revision) {
+ case 2:
+ case 3:
+ wm8994->hubs.dcs_codes = -5;
+ wm8994->hubs.hp_startup_mode = 1;
+ wm8994->hubs.dcs_readback_mode = 1;
+ break;
+ default:
+ wm8994->hubs.dcs_readback_mode = 1;
+ break;
+ }
+
+ case WM8958:
wm8994->hubs.dcs_readback_mode = 1;
break;
+
default:
- wm8994->hubs.dcs_readback_mode = 1;
break;
}
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
- wm8994_mic_irq, "Mic 1 detect", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 detect IRQ: %d\n", ret);
-
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
- wm8994_mic_irq, "Mic 1 short", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 short IRQ: %d\n", ret);
-
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
- wm8994_mic_irq, "Mic 2 detect", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 detect IRQ: %d\n", ret);
+ switch (control->type) {
+ case WM8994:
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_DET,
+ wm8994_mic_irq, "Mic 1 detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic1 detect IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_SHRT,
+ wm8994_mic_irq, "Mic 1 short",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic1 short IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC2_DET,
+ wm8994_mic_irq, "Mic 2 detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic2 detect IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC2_SHRT,
+ wm8994_mic_irq, "Mic 2 short",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic2 short IRQ: %d\n",
+ ret);
+ break;
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
- wm8994_mic_irq, "Mic 2 short", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 short IRQ: %d\n", ret);
+ case WM8958:
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_DET,
+ wm8958_mic_irq, "Mic detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic detect IRQ: %d\n",
+ ret);
+ break;
+ }
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
@@ -4034,10 +3096,36 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
wm_hubs_add_analogue_controls(codec);
snd_soc_add_controls(codec, wm8994_snd_controls,
ARRAY_SIZE(wm8994_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
ARRAY_SIZE(wm8994_dapm_widgets));
+
+ switch (control->type) {
+ case WM8994:
+ snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
+ ARRAY_SIZE(wm8994_specific_dapm_widgets));
+ break;
+ case WM8958:
+ snd_soc_add_controls(codec, wm8958_snd_controls,
+ ARRAY_SIZE(wm8958_snd_controls));
+ snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
+ ARRAY_SIZE(wm8958_dapm_widgets));
+ break;
+ }
+
+
wm_hubs_add_analogue_routes(codec, 0, 0);
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ switch (control->type) {
+ case WM8994:
+ snd_soc_dapm_add_routes(dapm, wm8994_intercon,
+ ARRAY_SIZE(wm8994_intercon));
+ break;
+ case WM8958:
+ snd_soc_dapm_add_routes(dapm, wm8958_intercon,
+ ARRAY_SIZE(wm8958_intercon));
+ break;
+ }
return 0;
@@ -4054,13 +3142,29 @@ err:
static int wm8994_codec_remove(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = codec->control_data;
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
+ pm_runtime_disable(codec->dev);
+
+ switch (control->type) {
+ case WM8994:
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
+ wm8994);
+ break;
+
+ case WM8958:
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
+ wm8994);
+ break;
+ }
kfree(wm8994->retune_mobile_texts);
kfree(wm8994->drc_texts);
kfree(wm8994);
@@ -4073,11 +3177,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.remove = wm8994_codec_remove,
.suspend = wm8994_suspend,
.resume = wm8994_resume,
- .read = wm8994_read,
- .write = wm8994_write,
+ .read = wm8994_read,
+ .write = wm8994_write,
.readable_register = wm8994_readable,
.volatile_register = wm8994_volatile,
.set_bias_level = wm8994_set_bias_level,
+
+ .reg_cache_size = WM8994_CACHE_SIZE,
+ .reg_cache_default = wm8994_reg_defaults,
+ .reg_word_size = 2,
+ .compress_type = SND_SOC_RBTREE_COMPRESSION,
};
static int __devinit wm8994_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d8dce260c430..0c355bfc88f1 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,7 +28,21 @@
#define WM8994_FLL_SRC_LRCLK 3
#define WM8994_FLL_SRC_BCLK 4
+typedef void (*wm8958_micdet_cb)(u16 status, void *data);
+
int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
int micbias, int det, int shrt);
+int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8958_micdet_cb cb, void *cb_data);
+
+#define WM8994_CACHE_SIZE 1570
+
+struct wm8994_access_mask {
+ unsigned short readable; /* Mask of readable bits */
+ unsigned short writable; /* Mask of writable bits */
+};
+
+extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
+extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index ecc7c37180c7..e5055b28c638 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -591,6 +590,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
+ /* Set gain to the recommended value */
+ snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
+ WM9081_FLL_GAIN_MASK, 0);
+
/* Enable the FLL */
snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
@@ -805,7 +808,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
/* Initial cold start */
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Disable LINEOUT discharge */
reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
reg &= ~WM9081_LINEOUT_DISCH;
@@ -865,7 +868,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1228,6 +1231,7 @@ static struct snd_soc_dai_driver wm9081_dai = {
static int wm9081_probe(struct snd_soc_codec *codec)
{
struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
u16 reg;
@@ -1269,9 +1273,9 @@ static int wm9081_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(wm9081_eq_controls));
}
- snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
ARRAY_SIZE(wm9081_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 99c046ba46bb..7ba5807cac36 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/wm9090.h>
@@ -443,31 +442,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
static int wm9090_add_controls(struct snd_soc_codec *codec)
{
struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
- snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
ARRAY_SIZE(wm9090_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
snd_soc_add_controls(codec, wm9090_controls,
ARRAY_SIZE(wm9090_controls));
if (wm9090->pdata.lin1_diff) {
- snd_soc_dapm_add_routes(codec, audio_map_in1_diff,
+ snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
ARRAY_SIZE(audio_map_in1_diff));
} else {
- snd_soc_dapm_add_routes(codec, audio_map_in1_se,
+ snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
ARRAY_SIZE(audio_map_in1_se));
snd_soc_add_controls(codec, wm9090_in1_se_controls,
ARRAY_SIZE(wm9090_in1_se_controls));
}
if (wm9090->pdata.lin2_diff) {
- snd_soc_dapm_add_routes(codec, audio_map_in2_diff,
+ snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
ARRAY_SIZE(audio_map_in2_diff));
} else {
- snd_soc_dapm_add_routes(codec, audio_map_in2_se,
+ snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
ARRAY_SIZE(audio_map_in2_se));
snd_soc_add_controls(codec, wm9090_in2_se_controls,
ARRAY_SIZE(wm9090_in2_se_controls));
@@ -514,7 +514,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Restore the register cache */
for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (reg_cache[i] == wm9090_reg_defaults[i])
@@ -544,7 +544,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index a144acda751c..47b357adabdd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -19,7 +19,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9705.h"
@@ -203,9 +202,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9705_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
ARRAY_SIZE(wm9705_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index d2f224d62744..bf5d4ef1a2a6 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,7 +20,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9712.h"
#define WM9712_VERSION "0.4"
@@ -432,10 +431,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9712_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets,
- ARRAY_SIZE(wm9712_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
+ ARRAY_SIZE(wm9712_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -570,7 +570,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 7da13b07a53d..38ed98558718 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -26,7 +26,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9713.h"
@@ -647,10 +646,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9713_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
ARRAY_SIZE(wm9713_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1147,7 +1148,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 0e24092722c3..c466982eed23 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -22,7 +22,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -94,41 +93,61 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
u16 reg, reg_l, reg_r, dcs_cfg;
- /* Set for 32 series updates */
- snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
- WM8993_DCS_SERIES_NO_01_MASK,
- 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
+ /* If we're using a digital only path and have a previously
+ * callibrated DC servo offset stored then use that. */
+ if (hubs->class_w && hubs->class_w_dcs) {
+ dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
+ hubs->class_w_dcs);
+ snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_DAC_WR_0 |
+ WM8993_DCS_TRIG_DAC_WR_1);
+ return;
+ }
+
+ /* Devices not using a DCS code correction have startup mode */
+ if (hubs->dcs_codes) {
+ /* Set for 32 series updates */
+ snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
+ WM8993_DCS_SERIES_NO_01_MASK,
+ 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_SERIES_0 |
+ WM8993_DCS_TRIG_SERIES_1);
+ } else {
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_STARTUP_0 |
+ WM8993_DCS_TRIG_STARTUP_1);
+ }
+
+ /* Different chips in the family support different readback
+ * methods.
+ */
+ switch (hubs->dcs_readback_mode) {
+ case 0:
+ reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+ & WM8993_DCS_INTEG_CHAN_0_MASK;
+ reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+ & WM8993_DCS_INTEG_CHAN_1_MASK;
+ break;
+ case 1:
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+ reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+ >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+ break;
+ default:
+ WARN(1, "Unknown DCS readback method\n");
+ break;
+ }
+
+ dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
/* Apply correction to DC servo result */
if (hubs->dcs_codes) {
dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes);
- /* Different chips in the family support different
- * readback methods.
- */
- switch (hubs->dcs_readback_mode) {
- case 0:
- reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
- & WM8993_DCS_INTEG_CHAN_0_MASK;;
- reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
- & WM8993_DCS_INTEG_CHAN_1_MASK;
- break;
- case 1:
- reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
- reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
- >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
- reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
- break;
- default:
- WARN(1, "Unknown DCS readback method\n");
- break;
- }
-
- dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
-
/* HPOUT1L */
if (reg_l + hubs->dcs_codes > 0 &&
reg_l + hubs->dcs_codes < 0xff)
@@ -148,7 +167,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
wait_for_dc_servo(codec,
WM8993_DCS_TRIG_DAC_WR_0 |
WM8993_DCS_TRIG_DAC_WR_1);
+ } else {
+ dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ dcs_cfg |= reg_r;
}
+
+ /* Save the callibrated offset if we're in class W mode and
+ * therefore don't have any analogue signal mixed in. */
+ if (hubs->class_w)
+ hubs->class_w_dcs = dcs_cfg;
}
/*
@@ -163,6 +190,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ /* Updating the analogue gains invalidates the DC servo cache */
+ hubs->class_w_dcs = 0;
+
/* If we're applying an offset correction then updating the
* callibration would be likely to introduce further offsets. */
if (hubs->dcs_codes)
@@ -791,6 +821,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = {
int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* Latch volume update bits & default ZC on */
snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
WM8993_IN1_VU, WM8993_IN1_VU);
@@ -819,7 +851,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, analogue_snd_controls,
ARRAY_SIZE(analogue_snd_controls));
- snd_soc_dapm_new_controls(codec, analogue_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
ARRAY_SIZE(analogue_dapm_widgets));
return 0;
}
@@ -828,24 +860,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
int lineout1_diff, int lineout2_diff)
{
- snd_soc_dapm_add_routes(codec, analogue_routes,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_add_routes(dapm, analogue_routes,
ARRAY_SIZE(analogue_routes));
if (lineout1_diff)
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout1_diff_routes,
ARRAY_SIZE(lineout1_diff_routes));
else
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout1_se_routes,
ARRAY_SIZE(lineout1_se_routes));
if (lineout2_diff)
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout2_diff_routes,
ARRAY_SIZE(lineout2_diff_routes));
else
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout2_se_routes,
ARRAY_SIZE(lineout2_se_routes));
@@ -872,7 +906,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
* VMID as an output and can disable it.
*/
if (lineout1_diff && lineout2_diff)
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
if (lineout1fb)
snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index e51c16683589..f8a5e976b5e6 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,6 +23,9 @@ struct wm_hubs_data {
int dcs_codes;
int dcs_readback_mode;
int hp_startup_mode;
+
+ bool class_w;
+ u16 class_w_dcs;
};
extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index bc9e6b0b3f6f..24b031e26342 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/dma.h>
#include <asm/mach-types.h>
@@ -132,26 +131,27 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add davinci-evm specific widgets */
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* Set up davinci-evm specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* not connected */
- snd_soc_dapm_disable_pin(codec, "MONO_LOUT");
- snd_soc_dapm_disable_pin(codec, "HPLCOM");
- snd_soc_dapm_disable_pin(codec, "HPRCOM");
+ snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_disable_pin(dapm, "HPLCOM");
+ snd_soc_dapm_disable_pin(dapm, "HPRCOM");
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 6c6666a1f942..0fe558c65145 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/dma.h>
#include <asm/mach-types.h>
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 4f4873359613..9ac93f6b4f85 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -352,13 +352,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
.playback = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.capture = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 2f121ddbe4bb..06670776f649 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.rate_min = SNDRV_PCM_RATE_8000,
- .rate_max = SNDRV_PCM_RATE_48000,
+ .rate_max = SNDRV_PCM_RATE_96000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index 28ab5ff772ac..dfe1d7f74ea6 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -15,7 +15,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -79,11 +78,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index dd4fffdbd177..e20c9e1457c0 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include "../codecs/tlv320aic23.h"
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 390b6ffc2658..30894ea7f333 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -456,13 +456,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
static struct snd_soc_dai_driver imx_ssi_dai = {
.probe = imx_ssi_dai_probe,
.playback = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.capture = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 9eabc28667e6..a7deb5cb2433 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -17,7 +17,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
static struct snd_soc_card imx_phycore;
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index 30fdb15065be..75b4c72787e2 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audmux.h>
@@ -213,11 +212,12 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
+ snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
ARRAY_SIZE(wm1133_ev1_widgets));
- snd_soc_dapm_add_routes(codec, wm1133_ev1_map,
+ snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
ARRAY_SIZE(wm1133_ev1_map));
/* Headphone jack detection */
@@ -234,7 +234,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
SND_JACK_BTN_0);
- snd_soc_dapm_force_enable_pin(codec, "Mic Bias");
+ snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
return 0;
}
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index f3cffd183401..419bf4f5534a 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -28,7 +28,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "jz4740-i2s.h"
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index ef1a99e6a3bd..49723e3e7e38 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -19,7 +19,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <linux/gpio.h>
#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
@@ -59,10 +58,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_nc_pin(codec, "LIN");
- snd_soc_dapm_nc_pin(codec, "RIN");
+ snd_soc_dapm_nc_pin(dapm, "LIN");
+ snd_soc_dapm_nc_pin(dapm, "RIN");
ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
if (ret < 0) {
@@ -70,9 +70,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
- snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets));
- snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
+ ARRAY_SIZE(qi_lb60_widgets));
+ snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
+ ARRAY_SIZE(qi_lb60_routes));
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 16ec2a2dba4d..8f49e165f4d1 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -11,10 +11,19 @@ config SND_KIRKWOOD_SOC_I2S
config SND_KIRKWOOD_SOC_OPENRD
tristate "SoC Audio support for Kirkwood Openrd Client"
- depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT
+ depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE)
select SND_KIRKWOOD_SOC_I2S
select SND_SOC_CS42L51
help
Say Y if you want to add support for SoC audio on
Openrd Client.
+config SND_KIRKWOOD_SOC_T5325
+ tristate "SoC Audio support for HP t5325"
+ depends on SND_KIRKWOOD_SOC && MACH_T5325
+ select SND_KIRKWOOD_SOC_I2S
+ select SND_SOC_ALC5623
+ help
+ Say Y if you want to add support for SoC audio on
+ the HP t5325 thin client.
+
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
index 33a16dcab5b5..3e62ae9e7bbe 100644
--- a/sound/soc/kirkwood/Makefile
+++ b/sound/soc/kirkwood/Makefile
@@ -5,5 +5,7 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
snd-soc-openrd-objs := kirkwood-openrd.o
+snd-soc-t5325-objs := kirkwood-t5325.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
+obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 9d7c81e921f1..d863afb3ee52 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -86,7 +86,7 @@ static int __init openrd_client_init(void)
{
int ret;
- if (!machine_is_openrd_client())
+ if (!machine_is_openrd_client() && !machine_is_openrd_ultimate())
return 0;
openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
new file mode 100644
index 000000000000..c8d21956ab52
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -0,0 +1,141 @@
+/*
+ * kirkwood-t5325.c
+ *
+ * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <mach/kirkwood.h>
+#include <plat/audio.h>
+#include <asm/mach-types.h>
+#include "../codecs/alc5623.h"
+
+static int t5325_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret;
+ unsigned int freq, fmt;
+
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0)
+ return ret;
+
+ freq = params_rate(params) * 256;
+
+ return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
+
+}
+
+static struct snd_soc_ops t5325_ops = {
+ .hw_params = t5325_hw_params,
+};
+
+static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route t5325_route[] = {
+ { "Headphone Jack", NULL, "HPL" },
+ { "Headphone Jack", NULL, "HPR" },
+
+ {"Speaker", NULL, "SPKOUT"},
+ {"Speaker", NULL, "SPKOUTN"},
+
+ { "MIC1", NULL, "Mic Jack" },
+ { "MIC2", NULL, "Mic Jack" },
+};
+
+static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets,
+ ARRAY_SIZE(t5325_dapm_widgets));
+
+ snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route));
+
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
+
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link t5325_dai[] = {
+{
+ .name = "ALC5621",
+ .stream_name = "ALC5621 HiFi",
+ .cpu_dai_name = "kirkwood-i2s",
+ .platform_name = "kirkwood-pcm-audio",
+ .codec_dai_name = "alc5621-hifi",
+ .codec_name = "alc562x-codec.0-001a",
+ .ops = &t5325_ops,
+ .init = t5325_dai_init,
+},
+};
+
+
+static struct snd_soc_card t5325 = {
+ .name = "t5325",
+ .dai_link = t5325_dai,
+ .num_links = ARRAY_SIZE(t5325_dai),
+};
+
+static struct platform_device *t5325_snd_device;
+
+static int __init t5325_init(void)
+{
+ int ret;
+
+ if (!machine_is_t5325())
+ return 0;
+
+ t5325_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!t5325_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(t5325_snd_device,
+ &t5325);
+
+ ret = platform_device_add(t5325_snd_device);
+ if (ret) {
+ printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
+ platform_device_put(t5325_snd_device);
+ }
+
+ return ret;
+}
+module_init(t5325_init);
+
+static void __exit t5325_exit(void)
+{
+ platform_device_unregister(t5325_snd_device);
+}
+module_exit(t5325_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
index 161f5b667d7b..38a2d0d883b5 100644
--- a/sound/soc/nuc900/nuc900-audio.c
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "nuc900-audio.h"
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 979dd508305f..161750443ebc 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -114,20 +113,21 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add am3517-evm specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up davinci-evm specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic In");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 438146addbb8..2101bdcee21f 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -26,7 +26,7 @@
#include <linux/spinlock.h>
#include <linux/tty.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -94,6 +94,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
unsigned short pins;
int pin, changed = 0;
@@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
/* Setup pins after corresponding bits if changed */
pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
else
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
}
pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
else
- snd_soc_dapm_disable_pin(codec, "Earpiece");
+ snd_soc_dapm_disable_pin(dapm, "Earpiece");
}
pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Microphone");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
else
- snd_soc_dapm_disable_pin(codec, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Microphone");
}
pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
}
pin = !!(pins & (1 << AMS_DELTA_AGC));
if (pin != ams_delta_audio_agc) {
ams_delta_audio_agc = pin;
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "AGCIN");
+ snd_soc_dapm_enable_pin(dapm, "AGCIN");
else
- snd_soc_dapm_disable_pin(codec, "AGCIN");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
}
if (changed)
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
mutex_unlock(&codec->mutex);
@@ -164,19 +165,20 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned short pins, mode;
- pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") <<
+ pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
AMS_DELTA_MOUTHPIECE) |
- (snd_soc_dapm_get_pin_status(codec, "Earpiece") <<
+ (snd_soc_dapm_get_pin_status(dapm, "Earpiece") <<
AMS_DELTA_EARPIECE));
if (pins)
- pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+ pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
AMS_DELTA_MICROPHONE);
else
- pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+ pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
AMS_DELTA_MICROPHONE) |
- (snd_soc_dapm_get_pin_status(codec, "Speaker") <<
+ (snd_soc_dapm_get_pin_status(dapm, "Speaker") <<
AMS_DELTA_SPEAKER) |
(ams_delta_audio_agc << AMS_DELTA_AGC));
@@ -300,6 +302,7 @@ static int cx81801_open(struct tty_struct *tty)
static void cx81801_close(struct tty_struct *tty)
{
struct snd_soc_codec *codec = tty->disc_data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
del_timer_sync(&cx81801_timer);
@@ -312,12 +315,12 @@ static void cx81801_close(struct tty_struct *tty)
v253_ops.close(tty);
/* Revert back to default audio input/output constellation */
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
- snd_soc_dapm_enable_pin(codec, "Earpiece");
- snd_soc_dapm_enable_pin(codec, "Microphone");
- snd_soc_dapm_disable_pin(codec, "Speaker");
- snd_soc_dapm_disable_pin(codec, "AGCIN");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
+ snd_soc_dapm_sync(dapm);
}
/* Line discipline .hangup() */
@@ -432,16 +435,16 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card,
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
AMS_DELTA_LATCH2_MODEM_NRESET);
break;
case SND_SOC_BIAS_OFF:
- if (codec->bias_level != SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level != SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
0);
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -492,6 +495,7 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_card *card = rtd->card;
int ret;
@@ -541,7 +545,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Add board specific DAPM widgets and routes */
- ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
ARRAY_SIZE(ams_delta_dapm_widgets));
if (ret) {
dev_warn(card->dev,
@@ -550,7 +554,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
- ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map,
+ ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
ARRAY_SIZE(ams_delta_audio_map));
if (ret) {
dev_warn(card->dev,
@@ -560,13 +564,13 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Set up initial pin constellation */
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
- snd_soc_dapm_enable_pin(codec, "Earpiece");
- snd_soc_dapm_enable_pin(codec, "Microphone");
- snd_soc_dapm_disable_pin(codec, "Speaker");
- snd_soc_dapm_disable_pin(codec, "AGCIN");
- snd_soc_dapm_disable_pin(codec, "AGCOUT");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
+ snd_soc_dapm_disable_pin(dapm, "AGCOUT");
+ snd_soc_dapm_sync(dapm);
/* Add virtual switch */
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 fd3a40f309c8..0ae34702995b 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a3b6d897ad84..fe215f3e8afc 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -27,7 +27,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -58,6 +57,7 @@ static int n810_dmic_func;
static void n810_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int hp = 0, line1l = 0;
switch (n810_jack_func) {
@@ -72,25 +72,25 @@ static void n810_ext_control(struct snd_soc_codec *codec)
}
if (n810_spk_func)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
if (hp)
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
else
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
if (line1l)
- snd_soc_dapm_enable_pin(codec, "LINE1L");
+ snd_soc_dapm_enable_pin(dapm, "LINE1L");
else
- snd_soc_dapm_disable_pin(codec, "LINE1L");
+ snd_soc_dapm_disable_pin(dapm, "LINE1L");
if (n810_dmic_func)
- snd_soc_dapm_enable_pin(codec, "DMic");
+ snd_soc_dapm_enable_pin(dapm, "DMic");
else
- snd_soc_dapm_disable_pin(codec, "DMic");
+ snd_soc_dapm_disable_pin(dapm, "DMic");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int n810_startup(struct snd_pcm_substream *substream)
@@ -274,17 +274,18 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Not connected */
- snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
- snd_soc_dapm_nc_pin(codec, "HPLCOM");
- snd_soc_dapm_nc_pin(codec, "HPRCOM");
- snd_soc_dapm_nc_pin(codec, "MIC3L");
- snd_soc_dapm_nc_pin(codec, "MIC3R");
- snd_soc_dapm_nc_pin(codec, "LINE1R");
- snd_soc_dapm_nc_pin(codec, "LINE2L");
- snd_soc_dapm_nc_pin(codec, "LINE2R");
+ snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_nc_pin(dapm, "HPLCOM");
+ snd_soc_dapm_nc_pin(dapm, "HPRCOM");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L");
+ snd_soc_dapm_nc_pin(dapm, "MIC3R");
+ snd_soc_dapm_nc_pin(dapm, "LINE1R");
+ snd_soc_dapm_nc_pin(dapm, "LINE2L");
+ snd_soc_dapm_nc_pin(dapm, "LINE2R");
/* Add N810 specific controls */
err = snd_soc_add_controls(codec, aic33_n810_controls,
@@ -293,13 +294,13 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add N810 specific widgets */
- snd_soc_dapm_new_controls(codec, aic33_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets,
ARRAY_SIZE(aic33_dapm_widgets));
/* Set up N810 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index cf3fc8a675b5..29b60d6796e7 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index e56832b0c444..40db813c0795 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 810f1e36da21..0daa04469836 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 4ee33ce2cb98..8047c521e318 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -28,7 +28,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <plat/mcbsp.h>
@@ -170,51 +169,53 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* All TWL4030 output pins are floating */
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "HSOL");
- snd_soc_dapm_nc_pin(codec, "HSOR");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
- snd_soc_dapm_nc_pin(codec, "HFL");
- snd_soc_dapm_nc_pin(codec, "HFR");
- snd_soc_dapm_nc_pin(codec, "VIBRA");
-
- ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "HSOL");
+ snd_soc_dapm_nc_pin(dapm, "HSOR");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+ snd_soc_dapm_nc_pin(dapm, "HFL");
+ snd_soc_dapm_nc_pin(dapm, "HFR");
+ snd_soc_dapm_nc_pin(dapm, "VIBRA");
+
+ ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets,
ARRAY_SIZE(omap3pandora_out_dapm_widgets));
if (ret < 0)
return ret;
- snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
+ snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
ARRAY_SIZE(omap3pandora_out_map));
- return snd_soc_dapm_sync(codec);
+ return snd_soc_dapm_sync(dapm);
}
static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Not comnnected */
- snd_soc_dapm_nc_pin(codec, "HSMIC");
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
+ snd_soc_dapm_nc_pin(dapm, "HSMIC");
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
- ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets,
ARRAY_SIZE(omap3pandora_in_dapm_widgets));
if (ret < 0)
return ret;
- snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
+ snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
ARRAY_SIZE(omap3pandora_in_map));
- return snd_soc_dapm_sync(codec);
+ return snd_soc_dapm_sync(dapm);
}
static struct snd_soc_ops omap3pandora_ops = {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 65ae00e976ef..7e75e775fb4a 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -116,19 +115,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add osk5912 specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up osk5912 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index e95a607937de..bbcf380bfb56 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 04b5723bf89b..150042a785d0 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -30,7 +30,6 @@
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/mcbsp.h>
#include <asm/mach-types.h>
@@ -58,19 +57,21 @@ static int rx51_jack_func;
static void rx51_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (rx51_spk_func)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
if (rx51_dmic_func)
- snd_soc_dapm_enable_pin(codec, "DMic");
+ snd_soc_dapm_enable_pin(dapm, "DMic");
else
- snd_soc_dapm_disable_pin(codec, "DMic");
+ snd_soc_dapm_disable_pin(dapm, "DMic");
gpio_set_value(RX51_TVOUT_SEL_GPIO,
rx51_jack_func == RX51_JACK_TVOUT);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int rx51_startup(struct snd_pcm_substream *substream)
@@ -244,12 +245,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "MIC3L");
- snd_soc_dapm_nc_pin(codec, "MIC3R");
- snd_soc_dapm_nc_pin(codec, "LINE1R");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L");
+ snd_soc_dapm_nc_pin(dapm, "MIC3R");
+ snd_soc_dapm_nc_pin(dapm, "LINE1R");
/* Add RX-51 specific controls */
err = snd_soc_add_controls(codec, aic34_rx51_controls,
@@ -258,13 +260,13 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add RX-51 specific widgets */
- snd_soc_dapm_new_controls(codec, aic34_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
ARRAY_SIZE(aic34_dapm_widgets));
/* Set up RX-51 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
/* AV jack detection */
err = snd_soc_jack_new(codec, "AV Jack",
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 07fbcf7d2411..3f72d17d1ef0 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -28,7 +28,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -191,39 +190,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add SDP3430 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets,
ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
if (ret)
return ret;
/* Set up SDP3430 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* SDP3430 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
/* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(codec, "AUXL");
- snd_soc_dapm_nc_pin(codec, "AUXR");
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
-
- snd_soc_dapm_nc_pin(codec, "OUTL");
- snd_soc_dapm_nc_pin(codec, "OUTR");
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
-
- ret = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "AUXL");
+ snd_soc_dapm_nc_pin(dapm, "AUXR");
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
+
+ snd_soc_dapm_nc_pin(dapm, "OUTL");
+ snd_soc_dapm_nc_pin(dapm, "OUTR");
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 4b4463db6ba0..ebbd62fc447c 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <plat/hardware.h>
@@ -129,6 +128,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add SDP4430 specific controls */
@@ -138,25 +138,25 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
return ret;
/* Add SDP4430 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
if (ret)
return ret;
/* Set up SDP4430 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* SDP4430 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
/* TWL6040 not connected pins */
- snd_soc_dapm_nc_pin(codec, "AFML");
- snd_soc_dapm_nc_pin(codec, "AFMR");
+ snd_soc_dapm_nc_pin(dapm, "AFML");
+ snd_soc_dapm_nc_pin(dapm, "AFMR");
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
return ret;
}
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 718031eeac34..01709940a43c 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -162,35 +161,36 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add Zoom2 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets,
ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
if (ret)
return ret;
/* Set up Zoom2 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* Zoom2 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
- snd_soc_dapm_enable_pin(codec, "Aux In");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Aux In");
/* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
-
- ret = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+
+ ret = snd_soc_dapm_sync(dapm);
return ret;
}
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index f451acd4935b..fc592f0d5fc7 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/corgi.h>
@@ -48,51 +47,53 @@ static int corgi_spk_func;
static void corgi_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
switch (corgi_jack_func) {
case CORGI_HP:
/* set = unmute headphone */
gpio_set_value(CORGI_GPIO_MUTE_L, 1);
gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_MIC:
/* reset = mute headphone */
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_LINE:
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_HEADSET:
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
break;
}
if (corgi_spk_func == CORGI_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int corgi_startup(struct snd_pcm_substream *substream)
@@ -279,10 +280,11 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
/* Add corgi specific controls */
err = snd_soc_add_controls(codec, wm8731_corgi_controls,
@@ -291,13 +293,13 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add corgi specific widgets */
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
ARRAY_SIZE(wm8731_dapm_widgets));
/* Set up corgi specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index c82cedb602fd..28333e7d9c50 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audio.h>
#include <mach/eseries-gpio.h>
@@ -92,23 +91,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
-
- snd_soc_dapm_nc_pin(codec, "HPOUTL");
- snd_soc_dapm_nc_pin(codec, "HPOUTR");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "CDINL");
- snd_soc_dapm_nc_pin(codec, "CDINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- snd_soc_dapm_new_controls(codec, e740_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_nc_pin(dapm, "HPOUTL");
+ snd_soc_dapm_nc_pin(dapm, "HPOUTR");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "CDINL");
+ snd_soc_dapm_nc_pin(dapm, "CDINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ snd_soc_dapm_new_controls(dapm, e740_dapm_widgets,
ARRAY_SIZE(e740_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 4c143803a75e..01bf31675c55 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audio.h>
#include <mach/eseries-gpio.h>
@@ -74,23 +73,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
-
- snd_soc_dapm_nc_pin(codec, "LOUT");
- snd_soc_dapm_nc_pin(codec, "ROUT");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "CDINL");
- snd_soc_dapm_nc_pin(codec, "CDINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- snd_soc_dapm_new_controls(codec, e750_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_nc_pin(dapm, "LOUT");
+ snd_soc_dapm_nc_pin(dapm, "ROUT");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "CDINL");
+ snd_soc_dapm_nc_pin(dapm, "CDINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ snd_soc_dapm_new_controls(dapm, e750_dapm_widgets,
ARRAY_SIZE(e750_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index d42e5fe832c5..c6a37c6ef23b 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/audio.h>
@@ -75,12 +74,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, e800_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, e800_dapm_widgets,
ARRAY_SIZE(e800_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index eadf9d351a04..fc22e6eefc98 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/audio.h>
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 5ef0526924b9..67dcc36cd621 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/uda1380.h>
#include <mach/magician.h>
@@ -44,27 +43,29 @@ static int magician_in_sel = MAGICIAN_MIC;
static void magician_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (magician_spk_switch)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
if (magician_hp_switch)
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
else
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
switch (magician_in_sel) {
case MAGICIAN_MIC:
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case MAGICIAN_MIC_EXT:
- snd_soc_dapm_disable_pin(codec, "Call Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
break;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int magician_startup(struct snd_pcm_substream *substream)
@@ -399,15 +400,16 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* NC codec pins */
- snd_soc_dapm_nc_pin(codec, "VOUTLHP");
- snd_soc_dapm_nc_pin(codec, "VOUTRHP");
+ snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
+ snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
/* FIXME: is anything connected here? */
- snd_soc_dapm_nc_pin(codec, "VINL");
- snd_soc_dapm_nc_pin(codec, "VINR");
+ snd_soc_dapm_nc_pin(dapm, "VINL");
+ snd_soc_dapm_nc_pin(dapm, "VINR");
/* Add magician specific controls */
err = snd_soc_add_controls(codec, uda1380_magician_controls,
@@ -416,13 +418,13 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add magician specific widgets */
- snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
ARRAY_SIZE(uda1380_dapm_widgets));
/* Set up magician specific audio path interconnects */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index f284cc54bc80..0d70fc8c12bd 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -50,7 +50,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/ac97_codec.h>
@@ -130,13 +129,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned short reg;
/* Add mioa701 specific widgets */
- snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets));
+ snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
/* Set up mioa701 specific audio path audio_mapnects */
- snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
/* Prepare GPIO8 for rear speaker amplifier */
reg = codec->driver->read(codec, AC97_GPIO_CFG);
@@ -146,12 +146,12 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
reg = codec->driver->read(codec, AC97_3D_CONTROL);
codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
- snd_soc_dapm_enable_pin(codec, "Front Speaker");
- snd_soc_dapm_enable_pin(codec, "Rear Speaker");
- snd_soc_dapm_enable_pin(codec, "Front Mic");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(dapm, "Front Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Rear Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Front Mic");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 13f6d485d571..857db96d4a4f 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -77,37 +76,38 @@ static struct snd_soc_card palm27x_asoc;
static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* add palm27x specific widgets */
- err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
ARRAY_SIZE(palm27x_dapm_widgets));
if (err)
return err;
/* set up palm27x specific audio path audio_map */
- err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (err)
return err;
/* connected pins */
if (machine_is_palmld())
- snd_soc_dapm_enable_pin(codec, "MIC1");
- snd_soc_dapm_enable_pin(codec, "HPOUTL");
- snd_soc_dapm_enable_pin(codec, "HPOUTR");
- snd_soc_dapm_enable_pin(codec, "LOUT2");
- snd_soc_dapm_enable_pin(codec, "ROUT2");
+ snd_soc_dapm_enable_pin(dapm, "MIC1");
+ snd_soc_dapm_enable_pin(dapm, "HPOUTL");
+ snd_soc_dapm_enable_pin(dapm, "HPOUTR");
+ snd_soc_dapm_enable_pin(dapm, "LOUT2");
+ snd_soc_dapm_enable_pin(dapm, "ROUT2");
/* not connected pins */
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONOOUT");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- err = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONOOUT");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ err = snd_soc_dapm_sync(dapm);
if (err)
return err;
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 84edd0385a21..6298ee115e27 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <asm/hardware/locomo.h>
@@ -46,6 +45,8 @@ static int poodle_spk_func;
static void poodle_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
if (poodle_jack_func == POODLE_HP) {
/* set = unmute headphone */
@@ -53,23 +54,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
POODLE_LOCOMO_GPIO_MUTE_L, 1);
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
} else {
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_L, 0);
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
}
/* set the enpoints to their new connetion states */
if (poodle_spk_func == POODLE_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int poodle_startup(struct snd_pcm_substream *substream)
@@ -244,11 +245,12 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
- snd_soc_dapm_enable_pin(codec, "MICIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
+ snd_soc_dapm_enable_pin(dapm, "MICIN");
/* Add poodle specific controls */
err = snd_soc_add_controls(codec, wm8731_poodle_controls,
@@ -257,13 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add poodle specific widgets */
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
ARRAY_SIZE(wm8731_dapm_widgets));
/* Set up poodle specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 2cda82bc5d2e..0fd60f423036 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -22,7 +22,6 @@
#include <linux/gpio.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index d63cb474b4e1..9595189fc681 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_saarb = {
static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_new_controls(codec, saarb_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets,
ARRAY_SIZE(saarb_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Speaker");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 1");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 3");
- snd_soc_dapm_disable_pin(codec, "Headset Mic 2");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 0b30d7de24ec..c2acb69b957a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/spitz.h>
@@ -46,61 +45,63 @@ static int spitz_spk_func;
static void spitz_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (spitz_spk_func == SPITZ_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* set up jack connection */
switch (spitz_jack_func) {
case SPITZ_HP:
/* enable and unmute hp jack, disable mic bias */
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
break;
case SPITZ_MIC:
/* enable mic jack and bias, mute hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
case SPITZ_LINE:
/* enable line jack, disable mic bias and mute hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
case SPITZ_HEADSET:
/* enable and unmute headset jack enable mic bias, mute L hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
break;
case SPITZ_HP_OFF:
/* jack removed, everything off */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int spitz_startup(struct snd_pcm_substream *substream)
@@ -281,16 +282,17 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* NC codec pins */
- snd_soc_dapm_nc_pin(codec, "RINPUT1");
- snd_soc_dapm_nc_pin(codec, "LINPUT2");
- snd_soc_dapm_nc_pin(codec, "RINPUT2");
- snd_soc_dapm_nc_pin(codec, "LINPUT3");
- snd_soc_dapm_nc_pin(codec, "RINPUT3");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONO1");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONO1");
/* Add spitz specific controls */
err = snd_soc_add_controls(codec, wm8750_spitz_controls,
@@ -299,13 +301,13 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add spitz specific widgets */
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
/* Set up spitz specific audio paths */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index 248c283fc4df..f881f65ec172 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_evb3 = {
static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_new_controls(codec, evb3_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets,
ARRAY_SIZE(evb3_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Speaker");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 1");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 3");
- snd_soc_dapm_disable_pin(codec, "Headset Mic 2");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 7b983f935454..f75804ef0897 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/tosa.h>
@@ -49,31 +48,33 @@ static int tosa_spk_func;
static void tosa_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
switch (tosa_jack_func) {
case TOSA_HP:
- snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case TOSA_MIC_INT:
- snd_soc_dapm_enable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case TOSA_HEADSET:
- snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
break;
}
if (tosa_spk_func == TOSA_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int tosa_startup(struct snd_pcm_substream *substream)
@@ -191,10 +192,11 @@ static const struct snd_kcontrol_new tosa_controls[] = {
static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONOOUT");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONOOUT");
/* add tosa specific controls */
err = snd_soc_add_controls(codec, tosa_controls,
@@ -203,13 +205,13 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* add tosa specific widgets */
- snd_soc_dapm_new_controls(codec, tosa_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
ARRAY_SIZE(tosa_dapm_widgets));
/* set up tosa specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4cc841b44182..2d4f896d7fec 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -140,22 +139,23 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* NC codec pins */
- snd_soc_dapm_disable_pin(codec, "LINPUT3");
- snd_soc_dapm_disable_pin(codec, "RINPUT3");
- snd_soc_dapm_disable_pin(codec, "OUT3");
- snd_soc_dapm_disable_pin(codec, "MONO");
+ snd_soc_dapm_disable_pin(dapm, "LINPUT3");
+ snd_soc_dapm_disable_pin(dapm, "RINPUT3");
+ snd_soc_dapm_disable_pin(dapm, "OUT3");
+ snd_soc_dapm_disable_pin(dapm, "MONO");
/* Add z2 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
/* Set up z2 specific audio paths */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
goto err;
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index d27e05af7759..b222a7d72027 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "../codecs/wm9713.h"
#include "pxa2xx-ac97.h"
@@ -73,21 +72,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
if (clk_pout)
snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
clk_get_rate(pout), 0);
- snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
ARRAY_SIZE(zylonite_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* Static setup for now */
- snd_soc_dapm_enable_pin(codec, "Headphone");
- snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Headphone");
+ snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
deleted file mode 100644
index d85bf8a0abb2..000000000000
--- a/sound/soc/s3c24xx/Kconfig
+++ /dev/null
@@ -1,171 +0,0 @@
-config SND_S3C24XX_SOC
- tristate "SoC Audio for the Samsung S3CXXXX chips"
- depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
- select S3C64XX_DMA if ARCH_S3C64XX
- select S3C2410_DMA if ARCH_S3C2410
- help
- Say Y or M if you want to add support for codecs attached to
- the S3C24XX AC97 or I2S interfaces. You will also need to
- select the audio interfaces to support below.
-
-config SND_S3C24XX_SOC_I2S
- tristate
- select S3C2410_DMA
-
-config SND_S3C_I2SV2_SOC
- tristate
-
-config SND_S3C2412_SOC_I2S
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C2410_DMA
-
-config SND_S3C64XX_SOC_I2S
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C64XX_DMA
-
-config SND_S3C64XX_SOC_I2S_V4
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C64XX_DMA
-
-config SND_S3C_SOC_PCM
- tristate
-
-config SND_S3C_SOC_AC97
- tristate
- select SND_SOC_AC97_BUS
-
-config SND_S5P_SOC_SPDIF
- tristate
- select SND_SOC_SPDIF
-
-config SND_S3C24XX_SOC_NEO1973_WM8753
- tristate "SoC I2S Audio support for NEO1973 - WM8753"
- depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_WM8753
- help
- Say Y if you want to add support for SoC audio on smdk2440
- with the WM8753.
-
-config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753
- tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
- depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_WM8753
- help
- This driver provides audio support for the Openmoko Neo FreeRunner
- smartphone.
-
-config SND_S3C24XX_SOC_JIVE_WM8750
- tristate "SoC I2S Audio support for Jive"
- depends on SND_S3C24XX_SOC && MACH_JIVE
- select SND_SOC_WM8750
- select SND_S3C2412_SOC_I2S
- help
- Sat Y if you want to add support for SoC audio on the Jive.
-
-config SND_S3C64XX_SOC_WM8580
- tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
- depends on SND_S3C24XX_SOC && MACH_SMDK6410
- select SND_SOC_WM8580
- select SND_S3C64XX_SOC_I2S_V4
- help
- Say Y if you want to add support for SoC audio on the SMDK6410.
-
-config SND_S3C24XX_SOC_SMDK2443_WM9710
- tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
- depends on SND_S3C24XX_SOC && MACH_SMDK2443
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_S3C_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on smdk2443
- with the WM9710.
-
-config SND_S3C24XX_SOC_LN2440SBC_ALC650
- tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_S3C_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on ln2440sbc
- with the ALC650.
-
-config SND_S3C24XX_SOC_S3C24XX_UDA134X
- tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_L3
- select SND_SOC_UDA134X
-
-config SND_S3C24XX_SOC_SIMTEC
- tristate
- help
- Internal node for common S3C24XX/Simtec suppor
-
-config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23
- tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_TLV320AIC23
- select SND_S3C24XX_SOC_SIMTEC
-
-config SND_S3C24XX_SOC_SIMTEC_HERMES
- tristate "SoC I2S Audio support for Simtec Hermes board"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_TLV320AIC3X
- select SND_S3C24XX_SOC_SIMTEC
-
-config SND_S3C24XX_SOC_RX1950_UDA1380
- tristate "Audio support for the HP iPAQ RX1950"
- depends on SND_S3C24XX_SOC && MACH_RX1950
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_UDA1380
- help
- This driver provides audio support for HP iPAQ RX1950 PDA.
-
-config SND_SOC_SMDK_WM9713
- tristate "SoC AC97 Audio support for SMDK with WM9713"
- depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
- select SND_SOC_WM9713
- select SND_S3C_SOC_AC97
- help
- Sat Y if you want to add support for SoC audio on the SMDK.
-
-config SND_S3C64XX_SOC_SMARTQ
- tristate "SoC I2S Audio support for SmartQ board"
- depends on SND_S3C24XX_SOC && MACH_SMARTQ
- select SND_S3C64XX_SOC_I2S
- select SND_SOC_WM8750
-
-config SND_S5PC110_SOC_AQUILA_WM8994
- tristate "SoC I2S Audio support for AQUILA - WM8994"
- depends on SND_S3C24XX_SOC && MACH_AQUILA
- select SND_S3C64XX_SOC_I2S_V4
- select SND_SOC_WM8994
- help
- Say Y if you want to add support for SoC audio on aquila
- with the WM8994.
-
-config SND_S5PV210_SOC_GONI_WM8994
- tristate "SoC I2S Audio support for GONI - WM8994"
- depends on SND_S3C24XX_SOC && MACH_GONI
- select SND_S3C64XX_SOC_I2S_V4
- select SND_SOC_WM8994
- help
- Say Y if you want to add support for SoC audio on goni
- with the WM8994.
-
-config SND_SOC_SMDK_SPDIF
- tristate "SoC S/PDIF Audio support for SMDK"
- depends on SND_S3C24XX_SOC && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
- select SND_S5P_SOC_SPDIF
- help
- Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
deleted file mode 100644
index ee8f41d6df99..000000000000
--- a/sound/soc/s3c24xx/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# S3c24XX Platform Support
-snd-soc-s3c24xx-objs := s3c-dma.o
-snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
-snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
-snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
-snd-soc-s3c-ac97-objs := s3c-ac97.o
-snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o
-snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
-snd-soc-s3c-pcm-objs := s3c-pcm.o
-snd-soc-samsung-spdif-objs := spdif.o
-
-obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
-obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
-obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
-obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
-obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
-obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o
-obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
-obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
-obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o
-
-# S3C24XX Machine Support
-snd-soc-jive-wm8750-objs := jive_wm8750.o
-snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
-snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
-snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
-snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
-snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
-snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
-snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
-snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
-snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
-snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
-snd-soc-smdk-wm9713-objs := smdk_wm9713.o
-snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
-snd-soc-aquila-wm8994-objs := aquila_wm8994.o
-snd-soc-goni-wm8994-objs := goni_wm8994.o
-snd-soc-smdk-spdif-objs := smdk_spdif.o
-
-obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
-obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
-obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
-obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
-obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
-obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
-obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
-obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
-obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
-obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o
-obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o
-obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o
diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c
deleted file mode 100644
index 235d1973f7d0..000000000000
--- a/sound/soc/s3c24xx/aquila_wm8994.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * aquila_wm8994.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <asm/mach-types.h>
-#include <mach/gpio.h>
-#include <mach/regs-clock.h>
-
-#include <linux/mfd/wm8994/core.h>
-#include <linux/mfd/wm8994/registers.h>
-#include "../codecs/wm8994.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
-
-static struct snd_soc_card aquila;
-static struct platform_device *aquila_snd_device;
-
-/* 3.5 pie jack */
-static struct snd_soc_jack jack;
-
-/* 3.5 pie jack detection DAPM pins */
-static struct snd_soc_jack_pin jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- }, {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- },
-};
-
-/* 3.5 pie jack detection gpios */
-static struct snd_soc_jack_gpio jack_gpios[] = {
- {
- .gpio = S5PV210_GPH0(6),
- .name = "DET_3.5",
- .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- .debounce_time = 200,
- },
-};
-
-static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_SPK("Ext Rcv", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Main Mic", NULL),
- SND_SOC_DAPM_MIC("2nd Mic", NULL),
- SND_SOC_DAPM_LINE("Radio In", NULL),
-};
-
-static const struct snd_soc_dapm_route aquila_dapm_routes[] = {
- {"Ext Spk", NULL, "SPKOUTLP"},
- {"Ext Spk", NULL, "SPKOUTLN"},
-
- {"Ext Rcv", NULL, "HPOUT2N"},
- {"Ext Rcv", NULL, "HPOUT2P"},
-
- {"Headset Stereophone", NULL, "HPOUT1L"},
- {"Headset Stereophone", NULL, "HPOUT1R"},
-
- {"IN1RN", NULL, "Headset Mic"},
- {"IN1RP", NULL, "Headset Mic"},
-
- {"IN1RN", NULL, "2nd Mic"},
- {"IN1RP", NULL, "2nd Mic"},
-
- {"IN1LN", NULL, "Main Mic"},
- {"IN1LP", NULL, "Main Mic"},
-
- {"IN2LN", NULL, "Radio In"},
- {"IN2RN", NULL, "Radio In"},
-};
-
-static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- int ret;
-
- /* add aquila specific widgets */
- snd_soc_dapm_new_controls(codec, aquila_dapm_widgets,
- ARRAY_SIZE(aquila_dapm_widgets));
-
- /* set up aquila specific audio routes */
- snd_soc_dapm_add_routes(codec, aquila_dapm_routes,
- ARRAY_SIZE(aquila_dapm_routes));
-
- /* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
- snd_soc_dapm_nc_pin(codec, "SPKOUTRN");
- snd_soc_dapm_nc_pin(codec, "SPKOUTRP");
-
- snd_soc_dapm_sync(codec);
-
- /* Headset jack detection */
- ret = snd_soc_jack_new(&aquila, "Headset Jack",
- SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
- &jack);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int aquila_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- /* set the cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the cpu system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops aquila_hifi_ops = {
- .hw_params = aquila_hifi_hw_params,
-};
-
-static int aquila_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- if (params_rate(params) != 8000)
- return -EINVAL;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_dai_driver voice_dai = {
- .name = "aquila-voice-dai",
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-};
-
-static struct snd_soc_ops aquila_voice_ops = {
- .hw_params = aquila_voice_hw_params,
-};
-
-static struct snd_soc_dai_link aquila_dai[] = {
-{
- .name = "WM8994",
- .stream_name = "WM8994 HiFi",
- .cpu_dai_name = "s3c64xx-i2s-v4",
- .codec_dai_name = "wm8994-hifi",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8994-codec.0-0x1a",
- .init = aquila_wm8994_init,
- .ops = &aquila_hifi_ops,
-}, {
- .name = "WM8994 Voice",
- .stream_name = "Voice",
- .cpu_dai_name = "aquila-voice-dai",
- .codec_dai_name = "wm8994-voice",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8994-codec.0-0x1a",
- .ops = &aquila_voice_ops,
-},
-};
-
-static struct snd_soc_card aquila = {
- .name = "aquila",
- .dai_link = aquila_dai,
- .num_links = ARRAY_SIZE(aquila_dai),
-};
-
-static int __init aquila_init(void)
-{
- int ret;
-
- if (!machine_is_aquila())
- return -ENODEV;
-
- aquila_snd_device = platform_device_alloc("soc-audio", -1);
- if (!aquila_snd_device)
- return -ENOMEM;
-
- /* register voice DAI here */
- ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai);
- if (ret)
- return ret;
-
- platform_set_drvdata(aquila_snd_device, &aquila);
- ret = platform_device_add(aquila_snd_device);
-
- if (ret)
- platform_device_put(aquila_snd_device);
-
- return ret;
-}
-
-static void __exit aquila_exit(void)
-{
- platform_device_unregister(aquila_snd_device);
-}
-
-module_init(aquila_init);
-module_exit(aquila_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)");
-MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
deleted file mode 100644
index a9628472ebfe..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c
- *
- * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include "s3c-dma.h"
-#include "regs-i2s-v2.h"
-#include "s3c64xx-i2s.h"
-
-static struct s3c2410_dma_client s3c64xx_dma_client_out = {
- .name = "I2Sv4 PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c64xx_dma_client_in = {
- .name = "I2Sv4 PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
-static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
-static struct s3c_i2sv2_info s3c64xx_i2sv4;
-
-static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
- int ret = 0;
-
- snd_soc_dai_set_drvdata(dai, i2s);
-
- ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
-
- return ret;
-}
-
-static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- struct s3c_dma_params *dma_data;
- u32 iismod;
-
- dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = i2s->dma_playback;
- else
- dma_data = i2s->dma_capture;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);
-
- iismod &= ~S3C64XX_IISMOD_BLC_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- iismod |= S3C64XX_IISMOD_BLC_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iismod |= S3C64XX_IISMOD_BLC_24BIT;
- break;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);
-
- return 0;
-}
-
-static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
- .hw_params = s3c_i2sv4_hw_params,
-};
-
-static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = {
- .symmetric_rates = 1,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
- },
- .probe = s3c64xx_i2sv4_probe,
- .ops = &s3c64xx_i2sv4_dai_ops,
-};
-
-static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
-{
- struct s3c_audio_pdata *i2s_pdata;
- struct s3c_i2sv2_info *i2s;
- struct resource *res;
- int ret;
-
- i2s = &s3c64xx_i2sv4;
-
- i2s->feature |= S3C_FEATURE_CDCLKCON;
-
- i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
- i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_playback->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_capture->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(res->start, resource_size(res),
- "s3c64xx-i2s-v4")) {
- dev_err(&pdev->dev, "Unable to request SFR region\n");
- return -EBUSY;
- }
- i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
- i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
-
- i2s->dma_capture->client = &s3c64xx_dma_client_in;
- i2s->dma_capture->dma_size = 4;
- i2s->dma_playback->client = &s3c64xx_dma_client_out;
- i2s->dma_playback->dma_size = 4;
-
- i2s->base = res->start;
-
- i2s_pdata = pdev->dev.platform_data;
- if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- return -EINVAL;
- }
-
- i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
- if (IS_ERR(i2s->iis_cclk)) {
- dev_err(&pdev->dev, "failed to get audio-bus\n");
- ret = PTR_ERR(i2s->iis_cclk);
- goto err;
- }
-
- clk_enable(i2s->iis_cclk);
-
- ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai);
- if (ret != 0)
- goto err_i2sv2;
-
- return 0;
-
-err_i2sv2:
- clk_put(i2s->iis_cclk);
-err:
- return ret;
-}
-
-static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
-{
- struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
- struct resource *res;
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_put(i2s->iis_cclk);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- else
- dev_warn(&pdev->dev, "Unable to get I2S SFR address\n");
-
- return 0;
-}
-
-static struct platform_driver s3c64xx_i2sv4_driver = {
- .probe = s3c64xx_i2sv4_dev_probe,
- .remove = s3c64xx_i2sv4_dev_remove,
- .driver = {
- .name = "s3c64xx-iis-v4",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c64xx_i2sv4_init(void)
-{
- return platform_driver_register(&s3c64xx_i2sv4_driver);
-}
-module_init(s3c64xx_i2sv4_init);
-
-static void __exit s3c64xx_i2sv4_exit(void)
-{
- platform_driver_unregister(&s3c64xx_i2sv4_driver);
-}
-module_exit(s3c64xx_i2sv4_exit);
-
-/* Module information */
-MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
-MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c64xx-iis-v4");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
deleted file mode 100644
index ae7acb6c4f1d..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s.c
- *
- * ALSA SoC Audio Layer - S3C64XX I2S driver
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <sound/soc.h>
-
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include "s3c-dma.h"
-#include "regs-i2s-v2.h"
-#include "s3c64xx-i2s.h"
-
-/* The value should be set to maximum of the total number
- * of I2Sv3 controllers that any supported SoC has.
- */
-#define MAX_I2SV3 2
-
-static struct s3c2410_dma_client s3c64xx_dma_client_out = {
- .name = "I2S PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c64xx_dma_client_in = {
- .name = "I2S PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
-static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
-static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
-
-struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
- u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
-
- if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
- return i2s->iis_cclk;
- else
- return i2s->iis_pclk;
-}
-EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
-
-static int s3c64xx_i2s_probe(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s;
- int ret;
-
- if (dai->id >= MAX_I2SV3) {
- dev_err(dai->dev, "id %d out of range\n", dai->id);
- return -EINVAL;
- }
-
- i2s = &s3c64xx_i2s[dai->id];
- snd_soc_dai_set_drvdata(dai, i2s);
-
- i2s->iis_cclk = clk_get(dai->dev, "audio-bus");
- if (IS_ERR(i2s->iis_cclk)) {
- dev_err(dai->dev, "failed to get audio-bus\n");
- ret = PTR_ERR(i2s->iis_cclk);
- goto err;
- }
-
- clk_enable(i2s->iis_cclk);
-
- ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
- if (ret)
- goto err_clk;
-
- return 0;
-
-err_clk:
- clk_disable(i2s->iis_cclk);
- clk_put(i2s->iis_cclk);
-err:
- kfree(i2s);
- return ret;
-}
-
-static int s3c64xx_i2s_remove(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
-
- clk_disable(i2s->iis_cclk);
- clk_put(i2s->iis_cclk);
- kfree(i2s);
- return 0;
-}
-
-static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
-
-static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = {
-{
- .name = "s3c64xx-i2s-0",
- .probe = s3c64xx_i2s_probe,
- .remove = s3c64xx_i2s_remove,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .ops = &s3c64xx_i2s_dai_ops,
- .symmetric_rates = 1,
-}, {
- .name = "s3c64xx-i2s-1",
- .probe = s3c64xx_i2s_probe,
- .remove = s3c64xx_i2s_remove,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .ops = &s3c64xx_i2s_dai_ops,
- .symmetric_rates = 1,
-},};
-
-static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
-{
- struct s3c_audio_pdata *i2s_pdata;
- struct s3c_i2sv2_info *i2s;
- struct resource *res;
- int i, ret;
-
- if (pdev->id >= MAX_I2SV3) {
- dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
- return -EINVAL;
- }
-
- i2s = &s3c64xx_i2s[pdev->id];
-
- i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
- i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_playback->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_capture->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(res->start, resource_size(res),
- "s3c64xx-i2s")) {
- dev_err(&pdev->dev, "Unable to request SFR region\n");
- return -EBUSY;
- }
- i2s->base = res->start;
-
- i2s_pdata = pdev->dev.platform_data;
- if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- return -EINVAL;
- }
- i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
- i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
-
- i2s->dma_capture->client = &s3c64xx_dma_client_in;
- i2s->dma_capture->dma_size = 4;
- i2s->dma_playback->client = &s3c64xx_dma_client_out;
- i2s->dma_playback->dma_size = 4;
-
- for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) {
- ret = s3c_i2sv2_register_dai(&pdev->dev, i,
- &s3c64xx_i2s_dai[i]);
- if (ret != 0)
- return ret;
- }
-
- return 0;
-}
-
-static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai));
- return 0;
-}
-
-static struct platform_driver s3c64xx_iis_driver = {
- .probe = s3c64xx_iis_dev_probe,
- .remove = s3c64xx_iis_dev_remove,
- .driver = {
- .name = "s3c64xx-iis",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c64xx_i2s_init(void)
-{
- return platform_driver_register(&s3c64xx_iis_driver);
-}
-module_init(s3c64xx_i2s_init);
-
-static void __exit s3c64xx_i2s_exit(void)
-{
- platform_driver_unregister(&s3c64xx_iis_driver);
-}
-module_exit(s3c64xx_i2s_exit);
-
-/* Module information */
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c64xx-iis");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
deleted file mode 100644
index de4075d26f0c..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s.h
- *
- * ALSA SoC Audio Layer - S3C64XX I2S driver
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
-#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
-
-struct clk;
-
-#include "s3c-i2s-v2.h"
-
-#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
-#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
-#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
-
-#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
-#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS
-#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK
-
-#define S3C64XX_I2S_RATES \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define S3C64XX_I2S_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
-
-#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index c1244c5bc730..bf3f3f9165e4 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <variant/dmac.h>
@@ -107,6 +106,7 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
char *differential = "Audio Out Differential";
char *stereo = "Audio Out Stereo";
@@ -114,10 +114,10 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
if (kcontrol->private_value == val)
return 0;
kcontrol->private_value = val;
- snd_soc_dapm_disable_pin(codec, val ? differential : stereo);
- snd_soc_dapm_sync(codec);
- snd_soc_dapm_enable_pin(codec, val ? stereo : differential);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, val ? differential : stereo);
+ snd_soc_dapm_sync(dapm);
+ snd_soc_dapm_enable_pin(dapm, val ? stereo : differential);
+ snd_soc_dapm_sync(dapm);
return 1;
}
@@ -137,35 +137,36 @@ static const struct snd_kcontrol_new audio_out_mux = {
static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add s6105 specific widgets */
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* Set up s6105 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* not present */
- snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
- snd_soc_dapm_nc_pin(codec, "LINE2L");
- snd_soc_dapm_nc_pin(codec, "LINE2R");
+ snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_nc_pin(dapm, "LINE2L");
+ snd_soc_dapm_nc_pin(dapm, "LINE2R");
/* not connected */
- snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */
- snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */
- snd_soc_dapm_nc_pin(codec, "LLOUT");
- snd_soc_dapm_nc_pin(codec, "RLOUT");
- snd_soc_dapm_nc_pin(codec, "HPRCOM");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */
+ snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */
+ snd_soc_dapm_nc_pin(dapm, "LLOUT");
+ snd_soc_dapm_nc_pin(dapm, "RLOUT");
+ snd_soc_dapm_nc_pin(dapm, "HPRCOM");
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Audio In");
+ snd_soc_dapm_enable_pin(dapm, "Audio In");
/* must correspond to audio_out_mux.private_value initializer */
- snd_soc_dapm_disable_pin(codec, "Audio Out Differential");
- snd_soc_dapm_sync(codec);
- snd_soc_dapm_enable_pin(codec, "Audio Out Stereo");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
+ snd_soc_dapm_sync(dapm);
+ snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
new file mode 100644
index 000000000000..67cdad4ee535
--- /dev/null
+++ b/sound/soc/samsung/Kconfig
@@ -0,0 +1,163 @@
+config ASOC_SAMSUNG
+ tristate "ASoC support for Samsung"
+ depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
+ select S3C64XX_DMA if ARCH_S3C64XX
+ select S3C2410_DMA if ARCH_S3C2410
+ help
+ Say Y or M if you want to add support for codecs attached to
+ the Samsung SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
+config SND_S3C24XX_I2S
+ tristate
+ select S3C2410_DMA
+
+config SND_S3C_I2SV2_SOC
+ tristate
+
+config SND_S3C2412_SOC_I2S
+ tristate
+ select SND_S3C_I2SV2_SOC
+ select S3C2410_DMA
+
+config SND_SAMSUNG_PCM
+ tristate
+
+config SND_SAMSUNG_AC97
+ tristate
+ select SND_SOC_AC97_BUS
+
+config SND_SAMSUNG_SPDIF
+ tristate
+ select SND_SOC_SPDIF
+
+config SND_SAMSUNG_I2S
+ tristate
+
+config ASOC_SAMSUNG_NEO1973_WM8753
+ tristate "SoC I2S Audio support for NEO1973 - WM8753"
+ depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01
+ select SND_S3C24XX_I2S
+ select SND_SOC_WM8753
+ help
+ Say Y if you want to add support for SoC audio on smdk2440
+ with the WM8753.
+
+config ASOC_SAMSUNG_NEO1973_GTA02_WM8753
+ tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
+ depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02
+ select SND_S3C24XX_I2S
+ select SND_SOC_WM8753
+ help
+ This driver provides audio support for the Openmoko Neo FreeRunner
+ smartphone.
+
+config ASOC_SAMSUNG_JIVE_WM8750
+ tristate "SoC I2S Audio support for Jive"
+ depends on ASOC_SAMSUNG && MACH_JIVE
+ select SND_SOC_WM8750
+ select SND_S3C2412_SOC_I2S
+ help
+ Sat Y if you want to add support for SoC audio on the Jive.
+
+config ASOC_SAMSUNG_SMDK_WM8580
+ tristate "SoC I2S Audio support for WM8580 on SMDK"
+ depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100)
+ select SND_SOC_WM8580
+ select SND_SAMSUNG_I2S
+ help
+ Say Y if you want to add support for SoC audio on the SMDKs.
+
+config ASOC_SAMSUNG_SMDK2443_WM9710
+ tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
+ depends on ASOC_SAMSUNG && MACH_SMDK2443
+ select S3C2410_DMA
+ select AC97_BUS
+ select SND_SOC_AC97_CODEC
+ select SND_SAMSUNG_AC97
+ help
+ Say Y if you want to add support for SoC audio on smdk2443
+ with the WM9710.
+
+config ASOC_SAMSUNG_LN2440SBC_ALC650
+ tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select S3C2410_DMA
+ select AC97_BUS
+ select SND_SOC_AC97_CODEC
+ select SND_SAMSUNG_AC97
+ help
+ Say Y if you want to add support for SoC audio on ln2440sbc
+ with the ALC650.
+
+config ASOC_SAMSUNG_S3C24XX_UDA134X
+ tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_L3
+ select SND_SOC_UDA134X
+
+config ASOC_SAMSUNG_SIMTEC
+ tristate
+ help
+ Internal node for common S3C24XX/Simtec suppor
+
+config ASOC_SAMSUNG_SIMTEC_TLV320AIC23
+ tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_TLV320AIC23
+ select ASOC_SAMSUNG_SIMTEC
+
+config ASOC_SAMSUNG_SIMTEC_HERMES
+ tristate "SoC I2S Audio support for Simtec Hermes board"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_TLV320AIC3X
+ select ASOC_SAMSUNG_SIMTEC
+
+config ASOC_SAMSUNG_H1940_UDA1380
+ tristate "Audio support for the HP iPAQ H1940"
+ depends on ASOC_SAMSUNG && ARCH_H1940
+ select SND_S3C24XX_I2S
+ select SND_SOC_UDA1380
+ help
+ This driver provides audio support for HP iPAQ h1940 PDA.
+
+config ASOC_SAMSUNG_RX1950_UDA1380
+ tristate "Audio support for the HP iPAQ RX1950"
+ depends on ASOC_SAMSUNG && MACH_RX1950
+ select SND_S3C24XX_I2S
+ select SND_SOC_UDA1380
+ help
+ This driver provides audio support for HP iPAQ RX1950 PDA.
+
+config ASOC_SAMSUNG_SMDK_WM9713
+ tristate "SoC AC97 Audio support for SMDK with WM9713"
+ depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
+ select SND_SOC_WM9713
+ select SND_SAMSUNG_AC97
+ help
+ Sat Y if you want to add support for SoC audio on the SMDK.
+
+config ASOC_SMARTQ
+ tristate "SoC I2S Audio support for SmartQ board"
+ depends on ASOC_SAMSUNG && MACH_SMARTQ
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM8750
+
+config ASOC_GONI_AQUILA_WM8994
+ tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
+ depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM8994
+ help
+ Say Y if you want to add support for SoC audio on goni or aquila
+ with the WM8994.
+
+config ASOC_SAMSUNG_SMDK_SPDIF
+ tristate "SoC S/PDIF Audio support for SMDK"
+ depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
+ select SND_SAMSUNG_SPDIF
+ help
+ Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
new file mode 100644
index 000000000000..622e76eb9775
--- /dev/null
+++ b/sound/soc/samsung/Makefile
@@ -0,0 +1,53 @@
+# S3c24XX Platform Support
+snd-soc-s3c24xx-objs := dma.o
+snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
+snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
+snd-soc-ac97-objs := ac97.o
+snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
+snd-soc-samsung-spdif-objs := spdif.o
+snd-soc-pcm-objs := pcm.o
+snd-soc-i2s-objs := i2s.o
+
+obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o
+obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
+obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
+obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
+obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
+obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
+obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
+obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
+
+# S3C24XX Machine Support
+snd-soc-jive-wm8750-objs := jive_wm8750.o
+snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
+snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
+snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
+snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
+snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
+snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
+snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
+snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
+snd-soc-h1940-uda1380-objs := h1940_uda1380.o
+snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
+snd-soc-smdk-wm8580-objs := smdk_wm8580.o
+snd-soc-smdk-wm9713-objs := smdk_wm9713.o
+snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
+snd-soc-goni-wm8994-objs := goni_wm8994.o
+snd-soc-smdk-spdif-objs := smdk_spdif.o
+
+obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
+obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
+obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
+obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
+obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
+obj-$(CONFIG_ASOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
+obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
+obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
+obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/samsung/ac97.c
index f891eb79b575..4770a9550341 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-ac97.c
+/* sound/soc/samsung/ac97.c
*
* ALSA SoC Audio Layer - S3C AC97 Controller driver
* Evolved from s3c2443-ac97.c
@@ -24,8 +24,8 @@
#include <mach/dma.h>
#include <plat/audio.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
#define AC_CMD_ADDR(x) (x << 16)
#define AC_CMD_DATA(x) (x & 0xffff)
@@ -122,7 +122,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
data = (stat & 0xffff);
if (addr != reg)
- pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n",
+ pr_err("ac97: req addr = %02x, rep addr = %02x\n",
reg, addr);
mutex_unlock(&s3c_ac97.lock);
@@ -334,7 +334,7 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
static struct snd_soc_dai_driver s3c_ac97_dai[] = {
[S3C_AC97_DAI_PCM] = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.ac97_control = 1,
.playback = {
.stream_name = "AC97 Playback",
@@ -351,7 +351,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = {
.ops = &s3c_ac97_dai_ops,
},
[S3C_AC97_DAI_MIC] = {
- .name = "s3c-ac97-mic",
+ .name = "samsung-ac97-mic",
.ac97_control = 1,
.capture = {
.stream_name = "AC97 Mic Capture",
@@ -407,7 +407,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
}
if (!request_mem_region(mem_res->start,
- resource_size(mem_res), "s3c-ac97")) {
+ resource_size(mem_res), "ac97")) {
dev_err(&pdev->dev, "Unable to request register region\n");
return -EBUSY;
}
@@ -431,7 +431,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
if (IS_ERR(s3c_ac97.ac97_clk)) {
- dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n");
+ dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
ret = -ENODEV;
goto err2;
}
@@ -446,7 +446,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
ret = request_irq(irq_res->start, s3c_ac97_irq,
IRQF_DISABLED, "AC97", NULL);
if (ret < 0) {
- dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n");
+ dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
goto err4;
}
@@ -497,7 +497,7 @@ static struct platform_driver s3c_ac97_driver = {
.probe = s3c_ac97_probe,
.remove = s3c_ac97_remove,
.driver = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.owner = THIS_MODULE,
},
};
@@ -517,4 +517,4 @@ module_exit(s3c_ac97_exit);
MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c-ac97");
+MODULE_ALIAS("platform:samsung-ac97");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/samsung/ac97.h
index 5dcedd07fdbb..0d0e1b511457 100644
--- a/sound/soc/s3c24xx/s3c-ac97.h
+++ b/sound/soc/samsung/ac97.h
@@ -1,11 +1,11 @@
-/* sound/soc/s3c24xx/s3c-ac97.h
+/* sound/soc/samsung/ac97.h
*
* ALSA SoC Audio Layer - S3C AC97 Controller driver
- * Evolved from s3c2443-ac97.h
+ * Evolved from s3c2443-ac97.h
*
* Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassi.brar@samsung.com>
- * Credits: Graeme Gregory, Sean Choi
+ * Author: Jaswinder Singh <jassi.brar@samsung.com>
+ * Credits: Graeme Gregory, Sean Choi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/samsung/dma.c
index 243f79bf43bb..21240198c5d6 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/samsung/dma.c
@@ -1,5 +1,5 @@
/*
- * s3c-dma.c -- ALSA Soc Audio Layer
+ * dma.c -- ALSA Soc Audio Layer
*
* (c) 2006 Wolfson Microelectronics PLC.
* Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
@@ -30,9 +30,9 @@
#include <mach/hardware.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
-static const struct snd_pcm_hardware s3c_dma_hardware = {
+static const struct snd_pcm_hardware dma_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
@@ -53,7 +53,7 @@ static const struct snd_pcm_hardware s3c_dma_hardware = {
.fifo_size = 32,
};
-struct s3c24xx_runtime_data {
+struct runtime_data {
spinlock_t lock;
int state;
unsigned int dma_loaded;
@@ -65,14 +65,14 @@ struct s3c24xx_runtime_data {
struct s3c_dma_params *params;
};
-/* s3c_dma_enqueue
+/* dma_enqueue
*
* place a dma buffer onto the queue for the dma system
* to handle.
*/
-static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
+static void dma_enqueue(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
dma_addr_t pos = prtd->dma_pos;
unsigned int limit;
int ret;
@@ -112,12 +112,12 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
prtd->dma_pos = pos;
}
-static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
+static void audio_buffdone(struct s3c2410_dma_chan *channel,
void *dev_id, int size,
enum s3c2410_dma_buffresult result)
{
struct snd_pcm_substream *substream = dev_id;
- struct s3c24xx_runtime_data *prtd;
+ struct runtime_data *prtd;
pr_debug("Entered %s\n", __func__);
@@ -132,17 +132,17 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
spin_lock(&prtd->lock);
if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
prtd->dma_loaded--;
- s3c_dma_enqueue(substream);
+ dma_enqueue(substream);
}
spin_unlock(&prtd->lock);
}
-static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
+static int dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned long totbytes = params_buffer_bytes(params);
struct s3c_dma_params *dma =
@@ -181,7 +181,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
}
s3c2410_dma_set_buffdone_fn(prtd->params->channel,
- s3c24xx_audio_buffdone);
+ audio_buffdone);
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
@@ -199,9 +199,9 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
+static int dma_hw_free(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
pr_debug("Entered %s\n", __func__);
@@ -216,9 +216,9 @@ static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
return 0;
}
-static int s3c_dma_prepare(struct snd_pcm_substream *substream)
+static int dma_prepare(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
@@ -249,14 +249,14 @@ static int s3c_dma_prepare(struct snd_pcm_substream *substream)
prtd->dma_pos = prtd->dma_start;
/* enqueue dma buffers */
- s3c_dma_enqueue(substream);
+ dma_enqueue(substream);
return ret;
}
-static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
+static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
@@ -289,10 +289,10 @@ static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
}
static snd_pcm_uframes_t
-s3c_dma_pointer(struct snd_pcm_substream *substream)
+dma_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
unsigned long res;
dma_addr_t src, dst;
@@ -324,17 +324,17 @@ s3c_dma_pointer(struct snd_pcm_substream *substream)
return bytes_to_frames(substream->runtime, res);
}
-static int s3c_dma_open(struct snd_pcm_substream *substream)
+static int dma_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd;
+ struct runtime_data *prtd;
pr_debug("Entered %s\n", __func__);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware);
+ snd_soc_set_runtime_hwparams(substream, &dma_hardware);
- prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+ prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL);
if (prtd == NULL)
return -ENOMEM;
@@ -344,22 +344,22 @@ static int s3c_dma_open(struct snd_pcm_substream *substream)
return 0;
}
-static int s3c_dma_close(struct snd_pcm_substream *substream)
+static int dma_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
pr_debug("Entered %s\n", __func__);
if (!prtd)
- pr_debug("s3c_dma_close called with prtd == NULL\n");
+ pr_debug("dma_close called with prtd == NULL\n");
kfree(prtd);
return 0;
}
-static int s3c_dma_mmap(struct snd_pcm_substream *substream,
+static int dma_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -372,23 +372,23 @@ static int s3c_dma_mmap(struct snd_pcm_substream *substream,
runtime->dma_bytes);
}
-static struct snd_pcm_ops s3c_dma_ops = {
- .open = s3c_dma_open,
- .close = s3c_dma_close,
+static struct snd_pcm_ops dma_ops = {
+ .open = dma_open,
+ .close = dma_close,
.ioctl = snd_pcm_lib_ioctl,
- .hw_params = s3c_dma_hw_params,
- .hw_free = s3c_dma_hw_free,
- .prepare = s3c_dma_prepare,
- .trigger = s3c_dma_trigger,
- .pointer = s3c_dma_pointer,
- .mmap = s3c_dma_mmap,
+ .hw_params = dma_hw_params,
+ .hw_free = dma_hw_free,
+ .prepare = dma_prepare,
+ .trigger = dma_trigger,
+ .pointer = dma_pointer,
+ .mmap = dma_mmap,
};
-static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = s3c_dma_hardware.buffer_bytes_max;
+ size_t size = dma_hardware.buffer_bytes_max;
pr_debug("Entered %s\n", __func__);
@@ -403,7 +403,7 @@ static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
return 0;
}
-static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
+static void dma_free_dma_buffers(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
@@ -426,9 +426,9 @@ static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
}
}
-static u64 s3c_dma_mask = DMA_BIT_MASK(32);
+static u64 dma_mask = DMA_BIT_MASK(32);
-static int s3c_dma_new(struct snd_card *card,
+static int dma_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
{
int ret = 0;
@@ -436,67 +436,67 @@ static int s3c_dma_new(struct snd_card *card,
pr_debug("Entered %s\n", __func__);
if (!card->dev->dma_mask)
- card->dev->dma_mask = &s3c_dma_mask;
+ card->dev->dma_mask = &dma_mask;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
if (dai->driver->playback.channels_min) {
- ret = s3c_preallocate_dma_buffer(pcm,
+ ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->driver->capture.channels_min) {
- ret = s3c_preallocate_dma_buffer(pcm,
+ ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}
- out:
+out:
return ret;
}
-static struct snd_soc_platform_driver s3c24xx_soc_platform = {
- .ops = &s3c_dma_ops,
- .pcm_new = s3c_dma_new,
- .pcm_free = s3c_dma_free_dma_buffers,
+static struct snd_soc_platform_driver samsung_asoc_platform = {
+ .ops = &dma_ops,
+ .pcm_new = dma_new,
+ .pcm_free = dma_free_dma_buffers,
};
-static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev)
+static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
{
- return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform);
+ return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
}
-static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev)
+static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
-static struct platform_driver s3c24xx_pcm_driver = {
+static struct platform_driver asoc_dma_driver = {
.driver = {
- .name = "s3c24xx-pcm-audio",
+ .name = "samsung-audio",
.owner = THIS_MODULE,
},
- .probe = s3c24xx_soc_platform_probe,
- .remove = __devexit_p(s3c24xx_soc_platform_remove),
+ .probe = samsung_asoc_platform_probe,
+ .remove = __devexit_p(samsung_asoc_platform_remove),
};
-static int __init snd_s3c24xx_pcm_init(void)
+static int __init samsung_asoc_init(void)
{
- return platform_driver_register(&s3c24xx_pcm_driver);
+ return platform_driver_register(&asoc_dma_driver);
}
-module_init(snd_s3c24xx_pcm_init);
+module_init(samsung_asoc_init);
-static void __exit snd_s3c24xx_pcm_exit(void)
+static void __exit samsung_asoc_exit(void)
{
- platform_driver_unregister(&s3c24xx_pcm_driver);
+ platform_driver_unregister(&asoc_dma_driver);
}
-module_exit(snd_s3c24xx_pcm_exit);
+module_exit(samsung_asoc_exit);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
+MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c24xx-pcm-audio");
+MODULE_ALIAS("platform:samsung-audio");
diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/samsung/dma.h
index 748c07d7c075..f8cd2b4223af 100644
--- a/sound/soc/s3c24xx/s3c-dma.h
+++ b/sound/soc/samsung/dma.h
@@ -1,5 +1,5 @@
/*
- * s3c-dma.h --
+ * dma.h --
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 694f702cc8e2..cc8528c0a49a 100644
--- a/sound/soc/s3c24xx/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <mach/gpio.h>
@@ -25,8 +24,16 @@
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include "../codecs/wm8994.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
+
+#define MACHINE_NAME 0
+#define CPU_VOICE_DAI 1
+
+static const char *aquila_str[] = {
+ [MACHINE_NAME] = "aquila",
+ [CPU_VOICE_DAI] = "aquila-voice-dai",
+};
static struct snd_soc_card goni;
static struct platform_device *goni_snd_device;
@@ -97,25 +104,31 @@ static const struct snd_soc_dapm_route goni_dapm_routes[] = {
static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* add goni specific widgets */
- snd_soc_dapm_new_controls(codec, goni_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
ARRAY_SIZE(goni_dapm_widgets));
/* set up goni specific audio routes */
- snd_soc_dapm_add_routes(codec, goni_dapm_routes,
+ snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
ARRAY_SIZE(goni_dapm_routes));
/* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
+ snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
+ snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
- snd_soc_dapm_sync(codec);
+ if (machine_is_aquila()) {
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
+ }
+
+ snd_soc_dapm_sync(dapm);
/* Headset jack detection */
ret = snd_soc_jack_new(&goni, "Headset Jack",
@@ -150,12 +163,6 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- /* set the cpu system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
@@ -236,9 +243,9 @@ static struct snd_soc_dai_link goni_dai[] = {
{
.name = "WM8994",
.stream_name = "WM8994 HiFi",
- .cpu_dai_name = "s3c64xx-i2s-v4",
+ .cpu_dai_name = "samsung-i2s.0",
.codec_dai_name = "wm8994-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8994-codec.0-0x1a",
.init = goni_wm8994_init,
.ops = &goni_hifi_ops,
@@ -247,7 +254,7 @@ static struct snd_soc_dai_link goni_dai[] = {
.stream_name = "Voice",
.cpu_dai_name = "goni-voice-dai",
.codec_dai_name = "wm8994-voice",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8994-codec.0-0x1a",
.ops = &goni_voice_ops,
},
@@ -263,7 +270,11 @@ static int __init goni_init(void)
{
int ret;
- if (!machine_is_goni())
+ if (machine_is_aquila()) {
+ voice_dai.name = aquila_str[CPU_VOICE_DAI];
+ goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI];
+ goni.name = aquila_str[MACHINE_NAME];
+ } else if (!machine_is_goni())
return -ENODEV;
goni_snd_device = platform_device_alloc("soc-audio", -1);
@@ -272,20 +283,25 @@ static int __init goni_init(void)
/* register voice DAI here */
ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai);
- if (ret)
+ if (ret) {
+ platform_device_put(goni_snd_device);
return ret;
+ }
platform_set_drvdata(goni_snd_device, &goni);
ret = platform_device_add(goni_snd_device);
- if (ret)
+ if (ret) {
+ snd_soc_unregister_dai(&goni_snd_device->dev);
platform_device_put(goni_snd_device);
+ }
return ret;
}
static void __exit goni_exit(void)
{
+ snd_soc_unregister_dai(&goni_snd_device->dev);
platform_device_unregister(goni_snd_device);
}
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
new file mode 100644
index 000000000000..c45f7ce14d61
--- /dev/null
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -0,0 +1,296 @@
+/*
+ * h1940-uda1380.c -- ALSA Soc Audio Layer
+ *
+ * Copyright (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com>
+ *
+ * Based on version from Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#include <sound/soc.h>
+#include <sound/uda1380.h>
+#include <sound/jack.h>
+
+#include <plat/regs-iis.h>
+
+#include <mach/h1940-latch.h>
+
+#include <asm/mach-types.h>
+
+#include "dma.h"
+#include "s3c24xx-i2s.h"
+#include "../codecs/uda1380.h"
+
+static unsigned int rates[] = {
+ 11025,
+ 22050,
+ 44100,
+};
+
+static struct snd_pcm_hw_constraint_list hw_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static struct snd_soc_jack hp_jack;
+
+static struct snd_soc_jack_pin hp_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Speaker",
+ .mask = SND_JACK_HEADPHONE,
+ .invert = 1,
+ },
+};
+
+static struct snd_soc_jack_gpio hp_jack_gpios[] = {
+ {
+ .gpio = S3C2410_GPG(4),
+ .name = "hp-gpio",
+ .report = SND_JACK_HEADPHONE,
+ .invert = 1,
+ .debounce_time = 200,
+ },
+};
+
+static int h1940_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.rate_min = hw_rates.list[0];
+ runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1];
+ runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
+
+ return snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &hw_rates);
+}
+
+static int h1940_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int div;
+ int ret;
+ unsigned int rate = params_rate(params);
+
+ switch (rate) {
+ case 11025:
+ case 22050:
+ case 44100:
+ div = s3c24xx_i2s_get_clockrate() / (384 * rate);
+ if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate))
+ div++;
+ break;
+ default:
+ dev_err(&rtd->dev, "%s: rate %d is not supported\n",
+ __func__, rate);
+ return -EINVAL;
+ }
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* select clock source */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+
+ /* set MCLK division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
+ S3C2410_IISMOD_384FS);
+ if (ret < 0)
+ return ret;
+
+ /* set BCLK division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
+ S3C2410_IISMOD_32FS);
+ if (ret < 0)
+ return ret;
+
+ /* set prescaler division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
+ S3C24XX_PRESCALE(div, div));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops h1940_ops = {
+ .startup = h1940_startup,
+ .hw_params = h1940_hw_params,
+};
+
+static int h1940_spk_power(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ gpio_set_value(H1940_LATCH_AUDIO_POWER, 1);
+ else
+ gpio_set_value(H1940_LATCH_AUDIO_POWER, 0);
+
+ return 0;
+}
+
+/* h1940 machine dapm widgets */
+static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_SPK("Speaker", h1940_spk_power),
+};
+
+/* h1940 machine audio_map */
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* headphone connected to VOUTLHP, VOUTRHP */
+ {"Headphone Jack", NULL, "VOUTLHP"},
+ {"Headphone Jack", NULL, "VOUTRHP"},
+
+ /* ext speaker connected to VOUTL, VOUTR */
+ {"Speaker", NULL, "VOUTL"},
+ {"Speaker", NULL, "VOUTR"},
+
+ /* mic is connected to VINM */
+ {"VINM", NULL, "Mic Jack"},
+};
+
+static struct platform_device *s3c24xx_snd_device;
+
+static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int err;
+
+ /* Add h1940 specific widgets */
+ err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
+ ARRAY_SIZE(uda1380_dapm_widgets));
+ if (err)
+ return err;
+
+ /* Set up h1940 specific audio path audio_mapnects */
+ err = snd_soc_dapm_add_routes(dapm, audio_map,
+ ARRAY_SIZE(audio_map));
+ if (err)
+ return err;
+
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
+ &hp_jack);
+
+ snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
+ hp_jack_pins);
+
+ snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
+ hp_jack_gpios);
+
+ return 0;
+}
+
+/* s3c24xx digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link h1940_uda1380_dai[] = {
+ {
+ .name = "uda1380",
+ .stream_name = "UDA1380 Duplex",
+ .cpu_dai_name = "s3c24xx-iis",
+ .codec_dai_name = "uda1380-hifi",
+ .init = h1940_uda1380_init,
+ .platform_name = "samsung-audio",
+ .codec_name = "uda1380-codec.0-001a",
+ .ops = &h1940_ops,
+ },
+};
+
+static struct snd_soc_card h1940_asoc = {
+ .name = "h1940",
+ .dai_link = h1940_uda1380_dai,
+ .num_links = ARRAY_SIZE(h1940_uda1380_dai),
+};
+
+static int __init h1940_init(void)
+{
+ int ret;
+
+ if (!machine_is_h1940())
+ return -ENODEV;
+
+ /* configure some gpios */
+ ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power");
+ if (ret)
+ goto err_out;
+
+ ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0);
+ if (ret)
+ goto err_gpio;
+
+ s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!s3c24xx_snd_device) {
+ ret = -ENOMEM;
+ goto err_gpio;
+ }
+
+ platform_set_drvdata(s3c24xx_snd_device, &h1940_asoc);
+ ret = platform_device_add(s3c24xx_snd_device);
+
+ if (ret)
+ goto err_plat;
+
+ return 0;
+
+err_plat:
+ platform_device_put(s3c24xx_snd_device);
+err_gpio:
+ gpio_free(H1940_LATCH_AUDIO_POWER);
+
+err_out:
+ return ret;
+}
+
+static void __exit h1940_exit(void)
+{
+ platform_device_unregister(s3c24xx_snd_device);
+ snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
+ hp_jack_gpios);
+ gpio_free(H1940_LATCH_AUDIO_POWER);
+}
+
+module_init(h1940_init);
+module_exit(h1940_exit);
+
+/* Module information */
+MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick");
+MODULE_DESCRIPTION("ALSA SoC H1940");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
new file mode 100644
index 000000000000..d6de3f0eeff8
--- /dev/null
+++ b/sound/soc/samsung/i2s.c
@@ -0,0 +1,1256 @@
+/* sound/soc/samsung/i2s.c
+ *
+ * ALSA SoC Audio Layer - Samsung I2S Controller driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <plat/audio.h>
+
+#include "dma.h"
+#include "i2s.h"
+
+#define I2SCON 0x0
+#define I2SMOD 0x4
+#define I2SFIC 0x8
+#define I2SPSR 0xc
+#define I2STXD 0x10
+#define I2SRXD 0x14
+#define I2SFICS 0x18
+#define I2STXDS 0x1c
+
+#define CON_RSTCLR (1 << 31)
+#define CON_FRXOFSTATUS (1 << 26)
+#define CON_FRXORINTEN (1 << 25)
+#define CON_FTXSURSTAT (1 << 24)
+#define CON_FTXSURINTEN (1 << 23)
+#define CON_TXSDMA_PAUSE (1 << 20)
+#define CON_TXSDMA_ACTIVE (1 << 18)
+
+#define CON_FTXURSTATUS (1 << 17)
+#define CON_FTXURINTEN (1 << 16)
+#define CON_TXFIFO2_EMPTY (1 << 15)
+#define CON_TXFIFO1_EMPTY (1 << 14)
+#define CON_TXFIFO2_FULL (1 << 13)
+#define CON_TXFIFO1_FULL (1 << 12)
+
+#define CON_LRINDEX (1 << 11)
+#define CON_TXFIFO_EMPTY (1 << 10)
+#define CON_RXFIFO_EMPTY (1 << 9)
+#define CON_TXFIFO_FULL (1 << 8)
+#define CON_RXFIFO_FULL (1 << 7)
+#define CON_TXDMA_PAUSE (1 << 6)
+#define CON_RXDMA_PAUSE (1 << 5)
+#define CON_TXCH_PAUSE (1 << 4)
+#define CON_RXCH_PAUSE (1 << 3)
+#define CON_TXDMA_ACTIVE (1 << 2)
+#define CON_RXDMA_ACTIVE (1 << 1)
+#define CON_ACTIVE (1 << 0)
+
+#define MOD_OPCLK_CDCLK_OUT (0 << 30)
+#define MOD_OPCLK_CDCLK_IN (1 << 30)
+#define MOD_OPCLK_BCLK_OUT (2 << 30)
+#define MOD_OPCLK_PCLK (3 << 30)
+#define MOD_OPCLK_MASK (3 << 30)
+#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
+
+#define MOD_BLCS_SHIFT 26
+#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
+#define MOD_BLCP_SHIFT 24
+#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
+
+#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
+#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
+#define MOD_C1DD_HHALF (1 << 19)
+#define MOD_C1DD_LHALF (1 << 18)
+#define MOD_DC2_EN (1 << 17)
+#define MOD_DC1_EN (1 << 16)
+#define MOD_BLC_16BIT (0 << 13)
+#define MOD_BLC_8BIT (1 << 13)
+#define MOD_BLC_24BIT (2 << 13)
+#define MOD_BLC_MASK (3 << 13)
+
+#define MOD_IMS_SYSMUX (1 << 10)
+#define MOD_SLAVE (1 << 11)
+#define MOD_TXONLY (0 << 8)
+#define MOD_RXONLY (1 << 8)
+#define MOD_TXRX (2 << 8)
+#define MOD_MASK (3 << 8)
+#define MOD_LR_LLOW (0 << 7)
+#define MOD_LR_RLOW (1 << 7)
+#define MOD_SDF_IIS (0 << 5)
+#define MOD_SDF_MSB (1 << 5)
+#define MOD_SDF_LSB (2 << 5)
+#define MOD_SDF_MASK (3 << 5)
+#define MOD_RCLK_256FS (0 << 3)
+#define MOD_RCLK_512FS (1 << 3)
+#define MOD_RCLK_384FS (2 << 3)
+#define MOD_RCLK_768FS (3 << 3)
+#define MOD_RCLK_MASK (3 << 3)
+#define MOD_BCLK_32FS (0 << 1)
+#define MOD_BCLK_48FS (1 << 1)
+#define MOD_BCLK_16FS (2 << 1)
+#define MOD_BCLK_24FS (3 << 1)
+#define MOD_BCLK_MASK (3 << 1)
+#define MOD_8BIT (1 << 0)
+
+#define MOD_CDCLKCON (1 << 12)
+
+#define PSR_PSREN (1 << 15)
+
+#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
+#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
+
+#define FIC_TXFLUSH (1 << 15)
+#define FIC_RXFLUSH (1 << 7)
+#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
+#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
+#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+struct i2s_dai {
+ /* Platform device for this DAI */
+ struct platform_device *pdev;
+ /* IOREMAP'd SFRs */
+ void __iomem *addr;
+ /* Physical base address of SFRs */
+ u32 base;
+ /* Rate of RCLK source clock */
+ unsigned long rclk_srcrate;
+ /* Frame Clock */
+ unsigned frmclk;
+ /*
+ * Specifically requested RCLK,BCLK by MACHINE Driver.
+ * 0 indicates CPU driver is free to choose any value.
+ */
+ unsigned rfs, bfs;
+ /* I2S Controller's core clock */
+ struct clk *clk;
+ /* Clock for generating I2S signals */
+ struct clk *op_clk;
+ /* Array of clock names for op_clk */
+ const char **src_clk;
+ /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
+ struct i2s_dai *pri_dai;
+ /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
+ struct i2s_dai *sec_dai;
+#define DAI_OPENED (1 << 0) /* Dai is opened */
+#define DAI_MANAGER (1 << 1) /* Dai is the manager */
+ unsigned mode;
+ /* Driver for this DAI */
+ struct snd_soc_dai_driver i2s_dai_drv;
+ /* DMA parameters */
+ struct s3c_dma_params dma_playback;
+ struct s3c_dma_params dma_capture;
+ u32 quirks;
+ u32 suspend_i2smod;
+ u32 suspend_i2scon;
+ u32 suspend_i2spsr;
+};
+
+/* Lock for cross i/f checks */
+static DEFINE_SPINLOCK(lock);
+
+/* If this is the 'overlay' stereo DAI */
+static inline bool is_secondary(struct i2s_dai *i2s)
+{
+ return i2s->pri_dai ? true : false;
+}
+
+/* If operating in SoC-Slave mode */
+static inline bool is_slave(struct i2s_dai *i2s)
+{
+ return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
+}
+
+/* If this interface of the controller is transmitting data */
+static inline bool tx_active(struct i2s_dai *i2s)
+{
+ u32 active;
+
+ if (!i2s)
+ return false;
+
+ active = readl(i2s->addr + I2SMOD);
+
+ if (is_secondary(i2s))
+ active &= CON_TXSDMA_ACTIVE;
+ else
+ active &= CON_TXDMA_ACTIVE;
+
+ return active ? true : false;
+}
+
+/* If the other interface of the controller is transmitting data */
+static inline bool other_tx_active(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ return tx_active(other);
+}
+
+/* If any interface of the controller is transmitting data */
+static inline bool any_tx_active(struct i2s_dai *i2s)
+{
+ return tx_active(i2s) || other_tx_active(i2s);
+}
+
+/* If this interface of the controller is receiving data */
+static inline bool rx_active(struct i2s_dai *i2s)
+{
+ u32 active;
+
+ if (!i2s)
+ return false;
+
+ active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE;
+
+ return active ? true : false;
+}
+
+/* If the other interface of the controller is receiving data */
+static inline bool other_rx_active(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ return rx_active(other);
+}
+
+/* If any interface of the controller is receiving data */
+static inline bool any_rx_active(struct i2s_dai *i2s)
+{
+ return rx_active(i2s) || other_rx_active(i2s);
+}
+
+/* If the other DAI is transmitting or receiving data */
+static inline bool other_active(struct i2s_dai *i2s)
+{
+ return other_rx_active(i2s) || other_tx_active(i2s);
+}
+
+/* If this DAI is transmitting or receiving data */
+static inline bool this_active(struct i2s_dai *i2s)
+{
+ return tx_active(i2s) || rx_active(i2s);
+}
+
+/* If the controller is active anyway */
+static inline bool any_active(struct i2s_dai *i2s)
+{
+ return this_active(i2s) || other_active(i2s);
+}
+
+static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
+{
+ return snd_soc_dai_get_drvdata(dai);
+}
+
+static inline bool is_opened(struct i2s_dai *i2s)
+{
+ if (i2s && (i2s->mode & DAI_OPENED))
+ return true;
+ else
+ return false;
+}
+
+static inline bool is_manager(struct i2s_dai *i2s)
+{
+ if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
+ return true;
+ else
+ return false;
+}
+
+/* Read RCLK of I2S (in multiples of LRCLK) */
+static inline unsigned get_rfs(struct i2s_dai *i2s)
+{
+ u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
+
+ switch (rfs) {
+ case 3: return 768;
+ case 2: return 384;
+ case 1: return 512;
+ default: return 256;
+ }
+}
+
+/* Write RCLK of I2S (in multiples of LRCLK) */
+static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
+{
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ mod &= ~MOD_RCLK_MASK;
+
+ switch (rfs) {
+ case 768:
+ mod |= MOD_RCLK_768FS;
+ break;
+ case 512:
+ mod |= MOD_RCLK_512FS;
+ break;
+ case 384:
+ mod |= MOD_RCLK_384FS;
+ break;
+ default:
+ mod |= MOD_RCLK_256FS;
+ break;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+}
+
+/* Read Bit-Clock of I2S (in multiples of LRCLK) */
+static inline unsigned get_bfs(struct i2s_dai *i2s)
+{
+ u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
+
+ switch (bfs) {
+ case 3: return 24;
+ case 2: return 16;
+ case 1: return 48;
+ default: return 32;
+ }
+}
+
+/* Write Bit-Clock of I2S (in multiples of LRCLK) */
+static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
+{
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ mod &= ~MOD_BCLK_MASK;
+
+ switch (bfs) {
+ case 48:
+ mod |= MOD_BCLK_48FS;
+ break;
+ case 32:
+ mod |= MOD_BCLK_32FS;
+ break;
+ case 24:
+ mod |= MOD_BCLK_24FS;
+ break;
+ case 16:
+ mod |= MOD_BCLK_16FS;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
+ return;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+}
+
+/* Sample-Size */
+static inline int get_blc(struct i2s_dai *i2s)
+{
+ int blc = readl(i2s->addr + I2SMOD);
+
+ blc = (blc >> 13) & 0x3;
+
+ switch (blc) {
+ case 2: return 24;
+ case 1: return 8;
+ default: return 16;
+ }
+}
+
+/* TX Channel Control */
+static void i2s_txctrl(struct i2s_dai *i2s, int on)
+{
+ void __iomem *addr = i2s->addr;
+ u32 con = readl(addr + I2SCON);
+ u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+
+ if (on) {
+ con |= CON_ACTIVE;
+ con &= ~CON_TXCH_PAUSE;
+
+ if (is_secondary(i2s)) {
+ con |= CON_TXSDMA_ACTIVE;
+ con &= ~CON_TXSDMA_PAUSE;
+ } else {
+ con |= CON_TXDMA_ACTIVE;
+ con &= ~CON_TXDMA_PAUSE;
+ }
+
+ if (any_rx_active(i2s))
+ mod |= MOD_TXRX;
+ else
+ mod |= MOD_TXONLY;
+ } else {
+ if (is_secondary(i2s)) {
+ con |= CON_TXSDMA_PAUSE;
+ con &= ~CON_TXSDMA_ACTIVE;
+ } else {
+ con |= CON_TXDMA_PAUSE;
+ con &= ~CON_TXDMA_ACTIVE;
+ }
+
+ if (other_tx_active(i2s)) {
+ writel(con, addr + I2SCON);
+ return;
+ }
+
+ con |= CON_TXCH_PAUSE;
+
+ if (any_rx_active(i2s))
+ mod |= MOD_RXONLY;
+ else
+ con &= ~CON_ACTIVE;
+ }
+
+ writel(mod, addr + I2SMOD);
+ writel(con, addr + I2SCON);
+}
+
+/* RX Channel Control */
+static void i2s_rxctrl(struct i2s_dai *i2s, int on)
+{
+ void __iomem *addr = i2s->addr;
+ u32 con = readl(addr + I2SCON);
+ u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+
+ if (on) {
+ con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
+ con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
+
+ if (any_tx_active(i2s))
+ mod |= MOD_TXRX;
+ else
+ mod |= MOD_RXONLY;
+ } else {
+ con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
+ con &= ~CON_RXDMA_ACTIVE;
+
+ if (any_tx_active(i2s))
+ mod |= MOD_TXONLY;
+ else
+ con &= ~CON_ACTIVE;
+ }
+
+ writel(mod, addr + I2SMOD);
+ writel(con, addr + I2SCON);
+}
+
+/* Flush FIFO of an interface */
+static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
+{
+ void __iomem *fic;
+ u32 val;
+
+ if (!i2s)
+ return;
+
+ if (is_secondary(i2s))
+ fic = i2s->addr + I2SFICS;
+ else
+ fic = i2s->addr + I2SFIC;
+
+ /* Flush the FIFO */
+ writel(readl(fic) | flush, fic);
+
+ /* Be patient */
+ val = msecs_to_loops(1) / 1000; /* 1 usec */
+ while (--val)
+ cpu_relax();
+
+ writel(readl(fic) & ~flush, fic);
+}
+
+static int i2s_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int rfs, int dir)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ switch (clk_id) {
+ case SAMSUNG_I2S_CDCLK:
+ /* Shouldn't matter in GATING(CLOCK_IN) mode */
+ if (dir == SND_SOC_CLOCK_IN)
+ rfs = 0;
+
+ if ((rfs && other->rfs && (other->rfs != rfs)) ||
+ (any_active(i2s) &&
+ (((dir == SND_SOC_CLOCK_IN)
+ && !(mod & MOD_CDCLKCON)) ||
+ ((dir == SND_SOC_CLOCK_OUT)
+ && (mod & MOD_CDCLKCON))))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ if (dir == SND_SOC_CLOCK_IN)
+ mod |= MOD_CDCLKCON;
+ else
+ mod &= ~MOD_CDCLKCON;
+
+ i2s->rfs = rfs;
+ break;
+
+ case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
+ case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
+ if ((i2s->quirks & QUIRK_NO_MUXPSR)
+ || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
+ clk_id = 0;
+ else
+ clk_id = 1;
+
+ if (!any_active(i2s)) {
+ if (i2s->op_clk) {
+ if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
+ (!clk_id && (mod & MOD_IMS_SYSMUX))) {
+ clk_disable(i2s->op_clk);
+ clk_put(i2s->op_clk);
+ } else {
+ return 0;
+ }
+ }
+
+ i2s->op_clk = clk_get(&i2s->pdev->dev,
+ i2s->src_clk[clk_id]);
+ clk_enable(i2s->op_clk);
+ i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
+
+ /* Over-ride the other's */
+ if (other) {
+ other->op_clk = i2s->op_clk;
+ other->rclk_srcrate = i2s->rclk_srcrate;
+ }
+ } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
+ || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ } else {
+ /* Call can't be on the active DAI */
+ i2s->op_clk = other->op_clk;
+ i2s->rclk_srcrate = other->rclk_srcrate;
+ return 0;
+ }
+
+ if (clk_id == 0)
+ mod &= ~MOD_IMS_SYSMUX;
+ else
+ mod |= MOD_IMS_SYSMUX;
+ break;
+
+ default:
+ dev_err(&i2s->pdev->dev, "We don't serve that!\n");
+ return -EINVAL;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+
+ return 0;
+}
+
+static int i2s_set_fmt(struct snd_soc_dai *dai,
+ unsigned int fmt)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 mod = readl(i2s->addr + I2SMOD);
+ u32 tmp = 0;
+
+ /* Format is priority */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_RIGHT_J:
+ tmp |= MOD_LR_RLOW;
+ tmp |= MOD_SDF_MSB;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ tmp |= MOD_LR_RLOW;
+ tmp |= MOD_SDF_LSB;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ tmp |= MOD_SDF_IIS;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Format not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * INV flag is relative to the FORMAT flag - if set it simply
+ * flips the polarity specified by the Standard
+ */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ if (tmp & MOD_LR_RLOW)
+ tmp &= ~MOD_LR_RLOW;
+ else
+ tmp |= MOD_LR_RLOW;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Polarity not supported\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ tmp |= MOD_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ /* Set default source clock in Master mode */
+ if (i2s->rclk_srcrate == 0)
+ i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
+ 0, SND_SOC_CLOCK_IN);
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
+ return -EINVAL;
+ }
+
+ if (any_active(i2s) &&
+ ((mod & (MOD_SDF_MASK | MOD_LR_RLOW
+ | MOD_SLAVE)) != tmp)) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
+ mod |= tmp;
+ writel(mod, i2s->addr + I2SMOD);
+
+ return 0;
+}
+
+static int i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ if (!is_secondary(i2s))
+ mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
+
+ switch (params_channels(params)) {
+ case 6:
+ mod |= MOD_DC2_EN;
+ case 4:
+ mod |= MOD_DC1_EN;
+ break;
+ case 2:
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "%d channels not supported\n",
+ params_channels(params));
+ return -EINVAL;
+ }
+
+ if (is_secondary(i2s))
+ mod &= ~MOD_BLCS_MASK;
+ else
+ mod &= ~MOD_BLCP_MASK;
+
+ if (is_manager(i2s))
+ mod &= ~MOD_BLC_MASK;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_8BIT;
+ else
+ mod |= MOD_BLCP_8BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_8BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_16BIT;
+ else
+ mod |= MOD_BLCP_16BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_16BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_24BIT;
+ else
+ mod |= MOD_BLCP_24BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_24BIT;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
+ params_format(params));
+ return -EINVAL;
+ }
+ writel(mod, i2s->addr + I2SMOD);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_soc_dai_set_dma_data(dai, substream,
+ (void *)&i2s->dma_playback);
+ else
+ snd_soc_dai_set_dma_data(dai, substream,
+ (void *)&i2s->dma_capture);
+
+ i2s->frmclk = params_rate(params);
+
+ return 0;
+}
+
+/* We set constraints on the substream acc to the version of I2S */
+static int i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ i2s->mode |= DAI_OPENED;
+
+ if (is_manager(other))
+ i2s->mode &= ~DAI_MANAGER;
+ else
+ i2s->mode |= DAI_MANAGER;
+
+ /* Enforce set_sysclk in Master mode */
+ i2s->rclk_srcrate = 0;
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ return 0;
+}
+
+static void i2s_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ i2s->mode &= ~DAI_OPENED;
+ i2s->mode &= ~DAI_MANAGER;
+
+ if (is_opened(other))
+ other->mode |= DAI_MANAGER;
+
+ /* Reset any constraint on RFS and BFS */
+ i2s->rfs = 0;
+ i2s->bfs = 0;
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ /* Gate CDCLK by default */
+ if (!is_opened(other))
+ i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
+}
+
+static int config_setup(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned rfs, bfs, blc;
+ u32 psr;
+
+ blc = get_blc(i2s);
+
+ bfs = i2s->bfs;
+
+ if (!bfs && other)
+ bfs = other->bfs;
+
+ /* Select least possible multiple(2) if no constraint set */
+ if (!bfs)
+ bfs = blc * 2;
+
+ rfs = i2s->rfs;
+
+ if (!rfs && other)
+ rfs = other->rfs;
+
+ if ((rfs == 256 || rfs == 512) && (blc == 24)) {
+ dev_err(&i2s->pdev->dev,
+ "%d-RFS not supported for 24-blc\n", rfs);
+ return -EINVAL;
+ }
+
+ if (!rfs) {
+ if (bfs == 16 || bfs == 32)
+ rfs = 256;
+ else
+ rfs = 384;
+ }
+
+ /* If already setup and running */
+ if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ /* Don't bother RFS, BFS & PSR in Slave mode */
+ if (is_slave(i2s))
+ return 0;
+
+ set_bfs(i2s, bfs);
+ set_rfs(i2s, rfs);
+
+ if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+ psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
+ writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
+ dev_dbg(&i2s->pdev->dev,
+ "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
+ i2s->rclk_srcrate, psr, rfs, bfs);
+ }
+
+ return 0;
+}
+
+static int i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct i2s_dai *i2s = to_info(rtd->cpu_dai);
+ unsigned long flags;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ local_irq_save(flags);
+
+ if (capture)
+ i2s_fifo(i2s, FIC_RXFLUSH);
+ else
+ i2s_fifo(i2s, FIC_TXFLUSH);
+
+ if (config_setup(i2s)) {
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+
+ if (capture)
+ i2s_rxctrl(i2s, 1);
+ else
+ i2s_txctrl(i2s, 1);
+
+ local_irq_restore(flags);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ local_irq_save(flags);
+
+ if (capture)
+ i2s_rxctrl(i2s, 0);
+ else
+ i2s_txctrl(i2s, 0);
+
+ local_irq_restore(flags);
+ break;
+ }
+
+ return 0;
+}
+
+static int i2s_set_clkdiv(struct snd_soc_dai *dai,
+ int div_id, int div)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ switch (div_id) {
+ case SAMSUNG_I2S_DIV_BCLK:
+ if ((any_active(i2s) && div && (get_bfs(i2s) != div))
+ || (other && other->bfs && (other->bfs != div))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+ i2s->bfs = div;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev,
+ "Invalid clock divider(%d)\n", div_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_sframes_t
+i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 reg = readl(i2s->addr + I2SFIC);
+ snd_pcm_sframes_t delay;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ delay = FIC_RXCOUNT(reg);
+ else if (is_secondary(i2s))
+ delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
+ else
+ delay = FIC_TXCOUNT(reg);
+
+ return delay;
+}
+
+#ifdef CONFIG_PM
+static int i2s_suspend(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+
+ if (dai->active) {
+ i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
+ i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
+ i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+ }
+
+ return 0;
+}
+
+static int i2s_resume(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+
+ if (dai->active) {
+ writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
+ writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
+ writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
+ }
+
+ return 0;
+}
+#else
+#define i2s_suspend NULL
+#define i2s_resume NULL
+#endif
+
+static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (other && other->clk) /* If this is probe on secondary */
+ goto probe_exit;
+
+ i2s->addr = ioremap(i2s->base, 0x100);
+ if (i2s->addr == NULL) {
+ dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
+ return -ENXIO;
+ }
+
+ i2s->clk = clk_get(&i2s->pdev->dev, "iis");
+ if (IS_ERR(i2s->clk)) {
+ dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
+ iounmap(i2s->addr);
+ return -ENOENT;
+ }
+ clk_enable(i2s->clk);
+
+ if (other) {
+ other->addr = i2s->addr;
+ other->clk = i2s->clk;
+ }
+
+ if (i2s->quirks & QUIRK_NEED_RSTCLR)
+ writel(CON_RSTCLR, i2s->addr + I2SCON);
+
+probe_exit:
+ /* Reset any constraint on RFS and BFS */
+ i2s->rfs = 0;
+ i2s->bfs = 0;
+ i2s_txctrl(i2s, 0);
+ i2s_rxctrl(i2s, 0);
+ i2s_fifo(i2s, FIC_TXFLUSH);
+ i2s_fifo(other, FIC_TXFLUSH);
+ i2s_fifo(i2s, FIC_RXFLUSH);
+
+ /* Gate CDCLK by default */
+ if (!is_opened(other))
+ i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
+
+ return 0;
+}
+
+static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (!other || !other->clk) {
+
+ if (i2s->quirks & QUIRK_NEED_RSTCLR)
+ writel(0, i2s->addr + I2SCON);
+
+ clk_disable(i2s->clk);
+ clk_put(i2s->clk);
+
+ iounmap(i2s->addr);
+ }
+
+ i2s->clk = NULL;
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
+ .trigger = i2s_trigger,
+ .hw_params = i2s_hw_params,
+ .set_fmt = i2s_set_fmt,
+ .set_clkdiv = i2s_set_clkdiv,
+ .set_sysclk = i2s_set_sysclk,
+ .startup = i2s_startup,
+ .shutdown = i2s_shutdown,
+ .delay = i2s_delay,
+};
+
+#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
+
+#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static __devinit
+struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
+{
+ struct i2s_dai *i2s;
+
+ i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL);
+ if (i2s == NULL)
+ return NULL;
+
+ i2s->pdev = pdev;
+ i2s->pri_dai = NULL;
+ i2s->sec_dai = NULL;
+ i2s->i2s_dai_drv.symmetric_rates = 1;
+ i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
+ i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
+ i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
+ i2s->i2s_dai_drv.suspend = i2s_suspend;
+ i2s->i2s_dai_drv.resume = i2s_resume;
+ i2s->i2s_dai_drv.playback.channels_min = 2;
+ i2s->i2s_dai_drv.playback.channels_max = 2;
+ i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
+ i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
+
+ if (!sec) {
+ i2s->i2s_dai_drv.capture.channels_min = 2;
+ i2s->i2s_dai_drv.capture.channels_max = 2;
+ i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
+ i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
+ } else { /* Create a new platform_device for Secondary */
+ i2s->pdev = platform_device_register_resndata(NULL,
+ pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
+ NULL, 0, NULL, 0);
+ if (IS_ERR(i2s->pdev)) {
+ kfree(i2s);
+ return NULL;
+ }
+ }
+
+ /* Pre-assign snd_soc_dai_set_drvdata */
+ dev_set_drvdata(&i2s->pdev->dev, i2s);
+
+ return i2s;
+}
+
+static __devinit int samsung_i2s_probe(struct platform_device *pdev)
+{
+ u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
+ struct i2s_dai *pri_dai, *sec_dai = NULL;
+ struct s3c_audio_pdata *i2s_pdata;
+ struct samsung_i2s *i2s_cfg;
+ struct resource *res;
+ u32 regs_base, quirks;
+ int ret = 0;
+
+ /* Call during Seconday interface registration */
+ if (pdev->id >= SAMSUNG_I2S_SECOFF) {
+ sec_dai = dev_get_drvdata(&pdev->dev);
+ snd_soc_register_dai(&sec_dai->pdev->dev,
+ &sec_dai->i2s_dai_drv);
+ return 0;
+ }
+
+ i2s_pdata = pdev->dev.platform_data;
+ if (i2s_pdata == NULL) {
+ dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
+ return -ENXIO;
+ }
+ dma_pl_chan = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
+ return -ENXIO;
+ }
+ dma_cp_chan = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
+ if (res)
+ dma_pl_sec_chan = res->start;
+ else
+ dma_pl_sec_chan = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
+ return -ENXIO;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res),
+ "samsung-i2s")) {
+ dev_err(&pdev->dev, "Unable to request SFR region\n");
+ return -EBUSY;
+ }
+ regs_base = res->start;
+
+ i2s_cfg = &i2s_pdata->type.i2s;
+ quirks = i2s_cfg->quirks;
+
+ pri_dai = i2s_alloc_dai(pdev, false);
+ if (!pri_dai) {
+ dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
+ pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
+ pri_dai->dma_playback.client =
+ (struct s3c2410_dma_client *)&pri_dai->dma_playback;
+ pri_dai->dma_capture.client =
+ (struct s3c2410_dma_client *)&pri_dai->dma_capture;
+ pri_dai->dma_playback.channel = dma_pl_chan;
+ pri_dai->dma_capture.channel = dma_cp_chan;
+ pri_dai->src_clk = i2s_cfg->src_clk;
+ pri_dai->dma_playback.dma_size = 4;
+ pri_dai->dma_capture.dma_size = 4;
+ pri_dai->base = regs_base;
+ pri_dai->quirks = quirks;
+
+ if (quirks & QUIRK_PRI_6CHAN)
+ pri_dai->i2s_dai_drv.playback.channels_max = 6;
+
+ if (quirks & QUIRK_SEC_DAI) {
+ sec_dai = i2s_alloc_dai(pdev, true);
+ if (!sec_dai) {
+ dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+ sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
+ sec_dai->dma_playback.client =
+ (struct s3c2410_dma_client *)&sec_dai->dma_playback;
+ /* Use iDMA always if SysDMA not provided */
+ sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
+ sec_dai->src_clk = i2s_cfg->src_clk;
+ sec_dai->dma_playback.dma_size = 4;
+ sec_dai->base = regs_base;
+ sec_dai->quirks = quirks;
+ sec_dai->pri_dai = pri_dai;
+ pri_dai->sec_dai = sec_dai;
+ }
+
+ if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
+ dev_err(&pdev->dev, "Unable to configure gpio\n");
+ ret = -EINVAL;
+ goto err3;
+ }
+
+ snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
+
+ return 0;
+err3:
+ kfree(sec_dai);
+err2:
+ kfree(pri_dai);
+err1:
+ release_mem_region(regs_base, resource_size(res));
+
+ return ret;
+}
+
+static __devexit int samsung_i2s_remove(struct platform_device *pdev)
+{
+ struct i2s_dai *i2s, *other;
+
+ i2s = dev_get_drvdata(&pdev->dev);
+ other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (other) {
+ other->pri_dai = NULL;
+ other->sec_dai = NULL;
+ } else {
+ struct resource *res;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+ }
+
+ i2s->pri_dai = NULL;
+ i2s->sec_dai = NULL;
+
+ kfree(i2s);
+
+ snd_soc_unregister_dai(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver samsung_i2s_driver = {
+ .probe = samsung_i2s_probe,
+ .remove = samsung_i2s_remove,
+ .driver = {
+ .name = "samsung-i2s",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init samsung_i2s_init(void)
+{
+ return platform_driver_register(&samsung_i2s_driver);
+}
+module_init(samsung_i2s_init);
+
+static void __exit samsung_i2s_exit(void)
+{
+ platform_driver_unregister(&samsung_i2s_driver);
+}
+module_exit(samsung_i2s_exit);
+
+/* Module information */
+MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Samsung I2S Interface");
+MODULE_ALIAS("platform:samsung-i2s");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
new file mode 100644
index 000000000000..8e15f6a616d1
--- /dev/null
+++ b/sound/soc/samsung/i2s.h
@@ -0,0 +1,29 @@
+/* sound/soc/samsung/i2s.h
+ *
+ * ALSA SoC Audio Layer - Samsung I2S Controller driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SND_SOC_SAMSUNG_I2S_H
+#define __SND_SOC_SAMSUNG_I2S_H
+
+/*
+ * Maximum number of I2S blocks that any SoC can have.
+ * The secondary interface of a CPU dai(if there exists any),
+ * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
+ */
+#define SAMSUNG_I2S_SECOFF 4
+
+#define SAMSUNG_I2S_DIV_BCLK 1
+
+#define SAMSUNG_I2S_RCLKSRC_0 0
+#define SAMSUNG_I2S_RCLKSRC_1 1
+#define SAMSUNG_I2S_CDCLK 2
+
+#endif /* __SND_SOC_SAMSUNG_I2S_H */
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 49605cd83947..08802520e014 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/jive_wm8750.c
+/* sound/soc/samsung/jive_wm8750.c
*
* Copyright 2007,2008 Simtec Electronics
*
@@ -21,11 +21,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c2412-i2s.h"
#include "../codecs/wm8750.h"
@@ -111,18 +110,19 @@ static struct snd_soc_ops jive_ops = {
static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* These endpoints are not being used. */
- snd_soc_dapm_nc_pin(codec, "LINPUT2");
- snd_soc_dapm_nc_pin(codec, "RINPUT2");
- snd_soc_dapm_nc_pin(codec, "LINPUT3");
- snd_soc_dapm_nc_pin(codec, "RINPUT3");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONO");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONO");
/* Add jive specific widgets */
- err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
if (err) {
printk(KERN_ERR "%s: failed to add widgets (%d)\n",
@@ -130,8 +130,8 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
return err;
}
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -141,7 +141,7 @@ static struct snd_soc_dai_link jive_dai = {
.stream_name = "WM8750",
.cpu_dai_name = "s3c2412-i2s",
.codec_dai_name = "wm8750-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8750-codec.0-0x1a",
.init = jive_wm8750_init,
.ops = &jive_ops,
diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/samsung/lm4857.h
index 0cf5b7011d6f..0cf5b7011d6f 100644
--- a/sound/soc/s3c24xx/lm4857.h
+++ b/sound/soc/samsung/lm4857.h
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index abe64abe8c84..a2bb34def740 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -21,10 +21,9 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card ln2440sbc;
@@ -32,10 +31,10 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 HiFi",
- .cpu_dai_name = "s3c-ac97",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
index e97bdf150a03..3eec610c10f9 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/samsung/neo1973_gta02_wm8753.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
@@ -32,7 +31,7 @@
#include <asm/io.h>
#include <mach/gta02.h>
#include "../codecs/wm8753.h"
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
static struct snd_soc_card neo1973_gta02;
@@ -333,16 +332,17 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "OUT4");
- snd_soc_dapm_nc_pin(codec, "LINE1");
- snd_soc_dapm_nc_pin(codec, "LINE2");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT4");
+ snd_soc_dapm_nc_pin(dapm, "LINE1");
+ snd_soc_dapm_nc_pin(dapm, "LINE2");
/* Add neo1973 gta02 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
ARRAY_SIZE(wm8753_dapm_widgets));
/* add neo1973 gta02 specific controls */
@@ -353,25 +353,25 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* set up neo1973 gta02 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* set endpoints to default off mode */
- snd_soc_dapm_disable_pin(codec, "Stereo Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Handset Mic");
- snd_soc_dapm_disable_pin(codec, "Handset Spk");
+ snd_soc_dapm_disable_pin(dapm, "Stereo Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Handset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Handset Spk");
/* allow audio paths from the GSM modem to run during suspend */
- snd_soc_dapm_ignore_suspend(codec, "Stereo Out");
- snd_soc_dapm_ignore_suspend(codec, "GSM Line Out");
- snd_soc_dapm_ignore_suspend(codec, "GSM Line In");
- snd_soc_dapm_ignore_suspend(codec, "Headset Mic");
- snd_soc_dapm_ignore_suspend(codec, "Handset Mic");
- snd_soc_dapm_ignore_suspend(codec, "Handset Spk");
+ snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
+ snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
+ snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "wm8753-hifi",
.init = neo1973_gta02_wm8753_init,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8753-codec.0-0x1a",
.ops = &neo1973_gta02_hifi_ops,
},
@@ -411,7 +411,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
.codec_dai_name = "wm8753-voice",
.ops = &neo1973_gta02_voice_ops,
.codec_name = "wm8753-codec.0-0x1a",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
@@ -438,25 +438,21 @@ static int __init neo1973_gta02_init(void)
return -ENOMEM;
/* register bluetooth DAI here */
- ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai);
- if (ret) {
- platform_device_put(neo1973_gta02_snd_device);
- return ret;
- }
+ ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
+ if (ret)
+ goto err_put_device;
platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
ret = platform_device_add(neo1973_gta02_snd_device);
- if (ret) {
- platform_device_put(neo1973_gta02_snd_device);
- return ret;
- }
+ if (ret)
+ goto err_unregister_dai;
/* Initialise GPIOs used by amp */
ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
if (ret) {
pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
- goto err_unregister_device;
+ goto err_del_device;
}
ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
@@ -483,15 +479,19 @@ err_free_gpio_amp_shut:
gpio_free(GTA02_GPIO_AMP_SHUT);
err_free_gpio_hp_in:
gpio_free(GTA02_GPIO_HP_IN);
-err_unregister_device:
- platform_device_unregister(neo1973_gta02_snd_device);
+err_del_device:
+ platform_device_del(neo1973_gta02_snd_device);
+err_unregister_dai:
+ snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
+err_put_device:
+ platform_device_put(neo1973_gta02_snd_device);
return ret;
}
module_init(neo1973_gta02_init);
static void __exit neo1973_gta02_exit(void)
{
- snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1);
+ snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
platform_device_unregister(neo1973_gta02_snd_device);
gpio_free(GTA02_GPIO_HP_IN);
gpio_free(GTA02_GPIO_AMP_SHUT);
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index f4f2ee731f01..c7a24514beb5 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <asm/mach-types.h>
@@ -36,7 +35,7 @@
#include "../codecs/wm8753.h"
#include "lm4857.h"
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
/* define the scenarios */
@@ -237,81 +236,83 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
pr_debug("Entered %s\n", __func__);
switch (neo1973_scenario) {
case NEO_AUDIO_OFF:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_HANDSET:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_HEADSET:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_BLUETOOTH:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_STEREO_TO_SPEAKERS:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_STEREO_TO_HEADPHONES:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_HANDSET:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_HEADSET:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_BLUETOOTH:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
default:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -502,20 +503,21 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
pr_debug("Entered %s\n", __func__);
/* set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "LOUT2");
- snd_soc_dapm_nc_pin(codec, "ROUT2");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "OUT4");
- snd_soc_dapm_nc_pin(codec, "LINE1");
- snd_soc_dapm_nc_pin(codec, "LINE2");
+ snd_soc_dapm_nc_pin(dapm, "LOUT2");
+ snd_soc_dapm_nc_pin(dapm, "ROUT2");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT4");
+ snd_soc_dapm_nc_pin(dapm, "LINE1");
+ snd_soc_dapm_nc_pin(dapm, "LINE2");
/* Add neo1973 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
ARRAY_SIZE(wm8753_dapm_widgets));
/* set endpoints to default mode */
@@ -528,10 +530,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* set up neo1973 specific audio routes */
- err = snd_soc_dapm_add_routes(codec, dapm_routes,
+ err = snd_soc_dapm_add_routes(dapm, dapm_routes,
ARRAY_SIZE(dapm_routes));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -556,7 +558,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
{ /* Hifi Playback - for similatious use with voice below */
.name = "WM8753",
.stream_name = "WM8753 HiFi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "wm8753-hifi",
.codec_name = "wm8753-codec.0-0x1a",
@@ -566,7 +568,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
{ /* Voice via BT */
.name = "Bluetooth",
.stream_name = "Voice",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "bluetooth-dai",
.codec_dai_name = "wm8753-voice",
.codec_name = "wm8753-codec.0-0x1a",
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/samsung/pcm.c
index 2e020e1b4eab..48d0b750406b 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-pcm.c
+/* sound/soc/samsung/pcm.c
*
* ALSA SoC Audio Layer - S3C PCM-Controller driver
*
@@ -29,8 +29,8 @@
#include <plat/audio.h>
#include <plat/dma.h>
-#include "s3c-dma.h"
-#include "s3c-pcm.h"
+#include "dma.h"
+#include "pcm.h"
static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
.name = "PCM Stereo out"
diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/samsung/pcm.h
index f60baa19387d..03393dcf852d 100644
--- a/sound/soc/s3c24xx/s3c-pcm.h
+++ b/sound/soc/samsung/pcm.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-pcm.h
+/* sound/soc/samsung/pcm.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h
index 5e5e5680580b..5e5e5680580b 100644
--- a/sound/soc/s3c24xx/regs-i2s-v2.h
+++ b/sound/soc/samsung/regs-i2s-v2.h
diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 468cc11fdf47..5a4587e02886 100644
--- a/sound/soc/s3c24xx/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -25,7 +25,6 @@
#include <linux/clk.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/uda1380.h>
#include <sound/jack.h>
@@ -35,7 +34,7 @@
#include <asm/mach-types.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "../codecs/uda1380.h"
@@ -95,7 +94,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
.cpu_dai_name = "s3c24xx-iis",
.codec_dai_name = "uda1380-hifi",
.init = rx1950_uda1380_init,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "uda1380-codec.0-001a",
.ops = &rx1950_ops,
},
@@ -228,26 +227,27 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Add rx1950 specific widgets */
- err = snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
ARRAY_SIZE(uda1380_dapm_widgets));
if (err)
return err;
/* Set up rx1950 specific audio path audio_mapnects */
- err = snd_soc_dapm_add_routes(codec, audio_map,
+ err = snd_soc_dapm_add_routes(dapm, audio_map,
ARRAY_SIZE(audio_map));
if (err)
return err;
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
&hp_jack);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index b3866d5b19e9..094f36e41e83 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-i2c-v2.c
+/* sound/soc/samsung/s3c-i2c-v2.c
*
* ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
*
@@ -28,7 +28,7 @@
#include "regs-i2s-v2.h"
#include "s3c-i2s-v2.h"
-#include "s3c-dma.h"
+#include "dma.h"
#undef S3C_IIS_V2_SUPPORTED
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h
index d45830151484..f8297d9bb8a3 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/samsung/s3c-i2s-v2.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-i2s-v2.h
+/* sound/soc/samsung/s3c-i2s-v2.h
*
* ALSA Soc Audio Layer - S3C_I2SV2 I2S driver
*
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 4a861cfa52c5..7ea837867124 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c2412-i2s.c
+/* sound/soc/samsung/s3c2412-i2s.c
*
* ALSA Soc Audio Layer - S3C2412 I2S driver
*
@@ -35,7 +35,7 @@
#include <mach/regs-gpio.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "regs-i2s-v2.h"
#include "s3c2412-i2s.h"
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h
index 01a0471ac65c..02ad5794c0a9 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/samsung/s3c2412-i2s.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c2412-i2s.c
+/* sound/soc/samsung/s3c2412-i2s.c
*
* ALSA Soc Audio Layer - S3C2412 I2S driver
*
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index e060daaa458f..13e41ed8e22b 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -38,7 +38,7 @@
#include <plat/regs-iis.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
static struct s3c2410_dma_client s3c24xx_dma_client_out = {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h
index f9ca04edacb7..f9ca04edacb7 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.h
+++ b/sound/soc/samsung/s3c24xx-i2s.h
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index c4c111442010..a434032d1832 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec.c
+/* sound/soc/samsung/s3c24xx_simtec.c
*
* Copyright 2009 Simtec Electronics
*
@@ -17,11 +17,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h
index e63d5ff9c41f..8270748a2c41 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.h
+++ b/sound/soc/samsung/s3c24xx_simtec.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec.h
+/* sound/soc/samsung/s3c24xx_simtec.h
*
* Copyright 2009 Simtec Electronics
*
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index f88453735ae2..0083aff5a83d 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+/* sound/soc/samsung/s3c24xx_simtec_hermes.c
*
* Copyright 2009 Simtec Electronics
*
@@ -14,11 +14,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
@@ -76,19 +75,20 @@ static const struct snd_soc_dapm_route base_map[] = {
static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, dapm_widgets,
ARRAY_SIZE(dapm_widgets));
- snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
+ snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
simtec_audio_init(rtd);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -99,7 +99,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = {
.codec_name = "tlv320aic3x-codec.0-0x1a",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.init = simtec_hermes_init,
};
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index c0967593510d..fbba4e367729 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
*
* Copyright 2009 Simtec Electronics
*
@@ -14,11 +14,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
@@ -65,19 +64,20 @@ static const struct snd_soc_dapm_route base_map[] = {
static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, dapm_widgets,
ARRAY_SIZE(dapm_widgets));
- snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
+ snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
simtec_audio_init(rtd);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -88,7 +88,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = {
.codec_name = "tlv320aic3x-codec.0-0x1a",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.init = simtec_tlv320aic23_init,
};
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index bd48ffbde880..cdc8ecbcb8ef 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -18,13 +18,12 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/s3c24xx_uda134x.h>
#include <sound/uda134x.h>
#include <plat/regs-iis.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "../codecs/uda134x.h"
@@ -231,7 +230,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
.codec_dai_name = "uda134x-hifi",
.cpu_dai_name = "s3c24xx-i2s",
.ops = &s3c24xx_uda134x_ops,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
};
static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index dd20ca7f4681..61e2b5219d42 100644
--- a/sound/soc/s3c24xx/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/smartq_wm8987.c
+/* sound/soc/samsung/smartq_wm8987.c
*
* Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com>
*
@@ -19,13 +19,13 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
#include "../codecs/wm8750.h"
@@ -39,15 +39,11 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct s3c_i2sv2_rate_calc div;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned int clk = 0;
int ret;
- s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
- s3c_i2sv2_get_clock(cpu_dai));
-
switch (params_rate(params)) {
case 8000:
case 16000:
@@ -78,20 +74,21 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
+ /* Use PCLK for I2S signal generation */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
+ 0, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
- /* set MCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div);
+ /* Gate the RCLK output on PAD */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
- /* set prescaler division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER,
- div.clk_div - 1);
+ /* set the codec system clock for DAC and ADC */
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
+ SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
@@ -156,12 +153,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LINPUT2", NULL, "Mic Bias"},
};
-static int smartq_wm8987_init(struct snd_soc_codec *codec)
+static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err = 0;
/* Add SmartQ specific widgets */
- snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets,
ARRAY_SIZE(wm8987_dapm_widgets));
/* add SmartQ specific controls */
@@ -172,25 +171,25 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec)
return err;
/* setup SmartQ specific audio path */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "LINPUT1");
- snd_soc_dapm_nc_pin(codec, "RINPUT1");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "ROUT1");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "ROUT1");
/* set endpoints to default off mode */
- snd_soc_dapm_enable_pin(codec, "Internal Speaker");
- snd_soc_dapm_enable_pin(codec, "Internal Mic");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Internal Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Internal Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- err = snd_soc_dapm_sync(codec);
+ err = snd_soc_dapm_sync(dapm);
if (err)
return err;
/* Headphone jack detection */
- err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack",
+ err = snd_soc_jack_new(codec, "Headphone Jack",
SND_JACK_HEADPHONE, &smartq_jack);
if (err)
return err;
@@ -211,9 +210,9 @@ static struct snd_soc_dai_link smartq_dai[] = {
{
.name = "wm8987",
.stream_name = "SmartQ Hi-Fi",
- .cpu_dai_name = "s3c64xx-i2s.0",
+ .cpu_dai_name = "samsung-i2s.0",
.codec_dai_name = "wm8750-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8750-codec.0-0x1a",
.init = smartq_wm8987_init,
.ops = &smartq_hifi_ops,
@@ -275,6 +274,7 @@ err_unregister_device:
static void __exit smartq_exit(void)
{
+ gpio_free(S3C64XX_GPK(12));
snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios),
smartq_jack_gpios);
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 4613288c2772..3be7e7e92d6e 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -17,10 +17,9 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card smdk2443;
@@ -28,10 +27,10 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 HiFi",
- .cpu_dai_name = "s3c-ac97",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index c8bd90488a87..cb2f4d04ab7e 100644
--- a/sound/soc/s3c24xx/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -18,7 +18,7 @@
#include <sound/soc.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "spdif.h"
/* Audio clock settings are belonged to board specific part. Every
@@ -28,7 +28,7 @@
static int set_audio_clock_heirachy(struct platform_device *pdev)
{
struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif;
- int ret;
+ int ret = 0;
fout_epll = clk_get(NULL, "fout_epll");
if (IS_ERR(fout_epll)) {
@@ -152,12 +152,10 @@ static struct snd_soc_ops smdk_spdif_ops = {
.hw_params = smdk_hw_params,
};
-static struct snd_soc_card smdk;
-
static struct snd_soc_dai_link smdk_dai = {
.name = "S/PDIF",
.stream_name = "S/PDIF PCM Playback",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "samsung-spdif",
.codec_dai_name = "dit-hifi",
.codec_name = "spdif-dit",
@@ -183,7 +181,7 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_spdif_dit_device);
if (ret)
- goto err2;
+ goto err1;
smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1);
if (!smdk_snd_spdif_device) {
@@ -195,17 +193,21 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_spdif_device);
if (ret)
- goto err1;
+ goto err3;
/* Set audio clock heirachy manually */
ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
if (ret)
- goto err1;
+ goto err4;
return 0;
-err1:
+err4:
+ platform_device_del(smdk_snd_spdif_device);
+err3:
platform_device_put(smdk_snd_spdif_device);
err2:
+ platform_device_del(smdk_snd_spdif_dit_device);
+err1:
platform_device_put(smdk_snd_spdif_dit_device);
return ret;
}
@@ -213,6 +215,7 @@ err2:
static void __exit smdk_exit(void)
{
platform_device_unregister(smdk_snd_spdif_device);
+ platform_device_unregister(smdk_snd_spdif_dit_device);
}
module_init(smdk_init);
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 052e499b68d1..e2d56b9bac5a 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -1,5 +1,5 @@
/*
- * smdk64xx_wm8580.c
+ * smdk_wm8580.c
*
* Copyright (c) 2009 Samsung Electronics Co. Ltd
* Author: Jaswinder Singh <jassi.brar@samsung.com>
@@ -16,11 +16,12 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
#include "../codecs/wm8580.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
/*
* Default CFG switch settings to use this driver:
@@ -28,10 +29,10 @@
* SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On
*/
-/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
-#define SMDK64XX_WM8580_FREQ 12000000
+/* SMDK has a 12MHZ crystal attached to WM8580 */
+#define SMDK_WM8580_FREQ 12000000
-static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
+static int smdk_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -96,17 +97,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* We use PCLK for basic ops in SoC-Slave mode */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
/* Set WM8580 to drive MCLK from its PLLA */
ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
WM8580_CLKSRC_PLLA);
@@ -114,7 +104,7 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
return ret;
ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
- SMDK64XX_WM8580_FREQ, pll_out);
+ SMDK_WM8580_FREQ, pll_out);
if (ret < 0)
return ret;
@@ -123,32 +113,24 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
- if (ret < 0)
- return ret;
-
return 0;
}
/*
- * SMDK64XX WM8580 DAI operations.
+ * SMDK WM8580 DAI operations.
*/
-static struct snd_soc_ops smdk64xx_ops = {
- .hw_params = smdk64xx_hw_params,
+static struct snd_soc_ops smdk_ops = {
+ .hw_params = smdk_hw_params,
};
-/* SMDK64xx Playback widgets */
+/* SMDK Playback widgets */
static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
SND_SOC_DAPM_HP("Front", NULL),
SND_SOC_DAPM_HP("Center+Sub", NULL),
SND_SOC_DAPM_HP("Rear", NULL),
};
-/* SMDK64xx Capture widgets */
+/* SMDK Capture widgets */
static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
SND_SOC_DAPM_MIC("MicIn", NULL),
SND_SOC_DAPM_LINE("LineIn", NULL),
@@ -179,94 +161,131 @@ static const struct snd_soc_dapm_route audio_map_rx[] = {
{"Rear", NULL, "VOUT3R"},
};
-static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
+static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- /* Add smdk64xx specific Capture widgets */
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
+ /* Add smdk specific Capture widgets */
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt,
ARRAY_SIZE(wm8580_dapm_widgets_cpt));
/* Set up PAIFTX audio path */
- snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx));
+ snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx));
/* Enabling the microphone requires the fitting of a 0R
* resistor to connect the line from the microphone jack.
*/
- snd_soc_dapm_disable_pin(codec, "MicIn");
+ snd_soc_dapm_disable_pin(dapm, "MicIn");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
-static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
+static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- /* Add smdk64xx specific Playback widgets */
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
+ /* Add smdk specific Playback widgets */
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk,
ARRAY_SIZE(wm8580_dapm_widgets_pbk));
/* Set up PAIFRX audio path */
- snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx));
+ snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx));
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
-static struct snd_soc_dai_link smdk64xx_dai[] = {
-{ /* Primary Playback i/f */
- .name = "WM8580 PAIF RX",
- .stream_name = "Playback",
- .cpu_dai_name = "s3c64xx-iis-v4",
- .codec_dai_name = "wm8580-hifi-playback",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8580-codec.0-001b",
- .init = smdk64xx_wm8580_init_paifrx,
- .ops = &smdk64xx_ops,
-},
-{ /* Primary Capture i/f */
- .name = "WM8580 PAIF TX",
- .stream_name = "Capture",
- .cpu_dai_name = "s3c64xx-iis-v4",
- .codec_dai_name = "wm8580-hifi-capture",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8580-codec.0-001b",
- .init = smdk64xx_wm8580_init_paiftx,
- .ops = &smdk64xx_ops,
-},
+enum {
+ PRI_PLAYBACK = 0,
+ PRI_CAPTURE,
+ SEC_PLAYBACK,
+};
+
+static struct snd_soc_dai_link smdk_dai[] = {
+ [PRI_PLAYBACK] = { /* Primary Playback i/f */
+ .name = "WM8580 PAIF RX",
+ .stream_name = "Playback",
+ .cpu_dai_name = "samsung-i2s.2",
+ .codec_dai_name = "wm8580-hifi-playback",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paifrx,
+ .ops = &smdk_ops,
+ },
+ [PRI_CAPTURE] = { /* Primary Capture i/f */
+ .name = "WM8580 PAIF TX",
+ .stream_name = "Capture",
+ .cpu_dai_name = "samsung-i2s.2",
+ .codec_dai_name = "wm8580-hifi-capture",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paiftx,
+ .ops = &smdk_ops,
+ },
+ [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
+ .name = "Sec_FIFO TX",
+ .stream_name = "Playback",
+ .cpu_dai_name = "samsung-i2s.x",
+ .codec_dai_name = "wm8580-hifi-playback",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paifrx,
+ .ops = &smdk_ops,
+ },
};
-static struct snd_soc_card smdk64xx = {
- .name = "SMDK64xx 5.1",
- .dai_link = smdk64xx_dai,
- .num_links = ARRAY_SIZE(smdk64xx_dai),
+static struct snd_soc_card smdk = {
+ .name = "SMDK-I2S",
+ .dai_link = smdk_dai,
+ .num_links = 2,
};
-static struct platform_device *smdk64xx_snd_device;
+static struct platform_device *smdk_snd_device;
-static int __init smdk64xx_audio_init(void)
+static int __init smdk_audio_init(void)
{
int ret;
+ char *str;
+
+ if (machine_is_smdkc100()) {
+ smdk.num_links = 3;
+ /* S5PC100 has I2S0 as v5 */
+ str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
+ str[strlen(str) - 1] = '0';
+ str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name;
+ str[strlen(str) - 1] = '0';
+ /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
+ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
+ str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
+ }
- smdk64xx_snd_device = platform_device_alloc("soc-audio", -1);
- if (!smdk64xx_snd_device)
+ smdk_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!smdk_snd_device)
return -ENOMEM;
- platform_set_drvdata(smdk64xx_snd_device, &smdk64xx);
- ret = platform_device_add(smdk64xx_snd_device);
+ platform_set_drvdata(smdk_snd_device, &smdk);
+ ret = platform_device_add(smdk_snd_device);
if (ret)
- platform_device_put(smdk64xx_snd_device);
+ platform_device_put(smdk_snd_device);
return ret;
}
-module_init(smdk64xx_audio_init);
+module_init(smdk_audio_init);
+
+static void __exit smdk_audio_exit(void)
+{
+ platform_device_unregister(smdk_snd_device);
+}
+module_exit(smdk_audio_exit);
MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
-MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580");
+MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 33ba8fdbcf07..238cb3a38c5d 100644
--- a/sound/soc/s3c24xx/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -15,8 +15,8 @@
#include <linux/device.h>
#include <sound/soc.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card smdk;
@@ -45,8 +45,8 @@ static struct snd_soc_card smdk;
static struct snd_soc_dai_link smdk_dai = {
.name = "AC97",
.stream_name = "AC97 PCM",
- .platform_name = "s3c24xx-pcm-audio",
- .cpu_dai_name = "s3c-ac97",
+ .platform_name = "samsung-audio",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "wm9713-hifi",
.codec_name = "wm9713-codec",
};
@@ -70,24 +70,27 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_wm9713_device);
if (ret)
- goto err;
+ goto err1;
smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
if (!smdk_snd_ac97_device) {
ret = -ENOMEM;
- goto err;
+ goto err2;
}
platform_set_drvdata(smdk_snd_ac97_device, &smdk);
ret = platform_device_add(smdk_snd_ac97_device);
- if (ret) {
- platform_device_put(smdk_snd_ac97_device);
- goto err;
- }
+ if (ret)
+ goto err3;
return 0;
-err:
+
+err3:
+ platform_device_put(smdk_snd_ac97_device);
+err2:
+ platform_device_del(smdk_snd_wm9713_device);
+err1:
platform_device_put(smdk_snd_wm9713_device);
return ret;
}
diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/samsung/spdif.c
index ce554e9cabcc..f0816404ea3e 100644
--- a/sound/soc/s3c24xx/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/spdif.c
+/* sound/soc/samsung/spdif.c
*
* ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
*
@@ -20,7 +20,7 @@
#include <plat/audio.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "spdif.h"
/* Registers */
diff --git a/sound/soc/s3c24xx/spdif.h b/sound/soc/samsung/spdif.h
index 3ed55592710f..4f72cb446dbf 100644
--- a/sound/soc/s3c24xx/spdif.h
+++ b/sound/soc/samsung/spdif.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/spdif.h
+/* sound/soc/samsung/spdif.h
*
* ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
*
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index d96602de71de..a14820ac9665 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -12,6 +12,14 @@
#include <linux/platform_device.h>
#include <sound/sh_fsi.h>
+struct fsi_ak4642_data {
+ const char *name;
+ const char *card;
+ const char *cpu_dai;
+ const char *codec;
+ const char *platform;
+};
+
static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->codec_dai;
@@ -27,37 +35,42 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
}
static struct snd_soc_dai_link fsi_dai_link = {
- .name = "AK4642",
- .stream_name = "AK4642",
- .cpu_dai_name = "fsia-dai", /* fsi A */
.codec_dai_name = "ak4642-hifi",
-#ifdef CONFIG_MACH_AP4EVB
- .platform_name = "sh_fsi2",
- .codec_name = "ak4642-codec.0-0013",
-#else
- .platform_name = "sh_fsi.0",
- .codec_name = "ak4642-codec.0-0012",
-#endif
.init = fsi_ak4642_dai_init,
- .ops = NULL,
};
static struct snd_soc_card fsi_soc_card = {
- .name = "FSI (AK4642)",
.dai_link = &fsi_dai_link,
.num_links = 1,
};
static struct platform_device *fsi_snd_device;
-static int __init fsi_ak4642_init(void)
+static int fsi_ak4642_probe(struct platform_device *pdev)
{
int ret = -ENOMEM;
+ const struct platform_device_id *id_entry;
+ struct fsi_ak4642_data *pdata;
+
+ id_entry = pdev->id_entry;
+ if (!id_entry) {
+ dev_err(&pdev->dev, "unknown fsi ak4642\n");
+ return -ENODEV;
+ }
+
+ pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A);
if (!fsi_snd_device)
goto out;
+ fsi_dai_link.name = pdata->name;
+ fsi_dai_link.stream_name = pdata->name;
+ fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
+ fsi_dai_link.platform_name = pdata->platform;
+ fsi_dai_link.codec_name = pdata->codec;
+ fsi_soc_card.name = pdata->card;
+
platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_snd_device);
@@ -68,9 +81,108 @@ out:
return ret;
}
-static void __exit fsi_ak4642_exit(void)
+static int fsi_ak4642_remove(struct platform_device *pdev)
{
platform_device_unregister(fsi_snd_device);
+ return 0;
+}
+
+static struct fsi_ak4642_data fsi_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIA (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIB (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIA (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIB (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2A (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2B (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2A (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2B (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct platform_device_id fsi_id_table[] = {
+ /* FSI */
+ { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
+ { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
+ { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
+ { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
+
+ /* FSI 2 */
+ { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
+ { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
+ { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
+ { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
+ {},
+};
+
+static struct platform_driver fsi_ak4642 = {
+ .driver = {
+ .name = "fsi-ak4642-audio",
+ },
+ .probe = fsi_ak4642_probe,
+ .remove = fsi_ak4642_remove,
+ .id_table = fsi_id_table,
+};
+
+static int __init fsi_ak4642_init(void)
+{
+ return platform_driver_register(&fsi_ak4642);
+}
+
+static void __exit fsi_ak4642_exit(void)
+{
+ platform_driver_unregister(&fsi_ak4642);
}
module_init(fsi_ak4642_init);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 4c2404b1b862..97c5394aa7d7 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,20 +19,26 @@
#include <sound/soc.h>
#include <sound/sh_fsi.h>
-#define DO_FMT 0x0000
-#define DOFF_CTL 0x0004
-#define DOFF_ST 0x0008
-#define DI_FMT 0x000C
-#define DIFF_CTL 0x0010
-#define DIFF_ST 0x0014
-#define CKG1 0x0018
-#define CKG2 0x001C
-#define DIDT 0x0020
-#define DODT 0x0024
-#define MUTE_ST 0x0028
-#define OUT_SEL 0x0030
-#define REG_END OUT_SEL
-
+/* PortA/PortB register */
+#define REG_DO_FMT 0x0000
+#define REG_DOFF_CTL 0x0004
+#define REG_DOFF_ST 0x0008
+#define REG_DI_FMT 0x000C
+#define REG_DIFF_CTL 0x0010
+#define REG_DIFF_ST 0x0014
+#define REG_CKG1 0x0018
+#define REG_CKG2 0x001C
+#define REG_DIDT 0x0020
+#define REG_DODT 0x0024
+#define REG_MUTE_ST 0x0028
+#define REG_OUT_SEL 0x0030
+
+/* master register */
+#define MST_CLK_RST 0x0210
+#define MST_SOFT_RST 0x0214
+#define MST_FIFO_SZ 0x0218
+
+/* core register (depend on FSI version) */
#define A_MST_CTLR 0x0180
#define B_MST_CTLR 0x01A0
#define CPU_INT_ST 0x01F4
@@ -41,22 +47,23 @@
#define INT_ST 0x0200
#define IEMSK 0x0204
#define IMSK 0x0208
-#define MUTE 0x020C
-#define CLK_RST 0x0210
-#define SOFT_RST 0x0214
-#define FIFO_SZ 0x0218
-#define MREG_START A_MST_CTLR
-#define MREG_END FIFO_SZ
/* DO_FMT */
/* DI_FMT */
+#define CR_BWS_24 (0x0 << 20) /* FSI2 */
+#define CR_BWS_16 (0x1 << 20) /* FSI2 */
+#define CR_BWS_20 (0x2 << 20) /* FSI2 */
+
+#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */
+
#define CR_MONO (0x0 << 4)
#define CR_MONO_D (0x1 << 4)
#define CR_PCM (0x2 << 4)
#define CR_I2S (0x3 << 4)
#define CR_TDM (0x4 << 4)
#define CR_TDM_D (0x5 << 4)
-#define CR_SPDIF 0x00100120
/* DOFF_CTL */
/* DIFF_CTL */
@@ -93,6 +100,10 @@
#define IR (1 << 4) /* Interrupt Reset */
#define FSISR (1 << 0) /* Software Reset */
+/* OUT_SEL (FSI2) */
+#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */
+ /* 1: Biphase and serial */
+
/* FIFO_SZ */
#define FIFO_SZ_MASK 0x7
@@ -133,8 +144,6 @@ struct fsi_priv {
struct fsi_stream capture;
long rate;
-
- u32 mst_ctrl;
};
struct fsi_core {
@@ -143,6 +152,8 @@ struct fsi_core {
u32 int_st;
u32 iemsk;
u32 imsk;
+ u32 a_mclk;
+ u32 b_mclk;
};
struct fsi_master {
@@ -182,62 +193,22 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
__fsi_reg_write(reg, val);
}
-static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
+#define fsi_reg_write(p, r, d)\
+ __fsi_reg_write((u32)(p->base + REG_##r), d)
- __fsi_reg_write((u32)(fsi->base + reg), data);
-}
+#define fsi_reg_read(p, r)\
+ __fsi_reg_read((u32)(p->base + REG_##r))
-static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
+#define fsi_reg_mask_set(p, r, m, d)\
+ __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
- return __fsi_reg_read((u32)(fsi->base + reg));
-}
-
-static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
-}
-
-static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
-{
- unsigned long flags;
-
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&master->lock, flags);
- __fsi_reg_write((u32)(master->base + reg), data);
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-static u32 fsi_master_read(struct fsi_master *master, u32 reg)
+#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
+#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
+static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
{
u32 ret;
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
-
spin_lock_irqsave(&master->lock, flags);
ret = __fsi_reg_read((u32)(master->base + reg));
spin_unlock_irqrestore(&master->lock, flags);
@@ -245,17 +216,13 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg)
return ret;
}
-static void fsi_master_mask_set(struct fsi_master *master,
+#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
+#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d)
+static void _fsi_master_mask_set(struct fsi_master *master,
u32 reg, u32 mask, u32 data)
{
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
spin_lock_irqsave(&master->lock, flags);
__fsi_reg_mask_set((u32)(master->base + reg), mask, data);
spin_unlock_irqrestore(&master->lock, flags);
@@ -375,11 +342,13 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
{
u32 status;
- u32 reg = is_play ? DOFF_ST : DIFF_ST;
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
int data_num;
- status = fsi_reg_read(fsi, reg);
+ status = is_play ?
+ fsi_reg_read(fsi, DOFF_ST) :
+ fsi_reg_read(fsi, DIFF_ST);
+
data_num = 0x1ff & (status >> 8);
data_num *= io->chan_num;
@@ -473,8 +442,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
- fsi_master_mask_set(master, master->core->imsk, data, data);
- fsi_master_mask_set(master, master->core->iemsk, data, data);
+ fsi_core_mask_set(master, imsk, data, data);
+ fsi_core_mask_set(master, iemsk, data, data);
}
static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -482,18 +451,13 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
- fsi_master_mask_set(master, master->core->imsk, data, 0);
- fsi_master_mask_set(master, master->core->iemsk, data, 0);
+ fsi_core_mask_set(master, imsk, data, 0);
+ fsi_core_mask_set(master, iemsk, data, 0);
}
static u32 fsi_irq_get_status(struct fsi_master *master)
{
- return fsi_master_read(master, master->core->int_st);
-}
-
-static void fsi_irq_clear_all_status(struct fsi_master *master)
-{
- fsi_master_write(master, master->core->int_st, 0);
+ return fsi_core_read(master, int_st);
}
static void fsi_irq_clear_status(struct fsi_priv *fsi)
@@ -505,7 +469,7 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
/* clear interrupt factor */
- fsi_master_mask_set(master, master->core->int_st, data, 0);
+ fsi_core_mask_set(master, int_st, data, 0);
}
/*
@@ -516,17 +480,19 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
{
struct fsi_master *master = fsi_get_master(fsi);
- u32 val = BP | SE;
+ u32 mask, val;
if (master->core->ver < 2) {
pr_err("fsi: register access err (%s)\n", __func__);
return;
}
- if (enable)
- fsi_master_mask_set(master, fsi->mst_ctrl, val, val);
- else
- fsi_master_mask_set(master, fsi->mst_ctrl, val, 0);
+ mask = BP | SE;
+ val = enable ? mask : 0;
+
+ fsi_is_port_a(fsi) ?
+ fsi_core_mask_set(master, a_mclk, mask, val) :
+ fsi_core_mask_set(master, b_mclk, mask, val);
}
/*
@@ -550,7 +516,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
{
struct fsi_master *master = fsi_get_master(fsi);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- u32 ctrl, shift, i;
+ u32 shift, i;
/* get on-chip RAM capacity */
shift = fsi_master_read(master, FIFO_SZ);
@@ -583,13 +549,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
dev_dbg(dai->dev, "%d channel %d store\n",
io->chan_num, io->fifo_max_num);
- ctrl = is_play ? DOFF_CTL : DIFF_CTL;
-
- /* set interrupt generation factor */
- fsi_reg_write(fsi, ctrl, IRQ_HALF);
-
- /* clear FIFO */
- fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
+ /*
+ * set interrupt generation factor
+ * clear FIFO
+ */
+ if (is_play) {
+ fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
+ } else {
+ fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
+ }
}
static void fsi_soft_all_reset(struct fsi_master *master)
@@ -610,7 +580,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
struct snd_pcm_substream *substream = NULL;
int is_play = fsi_stream_is_play(stream);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- u32 status_reg = is_play ? DOFF_ST : DIFF_ST;
int data_residue_num;
int data_num;
int data_num_max;
@@ -701,14 +670,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
/* check fifo status */
if (!startup) {
struct snd_soc_dai *dai = fsi_get_dai(substream);
- u32 status = fsi_reg_read(fsi, status_reg);
+ u32 status = is_play ?
+ fsi_reg_read(fsi, DOFF_ST) :
+ fsi_reg_read(fsi, DIFF_ST);
if (status & ERR_OVER)
dev_err(dai->dev, "over run\n");
if (status & ERR_UNDER)
dev_err(dai->dev, "under run\n");
}
- fsi_reg_write(fsi, status_reg, 0);
+
+ is_play ?
+ fsi_reg_write(fsi, DOFF_ST, 0) :
+ fsi_reg_write(fsi, DIFF_ST, 0);
/* re-enable irq */
fsi_irq_enable(fsi, is_play);
@@ -747,7 +721,8 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
if (int_st & AB_IO(1, BI_SHIFT))
fsi_data_pop(&master->fsib, 0);
- fsi_irq_clear_all_status(master);
+ fsi_irq_clear_status(&master->fsia);
+ fsi_irq_clear_status(&master->fsib);
return IRQ_HANDLED;
}
@@ -764,7 +739,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
struct fsi_stream *io;
u32 flags = fsi_get_info_flags(fsi);
u32 fmt;
- u32 reg;
u32 data;
int is_play = fsi_is_play(substream);
int is_master;
@@ -796,7 +770,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
/* do fmt, di fmt */
data = 0;
- reg = is_play ? DO_FMT : DI_FMT;
fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
switch (fmt) {
case SH_FSI_FMT_MONO:
@@ -830,16 +803,18 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
dev_err(dai->dev, "This FSI can not use SPDIF\n");
return -EINVAL;
}
- data = CR_SPDIF;
+ data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
io->chan_num = 2;
fsi_spdif_clk_ctrl(fsi, 1);
- fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
+ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
break;
default:
dev_err(dai->dev, "unknown format.\n");
return -EINVAL;
}
- fsi_reg_write(fsi, reg, data);
+ is_play ?
+ fsi_reg_write(fsi, DO_FMT, data) :
+ fsi_reg_write(fsi, DI_FMT, data);
/* irq clear */
fsi_irq_disable(fsi, is_play);
@@ -1174,12 +1149,10 @@ static int fsi_probe(struct platform_device *pdev)
/* FSI A setting */
master->fsia.base = master->base;
master->fsia.master = master;
- master->fsia.mst_ctrl = A_MST_CTLR;
/* FSI B setting */
master->fsib.base = master->base + 0x40;
master->fsib.master = master;
- master->fsib.mst_ctrl = B_MST_CTLR;
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
@@ -1266,6 +1239,8 @@ static struct fsi_core fsi2_core = {
.int_st = CPU_INT_ST,
.iemsk = CPU_IEMSK,
.imsk = CPU_IMSK,
+ .a_mclk = A_MST_CTLR,
+ .b_mclk = B_MST_CTLR,
};
static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index ac6c49ce6fdf..df13338cb3e2 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -20,7 +20,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "../codecs/wm8978.h"
#include "siu.h"
@@ -140,11 +139,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, migor_dapm_widgets,
ARRAY_SIZE(migor_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index f8e0ab82ef59..917d3ceadc9d 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -12,7 +12,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/io.h>
#define IPSEL 0xFE400034
@@ -23,7 +22,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform;
static int machine_init(struct snd_soc_pcm_runtime *rtd)
{
- snd_soc_dapm_sync(rtd->codec);
+ snd_soc_dapm_sync(&rtd->codec->dapm);
return 0;
}
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9f4dcb921ff0..83c3430ad797 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -75,7 +75,7 @@ struct siu_firmware {
#include <sound/core.h>
#include <sound/pcm.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index af53b64d8af2..4973c2939d79 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -28,7 +28,7 @@
#include <asm/siu.h>
#include <sound/control.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include "siu.h"
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index ed29c9e1ed4e..a423babcf145 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -29,7 +29,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include <asm/siu.h>
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d214f02cbb65..0e17b4050425 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -14,27 +14,34 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
+#include <linux/lzo.h>
+#include <linux/bitmap.h>
+#include <linux/rbtree.h>
static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[2];
int ret;
@@ -42,16 +49,17 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
data[1] = value & 0x00ff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 2);
if (ret == 2)
return 0;
@@ -77,7 +85,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
msg[1] = data[0];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -94,23 +102,27 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[2];
int ret;
@@ -118,16 +130,17 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
data[1] = value & 0x00ff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 2);
if (ret == 2)
return 0;
@@ -153,7 +166,7 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -170,24 +183,25 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u8 *cache = codec->reg_cache;
u8 data[2];
+ int ret;
reg &= 0xff;
data[0] = reg;
data[1] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
if (codec->hw_write(codec->control_data, data, 2) == 2)
return 0;
else
@@ -197,7 +211,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u8 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
reg &= 0xff;
if (reg >= codec->driver->reg_cache_size ||
@@ -205,10 +220,14 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
#if defined(CONFIG_SPI_MASTER)
@@ -227,7 +246,7 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -244,24 +263,25 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *reg_cache = codec->reg_cache;
u8 data[3];
+ int ret;
data[0] = reg;
data[1] = (value >> 8) & 0xff;
data[2] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- reg_cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
if (codec->hw_write(codec->control_data, data, 3) == 3)
return 0;
else
@@ -271,17 +291,22 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
- } else {
- return cache[reg];
}
+
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
#if defined(CONFIG_SPI_MASTER)
@@ -301,7 +326,7 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data,
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -420,7 +445,8 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u8 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
reg &= 0xff;
if (reg >= codec->driver->reg_cache_size ||
@@ -428,16 +454,19 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u8 *cache = codec->reg_cache;
u8 data[3];
int ret;
@@ -447,16 +476,17 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
reg &= 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 3);
if (ret == 3)
return 0;
@@ -483,7 +513,7 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -534,23 +564,28 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+
+ return val;
}
static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[4];
int ret;
@@ -560,16 +595,17 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
data[3] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 4);
if (ret == 4)
return 0;
@@ -597,7 +633,7 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data,
msg[3] = data[3];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -692,8 +728,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
return -EINVAL;
}
- codec->driver->write = io_types[i].write;
- codec->driver->read = io_types[i].read;
+ codec->write = io_types[i].write;
+ codec->read = io_types[i].read;
switch (control) {
case SND_SOC_CUSTOM:
@@ -724,3 +760,923 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+
+struct snd_soc_rbtree_node {
+ struct rb_node node;
+ unsigned int reg;
+ unsigned int value;
+ unsigned int defval;
+} __attribute__ ((packed));
+
+struct snd_soc_rbtree_ctx {
+ struct rb_root root;
+};
+
+static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
+ struct rb_root *root, unsigned int reg)
+{
+ struct rb_node *node;
+ struct snd_soc_rbtree_node *rbnode;
+
+ node = root->rb_node;
+ while (node) {
+ rbnode = container_of(node, struct snd_soc_rbtree_node, node);
+ if (rbnode->reg < reg)
+ node = node->rb_left;
+ else if (rbnode->reg > reg)
+ node = node->rb_right;
+ else
+ return rbnode;
+ }
+
+ return NULL;
+}
+
+static int snd_soc_rbtree_insert(struct rb_root *root,
+ struct snd_soc_rbtree_node *rbnode)
+{
+ struct rb_node **new, *parent;
+ struct snd_soc_rbtree_node *rbnode_tmp;
+
+ parent = NULL;
+ new = &root->rb_node;
+ while (*new) {
+ rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
+ node);
+ parent = *new;
+ if (rbnode_tmp->reg < rbnode->reg)
+ new = &((*new)->rb_left);
+ else if (rbnode_tmp->reg > rbnode->reg)
+ new = &((*new)->rb_right);
+ else
+ return 0;
+ }
+
+ /* insert the node into the rbtree */
+ rb_link_node(&rbnode->node, parent, new);
+ rb_insert_color(&rbnode->node, root);
+
+ return 1;
+}
+
+static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct rb_node *node;
+ struct snd_soc_rbtree_node *rbnode;
+ unsigned int val;
+ int ret;
+
+ rbtree_ctx = codec->reg_cache;
+ for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
+ rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
+ if (rbnode->value == rbnode->defval)
+ continue;
+ ret = snd_soc_cache_read(codec, rbnode->reg, &val);
+ if (ret)
+ return ret;
+ ret = snd_soc_write(codec, rbnode->reg, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ rbnode->reg, val);
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbnode;
+
+ rbtree_ctx = codec->reg_cache;
+ rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
+ if (rbnode) {
+ if (rbnode->value == value)
+ return 0;
+ rbnode->value = value;
+ } else {
+ /* bail out early, no need to create the rbnode yet */
+ if (!value)
+ return 0;
+ /*
+ * for uninitialized registers whose value is changed
+ * from the default zero, create an rbnode and insert
+ * it into the tree.
+ */
+ rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
+ if (!rbnode)
+ return -ENOMEM;
+ rbnode->reg = reg;
+ rbnode->value = value;
+ snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbnode;
+
+ rbtree_ctx = codec->reg_cache;
+ rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
+ if (rbnode) {
+ *value = rbnode->value;
+ } else {
+ /* uninitialized registers default to 0 */
+ *value = 0;
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
+{
+ struct rb_node *next;
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbtree_node;
+
+ /* if we've already been called then just return */
+ rbtree_ctx = codec->reg_cache;
+ if (!rbtree_ctx)
+ return 0;
+
+ /* free up the rbtree */
+ next = rb_first(&rbtree_ctx->root);
+ while (next) {
+ rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
+ next = rb_next(&rbtree_node->node);
+ rb_erase(&rbtree_node->node, &rbtree_ctx->root);
+ kfree(rbtree_node);
+ }
+
+ /* release the resources */
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+
+ codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
+ if (!codec->reg_cache)
+ return -ENOMEM;
+
+ rbtree_ctx = codec->reg_cache;
+ rbtree_ctx->root = RB_ROOT;
+
+ if (!codec->reg_def_copy)
+ return 0;
+
+/*
+ * populate the rbtree with the initialized registers. All other
+ * registers will be inserted into the tree when they are first written.
+ *
+ * The reasoning behind this, is that we need to step through and
+ * dereference the cache in u8/u16 increments without sacrificing
+ * portability. This could also be done using memcpy() but that would
+ * be slightly more cryptic.
+ */
+#define snd_soc_rbtree_populate(cache) \
+({ \
+ int ret, i; \
+ struct snd_soc_rbtree_node *rbtree_node; \
+ \
+ ret = 0; \
+ cache = codec->reg_def_copy; \
+ for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
+ if (!cache[i]) \
+ continue; \
+ rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
+ if (!rbtree_node) { \
+ ret = -ENOMEM; \
+ snd_soc_cache_exit(codec); \
+ break; \
+ } \
+ rbtree_node->reg = i; \
+ rbtree_node->value = cache[i]; \
+ rbtree_node->defval = cache[i]; \
+ snd_soc_rbtree_insert(&rbtree_ctx->root, \
+ rbtree_node); \
+ } \
+ ret; \
+})
+
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ const u8 *cache;
+
+ return snd_soc_rbtree_populate(cache);
+ }
+ case 2: {
+ const u16 *cache;
+
+ return snd_soc_rbtree_populate(cache);
+ }
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+struct snd_soc_lzo_ctx {
+ void *wmem;
+ void *dst;
+ const void *src;
+ size_t src_len;
+ size_t dst_len;
+ size_t decompressed_size;
+ unsigned long *sync_bmp;
+ int sync_bmp_nbits;
+};
+
+#define LZO_BLOCK_NUM 8
+static int snd_soc_lzo_block_count(void)
+{
+ return LZO_BLOCK_NUM;
+}
+
+static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ if (!lzo_ctx->wmem)
+ return -ENOMEM;
+ return 0;
+}
+
+static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ size_t compress_size;
+ int ret;
+
+ ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
+ lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
+ if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
+ return -EINVAL;
+ lzo_ctx->dst_len = compress_size;
+ return 0;
+}
+
+static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ size_t dst_len;
+ int ret;
+
+ dst_len = lzo_ctx->dst_len;
+ ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
+ lzo_ctx->dst, &dst_len);
+ if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
+ return -EINVAL;
+ return 0;
+}
+
+static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
+ struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ int ret;
+
+ lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
+ lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
+ if (!lzo_ctx->dst) {
+ lzo_ctx->dst_len = 0;
+ return -ENOMEM;
+ }
+
+ ret = snd_soc_lzo_compress(lzo_ctx);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
+ struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ int ret;
+
+ lzo_ctx->dst_len = lzo_ctx->decompressed_size;
+ lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
+ if (!lzo_ctx->dst) {
+ lzo_ctx->dst_len = 0;
+ return -ENOMEM;
+ }
+
+ ret = snd_soc_lzo_decompress(lzo_ctx);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return (reg * codec_drv->reg_word_size) /
+ DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
+}
+
+static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
+ codec_drv->reg_word_size);
+}
+
+static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
+}
+
+static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ unsigned int val;
+ int i;
+ int ret;
+
+ lzo_blocks = codec->reg_cache;
+ for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ i, val);
+ }
+
+ return 0;
+}
+
+static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
+ int ret, blkindex, blkpos;
+ size_t blksize, tmp_dst_len;
+ void *tmp_dst;
+
+ /* index of the compressed lzo block */
+ blkindex = snd_soc_lzo_get_blkindex(codec, reg);
+ /* register index within the decompressed block */
+ blkpos = snd_soc_lzo_get_blkpos(codec, reg);
+ /* size of the compressed block */
+ blksize = snd_soc_lzo_get_blksize(codec);
+ lzo_blocks = codec->reg_cache;
+ lzo_block = lzo_blocks[blkindex];
+
+ /* save the pointer and length of the compressed block */
+ tmp_dst = lzo_block->dst;
+ tmp_dst_len = lzo_block->dst_len;
+
+ /* prepare the source to be the compressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* decompress the block */
+ ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
+ if (ret < 0) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+
+ /* write the new value to the cache */
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+ cache = lzo_block->dst;
+ if (cache[blkpos] == value) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+ cache[blkpos] = value;
+ }
+ break;
+ case 2: {
+ u16 *cache;
+ cache = lzo_block->dst;
+ if (cache[blkpos] == value) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+ cache[blkpos] = value;
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ /* prepare the source to be the decompressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* compress the block */
+ ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
+ if (ret < 0) {
+ kfree(lzo_block->dst);
+ kfree(lzo_block->src);
+ goto out;
+ }
+
+ /* set the bit so we know we have to sync this register */
+ set_bit(reg, lzo_block->sync_bmp);
+ kfree(tmp_dst);
+ kfree(lzo_block->src);
+ return 0;
+out:
+ lzo_block->dst = tmp_dst;
+ lzo_block->dst_len = tmp_dst_len;
+ return ret;
+}
+
+static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
+ int ret, blkindex, blkpos;
+ size_t blksize, tmp_dst_len;
+ void *tmp_dst;
+
+ *value = 0;
+ /* index of the compressed lzo block */
+ blkindex = snd_soc_lzo_get_blkindex(codec, reg);
+ /* register index within the decompressed block */
+ blkpos = snd_soc_lzo_get_blkpos(codec, reg);
+ /* size of the compressed block */
+ blksize = snd_soc_lzo_get_blksize(codec);
+ lzo_blocks = codec->reg_cache;
+ lzo_block = lzo_blocks[blkindex];
+
+ /* save the pointer and length of the compressed block */
+ tmp_dst = lzo_block->dst;
+ tmp_dst_len = lzo_block->dst_len;
+
+ /* prepare the source to be the compressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* decompress the block */
+ ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
+ if (ret >= 0) {
+ /* fetch the value from the cache */
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+ cache = lzo_block->dst;
+ *value = cache[blkpos];
+ }
+ break;
+ case 2: {
+ u16 *cache;
+ cache = lzo_block->dst;
+ *value = cache[blkpos];
+ }
+ break;
+ default:
+ BUG();
+ }
+ }
+
+ kfree(lzo_block->dst);
+ /* restore the pointer and length of the compressed block */
+ lzo_block->dst = tmp_dst;
+ lzo_block->dst_len = tmp_dst_len;
+ return 0;
+}
+
+static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ int i, blkcount;
+
+ lzo_blocks = codec->reg_cache;
+ if (!lzo_blocks)
+ return 0;
+
+ blkcount = snd_soc_lzo_block_count();
+ /*
+ * the pointer to the bitmap used for syncing the cache
+ * is shared amongst all lzo_blocks. Ensure it is freed
+ * only once.
+ */
+ if (lzo_blocks[0])
+ kfree(lzo_blocks[0]->sync_bmp);
+ for (i = 0; i < blkcount; ++i) {
+ if (lzo_blocks[i]) {
+ kfree(lzo_blocks[i]->wmem);
+ kfree(lzo_blocks[i]->dst);
+ }
+ /* each lzo_block is a pointer returned by kmalloc or NULL */
+ kfree(lzo_blocks[i]);
+ }
+ kfree(lzo_blocks);
+ codec->reg_cache = NULL;
+ return 0;
+}
+
+static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ size_t reg_size, bmp_size;
+ const struct snd_soc_codec_driver *codec_drv;
+ int ret, tofree, i, blksize, blkcount;
+ const char *p, *end;
+ unsigned long *sync_bmp;
+
+ ret = 0;
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+
+ /*
+ * If we have not been given a default register cache
+ * then allocate a dummy zero-ed out region, compress it
+ * and remember to free it afterwards.
+ */
+ tofree = 0;
+ if (!codec->reg_def_copy)
+ tofree = 1;
+
+ if (!codec->reg_def_copy) {
+ codec->reg_def_copy = kzalloc(reg_size,
+ GFP_KERNEL);
+ if (!codec->reg_def_copy)
+ return -ENOMEM;
+ }
+
+ blkcount = snd_soc_lzo_block_count();
+ codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
+ GFP_KERNEL);
+ if (!codec->reg_cache) {
+ ret = -ENOMEM;
+ goto err_tofree;
+ }
+ lzo_blocks = codec->reg_cache;
+
+ /*
+ * allocate a bitmap to be used when syncing the cache with
+ * the hardware. Each time a register is modified, the corresponding
+ * bit is set in the bitmap, so we know that we have to sync
+ * that register.
+ */
+ bmp_size = codec_drv->reg_cache_size;
+ sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
+ GFP_KERNEL);
+ if (!sync_bmp) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ bitmap_zero(sync_bmp, bmp_size);
+
+ /* allocate the lzo blocks and initialize them */
+ for (i = 0; i < blkcount; ++i) {
+ lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
+ GFP_KERNEL);
+ if (!lzo_blocks[i]) {
+ kfree(sync_bmp);
+ ret = -ENOMEM;
+ goto err;
+ }
+ lzo_blocks[i]->sync_bmp = sync_bmp;
+ lzo_blocks[i]->sync_bmp_nbits = reg_size;
+ /* alloc the working space for the compressed block */
+ ret = snd_soc_lzo_prepare(lzo_blocks[i]);
+ if (ret < 0)
+ goto err;
+ }
+
+ blksize = snd_soc_lzo_get_blksize(codec);
+ p = codec->reg_def_copy;
+ end = codec->reg_def_copy + reg_size;
+ /* compress the register map and fill the lzo blocks */
+ for (i = 0; i < blkcount; ++i, p += blksize) {
+ lzo_blocks[i]->src = p;
+ if (p + blksize > end)
+ lzo_blocks[i]->src_len = end - p;
+ else
+ lzo_blocks[i]->src_len = blksize;
+ ret = snd_soc_lzo_compress_cache_block(codec,
+ lzo_blocks[i]);
+ if (ret < 0)
+ goto err;
+ lzo_blocks[i]->decompressed_size =
+ lzo_blocks[i]->src_len;
+ }
+
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
+ return 0;
+err:
+ snd_soc_cache_exit(codec);
+err_tofree:
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
+ return ret;
+}
+
+static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
+{
+ int i;
+ int ret;
+ const struct snd_soc_codec_driver *codec_drv;
+ unsigned int val;
+
+ codec_drv = codec->driver;
+ for (i = 0; i < codec_drv->reg_cache_size; ++i) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ if (codec_drv->reg_cache_default) {
+ switch (codec_drv->reg_word_size) {
+ case 1: {
+ const u8 *cache;
+
+ cache = codec_drv->reg_cache_default;
+ if (cache[i] == val)
+ continue;
+ }
+ break;
+ case 2: {
+ const u16 *cache;
+
+ cache = codec_drv->reg_cache_default;
+ if (cache[i] == val)
+ continue;
+ }
+ break;
+ default:
+ BUG();
+ }
+ }
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ i, val);
+ }
+ return 0;
+}
+
+static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+
+ cache = codec->reg_cache;
+ cache[reg] = value;
+ }
+ break;
+ case 2: {
+ u16 *cache;
+
+ cache = codec->reg_cache;
+ cache[reg] = value;
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+
+ cache = codec->reg_cache;
+ *value = cache[reg];
+ }
+ break;
+ case 2: {
+ u16 *cache;
+
+ cache = codec->reg_cache;
+ *value = cache[reg];
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
+{
+ if (!codec->reg_cache)
+ return 0;
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+ return 0;
+}
+
+static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+
+ /*
+ * for flat compression, we don't need to keep a copy of the
+ * original defaults register cache as it will definitely not
+ * be marked as __devinitconst
+ */
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+
+ if (codec_drv->reg_cache_default)
+ codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
+ else
+ codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
+ if (!codec->reg_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/* an array of all supported compression types */
+static const struct snd_soc_cache_ops cache_types[] = {
+ {
+ .id = SND_SOC_FLAT_COMPRESSION,
+ .name = "flat",
+ .init = snd_soc_flat_cache_init,
+ .exit = snd_soc_flat_cache_exit,
+ .read = snd_soc_flat_cache_read,
+ .write = snd_soc_flat_cache_write,
+ .sync = snd_soc_flat_cache_sync
+ },
+ {
+ .id = SND_SOC_LZO_COMPRESSION,
+ .name = "LZO",
+ .init = snd_soc_lzo_cache_init,
+ .exit = snd_soc_lzo_cache_exit,
+ .read = snd_soc_lzo_cache_read,
+ .write = snd_soc_lzo_cache_write,
+ .sync = snd_soc_lzo_cache_sync
+ },
+ {
+ .id = SND_SOC_RBTREE_COMPRESSION,
+ .name = "rbtree",
+ .init = snd_soc_rbtree_cache_init,
+ .exit = snd_soc_rbtree_cache_exit,
+ .read = snd_soc_rbtree_cache_read,
+ .write = snd_soc_rbtree_cache_write,
+ .sync = snd_soc_rbtree_cache_sync
+ }
+};
+
+int snd_soc_cache_init(struct snd_soc_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
+ if (cache_types[i].id == codec->compress_type)
+ break;
+ if (i == ARRAY_SIZE(cache_types)) {
+ dev_err(codec->dev, "Could not match compress type: %d\n",
+ codec->compress_type);
+ return -EINVAL;
+ }
+
+ mutex_init(&codec->cache_rw_mutex);
+ codec->cache_ops = &cache_types[i];
+
+ if (codec->cache_ops->init) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ return codec->cache_ops->init(codec);
+ }
+ return -EINVAL;
+}
+
+/*
+ * NOTE: keep in mind that this function might be called
+ * multiple times.
+ */
+int snd_soc_cache_exit(struct snd_soc_codec *codec)
+{
+ if (codec->cache_ops && codec->cache_ops->exit) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ return codec->cache_ops->exit(codec);
+ }
+ return -EINVAL;
+}
+
+/**
+ * snd_soc_cache_read: Fetch the value of a given register from the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The value to be returned.
+ */
+int snd_soc_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ int ret;
+
+ mutex_lock(&codec->cache_rw_mutex);
+
+ if (value && codec->cache_ops && codec->cache_ops->read) {
+ ret = codec->cache_ops->read(codec, reg, value);
+ mutex_unlock(&codec->cache_rw_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&codec->cache_rw_mutex);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_read);
+
+/**
+ * snd_soc_cache_write: Set the value of a given register in the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The new register value.
+ */
+int snd_soc_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ mutex_lock(&codec->cache_rw_mutex);
+
+ if (codec->cache_ops && codec->cache_ops->write) {
+ ret = codec->cache_ops->write(codec, reg, value);
+ mutex_unlock(&codec->cache_rw_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&codec->cache_rw_mutex);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_write);
+
+/**
+ * snd_soc_cache_sync: Sync the register cache with the hardware.
+ *
+ * @codec: CODEC to configure.
+ *
+ * Any registers that should not be synced should be marked as
+ * volatile. In general drivers can choose not to use the provided
+ * syncing functionality if they so require.
+ */
+int snd_soc_cache_sync(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ if (!codec->cache_sync) {
+ return 0;
+ }
+
+ if (codec->cache_ops && codec->cache_ops->sync) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ ret = codec->cache_ops->sync(codec);
+ if (!ret)
+ codec->cache_sync = 0;
+ return ret;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 85b7d548f167..1dc4b11c1988 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -33,12 +33,15 @@
#include <linux/slab.h>
#include <sound/ac97_codec.h>
#include <sound/core.h>
+#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/asoc.h>
+
#define NAME_SIZE 32
static DEFINE_MUTEX(pcm_mutex);
@@ -67,25 +70,6 @@ static int pmdown_time = 5000;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
-/*
- * This function forces any delayed work to be queued and run.
- */
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
-
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
-
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
- }
- return ret;
-}
-
/* codec register dump */
static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
{
@@ -114,7 +98,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
* the register being volatile and the device being
* powered off.
*/
- ret = codec->driver->read(codec, i);
+ ret = snd_soc_read(codec, i);
if (ret >= 0)
count += snprintf(buf + count,
PAGE_SIZE - count,
@@ -225,7 +209,7 @@ static ssize_t codec_reg_write_file(struct file *file,
start++;
if (strict_strtoul(start, 16, &value))
return -EINVAL;
- codec->driver->write(codec, reg, value);
+ snd_soc_write(codec, reg, value);
return buf_size;
}
@@ -238,8 +222,10 @@ static const struct file_operations codec_reg_fops = {
static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
{
- codec->debugfs_codec_root = debugfs_create_dir(codec->name ,
- debugfs_root);
+ struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
+
+ codec->debugfs_codec_root = debugfs_create_dir(codec->name,
+ debugfs_card_root);
if (!codec->debugfs_codec_root) {
printk(KERN_WARNING
"ASoC: Failed to create codec debugfs directory\n");
@@ -253,20 +239,13 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
printk(KERN_WARNING
"ASoC: Failed to create codec register debugfs file\n");
- codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
- codec->debugfs_codec_root,
- &codec->pop_time);
- if (!codec->debugfs_pop_time)
- printk(KERN_WARNING
- "Failed to create pop time debugfs file\n");
-
- codec->debugfs_dapm = debugfs_create_dir("dapm",
+ codec->dapm.debugfs_dapm = debugfs_create_dir("dapm",
codec->debugfs_codec_root);
- if (!codec->debugfs_dapm)
+ if (!codec->dapm.debugfs_dapm)
printk(KERN_WARNING
"Failed to create DAPM debugfs directory\n");
- snd_soc_dapm_debugfs_init(codec);
+ snd_soc_dapm_debugfs_init(&codec->dapm);
}
static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
@@ -374,6 +353,29 @@ static const struct file_operations platform_list_fops = {
.llseek = default_llseek,/* read accesses f_pos */
};
+static void soc_init_card_debugfs(struct snd_soc_card *card)
+{
+ card->debugfs_card_root = debugfs_create_dir(card->name,
+ debugfs_root);
+ if (!card->debugfs_card_root) {
+ dev_warn(card->dev,
+ "ASoC: Failed to create codec debugfs directory\n");
+ return;
+ }
+
+ card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
+ card->debugfs_card_root,
+ &card->pop_time);
+ if (!card->debugfs_pop_time)
+ dev_warn(card->dev,
+ "Failed to create pop time debugfs file\n");
+}
+
+static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
+{
+ debugfs_remove_recursive(card->debugfs_card_root);
+}
+
#else
static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
@@ -383,6 +385,14 @@ static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
{
}
+
+static inline void soc_init_card_debugfs(struct snd_soc_card *card)
+{
+}
+
+static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
+{
+}
#endif
#ifdef CONFIG_SND_SOC_AC97_BUS
@@ -497,7 +507,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
- /* Check that the codec and cpu DAI's are compatible */
+ /* Check that the codec and cpu DAIs are compatible */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
runtime->hw.rate_min =
max(codec_dai_drv->playback.rate_min,
@@ -846,7 +856,7 @@ codec_err:
}
/*
- * Free's resources allocated by hw_params, can be called multiple times
+ * Frees resources allocated by hw_params, can be called multiple times
*/
static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
{
@@ -870,7 +880,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
if (platform->driver->ops->hw_free)
platform->driver->ops->hw_free(substream);
- /* now free hw params for the DAI's */
+ /* now free hw params for the DAIs */
if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
@@ -958,6 +968,7 @@ static int soc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
int i;
/* If the initialization of this soc device failed, there is no codec
@@ -976,7 +987,7 @@ static int soc_suspend(struct device *dev)
/* we're going to block userspace touching us until resume completes */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
- /* mute any active DAC's */
+ /* mute any active DACs */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_dai *dai = card->rtd[i].codec_dai;
struct snd_soc_dai_driver *drv = dai->driver;
@@ -1016,8 +1027,8 @@ static int soc_suspend(struct device *dev)
/* close any waiting streams and save state */
for (i = 0; i < card->num_rtd; i++) {
- run_delayed_work(&card->rtd[i].delayed_work);
- card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level;
+ flush_delayed_work_sync(&card->rtd[i].delayed_work);
+ card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
}
for (i = 0; i < card->num_rtd; i++) {
@@ -1036,12 +1047,11 @@ static int soc_suspend(struct device *dev)
}
/* suspend all CODECs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_codec *codec = card->rtd[i].codec;
+ list_for_each_entry(codec, &card->codec_dev_list, card_list) {
/* If there are paths active then the CODEC will be held with
* bias _ON and should not be suspended. */
if (!codec->suspended && codec->driver->suspend) {
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
codec->driver->suspend(codec, PMSG_SUSPEND);
@@ -1078,6 +1088,7 @@ static void soc_resume_deferred(struct work_struct *work)
struct snd_soc_card *card =
container_of(work, struct snd_soc_card, deferred_resume_work);
struct platform_device *pdev = to_platform_device(card->dev);
+ struct snd_soc_codec *codec;
int i;
/* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
@@ -1103,14 +1114,13 @@ static void soc_resume_deferred(struct work_struct *work)
cpu_dai->driver->resume(cpu_dai);
}
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_codec *codec = card->rtd[i].codec;
+ list_for_each_entry(codec, &card->codec_dev_list, card_list) {
/* If the CODEC was idle over suspend then it will have been
* left with bias OFF or STANDBY and suspended so we must now
* resume. Otherwise the suspend was suppressed.
*/
if (codec->driver->resume && codec->suspended) {
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
codec->driver->resume(codec);
@@ -1299,6 +1309,27 @@ out:
return 1;
}
+static void soc_remove_codec(struct snd_soc_codec *codec)
+{
+ int err;
+
+ if (codec->driver->remove) {
+ err = codec->driver->remove(codec);
+ if (err < 0)
+ dev_err(codec->dev,
+ "asoc: failed to remove %s: %d\n",
+ codec->name, err);
+ }
+
+ /* Make sure all DAPM widgets are freed */
+ snd_soc_dapm_free(&codec->dapm);
+
+ soc_cleanup_codec_debugfs(codec);
+ codec->probed = 0;
+ list_del(&codec->card_list);
+ module_put(codec->dev->driver->owner);
+}
+
static void soc_remove_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1310,6 +1341,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
/* unregister the rtd device */
if (rtd->dev_registered) {
device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
device_unregister(&rtd->dev);
rtd->dev_registered = 0;
}
@@ -1338,22 +1370,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
}
/* remove the CODEC */
- if (codec && codec->probed) {
- if (codec->driver->remove) {
- err = codec->driver->remove(codec);
- if (err < 0)
- printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(codec);
-
- soc_cleanup_codec_debugfs(codec);
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- codec->probed = 0;
- list_del(&codec->card_list);
- module_put(codec->dev->driver->owner);
- }
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
/* remove the cpu_dai */
if (cpu_dai && cpu_dai->probed) {
@@ -1368,8 +1386,122 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
}
}
+static void soc_set_name_prefix(struct snd_soc_card *card,
+ struct snd_soc_codec *codec)
+{
+ int i;
+
+ if (card->codec_conf == NULL)
+ return;
+
+ for (i = 0; i < card->num_configs; i++) {
+ struct snd_soc_codec_conf *map = &card->codec_conf[i];
+ if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
+ codec->name_prefix = map->name_prefix;
+ break;
+ }
+ }
+}
+
+static int soc_probe_codec(struct snd_soc_card *card,
+ struct snd_soc_codec *codec)
+{
+ int ret = 0;
+
+ codec->card = card;
+ codec->dapm.card = card;
+ soc_set_name_prefix(card, codec);
+
+ if (codec->driver->probe) {
+ ret = codec->driver->probe(codec);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "asoc: failed to probe CODEC %s: %d\n",
+ codec->name, ret);
+ return ret;
+ }
+ }
+
+ soc_init_codec_debugfs(codec);
+
+ /* mark codec as probed and add to card codec list */
+ codec->probed = 1;
+ list_add(&codec->card_list, &card->codec_dev_list);
+
+ return ret;
+}
+
static void rtd_release(struct device *dev) {}
+static int soc_post_component_init(struct snd_soc_card *card,
+ struct snd_soc_codec *codec,
+ int num, int dailess)
+{
+ struct snd_soc_dai_link *dai_link = NULL;
+ struct snd_soc_aux_dev *aux_dev = NULL;
+ struct snd_soc_pcm_runtime *rtd;
+ const char *temp, *name;
+ int ret = 0;
+
+ if (!dailess) {
+ dai_link = &card->dai_link[num];
+ rtd = &card->rtd[num];
+ name = dai_link->name;
+ } else {
+ aux_dev = &card->aux_dev[num];
+ rtd = &card->rtd_aux[num];
+ name = aux_dev->name;
+ }
+
+ /* machine controls, routes and widgets are not prefixed */
+ temp = codec->name_prefix;
+ codec->name_prefix = NULL;
+
+ /* do machine specific initialization */
+ if (!dailess && dai_link->init)
+ ret = dai_link->init(rtd);
+ else if (dailess && aux_dev->init)
+ ret = aux_dev->init(&codec->dapm);
+ if (ret < 0) {
+ dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
+ return ret;
+ }
+ codec->name_prefix = temp;
+
+ /* Make sure all DAPM widgets are instantiated */
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ snd_soc_dapm_sync(&codec->dapm);
+
+ /* register the rtd device */
+ rtd->codec = codec;
+ rtd->card = card;
+ rtd->dev.parent = card->dev;
+ rtd->dev.release = rtd_release;
+ rtd->dev.init_name = name;
+ ret = device_register(&rtd->dev);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "asoc: failed to register runtime device: %d\n", ret);
+ return ret;
+ }
+ rtd->dev_registered = 1;
+
+ /* add DAPM sysfs entries for this codec */
+ ret = snd_soc_dapm_sys_add(&rtd->dev);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec dapm sysfs entries: %d\n",
+ ret);
+
+ /* add codec sysfs entries */
+ ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec sysfs files: %d\n", ret);
+
+ return 0;
+}
+
static int soc_probe_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_dai_link *dai_link = &card->dai_link[num];
@@ -1383,10 +1515,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* config components */
codec_dai->codec = codec;
- codec->card = card;
cpu_dai->platform = platform;
- rtd->card = card;
- rtd->dev.parent = card->dev;
codec_dai->card = card;
cpu_dai->card = card;
@@ -1410,20 +1539,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* probe the CODEC */
if (!codec->probed) {
- if (codec->driver->probe) {
- ret = codec->driver->probe(codec);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
- codec->name);
- return ret;
- }
- }
-
- soc_init_codec_debugfs(codec);
-
- /* mark codec as probed and add to card codec list */
- codec->probed = 1;
- list_add(&codec->card_list, &card->codec_dev_list);
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
}
/* probe the platform */
@@ -1460,43 +1578,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* DAPM dai link stream work */
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
- /* now that all clients have probed, initialise the DAI link */
- if (dai_link->init) {
- ret = dai_link->init(rtd);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
- return ret;
- }
- }
-
- /* Make sure all DAPM widgets are instantiated */
- snd_soc_dapm_new_widgets(codec);
- snd_soc_dapm_sync(codec);
-
- /* register the rtd device */
- rtd->dev.release = rtd_release;
- rtd->dev.init_name = dai_link->name;
- ret = device_register(&rtd->dev);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
+ ret = soc_post_component_init(card, codec, num, 0);
+ if (ret)
return ret;
- }
- rtd->dev_registered = 1;
ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
if (ret < 0)
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
- /* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(&rtd->dev);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
-
- /* add codec sysfs entries */
- ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
-
/* create the pcm */
ret = soc_new_pcm(rtd, num);
if (ret < 0) {
@@ -1551,9 +1640,85 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
}
#endif
+static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
+{
+ struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
+ struct snd_soc_codec *codec;
+ int ret = -ENODEV;
+
+ /* find CODEC from registered CODECs*/
+ list_for_each_entry(codec, &codec_list, list) {
+ if (!strcmp(codec->name, aux_dev->codec_name)) {
+ if (codec->probed) {
+ dev_err(codec->dev,
+ "asoc: codec already probed");
+ ret = -EBUSY;
+ goto out;
+ }
+ goto found;
+ }
+ }
+ /* codec not found */
+ dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
+ goto out;
+
+found:
+ if (!try_module_get(codec->dev->driver->owner))
+ return -ENODEV;
+
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
+
+ ret = soc_post_component_init(card, codec, num, 1);
+
+out:
+ return ret;
+}
+
+static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
+{
+ struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
+ struct snd_soc_codec *codec = rtd->codec;
+
+ /* unregister the rtd device */
+ if (rtd->dev_registered) {
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
+ device_unregister(&rtd->dev);
+ rtd->dev_registered = 0;
+ }
+
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
+}
+
+static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
+ enum snd_soc_compress_type compress_type)
+{
+ int ret;
+
+ if (codec->cache_init)
+ return 0;
+
+ /* override the compress_type if necessary */
+ if (compress_type && codec->compress_type != compress_type)
+ codec->compress_type = compress_type;
+ ret = snd_soc_cache_init(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache compression type: %d\n",
+ ret);
+ return ret;
+ }
+ codec->cache_init = 1;
+ return 0;
+}
+
static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct platform_device *pdev = to_platform_device(card->dev);
+ struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
int ret, i;
mutex_lock(&card->mutex);
@@ -1573,6 +1738,39 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
return;
}
+ /* initialize the register cache for each available codec */
+ list_for_each_entry(codec, &codec_list, list) {
+ if (codec->cache_init)
+ continue;
+ /* check to see if we need to override the compress_type */
+ for (i = 0; i < card->num_configs; ++i) {
+ codec_conf = &card->codec_conf[i];
+ if (!strcmp(codec->name, codec_conf->dev_name)) {
+ compress_type = codec_conf->compress_type;
+ if (compress_type && compress_type
+ != codec->compress_type)
+ break;
+ }
+ }
+ if (i == card->num_configs) {
+ /* no need to override the compress_type so
+ * go ahead and do the standard thing */
+ ret = snd_soc_init_codec_cache(codec, 0);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ continue;
+ }
+ /* override the compress_type with the one supplied in
+ * the machine driver */
+ ret = snd_soc_init_codec_cache(codec, compress_type);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ }
+
/* card bind complete so register a sound card */
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
card->owner, 0, &card->snd_card);
@@ -1605,6 +1803,15 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
}
}
+ for (i = 0; i < card->num_aux_devs; i++) {
+ ret = soc_probe_aux_dev(card, i);
+ if (ret < 0) {
+ pr_err("asoc: failed to add auxiliary devices %s: %d\n",
+ card->name, ret);
+ goto probe_aux_dev_err;
+ }
+ }
+
snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
"%s", card->name);
snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1613,7 +1820,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
ret = snd_card_register(card->snd_card);
if (ret < 0) {
printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
- goto probe_dai_err;
+ goto probe_aux_dev_err;
}
#ifdef CONFIG_SND_SOC_AC97_BUS
@@ -1623,8 +1830,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
if (ret < 0) {
printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
while (--i >= 0)
- soc_unregister_ac97_dai_link(&card->rtd[i]);
- goto probe_dai_err;
+ soc_unregister_ac97_dai_link(card->rtd[i].codec);
+ goto probe_aux_dev_err;
}
}
#endif
@@ -1633,6 +1840,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
mutex_unlock(&card->mutex);
return;
+probe_aux_dev_err:
+ for (i = 0; i < card->num_aux_devs; i++)
+ soc_remove_aux_dev(card, i);
+
probe_dai_err:
for (i = 0; i < card->num_links; i++)
soc_remove_dai_link(card, i);
@@ -1669,6 +1880,8 @@ static int soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&card->codec_dev_list);
INIT_LIST_HEAD(&card->platform_dev_list);
+ soc_init_card_debugfs(card);
+
ret = snd_soc_register_card(card);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to register card\n");
@@ -1689,13 +1902,19 @@ static int soc_remove(struct platform_device *pdev)
/* make sure any delayed work runs */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- run_delayed_work(&rtd->delayed_work);
+ flush_delayed_work_sync(&rtd->delayed_work);
}
+ /* remove auxiliary devices */
+ for (i = 0; i < card->num_aux_devs; i++)
+ soc_remove_aux_dev(card, i);
+
/* remove and free each DAI */
for (i = 0; i < card->num_rtd; i++)
soc_remove_dai_link(card, i);
+ soc_cleanup_card_debugfs(card);
+
/* remove the card */
if (card->remove)
card->remove(pdev);
@@ -1720,7 +1939,7 @@ static int soc_poweroff(struct device *dev)
* now, we're shutting down so no imminent restart. */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- run_delayed_work(&rtd->delayed_work);
+ flush_delayed_work_sync(&rtd->delayed_work);
}
snd_soc_dapm_shutdown(card);
@@ -1879,6 +2098,27 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ unsigned int ret;
+
+ ret = codec->read(codec, reg);
+ dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
+ trace_snd_soc_reg_read(codec, reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_read);
+
+unsigned int snd_soc_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int val)
+{
+ dev_dbg(codec->dev, "write %x = %x\n", reg, val);
+ trace_snd_soc_reg_write(codec, reg, val);
+ return codec->write(codec, reg, val);
+}
+EXPORT_SYMBOL_GPL(snd_soc_write);
+
/**
* snd_soc_update_bits - update codec register bits
* @codec: audio codec
@@ -2019,14 +2259,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
const struct snd_kcontrol_new *controls, int num_controls)
{
struct snd_card *card = codec->card->snd_card;
+ char prefixed_name[44], *name;
int err, i;
for (i = 0; i < num_controls; i++) {
const struct snd_kcontrol_new *control = &controls[i];
- err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL));
+ if (codec->name_prefix) {
+ snprintf(prefixed_name, sizeof(prefixed_name), "%s %s",
+ codec->name_prefix, control->name);
+ name = prefixed_name;
+ } else {
+ name = control->name;
+ }
+ err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
if (err < 0) {
dev_err(codec->dev, "%s: Failed to add %s: %d\n",
- codec->name, control->name, err);
+ codec->name, name, err);
return err;
}
}
@@ -2863,10 +3111,12 @@ static int snd_soc_register_card(struct snd_soc_card *card)
if (!card->name || !card->dev)
return -EINVAL;
- card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * card->num_links,
- GFP_KERNEL);
+ card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
+ (card->num_links + card->num_aux_devs),
+ GFP_KERNEL);
if (card->rtd == NULL)
return -ENOMEM;
+ card->rtd_aux = &card->rtd[card->num_links];
for (i = 0; i < card->num_links; i++)
card->rtd[i].dai_link = &card->dai_link[i];
@@ -2908,7 +3158,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
* Simplify DAI link configuration by removing ".-1" from device names
* and sanitizing names.
*/
-static inline char *fmt_single_name(struct device *dev, int *id)
+static char *fmt_single_name(struct device *dev, int *id)
{
char *found, name[NAME_SIZE];
int id1, id2;
@@ -2916,7 +3166,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
if (dev_name(dev) == NULL)
return NULL;
- strncpy(name, dev_name(dev), NAME_SIZE);
+ strlcpy(name, dev_name(dev), NAME_SIZE);
/* are we a "%s.%d" name (platform and SPI components) */
found = strstr(name, dev->driver->name);
@@ -2939,7 +3189,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
/* sanitize component name for DAI link creation */
snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name);
- strncpy(name, tmp, NAME_SIZE);
+ strlcpy(name, tmp, NAME_SIZE);
} else
*id = 0;
}
@@ -3204,9 +3454,11 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
* @codec: codec to register
*/
int snd_soc_register_codec(struct device *dev,
- struct snd_soc_codec_driver *codec_drv,
- struct snd_soc_dai_driver *dai_drv, int num_dai)
+ const struct snd_soc_codec_driver *codec_drv,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai)
{
+ size_t reg_size;
struct snd_soc_codec *codec;
int ret, i;
@@ -3223,30 +3475,39 @@ int snd_soc_register_codec(struct device *dev,
return -ENOMEM;
}
- /* allocate CODEC register cache */
- if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
-
- if (codec_drv->reg_cache_default)
- codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
- codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL);
- else
- codec->reg_cache = kzalloc(codec_drv->reg_cache_size *
- codec_drv->reg_word_size, GFP_KERNEL);
-
- if (codec->reg_cache == NULL) {
- kfree(codec->name);
- kfree(codec);
- return -ENOMEM;
- }
- }
-
+ if (codec_drv->compress_type)
+ codec->compress_type = codec_drv->compress_type;
+ else
+ codec->compress_type = SND_SOC_FLAT_COMPRESSION;
+
+ INIT_LIST_HEAD(&codec->dapm.widgets);
+ INIT_LIST_HEAD(&codec->dapm.paths);
+ codec->write = codec_drv->write;
+ codec->read = codec_drv->read;
+ codec->dapm.bias_level = SND_SOC_BIAS_OFF;
+ codec->dapm.dev = dev;
+ codec->dapm.codec = codec;
codec->dev = dev;
codec->driver = codec_drv;
- codec->bias_level = SND_SOC_BIAS_OFF;
codec->num_dai = num_dai;
mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+
+ /* allocate CODEC register cache */
+ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ /* it is necessary to make a copy of the default register cache
+ * because in the case of using a compression type that requires
+ * the default register cache to be marked as __devinitconst the
+ * kernel might have freed the array by the time we initialize
+ * the cache.
+ */
+ codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
+ if (!codec->reg_def_copy) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
for (i = 0; i < num_dai; i++) {
fixup_codec_formats(&dai_drv[i].playback);
@@ -3257,7 +3518,7 @@ int snd_soc_register_codec(struct device *dev,
if (num_dai) {
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0)
- goto error;
+ goto fail;
}
mutex_lock(&client_mutex);
@@ -3268,9 +3529,9 @@ int snd_soc_register_codec(struct device *dev,
pr_debug("Registered codec '%s'\n", codec->name);
return 0;
-error:
- if (codec->reg_cache)
- kfree(codec->reg_cache);
+fail:
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
kfree(codec->name);
kfree(codec);
return ret;
@@ -3304,8 +3565,8 @@ found:
pr_debug("Unregistered codec '%s'\n", codec->name);
- if (codec->reg_cache)
- kfree(codec->reg_cache);
+ snd_soc_cache_exit(codec);
+ kfree(codec->reg_def_copy);
kfree(codec->name);
kfree(codec);
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 75ed6491222d..3d310af28907 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -42,9 +42,11 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
+#include <trace/events/asoc.h>
+
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
[snd_soc_dapm_pre] = 0,
@@ -60,6 +62,7 @@ static int dapm_up_seq[] = {
[snd_soc_dapm_mixer_named_ctl] = 7,
[snd_soc_dapm_pga] = 8,
[snd_soc_dapm_adc] = 9,
+ [snd_soc_dapm_out_drv] = 10,
[snd_soc_dapm_hp] = 10,
[snd_soc_dapm_spk] = 10,
[snd_soc_dapm_post] = 11,
@@ -70,6 +73,7 @@ static int dapm_down_seq[] = {
[snd_soc_dapm_adc] = 1,
[snd_soc_dapm_hp] = 2,
[snd_soc_dapm_spk] = 2,
+ [snd_soc_dapm_out_drv] = 2,
[snd_soc_dapm_pga] = 4,
[snd_soc_dapm_mixer_named_ctl] = 5,
[snd_soc_dapm_mixer] = 5,
@@ -90,17 +94,24 @@ static void pop_wait(u32 pop_time)
schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
}
-static void pop_dbg(u32 pop_time, const char *fmt, ...)
+static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
{
va_list args;
+ char *buf;
- va_start(args, fmt);
+ if (!pop_time)
+ return;
- if (pop_time) {
- vprintk(fmt, args);
- }
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (buf == NULL)
+ return;
+ va_start(args, fmt);
+ vsnprintf(buf, PAGE_SIZE, fmt, args);
+ dev_info(dev, buf);
va_end(args);
+
+ kfree(buf);
}
/* create a new dapm widget */
@@ -120,37 +131,46 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
* Returns 0 for success else error.
*/
static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_codec *codec, enum snd_soc_bias_level level)
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
{
int ret = 0;
switch (level) {
case SND_SOC_BIAS_ON:
- dev_dbg(codec->dev, "Setting full bias\n");
+ dev_dbg(dapm->dev, "Setting full bias\n");
break;
case SND_SOC_BIAS_PREPARE:
- dev_dbg(codec->dev, "Setting bias prepare\n");
+ dev_dbg(dapm->dev, "Setting bias prepare\n");
break;
case SND_SOC_BIAS_STANDBY:
- dev_dbg(codec->dev, "Setting standby bias\n");
+ dev_dbg(dapm->dev, "Setting standby bias\n");
break;
case SND_SOC_BIAS_OFF:
- dev_dbg(codec->dev, "Setting bias off\n");
+ dev_dbg(dapm->dev, "Setting bias off\n");
break;
default:
- dev_err(codec->dev, "Setting invalid bias %d\n", level);
+ dev_err(dapm->dev, "Setting invalid bias %d\n", level);
return -EINVAL;
}
+ trace_snd_soc_bias_level_start(card, level);
+
if (card && card->set_bias_level)
ret = card->set_bias_level(card, level);
if (ret == 0) {
- if (codec->driver->set_bias_level)
- ret = codec->driver->set_bias_level(codec, level);
+ if (dapm->codec && dapm->codec->driver->set_bias_level)
+ ret = dapm->codec->driver->set_bias_level(dapm->codec, level);
else
- codec->bias_level = level;
+ dapm->bias_level = level;
+ }
+ if (ret == 0) {
+ if (card && card->set_bias_level_post)
+ ret = card->set_bias_level_post(card, level);
}
+ trace_snd_soc_bias_level_done(card, level);
+
return ret;
}
@@ -217,6 +237,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
break;
/* does not effect routing - always connected */
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_output:
case snd_soc_dapm_adc:
case snd_soc_dapm_input:
@@ -241,7 +262,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
}
/* connect mux widget to its interconnecting audio paths */
-static int dapm_connect_mux(struct snd_soc_codec *codec,
+static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
struct snd_soc_dapm_path *path, const char *control_name,
const struct snd_kcontrol_new *kcontrol)
@@ -251,7 +272,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
for (i = 0; i < e->max; i++) {
if (!(strcmp(control_name, e->texts[i]))) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->paths);
list_add(&path->list_sink, &dest->sources);
list_add(&path->list_source, &src->sinks);
path->name = (char*)e->texts[i];
@@ -264,7 +285,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
}
/* connect mixer widget to its interconnecting audio paths */
-static int dapm_connect_mixer(struct snd_soc_codec *codec,
+static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
struct snd_soc_dapm_path *path, const char *control_name)
{
@@ -273,7 +294,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec,
/* search for mixer kcontrol */
for (i = 0; i < dest->num_kcontrols; i++) {
if (!strcmp(control_name, dest->kcontrols[i].name)) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->paths);
list_add(&path->list_sink, &dest->sources);
list_add(&path->list_source, &src->sinks);
path->name = dest->kcontrols[i].name;
@@ -290,6 +311,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
int change, power;
unsigned int old, new;
struct snd_soc_codec *codec = widget->codec;
+ struct snd_soc_dapm_context *dapm = widget->dapm;
+ struct snd_soc_card *card = dapm->card;
/* check for valid widgets */
if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
@@ -309,24 +332,26 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
change = old != new;
if (change) {
- pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
+ pop_dbg(dapm->dev, card->pop_time,
+ "pop test %s : %s in %d ms\n",
widget->name, widget->power ? "on" : "off",
- codec->pop_time);
- pop_wait(codec->pop_time);
+ card->pop_time);
+ pop_wait(card->pop_time);
snd_soc_write(codec, widget->reg, new);
}
- pr_debug("reg %x old %x new %x change %d\n", widget->reg,
- old, new, change);
+ dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg,
+ old, new, change);
return change;
}
/* create new dapm mixer control */
-static int dapm_new_mixer(struct snd_soc_codec *codec,
+static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
int i, ret = 0;
size_t name_len;
struct snd_soc_dapm_path *path;
+ struct snd_card *card = dapm->codec->card->snd_card;
/* add kcontrol */
for (i = 0; i < w->num_kcontrols; i++) {
@@ -368,11 +393,11 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
path->long_name);
- ret = snd_ctl_add(codec->card->snd_card, path->kcontrol);
+ ret = snd_ctl_add(card, path->kcontrol);
if (ret < 0) {
- printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
- path->long_name,
- ret);
+ dev_err(dapm->dev,
+ "asoc: failed to add dapm kcontrol %s: %d\n",
+ path->long_name, ret);
kfree(path->long_name);
path->long_name = NULL;
return ret;
@@ -383,20 +408,22 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
}
/* create new dapm mux control */
-static int dapm_new_mux(struct snd_soc_codec *codec,
+static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
struct snd_soc_dapm_path *path = NULL;
struct snd_kcontrol *kcontrol;
+ struct snd_card *card = dapm->codec->card->snd_card;
int ret = 0;
if (!w->num_kcontrols) {
- printk(KERN_ERR "asoc: mux %s has no controls\n", w->name);
+ dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name);
return -EINVAL;
}
kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
- ret = snd_ctl_add(codec->card->snd_card, kcontrol);
+ ret = snd_ctl_add(card, kcontrol);
+
if (ret < 0)
goto err;
@@ -406,26 +433,27 @@ static int dapm_new_mux(struct snd_soc_codec *codec,
return ret;
err:
- printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
+ dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
return ret;
}
/* create new dapm volume control */
-static int dapm_new_pga(struct snd_soc_codec *codec,
+static int dapm_new_pga(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
if (w->num_kcontrols)
- pr_err("asoc: PGA controls not supported: '%s'\n", w->name);
+ dev_err(w->dapm->dev,
+ "asoc: PGA controls not supported: '%s'\n", w->name);
return 0;
}
/* reset 'walked' bit for each dapm path */
-static inline void dapm_clear_walk(struct snd_soc_codec *codec)
+static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_path *p;
- list_for_each_entry(p, &codec->dapm_paths, list)
+ list_for_each_entry(p, &dapm->paths, list)
p->walked = 0;
}
@@ -435,13 +463,14 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
*/
static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
{
- int level = snd_power_get_state(widget->codec->card->snd_card);
+ int level = snd_power_get_state(widget->dapm->codec->card->snd_card);
switch (level) {
case SNDRV_CTL_POWER_D3hot:
case SNDRV_CTL_POWER_D3cold:
if (widget->ignore_suspend)
- pr_debug("%s ignoring suspend\n", widget->name);
+ dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
+ widget->name);
return widget->ignore_suspend;
default:
return 1;
@@ -572,7 +601,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
/* call any power change event handlers */
if (w->event)
- pr_debug("power %s event for %s flags %x\n",
+ dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
w->power ? "on" : "off",
w->name, w->event_flags);
@@ -621,9 +650,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
int in, out;
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return out != 0 && in != 0;
}
@@ -634,7 +663,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
if (w->active) {
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return in != 0;
} else {
return dapm_generic_check_power(w);
@@ -648,7 +677,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
if (w->active) {
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return out != 0;
} else {
return dapm_generic_check_power(w);
@@ -674,7 +703,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
}
}
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return power;
}
@@ -687,8 +716,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
return sort[a->id] - sort[b->id];
if (a->reg != b->reg)
return a->reg - b->reg;
- if (a->codec != b->codec)
- return (unsigned long)a->codec - (unsigned long)b->codec;
+ if (a->dapm != b->dapm)
+ return (unsigned long)a->dapm - (unsigned long)b->dapm;
return 0;
}
@@ -709,12 +738,57 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
list_add_tail(&new_widget->power_list, list);
}
+static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
+ struct snd_soc_dapm_widget *w, int event)
+{
+ struct snd_soc_card *card = dapm->card;
+ const char *ev_name;
+ int power, ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ev_name = "PRE_PMU";
+ power = 1;
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ ev_name = "POST_PMU";
+ power = 1;
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ ev_name = "PRE_PMD";
+ power = 0;
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ev_name = "POST_PMD";
+ power = 0;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ if (w->power != power)
+ return;
+
+ if (w->event && (w->event_flags & event)) {
+ pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n",
+ w->name, ev_name);
+ trace_snd_soc_dapm_widget_event_start(w, event);
+ ret = w->event(w, NULL, event);
+ trace_snd_soc_dapm_widget_event_done(w, event);
+ if (ret < 0)
+ pr_err("%s: %s event failed: %d\n",
+ ev_name, w->name, ret);
+ }
+}
+
/* Apply the coalesced changes from a DAPM sequence */
-static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
+static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
struct list_head *pending)
{
+ struct snd_soc_card *card = dapm->card;
struct snd_soc_dapm_widget *w;
- int reg, power, ret;
+ int reg, power;
unsigned int value = 0;
unsigned int mask = 0;
unsigned int cur_mask;
@@ -735,64 +809,26 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
if (power)
value |= cur_mask;
- pop_dbg(codec->pop_time,
+ pop_dbg(dapm->dev, card->pop_time,
"pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
w->name, reg, value, mask);
- /* power up pre event */
- if (w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
- pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
- if (ret < 0)
- pr_err("%s: pre event failed: %d\n",
- w->name, ret);
- }
-
- /* power down pre event */
- if (!w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
- pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
- if (ret < 0)
- pr_err("%s: pre event failed: %d\n",
- w->name, ret);
- }
+ /* Check for events */
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU);
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD);
}
if (reg >= 0) {
- pop_dbg(codec->pop_time,
+ pop_dbg(dapm->dev, card->pop_time,
"pop test : Applying 0x%x/0x%x to %x in %dms\n",
- value, mask, reg, codec->pop_time);
- pop_wait(codec->pop_time);
- snd_soc_update_bits(codec, reg, mask, value);
+ value, mask, reg, card->pop_time);
+ pop_wait(card->pop_time);
+ snd_soc_update_bits(dapm->codec, reg, mask, value);
}
list_for_each_entry(w, pending, power_list) {
- /* power up post event */
- if (w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
- pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
- w->name);
- ret = w->event(w,
- NULL, SND_SOC_DAPM_POST_PMU);
- if (ret < 0)
- pr_err("%s: post event failed: %d\n",
- w->name, ret);
- }
-
- /* power down post event */
- if (!w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
- pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
- if (ret < 0)
- pr_err("%s: post event failed: %d\n",
- w->name, ret);
- }
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU);
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD);
}
}
@@ -804,8 +840,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
* Currently anything that requires more than a single write is not
* handled.
*/
-static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
- int event, int sort[])
+static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
+ struct list_head *list, int event, int sort[])
{
struct snd_soc_dapm_widget *w, *n;
LIST_HEAD(pending);
@@ -819,7 +855,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
/* Do we need to apply any queued changes? */
if (sort[w->id] != cur_sort || w->reg != cur_reg) {
if (!list_empty(&pending))
- dapm_seq_run_coalesced(codec, &pending);
+ dapm_seq_run_coalesced(dapm, &pending);
INIT_LIST_HEAD(&pending);
cur_sort = -1;
@@ -872,12 +908,12 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
}
if (ret < 0)
- pr_err("Failed to apply widget power: %d\n",
- ret);
+ dev_err(w->dapm->dev,
+ "Failed to apply widget power: %d\n", ret);
}
if (!list_empty(&pending))
- dapm_seq_run_coalesced(codec, &pending);
+ dapm_seq_run_coalesced(dapm, &pending);
}
/*
@@ -889,9 +925,9 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
* o Input pin to Output pin (bypass, sidetone)
* o DAC to ADC (loopback).
*/
-static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
+static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
{
- struct snd_soc_card *card = codec->card;
+ struct snd_soc_card *card = dapm->codec->card;
struct snd_soc_dapm_widget *w;
LIST_HEAD(up_list);
LIST_HEAD(down_list);
@@ -899,10 +935,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
int power;
int sys_power = 0;
+ trace_snd_soc_dapm_start(card);
+
/* Check which widgets we need to power and store them in
* lists indicating if they should be powered up or down.
*/
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
switch (w->id) {
case snd_soc_dapm_pre:
dapm_seq_insert(w, &down_list, dapm_down_seq);
@@ -925,6 +963,8 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
if (w->power == power)
continue;
+ trace_snd_soc_dapm_widget_power(w, power);
+
if (power)
dapm_seq_insert(w, &up_list, dapm_up_seq);
else
@@ -938,17 +978,20 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
/* If there are no DAPM widgets then try to figure out power from the
* event type.
*/
- if (list_empty(&codec->dapm_widgets)) {
+ if (list_empty(&dapm->widgets)) {
switch (event) {
case SND_SOC_DAPM_STREAM_START:
case SND_SOC_DAPM_STREAM_RESUME:
sys_power = 1;
break;
+ case SND_SOC_DAPM_STREAM_STOP:
+ sys_power = !!dapm->codec->active;
+ break;
case SND_SOC_DAPM_STREAM_SUSPEND:
sys_power = 0;
break;
case SND_SOC_DAPM_STREAM_NOP:
- switch (codec->bias_level) {
+ switch (dapm->bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
sys_power = 0;
@@ -963,52 +1006,59 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
}
}
- if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_dapm_set_bias_level(card, codec,
+ if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) {
+ ret = snd_soc_dapm_set_bias_level(card, dapm,
SND_SOC_BIAS_STANDBY);
if (ret != 0)
- pr_err("Failed to turn on bias: %d\n", ret);
+ dev_err(dapm->dev,
+ "Failed to turn on bias: %d\n", ret);
}
/* If we're changing to all on or all off then prepare */
- if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
- (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE);
+ if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) ||
+ (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) {
+ ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE);
if (ret != 0)
- pr_err("Failed to prepare bias: %d\n", ret);
+ dev_err(dapm->dev,
+ "Failed to prepare bias: %d\n", ret);
}
/* Power down widgets first; try to avoid amplifying pops. */
- dapm_seq_run(codec, &down_list, event, dapm_down_seq);
+ dapm_seq_run(dapm, &down_list, event, dapm_down_seq);
/* Now power up. */
- dapm_seq_run(codec, &up_list, event, dapm_up_seq);
+ dapm_seq_run(dapm, &up_list, event, dapm_up_seq);
/* If we just powered the last thing off drop to standby bias */
- if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY);
+ if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
+ ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
if (ret != 0)
- pr_err("Failed to apply standby bias: %d\n", ret);
+ dev_err(dapm->dev,
+ "Failed to apply standby bias: %d\n", ret);
}
/* If we're in standby and can support bias off then do that */
- if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
- codec->idle_bias_off) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
+ if (dapm->bias_level == SND_SOC_BIAS_STANDBY &&
+ dapm->idle_bias_off) {
+ ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF);
if (ret != 0)
- pr_err("Failed to turn off bias: %d\n", ret);
+ dev_err(dapm->dev,
+ "Failed to turn off bias: %d\n", ret);
}
/* If we just powered up then move to active bias */
- if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON);
+ if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
+ ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON);
if (ret != 0)
- pr_err("Failed to apply active bias: %d\n", ret);
+ dev_err(dapm->dev,
+ "Failed to apply active bias: %d\n", ret);
}
- pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
- codec->pop_time);
- pop_wait(codec->pop_time);
+ pop_dbg(dapm->dev, card->pop_time,
+ "DAPM sequencing finished, waiting %dms\n", card->pop_time);
+ pop_wait(card->pop_time);
+
+ trace_snd_soc_dapm_done(card);
return 0;
}
@@ -1035,9 +1085,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
return -ENOMEM;
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
w->name, w->power ? "On" : "Off", in, out);
@@ -1087,29 +1137,29 @@ static const struct file_operations dapm_widget_power_fops = {
.llseek = default_llseek,
};
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
struct dentry *d;
- if (!codec->debugfs_dapm)
+ if (!dapm->debugfs_dapm)
return;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!w->name)
continue;
d = debugfs_create_file(w->name, 0444,
- codec->debugfs_dapm, w,
+ dapm->debugfs_dapm, w,
&dapm_widget_power_fops);
if (!d)
- printk(KERN_WARNING
- "ASoC: Failed to create %s debugfs file\n",
- w->name);
+ dev_warn(w->dapm->dev,
+ "ASoC: Failed to create %s debugfs file\n",
+ w->name);
}
}
#else
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
{
}
#endif
@@ -1130,7 +1180,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
return 0;
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -1146,7 +1196,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
}
if (found)
- dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
@@ -1164,7 +1214,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
return -ENODEV;
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -1175,7 +1225,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
}
if (found)
- dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
@@ -1191,7 +1241,7 @@ static ssize_t dapm_widget_show(struct device *dev,
int count = 0;
char *state = "not set";
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &codec->dapm.widgets, list) {
/* only display widgets that burnm power */
switch (w->id) {
@@ -1203,6 +1253,7 @@ static ssize_t dapm_widget_show(struct device *dev,
case snd_soc_dapm_dac:
case snd_soc_dapm_adc:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
case snd_soc_dapm_supply:
@@ -1215,7 +1266,7 @@ static ssize_t dapm_widget_show(struct device *dev,
}
}
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_ON:
state = "On";
break;
@@ -1247,31 +1298,33 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
}
/* free all dapm widgets and resources */
-static void dapm_free_widgets(struct snd_soc_codec *codec)
+static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w, *next_w;
struct snd_soc_dapm_path *p, *next_p;
- list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) {
+ list_for_each_entry_safe(w, next_w, &dapm->widgets, list) {
list_del(&w->list);
+ kfree(w->name);
kfree(w);
}
- list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) {
+ list_for_each_entry_safe(p, next_p, &dapm->paths, list) {
list_del(&p->list);
kfree(p->long_name);
kfree(p);
}
}
-static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
+static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
const char *pin, int status)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!strcmp(w->name, pin)) {
- pr_debug("dapm: %s: pin %s\n", codec->name, pin);
+ dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
+ pin, status);
w->connected = status;
/* Allow disabling of forced pins */
if (status == 0)
@@ -1280,37 +1333,51 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
}
}
- pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
/**
* snd_soc_dapm_sync - scan and power dapm paths
- * @codec: audio codec
+ * @dapm: DAPM context
*
* Walks all dapm audio paths and powers widgets according to their
* stream or path usage.
*
* Returns 0 for success.
*/
-int snd_soc_dapm_sync(struct snd_soc_codec *codec)
+int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
{
- return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
+ return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
-static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
+static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route)
{
struct snd_soc_dapm_path *path;
struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
- const char *sink = route->sink;
+ const char *sink;
const char *control = route->control;
- const char *source = route->source;
+ const char *source;
+ char prefixed_sink[80];
+ char prefixed_source[80];
int ret = 0;
+ if (dapm->codec->name_prefix) {
+ snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
+ dapm->codec->name_prefix, route->sink);
+ sink = prefixed_sink;
+ snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
+ dapm->codec->name_prefix, route->source);
+ source = prefixed_source;
+ } else {
+ sink = route->sink;
+ source = route->source;
+ }
+
/* find src and dest widgets */
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!wsink && !(strcmp(w->name, sink))) {
wsink = w;
@@ -1353,7 +1420,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
/* connect static paths */
if (control == NULL) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 1;
@@ -1365,6 +1432,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_adc:
case snd_soc_dapm_dac:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_input:
case snd_soc_dapm_output:
case snd_soc_dapm_micbias:
@@ -1374,14 +1442,14 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_supply:
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 1;
return 0;
case snd_soc_dapm_mux:
case snd_soc_dapm_value_mux:
- ret = dapm_connect_mux(codec, wsource, wsink, path, control,
+ ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
&wsink->kcontrols[0]);
if (ret != 0)
goto err;
@@ -1389,7 +1457,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
- ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
+ ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
if (ret != 0)
goto err;
break;
@@ -1397,7 +1465,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_mic:
case snd_soc_dapm_line:
case snd_soc_dapm_spk:
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 0;
@@ -1406,15 +1474,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
return 0;
err:
- printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source,
- control, sink);
+ dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
+ source, control, sink);
kfree(path);
return ret;
}
/**
* snd_soc_dapm_add_routes - Add routes between DAPM widgets
- * @codec: codec
+ * @dapm: DAPM context
* @route: audio routes
* @num: number of routes
*
@@ -1425,17 +1493,16 @@ err:
* Returns 0 for success else error. On error all resources can be freed
* with a call to snd_soc_card_free().
*/
-int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
+int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num)
{
int i, ret;
for (i = 0; i < num; i++) {
- ret = snd_soc_dapm_add_route(codec, route);
+ ret = snd_soc_dapm_add_route(dapm, route);
if (ret < 0) {
- printk(KERN_ERR "Failed to add route %s->%s\n",
- route->source,
- route->sink);
+ dev_err(dapm->dev, "Failed to add route %s->%s\n",
+ route->source, route->sink);
return ret;
}
route++;
@@ -1447,17 +1514,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
/**
* snd_soc_dapm_new_widgets - add new dapm widgets
- * @codec: audio codec
+ * @dapm: DAPM context
*
* Checks the codec for any new dapm widgets and creates them if found.
*
* Returns 0 for success.
*/
-int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
+int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list)
+ list_for_each_entry(w, &dapm->widgets, list)
{
if (w->new)
continue;
@@ -1467,12 +1534,12 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
w->power_check = dapm_generic_check_power;
- dapm_new_mixer(codec, w);
+ dapm_new_mixer(dapm, w);
break;
case snd_soc_dapm_mux:
case snd_soc_dapm_value_mux:
w->power_check = dapm_generic_check_power;
- dapm_new_mux(codec, w);
+ dapm_new_mux(dapm, w);
break;
case snd_soc_dapm_adc:
case snd_soc_dapm_aif_out:
@@ -1483,8 +1550,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
w->power_check = dapm_dac_check_power;
break;
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
w->power_check = dapm_generic_check_power;
- dapm_new_pga(codec, w);
+ dapm_new_pga(dapm, w);
break;
case snd_soc_dapm_input:
case snd_soc_dapm_output:
@@ -1505,7 +1573,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
w->new = 1;
}
- dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -1889,7 +1957,7 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
mutex_lock(&codec->mutex);
ucontrol->value.integer.value[0] =
- snd_soc_dapm_get_pin_status(codec, pin);
+ snd_soc_dapm_get_pin_status(&codec->dapm, pin);
mutex_unlock(&codec->mutex);
@@ -1912,11 +1980,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
mutex_lock(&codec->mutex);
if (ucontrol->value.integer.value[0])
- snd_soc_dapm_enable_pin(codec, pin);
+ snd_soc_dapm_enable_pin(&codec->dapm, pin);
else
- snd_soc_dapm_disable_pin(codec, pin);
+ snd_soc_dapm_disable_pin(&codec->dapm, pin);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
mutex_unlock(&codec->mutex);
@@ -1926,26 +1994,42 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
/**
* snd_soc_dapm_new_control - create new dapm control
- * @codec: audio codec
+ * @dapm: DAPM context
* @widget: widget template
*
* Creates a new dapm control based upon the template.
*
* Returns 0 for success else error.
*/
-int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget)
{
struct snd_soc_dapm_widget *w;
+ size_t name_len;
if ((w = dapm_cnew_widget(widget)) == NULL)
return -ENOMEM;
- w->codec = codec;
+ name_len = strlen(widget->name) + 1;
+ if (dapm->codec->name_prefix)
+ name_len += 1 + strlen(dapm->codec->name_prefix);
+ w->name = kmalloc(name_len, GFP_KERNEL);
+ if (w->name == NULL) {
+ kfree(w);
+ return -ENOMEM;
+ }
+ if (dapm->codec->name_prefix)
+ snprintf(w->name, name_len, "%s %s",
+ dapm->codec->name_prefix, widget->name);
+ else
+ snprintf(w->name, name_len, "%s", widget->name);
+
+ w->dapm = dapm;
+ w->codec = dapm->codec;
INIT_LIST_HEAD(&w->sources);
INIT_LIST_HEAD(&w->sinks);
INIT_LIST_HEAD(&w->list);
- list_add(&w->list, &codec->dapm_widgets);
+ list_add(&w->list, &dapm->widgets);
/* machine layer set ups unconnected pins and insertions */
w->connected = 1;
@@ -1955,7 +2039,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
/**
* snd_soc_dapm_new_controls - create new dapm controls
- * @codec: audio codec
+ * @dapm: DAPM context
* @widget: widget array
* @num: number of widgets
*
@@ -1963,18 +2047,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
*
* Returns 0 for success else error.
*/
-int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num)
{
int i, ret;
for (i = 0; i < num; i++) {
- ret = snd_soc_dapm_new_control(codec, widget);
+ ret = snd_soc_dapm_new_control(dapm, widget);
if (ret < 0) {
- printk(KERN_ERR
- "ASoC: Failed to create DAPM control %s: %d\n",
- widget->name, ret);
+ dev_err(dapm->dev,
+ "ASoC: Failed to create DAPM control %s: %d\n",
+ widget->name, ret);
return ret;
}
widget++;
@@ -1983,34 +2067,17 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-
-/**
- * snd_soc_dapm_stream_event - send a stream event to the dapm core
- * @codec: audio codec
- * @stream: stream name
- * @event: stream event
- *
- * Sends a stream event to the dapm core. The core then makes any
- * necessary widget power changes.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
+static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
const char *stream, int event)
{
- struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_widget *w;
- if (stream == NULL)
- return 0;
-
- mutex_lock(&codec->mutex);
- list_for_each_entry(w, &codec->dapm_widgets, list)
+ list_for_each_entry(w, &dapm->widgets, list)
{
if (!w->sname)
continue;
- pr_debug("widget %s\n %s stream %s event %d\n",
- w->name, w->sname, stream, event);
+ dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
+ w->name, w->sname, stream, event);
if (strstr(w->sname, stream)) {
switch(event) {
case SND_SOC_DAPM_STREAM_START:
@@ -2028,7 +2095,30 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
}
}
- dapm_power_widgets(codec, event);
+ dapm_power_widgets(dapm, event);
+}
+
+/**
+ * snd_soc_dapm_stream_event - send a stream event to the dapm core
+ * @rtd: PCM runtime data
+ * @stream: stream name
+ * @event: stream event
+ *
+ * Sends a stream event to the dapm core. The core then makes any
+ * necessary widget power changes.
+ *
+ * Returns 0 for success else error.
+ */
+int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
+ const char *stream, int event)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+
+ if (stream == NULL)
+ return 0;
+
+ mutex_lock(&codec->mutex);
+ soc_dapm_stream_event(&codec->dapm, stream, event);
mutex_unlock(&codec->mutex);
return 0;
}
@@ -2036,7 +2126,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
/**
* snd_soc_dapm_enable_pin - enable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin and its parents or children widgets iff there is
@@ -2044,15 +2134,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 1);
+ return snd_soc_dapm_set_pin(dapm, pin, 1);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
/**
* snd_soc_dapm_force_enable_pin - force a pin to be enabled
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin regardless of any other state. This is
@@ -2062,42 +2152,45 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!strcmp(w->name, pin)) {
- pr_debug("dapm: %s: pin %s\n", codec->name, pin);
+ dev_dbg(w->dapm->dev,
+ "dapm: force enable pin %s\n", pin);
w->connected = 1;
w->force = 1;
return 0;
}
}
- pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
/**
* snd_soc_dapm_disable_pin - disable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Disables input/output pin and its parents or children widgets.
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 0);
+ return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
/**
* snd_soc_dapm_nc_pin - permanently disable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Marks the specified pin as being not connected, disabling it along
@@ -2109,26 +2202,27 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 0);
+ return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
/**
* snd_soc_dapm_get_pin_status - get audio pin status
- * @codec: audio codec
+ * @dapm: DAPM context
* @pin: audio signal pin endpoint (or start point)
*
* Get audio pin status - connected or disconnected.
*
* Returns 1 for connected otherwise 0.
*/
-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!strcmp(w->name, pin))
return w->connected;
}
@@ -2139,7 +2233,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
/**
* snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
- * @codec: audio codec
+ * @dapm: DAPM context
* @pin: audio signal pin endpoint (or start point)
*
* Mark the given endpoint or pin as ignoring suspend. When the
@@ -2148,18 +2242,19 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
* normal means at suspend time, it will not be turned on if it was not
* already enabled.
*/
-int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (!strcmp(w->name, pin)) {
w->ignore_suspend = 1;
return 0;
}
}
- pr_err("Unknown DAPM pin: %s\n", pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
@@ -2170,20 +2265,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
*
* Free all dapm widgets and resources.
*/
-void snd_soc_dapm_free(struct snd_soc_codec *codec)
+void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
{
- snd_soc_dapm_sys_remove(codec->dev);
- dapm_free_widgets(codec);
+ snd_soc_dapm_sys_remove(dapm->dev);
+ dapm_free_widgets(dapm);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
-static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
+static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
LIST_HEAD(down_list);
int powerdown = 0;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->widgets, list) {
if (w->power) {
dapm_seq_insert(w, &down_list, dapm_down_seq);
w->power = 0;
@@ -2195,9 +2290,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
* standby.
*/
if (powerdown) {
- snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE);
- dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
- snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY);
+ snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
+ dapm_seq_run(dapm, &down_list, 0, dapm_down_seq);
+ snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
}
}
@@ -2208,10 +2303,10 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
{
struct snd_soc_codec *codec;
- list_for_each_entry(codec, &card->codec_dev_list, list)
- soc_dapm_shutdown_codec(codec);
-
- snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
+ list_for_each_entry(codec, &card->codec_dev_list, list) {
+ soc_dapm_shutdown_codec(&codec->dapm);
+ snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF);
+ }
}
/* Module information */
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 8a0a9205b1e7..ac5a5bc7375a 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -13,11 +13,11 @@
#include <sound/jack.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
+#include <trace/events/asoc.h>
/**
* snd_soc_jack_new - Create a new jack
@@ -60,14 +60,18 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
{
struct snd_soc_codec *codec;
+ struct snd_soc_dapm_context *dapm;
struct snd_soc_jack_pin *pin;
int enable;
int oldstatus;
+ trace_snd_soc_jack_report(jack, mask, status);
+
if (!jack)
return;
codec = jack->codec;
+ dapm = &codec->dapm;
mutex_lock(&codec->mutex);
@@ -81,6 +85,8 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
if (mask && (jack->status == oldstatus))
goto out;
+ trace_snd_soc_jack_notify(jack, status);
+
list_for_each_entry(pin, &jack->pins, list) {
enable = pin->mask & jack->status;
@@ -88,15 +94,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
enable = !enable;
if (enable)
- snd_soc_dapm_enable_pin(codec, pin->pin);
+ snd_soc_dapm_enable_pin(dapm, pin->pin);
else
- snd_soc_dapm_disable_pin(codec, pin->pin);
+ snd_soc_dapm_disable_pin(dapm, pin->pin);
}
/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain(&jack->notifier, status, NULL);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
snd_jack_report(jack->jack, status);
@@ -207,6 +213,12 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
static irqreturn_t gpio_handler(int irq, void *data)
{
struct snd_soc_jack_gpio *gpio = data;
+ struct device *dev = gpio->jack->codec->card->dev;
+
+ trace_snd_soc_jack_irq(gpio->name);
+
+ if (device_may_wakeup(dev))
+ pm_wakeup_event(dev, gpio->debounce_time + 50);
schedule_delayed_work(&gpio->work,
msecs_to_jiffies(gpio->debounce_time));
@@ -263,11 +275,12 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
gpios[i].jack = jack;
- ret = request_irq(gpio_to_irq(gpios[i].gpio),
- gpio_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- jack->codec->dev->driver->name,
- &gpios[i]);
+ ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio),
+ gpio_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ jack->codec->dev->driver->name,
+ &gpios[i]);
if (ret)
goto err;