aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:46:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:46:37 -0400
commitd3e458d78167102cc961237cfceef6fffc80c0b3 (patch)
treee9195c1294daf053614e63ac52b0b44a28479017 /sound/soc
parentf2e1fbb5f2177227f71c4fc0491e531dd7acd385 (diff)
parentd351cf4603edb2a5bfa9a48d06c425511c63f2a3 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (308 commits) ALSA: sound/pci/asihpi: check adapter index in hpi_ioctl ALSA: aloop - Fix possible IRQ lock inversion ALSA: sound/core: merge list_del()/list_add_tail() to list_move_tail() ALSA: ctxfi - use list_move() instead of list_del()/list_add() combination ALSA: firewire - msleep needs delay.h ALSA: firewire-lib, firewire-speakers: handle packet queueing errors ALSA: firewire-lib: allocate DMA buffer separately ALSA: firewire-lib: use no-info SYT for packets without SYT sample ALSA: add LaCie FireWire Speakers/Griffin FireWave Surround driver ALSA: hda - Remove an unused variable in patch_realtek.c ALSA: hda - pin-adc-mux-dmic auto-configuration of 92HD8X codecs ALSA: hda - fix digital mic selection in mixer on 92HD8X codecs ALSA: hda - Move default input-src selection to init part ALSA: hda - Initialize special cases for input src in init phase ALSA: ctxfi - Clear input settings before initialization ALSA: ctxfi - Fix SPDIF status retrieval ALSA: ctxfi - Fix incorrect SPDIF status bit mask ALSA: ctxfi - Fix microphone boost codes/comments ALSA: atiixp - Fix wrong time-out checks during ac-link reset ALSA: intel8x0m: append 'm' to "r_intel8x0" ...
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/codecs/Kconfig34
-rw-r--r--sound/soc/codecs/Makefile18
-rw-r--r--sound/soc/codecs/ak4104.c1
-rw-r--r--sound/soc/codecs/ak4642.c24
-rw-r--r--sound/soc/codecs/cs4270.c8
-rw-r--r--sound/soc/codecs/cs4271.c667
-rw-r--r--sound/soc/codecs/dfbmcs320.c72
-rw-r--r--sound/soc/codecs/lm4857.c276
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/codecs/max9850.c389
-rw-r--r--sound/soc/codecs/max9850.h38
-rw-r--r--sound/soc/codecs/sgtl5000.c1513
-rw-r--r--sound/soc/codecs/sgtl5000.h400
-rw-r--r--sound/soc/codecs/sn95031.c949
-rw-r--r--sound/soc/codecs/sn95031.h132
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c794
-rw-r--r--sound/soc/codecs/tlv320aic32x4.h143
-rw-r--r--sound/soc/codecs/tlv320dac33.c1
-rw-r--r--sound/soc/codecs/twl6040.c4
-rw-r--r--sound/soc/codecs/wm2000.c14
-rw-r--r--sound/soc/codecs/wm8523.c8
-rw-r--r--sound/soc/codecs/wm8741.c13
-rw-r--r--sound/soc/codecs/wm8753.c296
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8900.c2
-rw-r--r--sound/soc/codecs/wm8903.c641
-rw-r--r--sound/soc/codecs/wm8903.h8
-rw-r--r--sound/soc/codecs/wm8904.c43
-rw-r--r--sound/soc/codecs/wm8955.c27
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c36
-rw-r--r--sound/soc/codecs/wm8978.c7
-rw-r--r--sound/soc/codecs/wm8991.c1427
-rw-r--r--sound/soc/codecs/wm8991.h833
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994-tables.c12
-rw-r--r--sound/soc/codecs/wm8994.c127
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm8995.c103
-rw-r--r--sound/soc/codecs/wm9081.c84
-rw-r--r--sound/soc/codecs/wm9090.c45
-rw-r--r--sound/soc/codecs/wm_hubs.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c28
-rw-r--r--sound/soc/davinci/davinci-mcasp.c29
-rw-r--r--sound/soc/ep93xx/Kconfig9
-rw-r--r--sound/soc/ep93xx/Makefile2
-rw-r--r--sound/soc/ep93xx/edb93xx.c142
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c31
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/fsl/p1022_ds.c6
-rw-r--r--sound/soc/imx/Kconfig10
-rw-r--r--sound/soc/imx/Makefile2
-rw-r--r--sound/soc/imx/imx-ssi.c5
-rw-r--r--sound/soc/imx/mx27vis-aic32x4.c137
-rw-r--r--sound/soc/mid-x86/Kconfig14
-rw-r--r--sound/soc/mid-x86/Makefile5
-rw-r--r--sound/soc/mid-x86/mfld_machine.c452
-rw-r--r--sound/soc/mid-x86/sst_platform.c474
-rw-r--r--sound/soc/mid-x86/sst_platform.h63
-rw-r--r--sound/soc/omap/Kconfig1
-rw-r--r--sound/soc/omap/rx51.c131
-rw-r--r--sound/soc/pxa/raumfeld.c20
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/z2.c7
-rw-r--r--sound/soc/pxa/zylonite.c9
-rw-r--r--sound/soc/samsung/Kconfig19
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/ac97.c8
-rw-r--r--sound/soc/samsung/ac97.h21
-rw-r--r--sound/soc/samsung/dma.c13
-rw-r--r--sound/soc/samsung/dma.h8
-rw-r--r--sound/soc/samsung/goni_wm8994.c10
-rw-r--r--sound/soc/samsung/h1940_uda1380.c9
-rw-r--r--sound/soc/samsung/i2s.c3
-rw-r--r--sound/soc/samsung/jive_wm8750.c11
-rw-r--r--sound/soc/samsung/lm4857.h32
-rw-r--r--sound/soc/samsung/ln2440sbc_alc650.c7
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c504
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c635
-rw-r--r--sound/soc/samsung/pcm.c118
-rw-r--r--sound/soc/samsung/pcm.h107
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c11
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c3
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c12
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c14
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c7
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c10
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c12
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c9
-rw-r--r--sound/soc/samsung/smartq_wm8987.c6
-rw-r--r--sound/soc/samsung/smdk2443_wm9710.c7
-rw-r--r--sound/soc/samsung/smdk_spdif.c5
-rw-r--r--sound/soc/samsung/smdk_wm8580.c7
-rw-r--r--sound/soc/samsung/smdk_wm9713.c5
-rw-r--r--sound/soc/samsung/spdif.c3
-rw-r--r--sound/soc/sh/fsi-ak4642.c24
-rw-r--r--sound/soc/sh/fsi-da7210.c13
-rw-r--r--sound/soc/sh/fsi-hdmi.c77
-rw-r--r--sound/soc/sh/fsi.c203
-rw-r--r--sound/soc/soc-cache.c386
-rw-r--r--sound/soc/soc-core.c548
-rw-r--r--sound/soc/soc-dapm.c257
-rw-r--r--sound/soc/soc-jack.c58
-rw-r--r--sound/soc/soc-utils.c23
-rw-r--r--sound/soc/tegra/Kconfig26
-rw-r--r--sound/soc/tegra/Makefile15
-rw-r--r--sound/soc/tegra/harmony.c393
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c155
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h45
-rw-r--r--sound/soc/tegra/tegra_das.c265
-rw-r--r--sound/soc/tegra/tegra_das.h135
-rw-r--r--sound/soc/tegra/tegra_i2s.c503
-rw-r--r--sound/soc/tegra/tegra_i2s.h165
-rw-r--r--sound/soc/tegra/tegra_pcm.c404
-rw-r--r--sound/soc/tegra/tegra_pcm.h55
119 files changed, 13693 insertions, 2473 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index a3efc52a34da..8224db5f0434 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -50,10 +50,12 @@ source "sound/soc/jz4740/Kconfig"
50source "sound/soc/nuc900/Kconfig" 50source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 51source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 52source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/mid-x86/Kconfig"
53source "sound/soc/pxa/Kconfig" 54source "sound/soc/pxa/Kconfig"
54source "sound/soc/samsung/Kconfig" 55source "sound/soc/samsung/Kconfig"
55source "sound/soc/s6000/Kconfig" 56source "sound/soc/s6000/Kconfig"
56source "sound/soc/sh/Kconfig" 57source "sound/soc/sh/Kconfig"
58source "sound/soc/tegra/Kconfig"
57source "sound/soc/txx9/Kconfig" 59source "sound/soc/txx9/Kconfig"
58 60
59# Supported codecs 61# Supported codecs
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index ce913bf5213c..1ed61c5df2c5 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC) += ep93xx/
10obj-$(CONFIG_SND_SOC) += fsl/ 10obj-$(CONFIG_SND_SOC) += fsl/
11obj-$(CONFIG_SND_SOC) += imx/ 11obj-$(CONFIG_SND_SOC) += imx/
12obj-$(CONFIG_SND_SOC) += jz4740/ 12obj-$(CONFIG_SND_SOC) += jz4740/
13obj-$(CONFIG_SND_SOC) += mid-x86/
13obj-$(CONFIG_SND_SOC) += nuc900/ 14obj-$(CONFIG_SND_SOC) += nuc900/
14obj-$(CONFIG_SND_SOC) += omap/ 15obj-$(CONFIG_SND_SOC) += omap/
15obj-$(CONFIG_SND_SOC) += kirkwood/ 16obj-$(CONFIG_SND_SOC) += kirkwood/
@@ -17,4 +18,5 @@ obj-$(CONFIG_SND_SOC) += pxa/
17obj-$(CONFIG_SND_SOC) += samsung/ 18obj-$(CONFIG_SND_SOC) += samsung/
18obj-$(CONFIG_SND_SOC) += s6000/ 19obj-$(CONFIG_SND_SOC) += s6000/
19obj-$(CONFIG_SND_SOC) += sh/ 20obj-$(CONFIG_SND_SOC) += sh/
21obj-$(CONFIG_SND_SOC) += tegra/
20obj-$(CONFIG_SND_SOC) += txx9/ 22obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c48b23c1d4fc..d63c1754e05f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,17 +26,24 @@ config SND_SOC_ALL_CODECS
26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
27 select SND_SOC_CS42L51 if I2C 27 select SND_SOC_CS42L51 if I2C
28 select SND_SOC_CS4270 if I2C 28 select SND_SOC_CS4270 if I2C
29 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
29 select SND_SOC_CX20442 30 select SND_SOC_CX20442
30 select SND_SOC_DA7210 if I2C 31 select SND_SOC_DA7210 if I2C
32 select SND_SOC_DFBMCS320
31 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C
32 select SND_SOC_MAX98088 if I2C 35 select SND_SOC_MAX98088 if I2C
36 select SND_SOC_MAX9850 if I2C
33 select SND_SOC_MAX9877 if I2C 37 select SND_SOC_MAX9877 if I2C
34 select SND_SOC_PCM3008 38 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C
40 select SND_SOC_SN95031 if INTEL_SCU_IPC
35 select SND_SOC_SPDIF 41 select SND_SOC_SPDIF
36 select SND_SOC_SSM2602 if I2C 42 select SND_SOC_SSM2602 if I2C
37 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
38 select SND_SOC_TLV320AIC23 if I2C 44 select SND_SOC_TLV320AIC23 if I2C
39 select SND_SOC_TLV320AIC26 if SPI_MASTER 45 select SND_SOC_TLV320AIC26 if SPI_MASTER
46 select SND_SOC_TVL320AIC32X4 if I2C
40 select SND_SOC_TLV320AIC3X if I2C 47 select SND_SOC_TLV320AIC3X if I2C
41 select SND_SOC_TPA6130A2 if I2C 48 select SND_SOC_TPA6130A2 if I2C
42 select SND_SOC_TLV320DAC33 if I2C 49 select SND_SOC_TLV320DAC33 if I2C
@@ -76,6 +83,7 @@ config SND_SOC_ALL_CODECS
76 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 83 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
77 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 84 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
78 select SND_SOC_WM8990 if I2C 85 select SND_SOC_WM8990 if I2C
86 select SND_SOC_WM8991 if I2C
79 select SND_SOC_WM8993 if I2C 87 select SND_SOC_WM8993 if I2C
80 select SND_SOC_WM8994 if MFD_WM8994 88 select SND_SOC_WM8994 if MFD_WM8994
81 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 89 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
@@ -155,6 +163,9 @@ config SND_SOC_CS4270_VD33_ERRATA
155 bool 163 bool
156 depends on SND_SOC_CS4270 164 depends on SND_SOC_CS4270
157 165
166config SND_SOC_CS4271
167 tristate
168
158config SND_SOC_CX20442 169config SND_SOC_CX20442
159 tristate 170 tristate
160 171
@@ -167,15 +178,28 @@ config SND_SOC_L3
167config SND_SOC_DA7210 178config SND_SOC_DA7210
168 tristate 179 tristate
169 180
181config SND_SOC_DFBMCS320
182 tristate
183
170config SND_SOC_DMIC 184config SND_SOC_DMIC
171 tristate 185 tristate
172 186
173config SND_SOC_MAX98088 187config SND_SOC_MAX98088
174 tristate 188 tristate
175 189
190config SND_SOC_MAX9850
191 tristate
192
176config SND_SOC_PCM3008 193config SND_SOC_PCM3008
177 tristate 194 tristate
178 195
196#Freescale sgtl5000 codec
197config SND_SOC_SGTL5000
198 tristate
199
200config SND_SOC_SN95031
201 tristate
202
179config SND_SOC_SPDIF 203config SND_SOC_SPDIF
180 tristate 204 tristate
181 205
@@ -192,6 +216,9 @@ config SND_SOC_TLV320AIC26
192 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 216 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
193 depends on SPI 217 depends on SPI
194 218
219config SND_SOC_TVL320AIC32X4
220 tristate
221
195config SND_SOC_TLV320AIC3X 222config SND_SOC_TLV320AIC3X
196 tristate 223 tristate
197 224
@@ -304,6 +331,9 @@ config SND_SOC_WM8988
304config SND_SOC_WM8990 331config SND_SOC_WM8990
305 tristate 332 tristate
306 333
334config SND_SOC_WM8991
335 tristate
336
307config SND_SOC_WM8993 337config SND_SOC_WM8993
308 tristate 338 tristate
309 339
@@ -326,6 +356,9 @@ config SND_SOC_WM9713
326 tristate 356 tristate
327 357
328# Amp 358# Amp
359config SND_SOC_LM4857
360 tristate
361
329config SND_SOC_MAX9877 362config SND_SOC_MAX9877
330 tristate 363 tristate
331 364
@@ -337,4 +370,3 @@ config SND_SOC_WM2000
337 370
338config SND_SOC_WM9090 371config SND_SOC_WM9090
339 tristate 372 tristate
340
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 579af9c4f128..379bc55f0723 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -12,19 +12,25 @@ snd-soc-ak4671-objs := ak4671.o
12snd-soc-cq93vc-objs := cq93vc.o 12snd-soc-cq93vc-objs := cq93vc.o
13snd-soc-cs42l51-objs := cs42l51.o 13snd-soc-cs42l51-objs := cs42l51.o
14snd-soc-cs4270-objs := cs4270.o 14snd-soc-cs4270-objs := cs4270.o
15snd-soc-cs4271-objs := cs4271.o
15snd-soc-cx20442-objs := cx20442.o 16snd-soc-cx20442-objs := cx20442.o
16snd-soc-da7210-objs := da7210.o 17snd-soc-da7210-objs := da7210.o
18snd-soc-dfbmcs320-objs := dfbmcs320.o
17snd-soc-dmic-objs := dmic.o 19snd-soc-dmic-objs := dmic.o
18snd-soc-l3-objs := l3.o 20snd-soc-l3-objs := l3.o
19snd-soc-max98088-objs := max98088.o 21snd-soc-max98088-objs := max98088.o
22snd-soc-max9850-objs := max9850.o
20snd-soc-pcm3008-objs := pcm3008.o 23snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o
21snd-soc-alc5623-objs := alc5623.o 25snd-soc-alc5623-objs := alc5623.o
26snd-soc-sn95031-objs := sn95031.o
22snd-soc-spdif-objs := spdif_transciever.o 27snd-soc-spdif-objs := spdif_transciever.o
23snd-soc-ssm2602-objs := ssm2602.o 28snd-soc-ssm2602-objs := ssm2602.o
24snd-soc-stac9766-objs := stac9766.o 29snd-soc-stac9766-objs := stac9766.o
25snd-soc-tlv320aic23-objs := tlv320aic23.o 30snd-soc-tlv320aic23-objs := tlv320aic23.o
26snd-soc-tlv320aic26-objs := tlv320aic26.o 31snd-soc-tlv320aic26-objs := tlv320aic26.o
27snd-soc-tlv320aic3x-objs := tlv320aic3x.o 32snd-soc-tlv320aic3x-objs := tlv320aic3x.o
33snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
28snd-soc-tlv320dac33-objs := tlv320dac33.o 34snd-soc-tlv320dac33-objs := tlv320dac33.o
29snd-soc-twl4030-objs := twl4030.o 35snd-soc-twl4030-objs := twl4030.o
30snd-soc-twl6040-objs := twl6040.o 36snd-soc-twl6040-objs := twl6040.o
@@ -61,6 +67,7 @@ snd-soc-wm8978-objs := wm8978.o
61snd-soc-wm8985-objs := wm8985.o 67snd-soc-wm8985-objs := wm8985.o
62snd-soc-wm8988-objs := wm8988.o 68snd-soc-wm8988-objs := wm8988.o
63snd-soc-wm8990-objs := wm8990.o 69snd-soc-wm8990-objs := wm8990.o
70snd-soc-wm8991-objs := wm8991.o
64snd-soc-wm8993-objs := wm8993.o 71snd-soc-wm8993-objs := wm8993.o
65snd-soc-wm8994-objs := wm8994.o wm8994-tables.o 72snd-soc-wm8994-objs := wm8994.o wm8994-tables.o
66snd-soc-wm8995-objs := wm8995.o 73snd-soc-wm8995-objs := wm8995.o
@@ -72,6 +79,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
72snd-soc-jz4740-codec-objs := jz4740.o 79snd-soc-jz4740-codec-objs := jz4740.o
73 80
74# Amp 81# Amp
82snd-soc-lm4857-objs := lm4857.o
75snd-soc-max9877-objs := max9877.o 83snd-soc-max9877-objs := max9877.o
76snd-soc-tpa6130a2-objs := tpa6130a2.o 84snd-soc-tpa6130a2-objs := tpa6130a2.o
77snd-soc-wm2000-objs := wm2000.o 85snd-soc-wm2000-objs := wm2000.o
@@ -88,23 +96,29 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
88obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 96obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
89obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 97obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
90obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 98obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
99obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
91obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 100obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
92obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 101obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
93obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 102obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
103obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
94obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 104obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
95obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 105obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
106obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
96obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 107obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
97obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
98obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
99obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
100obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
101obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
114obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
102obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 115obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
103obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 116obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
104obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 117obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
105obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 118obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
106obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 119obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
107obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 120obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
121obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o
108obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 122obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
109obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 123obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
110obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 124obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
@@ -141,6 +155,7 @@ obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
141obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o 155obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
142obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 156obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
143obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 157obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
158obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
144obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 159obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
145obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 160obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
146obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o 161obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
@@ -151,6 +166,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
151obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 166obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
152 167
153# Amp 168# Amp
169obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
154obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 170obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
155obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 171obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
156obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 172obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index c27f8f59dc66..cbf0b6d400b8 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -294,7 +294,6 @@ static struct spi_driver ak4104_spi_driver = {
294 294
295static int __init ak4104_init(void) 295static int __init ak4104_init(void)
296{ 296{
297 pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n");
298 return spi_register_driver(&ak4104_spi_driver); 297 return spi_register_driver(&ak4104_spi_driver);
299} 298}
300module_init(ak4104_init); 299module_init(ak4104_init);
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index f00eba313dfd..4be0570e3f1f 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -116,6 +116,12 @@
116#define BCKO_MASK (1 << 3) 116#define BCKO_MASK (1 << 3)
117#define BCKO_64 BCKO_MASK 117#define BCKO_64 BCKO_MASK
118 118
119#define DIF_MASK (3 << 0)
120#define DSP (0 << 0)
121#define RIGHT_J (1 << 0)
122#define LEFT_J (2 << 0)
123#define I2S (3 << 0)
124
119/* MD_CTL2 */ 125/* MD_CTL2 */
120#define FS0 (1 << 0) 126#define FS0 (1 << 0)
121#define FS1 (1 << 1) 127#define FS1 (1 << 1)
@@ -354,6 +360,24 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
354 snd_soc_update_bits(codec, PW_MGMT2, MS, data); 360 snd_soc_update_bits(codec, PW_MGMT2, MS, data);
355 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); 361 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
356 362
363 /* format type */
364 data = 0;
365 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
366 case SND_SOC_DAIFMT_LEFT_J:
367 data = LEFT_J;
368 break;
369 case SND_SOC_DAIFMT_I2S:
370 data = I2S;
371 break;
372 /* FIXME
373 * Please add RIGHT_J / DSP support here
374 */
375 default:
376 return -EINVAL;
377 break;
378 }
379 snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
380
357 return 0; 381 return 0;
358} 382}
359 383
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 8b51245f2318..0206a17d7283 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -193,12 +193,12 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
193/* The number of MCLK/LRCK ratios supported by the CS4270 */ 193/* The number of MCLK/LRCK ratios supported by the CS4270 */
194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) 194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
195 195
196static int cs4270_reg_is_readable(unsigned int reg) 196static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
197{ 197{
198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); 198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
199} 199}
200 200
201static int cs4270_reg_is_volatile(unsigned int reg) 201static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
202{ 202{
203 /* Unreadable registers are considered volatile */ 203 /* Unreadable registers are considered volatile */
204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) 204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
@@ -719,7 +719,7 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client)
719/* 719/*
720 * cs4270_id - I2C device IDs supported by this driver 720 * cs4270_id - I2C device IDs supported by this driver
721 */ 721 */
722static struct i2c_device_id cs4270_id[] = { 722static const struct i2c_device_id cs4270_id[] = {
723 {"cs4270", 0}, 723 {"cs4270", 0},
724 {} 724 {}
725}; 725};
@@ -743,8 +743,6 @@ static struct i2c_driver cs4270_i2c_driver = {
743 743
744static int __init cs4270_init(void) 744static int __init cs4270_init(void)
745{ 745{
746 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
747
748 return i2c_add_driver(&cs4270_i2c_driver); 746 return i2c_add_driver(&cs4270_i2c_driver);
749} 747}
750module_init(cs4270_init); 748module_init(cs4270_init);
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
new file mode 100644
index 000000000000..083aab96ca80
--- /dev/null
+++ b/sound/soc/codecs/cs4271.c
@@ -0,0 +1,667 @@
1/*
2 * CS4271 ASoC codec driver
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/delay.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/tlv.h>
28#include <linux/gpio.h>
29#include <linux/i2c.h>
30#include <linux/spi/spi.h>
31#include <sound/cs4271.h>
32
33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \
35 SNDRV_PCM_FMTBIT_S32_LE)
36#define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
37
38/*
39 * CS4271 registers
40 * High byte represents SPI chip address (0x10) + write command (0)
41 * Low byte - codec register address
42 */
43#define CS4271_MODE1 0x2001 /* Mode Control 1 */
44#define CS4271_DACCTL 0x2002 /* DAC Control */
45#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */
46#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */
47#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */
48#define CS4271_ADCCTL 0x2006 /* ADC Control */
49#define CS4271_MODE2 0x2007 /* Mode Control 2 */
50#define CS4271_CHIPID 0x2008 /* Chip ID */
51
52#define CS4271_FIRSTREG CS4271_MODE1
53#define CS4271_LASTREG CS4271_MODE2
54#define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
55
56/* Bit masks for the CS4271 registers */
57#define CS4271_MODE1_MODE_MASK 0xC0
58#define CS4271_MODE1_MODE_1X 0x00
59#define CS4271_MODE1_MODE_2X 0x80
60#define CS4271_MODE1_MODE_4X 0xC0
61
62#define CS4271_MODE1_DIV_MASK 0x30
63#define CS4271_MODE1_DIV_1 0x00
64#define CS4271_MODE1_DIV_15 0x10
65#define CS4271_MODE1_DIV_2 0x20
66#define CS4271_MODE1_DIV_3 0x30
67
68#define CS4271_MODE1_MASTER 0x08
69
70#define CS4271_MODE1_DAC_DIF_MASK 0x07
71#define CS4271_MODE1_DAC_DIF_LJ 0x00
72#define CS4271_MODE1_DAC_DIF_I2S 0x01
73#define CS4271_MODE1_DAC_DIF_RJ16 0x02
74#define CS4271_MODE1_DAC_DIF_RJ24 0x03
75#define CS4271_MODE1_DAC_DIF_RJ20 0x04
76#define CS4271_MODE1_DAC_DIF_RJ18 0x05
77
78#define CS4271_DACCTL_AMUTE 0x80
79#define CS4271_DACCTL_IF_SLOW 0x40
80
81#define CS4271_DACCTL_DEM_MASK 0x30
82#define CS4271_DACCTL_DEM_DIS 0x00
83#define CS4271_DACCTL_DEM_441 0x10
84#define CS4271_DACCTL_DEM_48 0x20
85#define CS4271_DACCTL_DEM_32 0x30
86
87#define CS4271_DACCTL_SVRU 0x08
88#define CS4271_DACCTL_SRD 0x04
89#define CS4271_DACCTL_INVA 0x02
90#define CS4271_DACCTL_INVB 0x01
91
92#define CS4271_DACVOL_BEQUA 0x40
93#define CS4271_DACVOL_SOFT 0x20
94#define CS4271_DACVOL_ZEROC 0x10
95
96#define CS4271_DACVOL_ATAPI_MASK 0x0F
97#define CS4271_DACVOL_ATAPI_M_M 0x00
98#define CS4271_DACVOL_ATAPI_M_BR 0x01
99#define CS4271_DACVOL_ATAPI_M_BL 0x02
100#define CS4271_DACVOL_ATAPI_M_BLR2 0x03
101#define CS4271_DACVOL_ATAPI_AR_M 0x04
102#define CS4271_DACVOL_ATAPI_AR_BR 0x05
103#define CS4271_DACVOL_ATAPI_AR_BL 0x06
104#define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
105#define CS4271_DACVOL_ATAPI_AL_M 0x08
106#define CS4271_DACVOL_ATAPI_AL_BR 0x09
107#define CS4271_DACVOL_ATAPI_AL_BL 0x0A
108#define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
109#define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
110#define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
111#define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
112#define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
113
114#define CS4271_VOLA_MUTE 0x80
115#define CS4271_VOLA_VOL_MASK 0x7F
116#define CS4271_VOLB_MUTE 0x80
117#define CS4271_VOLB_VOL_MASK 0x7F
118
119#define CS4271_ADCCTL_DITHER16 0x20
120
121#define CS4271_ADCCTL_ADC_DIF_MASK 0x10
122#define CS4271_ADCCTL_ADC_DIF_LJ 0x00
123#define CS4271_ADCCTL_ADC_DIF_I2S 0x10
124
125#define CS4271_ADCCTL_MUTEA 0x08
126#define CS4271_ADCCTL_MUTEB 0x04
127#define CS4271_ADCCTL_HPFDA 0x02
128#define CS4271_ADCCTL_HPFDB 0x01
129
130#define CS4271_MODE2_LOOP 0x10
131#define CS4271_MODE2_MUTECAEQUB 0x08
132#define CS4271_MODE2_FREEZE 0x04
133#define CS4271_MODE2_CPEN 0x02
134#define CS4271_MODE2_PDN 0x01
135
136#define CS4271_CHIPID_PART_MASK 0xF0
137#define CS4271_CHIPID_REV_MASK 0x0F
138
139/*
140 * Default CS4271 power-up configuration
141 * Array contains non-existing in hw register at address 0
142 * Array do not include Chip ID, as codec driver does not use
143 * registers read operations at all
144 */
145static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
146 0,
147 0,
148 CS4271_DACCTL_AMUTE,
149 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR,
150 0,
151 0,
152 0,
153 0,
154};
155
156struct cs4271_private {
157 /* SND_SOC_I2C or SND_SOC_SPI */
158 enum snd_soc_control_type bus_type;
159 void *control_data;
160 unsigned int mclk;
161 bool master;
162 bool deemph;
163 /* Current sample rate for de-emphasis control */
164 int rate;
165 /* GPIO driving Reset pin, if any */
166 int gpio_nreset;
167 /* GPIO that disable serial bus, if any */
168 int gpio_disable;
169};
170
171/*
172 * @freq is the desired MCLK rate
173 * MCLK rate should (c) be the sample rate, multiplied by one of the
174 * ratios listed in cs4271_mclk_fs_ratios table
175 */
176static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
177 int clk_id, unsigned int freq, int dir)
178{
179 struct snd_soc_codec *codec = codec_dai->codec;
180 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
181
182 cs4271->mclk = freq;
183 return 0;
184}
185
186static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 unsigned int format)
188{
189 struct snd_soc_codec *codec = codec_dai->codec;
190 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
191 unsigned int val = 0;
192 int ret;
193
194 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
195 case SND_SOC_DAIFMT_CBS_CFS:
196 cs4271->master = 0;
197 break;
198 case SND_SOC_DAIFMT_CBM_CFM:
199 cs4271->master = 1;
200 val |= CS4271_MODE1_MASTER;
201 break;
202 default:
203 dev_err(codec->dev, "Invalid DAI format\n");
204 return -EINVAL;
205 }
206
207 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
208 case SND_SOC_DAIFMT_LEFT_J:
209 val |= CS4271_MODE1_DAC_DIF_LJ;
210 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
211 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
212 if (ret < 0)
213 return ret;
214 break;
215 case SND_SOC_DAIFMT_I2S:
216 val |= CS4271_MODE1_DAC_DIF_I2S;
217 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
218 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
219 if (ret < 0)
220 return ret;
221 break;
222 default:
223 dev_err(codec->dev, "Invalid DAI format\n");
224 return -EINVAL;
225 }
226
227 ret = snd_soc_update_bits(codec, CS4271_MODE1,
228 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
229 if (ret < 0)
230 return ret;
231 return 0;
232}
233
234static int cs4271_deemph[] = {0, 44100, 48000, 32000};
235
236static int cs4271_set_deemph(struct snd_soc_codec *codec)
237{
238 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
239 int i, ret;
240 int val = CS4271_DACCTL_DEM_DIS;
241
242 if (cs4271->deemph) {
243 /* Find closest de-emphasis freq */
244 val = 1;
245 for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
246 if (abs(cs4271_deemph[i] - cs4271->rate) <
247 abs(cs4271_deemph[val] - cs4271->rate))
248 val = i;
249 val <<= 4;
250 }
251
252 ret = snd_soc_update_bits(codec, CS4271_DACCTL,
253 CS4271_DACCTL_DEM_MASK, val);
254 if (ret < 0)
255 return ret;
256 return 0;
257}
258
259static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
260 struct snd_ctl_elem_value *ucontrol)
261{
262 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
263 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
264
265 ucontrol->value.enumerated.item[0] = cs4271->deemph;
266 return 0;
267}
268
269static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
270 struct snd_ctl_elem_value *ucontrol)
271{
272 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
273 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
274
275 cs4271->deemph = ucontrol->value.enumerated.item[0];
276 return cs4271_set_deemph(codec);
277}
278
279struct cs4271_clk_cfg {
280 bool master; /* codec mode */
281 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
282 unsigned short ratio; /* MCLK / sample rate */
283 u8 ratio_mask; /* ratio bit mask for Master mode */
284};
285
286static struct cs4271_clk_cfg cs4271_clk_tab[] = {
287 {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
288 {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
289 {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
290 {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
291 {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
292 {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
293 {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
294 {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
295 {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
296 {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
297 {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
298 {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
299 {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
300 {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
301 {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
302 {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
303 {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
304 {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
305 {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
306 {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
307 {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
308 {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
309 {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
310 {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
311 {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
312 {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
313 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
314};
315
316#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
317
318static int cs4271_hw_params(struct snd_pcm_substream *substream,
319 struct snd_pcm_hw_params *params,
320 struct snd_soc_dai *dai)
321{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_codec *codec = rtd->codec;
324 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
325 int i, ret;
326 unsigned int ratio, val;
327
328 cs4271->rate = params_rate(params);
329
330 /* Configure DAC */
331 if (cs4271->rate < 50000)
332 val = CS4271_MODE1_MODE_1X;
333 else if (cs4271->rate < 100000)
334 val = CS4271_MODE1_MODE_2X;
335 else
336 val = CS4271_MODE1_MODE_4X;
337
338 ratio = cs4271->mclk / cs4271->rate;
339 for (i = 0; i < CS4171_NR_RATIOS; i++)
340 if ((cs4271_clk_tab[i].master == cs4271->master) &&
341 (cs4271_clk_tab[i].speed_mode == val) &&
342 (cs4271_clk_tab[i].ratio == ratio))
343 break;
344
345 if (i == CS4171_NR_RATIOS) {
346 dev_err(codec->dev, "Invalid sample rate\n");
347 return -EINVAL;
348 }
349
350 val |= cs4271_clk_tab[i].ratio_mask;
351
352 ret = snd_soc_update_bits(codec, CS4271_MODE1,
353 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
354 if (ret < 0)
355 return ret;
356
357 return cs4271_set_deemph(codec);
358}
359
360static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 int ret;
364 int val_a = 0;
365 int val_b = 0;
366
367 if (mute) {
368 val_a = CS4271_VOLA_MUTE;
369 val_b = CS4271_VOLB_MUTE;
370 }
371
372 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a);
373 if (ret < 0)
374 return ret;
375 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b);
376 if (ret < 0)
377 return ret;
378
379 return 0;
380}
381
382/* CS4271 controls */
383static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
384
385static const struct snd_kcontrol_new cs4271_snd_controls[] = {
386 SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
387 0, 0x7F, 1, cs4271_dac_tlv),
388 SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
389 SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
390 SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
391 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
392 cs4271_get_deemph, cs4271_put_deemph),
393 SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
394 SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
395 SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
396 SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
397 SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
398 SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
399 SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
400 SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
401 SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
402 SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
403 7, 1, 1),
404};
405
406static struct snd_soc_dai_ops cs4271_dai_ops = {
407 .hw_params = cs4271_hw_params,
408 .set_sysclk = cs4271_set_dai_sysclk,
409 .set_fmt = cs4271_set_dai_fmt,
410 .digital_mute = cs4271_digital_mute,
411};
412
413static struct snd_soc_dai_driver cs4271_dai = {
414 .name = "cs4271-hifi",
415 .playback = {
416 .stream_name = "Playback",
417 .channels_min = 2,
418 .channels_max = 2,
419 .rates = CS4271_PCM_RATES,
420 .formats = CS4271_PCM_FORMATS,
421 },
422 .capture = {
423 .stream_name = "Capture",
424 .channels_min = 2,
425 .channels_max = 2,
426 .rates = CS4271_PCM_RATES,
427 .formats = CS4271_PCM_FORMATS,
428 },
429 .ops = &cs4271_dai_ops,
430 .symmetric_rates = 1,
431};
432
433#ifdef CONFIG_PM
434static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
435{
436 int ret;
437 /* Set power-down bit */
438 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
439 if (ret < 0)
440 return ret;
441 return 0;
442}
443
444static int cs4271_soc_resume(struct snd_soc_codec *codec)
445{
446 int ret;
447 /* Restore codec state */
448 ret = snd_soc_cache_sync(codec);
449 if (ret < 0)
450 return ret;
451 /* then disable the power-down bit */
452 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
453 if (ret < 0)
454 return ret;
455 return 0;
456}
457#else
458#define cs4271_soc_suspend NULL
459#define cs4271_soc_resume NULL
460#endif /* CONFIG_PM */
461
462static int cs4271_probe(struct snd_soc_codec *codec)
463{
464 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
465 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
466 int ret;
467 int gpio_nreset = -EINVAL;
468
469 codec->control_data = cs4271->control_data;
470
471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
472 gpio_nreset = cs4271plat->gpio_nreset;
473
474 if (gpio_nreset >= 0)
475 if (gpio_request(gpio_nreset, "CS4271 Reset"))
476 gpio_nreset = -EINVAL;
477 if (gpio_nreset >= 0) {
478 /* Reset codec */
479 gpio_direction_output(gpio_nreset, 0);
480 udelay(1);
481 gpio_set_value(gpio_nreset, 1);
482 /* Give the codec time to wake up */
483 udelay(1);
484 }
485
486 cs4271->gpio_nreset = gpio_nreset;
487
488 /*
489 * In case of I2C, chip address specified in board data.
490 * So cache IO operations use 8 bit codec register address.
491 * In case of SPI, chip address and register address
492 * passed together as 16 bit value.
493 * Anyway, register address is masked with 0xFF inside
494 * soc-cache code.
495 */
496 if (cs4271->bus_type == SND_SOC_SPI)
497 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
498 cs4271->bus_type);
499 else
500 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
501 cs4271->bus_type);
502 if (ret) {
503 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
504 return ret;
505 }
506
507 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
508 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
509 if (ret < 0)
510 return ret;
511 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
512 if (ret < 0)
513 return ret;
514 /* Power-up sequence requires 85 uS */
515 udelay(85);
516
517 return snd_soc_add_controls(codec, cs4271_snd_controls,
518 ARRAY_SIZE(cs4271_snd_controls));
519}
520
521static int cs4271_remove(struct snd_soc_codec *codec)
522{
523 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
524 int gpio_nreset;
525
526 gpio_nreset = cs4271->gpio_nreset;
527
528 if (gpio_is_valid(gpio_nreset)) {
529 /* Set codec to the reset state */
530 gpio_set_value(gpio_nreset, 0);
531 gpio_free(gpio_nreset);
532 }
533
534 return 0;
535};
536
537static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
538 .probe = cs4271_probe,
539 .remove = cs4271_remove,
540 .suspend = cs4271_soc_suspend,
541 .resume = cs4271_soc_resume,
542 .reg_cache_default = cs4271_dflt_reg,
543 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
544 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
545 .compress_type = SND_SOC_FLAT_COMPRESSION,
546};
547
548#if defined(CONFIG_SPI_MASTER)
549static int __devinit cs4271_spi_probe(struct spi_device *spi)
550{
551 struct cs4271_private *cs4271;
552
553 cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
554 if (!cs4271)
555 return -ENOMEM;
556
557 spi_set_drvdata(spi, cs4271);
558 cs4271->control_data = spi;
559 cs4271->bus_type = SND_SOC_SPI;
560
561 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
562 &cs4271_dai, 1);
563}
564
565static int __devexit cs4271_spi_remove(struct spi_device *spi)
566{
567 snd_soc_unregister_codec(&spi->dev);
568 return 0;
569}
570
571static struct spi_driver cs4271_spi_driver = {
572 .driver = {
573 .name = "cs4271",
574 .owner = THIS_MODULE,
575 },
576 .probe = cs4271_spi_probe,
577 .remove = __devexit_p(cs4271_spi_remove),
578};
579#endif /* defined(CONFIG_SPI_MASTER) */
580
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582static const struct i2c_device_id cs4271_i2c_id[] = {
583 {"cs4271", 0},
584 {}
585};
586MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
587
588static int __devinit cs4271_i2c_probe(struct i2c_client *client,
589 const struct i2c_device_id *id)
590{
591 struct cs4271_private *cs4271;
592
593 cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
594 if (!cs4271)
595 return -ENOMEM;
596
597 i2c_set_clientdata(client, cs4271);
598 cs4271->control_data = client;
599 cs4271->bus_type = SND_SOC_I2C;
600
601 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
602 &cs4271_dai, 1);
603}
604
605static int __devexit cs4271_i2c_remove(struct i2c_client *client)
606{
607 snd_soc_unregister_codec(&client->dev);
608 return 0;
609}
610
611static struct i2c_driver cs4271_i2c_driver = {
612 .driver = {
613 .name = "cs4271",
614 .owner = THIS_MODULE,
615 },
616 .id_table = cs4271_i2c_id,
617 .probe = cs4271_i2c_probe,
618 .remove = __devexit_p(cs4271_i2c_remove),
619};
620#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
621
622/*
623 * We only register our serial bus driver here without
624 * assignment to particular chip. So if any of the below
625 * fails, there is some problem with I2C or SPI subsystem.
626 * In most cases this module will be compiled with support
627 * of only one serial bus.
628 */
629static int __init cs4271_modinit(void)
630{
631 int ret;
632
633#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
634 ret = i2c_add_driver(&cs4271_i2c_driver);
635 if (ret) {
636 pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
637 return ret;
638 }
639#endif
640
641#if defined(CONFIG_SPI_MASTER)
642 ret = spi_register_driver(&cs4271_spi_driver);
643 if (ret) {
644 pr_err("Failed to register CS4271 SPI driver: %d\n", ret);
645 return ret;
646 }
647#endif
648
649 return 0;
650}
651module_init(cs4271_modinit);
652
653static void __exit cs4271_modexit(void)
654{
655#if defined(CONFIG_SPI_MASTER)
656 spi_unregister_driver(&cs4271_spi_driver);
657#endif
658
659#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
660 i2c_del_driver(&cs4271_i2c_driver);
661#endif
662}
663module_exit(cs4271_modexit);
664
665MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
666MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
667MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
new file mode 100644
index 000000000000..704bbde65737
--- /dev/null
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -0,0 +1,72 @@
1/*
2 * Driver for the DFBM-CS320 bluetooth module
3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <sound/soc.h>
17
18static struct snd_soc_dai_driver dfbmcs320_dai = {
19 .name = "dfbmcs320-pcm",
20 .playback = {
21 .channels_min = 1,
22 .channels_max = 1,
23 .rates = SNDRV_PCM_RATE_8000,
24 .formats = SNDRV_PCM_FMTBIT_S16_LE,
25 },
26 .capture = {
27 .channels_min = 1,
28 .channels_max = 1,
29 .rates = SNDRV_PCM_RATE_8000,
30 .formats = SNDRV_PCM_FMTBIT_S16_LE,
31 },
32};
33
34static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
35
36static int __devinit dfbmcs320_probe(struct platform_device *pdev)
37{
38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
39 &dfbmcs320_dai, 1);
40}
41
42static int __devexit dfbmcs320_remove(struct platform_device *pdev)
43{
44 snd_soc_unregister_codec(&pdev->dev);
45
46 return 0;
47}
48
49static struct platform_driver dfmcs320_driver = {
50 .driver = {
51 .name = "dfbmcs320",
52 .owner = THIS_MODULE,
53 },
54 .probe = dfbmcs320_probe,
55 .remove = __devexit_p(dfbmcs320_remove),
56};
57
58static int __init dfbmcs320_init(void)
59{
60 return platform_driver_register(&dfmcs320_driver);
61}
62module_init(dfbmcs320_init);
63
64static void __exit dfbmcs320_exit(void)
65{
66 platform_driver_unregister(&dfmcs320_driver);
67}
68module_exit(dfbmcs320_exit);
69
70MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
71MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
72MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
new file mode 100644
index 000000000000..72de47e5d040
--- /dev/null
+++ b/sound/soc/codecs/lm4857.c
@@ -0,0 +1,276 @@
1/*
2 * LM4857 AMP driver
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/tlv.h>
24
25struct lm4857 {
26 struct i2c_client *i2c;
27 uint8_t mode;
28};
29
30static const uint8_t lm4857_default_regs[] = {
31 0x00, 0x00, 0x00, 0x00,
32};
33
34/* The register offsets in the cache array */
35#define LM4857_MVOL 0
36#define LM4857_LVOL 1
37#define LM4857_RVOL 2
38#define LM4857_CTRL 3
39
40/* the shifts required to set these bits */
41#define LM4857_3D 5
42#define LM4857_WAKEUP 5
43#define LM4857_EPGAIN 4
44
45static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value)
47{
48 uint8_t data;
49 int ret;
50
51 ret = snd_soc_cache_write(codec, reg, value);
52 if (ret < 0)
53 return ret;
54
55 data = (reg << 6) | value;
56 ret = i2c_master_send(codec->control_data, &data, 1);
57 if (ret != 1) {
58 dev_err(codec->dev, "Failed to write register: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65static unsigned int lm4857_read(struct snd_soc_codec *codec,
66 unsigned int reg)
67{
68 unsigned int val;
69 int ret;
70
71 ret = snd_soc_cache_read(codec, reg, &val);
72 if (ret)
73 return -1;
74
75 return val;
76}
77
78static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol)
80{
81 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
82 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
83
84 ucontrol->value.integer.value[0] = lm4857->mode;
85
86 return 0;
87}
88
89static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
94 uint8_t value = ucontrol->value.integer.value[0];
95
96 lm4857->mode = value;
97
98 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
99 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6);
100
101 return 1;
102}
103
104static int lm4857_set_bias_level(struct snd_soc_codec *codec,
105 enum snd_soc_bias_level level)
106{
107 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
108
109 switch (level) {
110 case SND_SOC_BIAS_ON:
111 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6);
112 break;
113 case SND_SOC_BIAS_STANDBY:
114 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0);
115 break;
116 default:
117 break;
118 }
119
120 codec->dapm.bias_level = level;
121
122 return 0;
123}
124
125static const char *lm4857_mode[] = {
126 "Earpiece",
127 "Loudspeaker",
128 "Loudspeaker + Headphone",
129 "Headphone",
130};
131
132static const struct soc_enum lm4857_mode_enum =
133 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
134
135static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
136 SND_SOC_DAPM_INPUT("IN"),
137
138 SND_SOC_DAPM_OUTPUT("LS"),
139 SND_SOC_DAPM_OUTPUT("HP"),
140 SND_SOC_DAPM_OUTPUT("EP"),
141};
142
143static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
144static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
145
146static const struct snd_kcontrol_new lm4857_controls[] = {
147 SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0,
148 stereo_tlv),
149 SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0,
150 stereo_tlv),
151 SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
152 mono_tlv),
153 SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0),
154 SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0),
155 SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL,
156 LM4857_WAKEUP, 1, 0),
157 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
158 LM4857_EPGAIN, 1, 0),
159
160 SOC_ENUM_EXT("Mode", lm4857_mode_enum,
161 lm4857_get_mode, lm4857_set_mode),
162};
163
164/* There is a demux inbetween the the input signal and the output signals.
165 * Currently there is no easy way to model it in ASoC and since it does not make
166 * much of a difference in practice simply connect the input direclty to the
167 * outputs. */
168static const struct snd_soc_dapm_route lm4857_routes[] = {
169 {"LS", NULL, "IN"},
170 {"HP", NULL, "IN"},
171 {"EP", NULL, "IN"},
172};
173
174static int lm4857_probe(struct snd_soc_codec *codec)
175{
176 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
177 struct snd_soc_dapm_context *dapm = &codec->dapm;
178 int ret;
179
180 codec->control_data = lm4857->i2c;
181
182 ret = snd_soc_add_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls));
184 if (ret)
185 return ret;
186
187 ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
188 ARRAY_SIZE(lm4857_dapm_widgets));
189 if (ret)
190 return ret;
191
192 ret = snd_soc_dapm_add_routes(dapm, lm4857_routes,
193 ARRAY_SIZE(lm4857_routes));
194 if (ret)
195 return ret;
196
197 snd_soc_dapm_new_widgets(dapm);
198
199 return 0;
200}
201
202static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
203 .write = lm4857_write,
204 .read = lm4857_read,
205 .probe = lm4857_probe,
206 .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
207 .reg_word_size = sizeof(uint8_t),
208 .reg_cache_default = lm4857_default_regs,
209 .set_bias_level = lm4857_set_bias_level,
210};
211
212static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
213 const struct i2c_device_id *id)
214{
215 struct lm4857 *lm4857;
216 int ret;
217
218 lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL);
219 if (!lm4857)
220 return -ENOMEM;
221
222 i2c_set_clientdata(i2c, lm4857);
223
224 lm4857->i2c = i2c;
225
226 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
227
228 if (ret) {
229 kfree(lm4857);
230 return ret;
231 }
232
233 return 0;
234}
235
236static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
237{
238 struct lm4857 *lm4857 = i2c_get_clientdata(i2c);
239
240 snd_soc_unregister_codec(&i2c->dev);
241 kfree(lm4857);
242
243 return 0;
244}
245
246static const struct i2c_device_id lm4857_i2c_id[] = {
247 { "lm4857", 0 },
248 { }
249};
250MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id);
251
252static struct i2c_driver lm4857_i2c_driver = {
253 .driver = {
254 .name = "lm4857",
255 .owner = THIS_MODULE,
256 },
257 .probe = lm4857_i2c_probe,
258 .remove = __devexit_p(lm4857_i2c_remove),
259 .id_table = lm4857_i2c_id,
260};
261
262static int __init lm4857_init(void)
263{
264 return i2c_add_driver(&lm4857_i2c_driver);
265}
266module_init(lm4857_init);
267
268static void __exit lm4857_exit(void)
269{
270 i2c_del_driver(&lm4857_i2c_driver);
271}
272module_exit(lm4857_exit);
273
274MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
275MODULE_DESCRIPTION("LM4857 amplifier driver");
276MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 89498f9ad2e5..bd0517cb7980 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -608,7 +608,7 @@ static struct {
608 { 0xFF, 0x00, 1 }, /* FF */ 608 { 0xFF, 0x00, 1 }, /* FF */
609}; 609};
610 610
611static int max98088_volatile_register(unsigned int reg) 611static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
612{ 612{
613 return max98088_access[reg].vol; 613 return max98088_access[reg].vol;
614} 614}
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
new file mode 100644
index 000000000000..208d2ee61855
--- /dev/null
+++ b/sound/soc/codecs/max9850.c
@@ -0,0 +1,389 @@
1/*
2 * max9850.c -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 *
6 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
7 *
8 * Initial development of this code was funded by
9 * MICRONIC Computer Systeme GmbH, http://www.mcsberlin.de/
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/tlv.h>
26
27#include "max9850.h"
28
29struct max9850_priv {
30 unsigned int sysclk;
31};
32
33/* max9850 register cache */
34static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
35 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36};
37
38/* these registers are not used at the moment but provided for the sake of
39 * completeness */
40static int max9850_volatile_register(struct snd_soc_codec *codec,
41 unsigned int reg)
42{
43 switch (reg) {
44 case MAX9850_STATUSA:
45 case MAX9850_STATUSB:
46 return 1;
47 default:
48 return 0;
49 }
50}
51
52static const unsigned int max9850_tlv[] = {
53 TLV_DB_RANGE_HEAD(4),
54 0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
55 0x20, 0x33, TLV_DB_SCALE_ITEM(-4150, 200, 0),
56 0x34, 0x37, TLV_DB_SCALE_ITEM(-150, 100, 0),
57 0x38, 0x3f, TLV_DB_SCALE_ITEM(250, 50, 0),
58};
59
60static const struct snd_kcontrol_new max9850_controls[] = {
61SOC_SINGLE_TLV("Headphone Volume", MAX9850_VOLUME, 0, 0x3f, 1, max9850_tlv),
62SOC_SINGLE("Headphone Switch", MAX9850_VOLUME, 7, 1, 1),
63SOC_SINGLE("Mono Switch", MAX9850_GENERAL_PURPOSE, 2, 1, 0),
64};
65
66static const struct snd_kcontrol_new max9850_mixer_controls[] = {
67 SOC_DAPM_SINGLE("Line In Switch", MAX9850_ENABLE, 1, 1, 0),
68};
69
70static const struct snd_soc_dapm_widget max9850_dapm_widgets[] = {
71SND_SOC_DAPM_SUPPLY("Charge Pump 1", MAX9850_ENABLE, 4, 0, NULL, 0),
72SND_SOC_DAPM_SUPPLY("Charge Pump 2", MAX9850_ENABLE, 5, 0, NULL, 0),
73SND_SOC_DAPM_SUPPLY("MCLK", MAX9850_ENABLE, 6, 0, NULL, 0),
74SND_SOC_DAPM_SUPPLY("SHDN", MAX9850_ENABLE, 7, 0, NULL, 0),
75SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", MAX9850_ENABLE, 2, 0,
76 &max9850_mixer_controls[0],
77 ARRAY_SIZE(max9850_mixer_controls)),
78SND_SOC_DAPM_PGA("Headphone Output", MAX9850_ENABLE, 3, 0, NULL, 0),
79SND_SOC_DAPM_DAC("DAC", "HiFi Playback", MAX9850_ENABLE, 0, 0),
80SND_SOC_DAPM_OUTPUT("OUTL"),
81SND_SOC_DAPM_OUTPUT("HPL"),
82SND_SOC_DAPM_OUTPUT("OUTR"),
83SND_SOC_DAPM_OUTPUT("HPR"),
84SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
85SND_SOC_DAPM_INPUT("INL"),
86SND_SOC_DAPM_INPUT("INR"),
87};
88
89static const struct snd_soc_dapm_route intercon[] = {
90 /* output mixer */
91 {"Output Mixer", NULL, "DAC"},
92 {"Output Mixer", "Line In Switch", "Line Input"},
93
94 /* outputs */
95 {"Headphone Output", NULL, "Output Mixer"},
96 {"HPL", NULL, "Headphone Output"},
97 {"HPR", NULL, "Headphone Output"},
98 {"OUTL", NULL, "Output Mixer"},
99 {"OUTR", NULL, "Output Mixer"},
100
101 /* inputs */
102 {"Line Input", NULL, "INL"},
103 {"Line Input", NULL, "INR"},
104
105 /* supplies */
106 {"Output Mixer", NULL, "Charge Pump 1"},
107 {"Output Mixer", NULL, "Charge Pump 2"},
108 {"Output Mixer", NULL, "SHDN"},
109 {"DAC", NULL, "MCLK"},
110};
111
112static int max9850_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *params,
114 struct snd_soc_dai *dai)
115{
116 struct snd_soc_codec *codec = dai->codec;
117 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
118 u64 lrclk_div;
119 u8 sf, da;
120
121 if (!max9850->sysclk)
122 return -EINVAL;
123
124 /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
125 sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
126 lrclk_div = (1 << 22);
127 lrclk_div *= params_rate(params);
128 lrclk_div *= sf;
129 do_div(lrclk_div, max9850->sysclk);
130
131 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
132 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
133
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE:
136 da = 0;
137 break;
138 case SNDRV_PCM_FORMAT_S20_3LE:
139 da = 0x2;
140 break;
141 case SNDRV_PCM_FORMAT_S24_LE:
142 da = 0x3;
143 break;
144 default:
145 return -EINVAL;
146 }
147 snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
148
149 return 0;
150}
151
152static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
153 int clk_id, unsigned int freq, int dir)
154{
155 struct snd_soc_codec *codec = codec_dai->codec;
156 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
157
158 /* calculate mclk -> iclk divider */
159 if (freq <= 13000000)
160 snd_soc_write(codec, MAX9850_CLOCK, 0x0);
161 else if (freq <= 26000000)
162 snd_soc_write(codec, MAX9850_CLOCK, 0x4);
163 else if (freq <= 40000000)
164 snd_soc_write(codec, MAX9850_CLOCK, 0x8);
165 else
166 return -EINVAL;
167
168 max9850->sysclk = freq;
169 return 0;
170}
171
172static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
173{
174 struct snd_soc_codec *codec = codec_dai->codec;
175 u8 da = 0;
176
177 /* set master/slave audio interface */
178 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
179 case SND_SOC_DAIFMT_CBM_CFM:
180 da |= MAX9850_MASTER;
181 break;
182 case SND_SOC_DAIFMT_CBS_CFS:
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 /* interface format */
189 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
190 case SND_SOC_DAIFMT_I2S:
191 da |= MAX9850_DLY;
192 break;
193 case SND_SOC_DAIFMT_RIGHT_J:
194 da |= MAX9850_RTJ;
195 break;
196 case SND_SOC_DAIFMT_LEFT_J:
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 /* clock inversion */
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 break;
206 case SND_SOC_DAIFMT_IB_IF:
207 da |= MAX9850_BCINV | MAX9850_INV;
208 break;
209 case SND_SOC_DAIFMT_IB_NF:
210 da |= MAX9850_BCINV;
211 break;
212 case SND_SOC_DAIFMT_NB_IF:
213 da |= MAX9850_INV;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 /* set da */
220 snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
221
222 return 0;
223}
224
225static int max9850_set_bias_level(struct snd_soc_codec *codec,
226 enum snd_soc_bias_level level)
227{
228 int ret;
229
230 switch (level) {
231 case SND_SOC_BIAS_ON:
232 break;
233 case SND_SOC_BIAS_PREPARE:
234 break;
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
237 ret = snd_soc_cache_sync(codec);
238 if (ret) {
239 dev_err(codec->dev,
240 "Failed to sync cache: %d\n", ret);
241 return ret;
242 }
243 }
244 break;
245 case SND_SOC_BIAS_OFF:
246 break;
247 }
248 codec->dapm.bias_level = level;
249 return 0;
250}
251
252#define MAX9850_RATES SNDRV_PCM_RATE_8000_48000
253
254#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
255 SNDRV_PCM_FMTBIT_S24_LE)
256
257static struct snd_soc_dai_ops max9850_dai_ops = {
258 .hw_params = max9850_hw_params,
259 .set_sysclk = max9850_set_dai_sysclk,
260 .set_fmt = max9850_set_dai_fmt,
261};
262
263static struct snd_soc_dai_driver max9850_dai = {
264 .name = "max9850-hifi",
265 .playback = {
266 .stream_name = "Playback",
267 .channels_min = 1,
268 .channels_max = 2,
269 .rates = MAX9850_RATES,
270 .formats = MAX9850_FORMATS
271 },
272 .ops = &max9850_dai_ops,
273};
274
275#ifdef CONFIG_PM
276static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state)
277{
278 max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
279
280 return 0;
281}
282
283static int max9850_resume(struct snd_soc_codec *codec)
284{
285 max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
286
287 return 0;
288}
289#else
290#define max9850_suspend NULL
291#define max9850_resume NULL
292#endif
293
294static int max9850_probe(struct snd_soc_codec *codec)
295{
296 struct snd_soc_dapm_context *dapm = &codec->dapm;
297 int ret;
298
299 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
300 if (ret < 0) {
301 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
302 return ret;
303 }
304
305 /* enable zero-detect */
306 snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
307 /* enable slew-rate control */
308 snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
309 /* set slew-rate 125ms */
310 snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
311
312 snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets,
313 ARRAY_SIZE(max9850_dapm_widgets));
314 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
315
316 snd_soc_add_controls(codec, max9850_controls,
317 ARRAY_SIZE(max9850_controls));
318
319 return 0;
320}
321
322static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
323 .probe = max9850_probe,
324 .suspend = max9850_suspend,
325 .resume = max9850_resume,
326 .set_bias_level = max9850_set_bias_level,
327 .reg_cache_size = ARRAY_SIZE(max9850_reg),
328 .reg_word_size = sizeof(u8),
329 .reg_cache_default = max9850_reg,
330 .volatile_register = max9850_volatile_register,
331};
332
333static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
334 const struct i2c_device_id *id)
335{
336 struct max9850_priv *max9850;
337 int ret;
338
339 max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL);
340 if (max9850 == NULL)
341 return -ENOMEM;
342
343 i2c_set_clientdata(i2c, max9850);
344
345 ret = snd_soc_register_codec(&i2c->dev,
346 &soc_codec_dev_max9850, &max9850_dai, 1);
347 if (ret < 0)
348 kfree(max9850);
349 return ret;
350}
351
352static __devexit int max9850_i2c_remove(struct i2c_client *client)
353{
354 snd_soc_unregister_codec(&client->dev);
355 kfree(i2c_get_clientdata(client));
356 return 0;
357}
358
359static const struct i2c_device_id max9850_i2c_id[] = {
360 { "max9850", 0 },
361 { }
362};
363MODULE_DEVICE_TABLE(i2c, max9850_i2c_id);
364
365static struct i2c_driver max9850_i2c_driver = {
366 .driver = {
367 .name = "max9850",
368 .owner = THIS_MODULE,
369 },
370 .probe = max9850_i2c_probe,
371 .remove = __devexit_p(max9850_i2c_remove),
372 .id_table = max9850_i2c_id,
373};
374
375static int __init max9850_init(void)
376{
377 return i2c_add_driver(&max9850_i2c_driver);
378}
379module_init(max9850_init);
380
381static void __exit max9850_exit(void)
382{
383 i2c_del_driver(&max9850_i2c_driver);
384}
385module_exit(max9850_exit);
386
387MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
388MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
389MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9850.h b/sound/soc/codecs/max9850.h
new file mode 100644
index 000000000000..72b1ddb04b0d
--- /dev/null
+++ b/sound/soc/codecs/max9850.h
@@ -0,0 +1,38 @@
1/*
2 * max9850.h -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _MAX9850_H
15#define _MAX9850_H
16
17#define MAX9850_STATUSA 0x00
18#define MAX9850_STATUSB 0x01
19#define MAX9850_VOLUME 0x02
20#define MAX9850_GENERAL_PURPOSE 0x03
21#define MAX9850_INTERRUPT 0x04
22#define MAX9850_ENABLE 0x05
23#define MAX9850_CLOCK 0x06
24#define MAX9850_CHARGE_PUMP 0x07
25#define MAX9850_LRCLK_MSB 0x08
26#define MAX9850_LRCLK_LSB 0x09
27#define MAX9850_DIGITAL_AUDIO 0x0a
28
29#define MAX9850_CACHEREGNUM 11
30
31/* MAX9850_DIGITAL_AUDIO */
32#define MAX9850_MASTER (1<<7)
33#define MAX9850_INV (1<<6)
34#define MAX9850_BCINV (1<<5)
35#define MAX9850_DLY (1<<3)
36#define MAX9850_RTJ (1<<2)
37
38#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
new file mode 100644
index 000000000000..1f7217f703ee
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.c
@@ -0,0 +1,1513 @@
1/*
2 * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/clk.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h>
23#include <sound/core.h>
24#include <sound/tlv.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30
31#include "sgtl5000.h"
32
33#define SGTL5000_DAP_REG_OFFSET 0x0100
34#define SGTL5000_MAX_REG_OFFSET 0x013A
35
36/* default value of sgtl5000 registers except DAP */
37static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = {
38 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */
39 0x0000, /* 0x0002, CHIP_DIG_POWER. */
40 0x0008, /* 0x0004, CHIP_CKL_CTRL */
41 0x0010, /* 0x0006, CHIP_I2S_CTRL */
42 0x0000, /* 0x0008, reserved */
43 0x0008, /* 0x000A, CHIP_SSS_CTRL */
44 0x0000, /* 0x000C, reserved */
45 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */
46 0x3c3c, /* 0x0010, CHIP_DAC_VOL */
47 0x0000, /* 0x0012, reserved */
48 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */
49 0x0000, /* 0x0016, reserved */
50 0x0000, /* 0x0018, reserved */
51 0x0000, /* 0x001A, reserved */
52 0x0000, /* 0x001E, reserved */
53 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */
54 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */
55 0x0111, /* 0x0024, CHIP_ANN_CTRL */
56 0x0000, /* 0x0026, CHIP_LINREG_CTRL */
57 0x0000, /* 0x0028, CHIP_REF_CTRL */
58 0x0000, /* 0x002A, CHIP_MIC_CTRL */
59 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */
60 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */
61 0x7060, /* 0x0030, CHIP_ANA_POWER */
62 0x5000, /* 0x0032, CHIP_PLL_CTRL */
63 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */
64 0x0000, /* 0x0036, CHIP_ANA_STATUS */
65 0x0000, /* 0x0038, reserved */
66 0x0000, /* 0x003A, CHIP_ANA_TEST2 */
67 0x0000, /* 0x003C, CHIP_SHORT_CTRL */
68 0x0000, /* reserved */
69};
70
71/* default value of dap registers */
72static const u16 sgtl5000_dap_regs[] = {
73 0x0000, /* 0x0100, DAP_CONTROL */
74 0x0000, /* 0x0102, DAP_PEQ */
75 0x0040, /* 0x0104, DAP_BASS_ENHANCE */
76 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */
77 0x0000, /* 0x0108, DAP_AUDIO_EQ */
78 0x0040, /* 0x010A, DAP_SGTL_SURROUND */
79 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */
80 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */
81 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */
82 0x0000, /* 0x0112, reserved */
83 0x0000, /* 0x0114, reserved */
84 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */
85 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */
86 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */
87 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */
88 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */
89 0x8000, /* 0x0120, DAP_MAIN_CHAN */
90 0x0000, /* 0x0122, DAP_MIX_CHAN */
91 0x0510, /* 0x0124, DAP_AVC_CTRL */
92 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */
93 0x0028, /* 0x0128, DAP_AVC_ATTACK */
94 0x0050, /* 0x012A, DAP_AVC_DECAY */
95 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */
96 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */
97 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */
98 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */
99 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */
100 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */
101 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */
102 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */
103};
104
105/* regulator supplies for sgtl5000, VDDD is an optional external supply */
106enum sgtl5000_regulator_supplies {
107 VDDA,
108 VDDIO,
109 VDDD,
110 SGTL5000_SUPPLY_NUM
111};
112
113/* vddd is optional supply */
114static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
115 "VDDA",
116 "VDDIO",
117 "VDDD"
118};
119
120#define LDO_CONSUMER_NAME "VDDD_LDO"
121#define LDO_VOLTAGE 1200000
122
123static struct regulator_consumer_supply ldo_consumer[] = {
124 REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
125};
126
127static struct regulator_init_data ldo_init_data = {
128 .constraints = {
129 .min_uV = 850000,
130 .max_uV = 1600000,
131 .valid_modes_mask = REGULATOR_MODE_NORMAL,
132 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
133 },
134 .num_consumer_supplies = 1,
135 .consumer_supplies = &ldo_consumer[0],
136};
137
138/*
139 * sgtl5000 internal ldo regulator,
140 * enabled when VDDD not provided
141 */
142struct ldo_regulator {
143 struct regulator_desc desc;
144 struct regulator_dev *dev;
145 int voltage;
146 void *codec_data;
147 bool enabled;
148};
149
150/* sgtl5000 private structure in codec */
151struct sgtl5000_priv {
152 int sysclk; /* sysclk rate */
153 int master; /* i2s master or not */
154 int fmt; /* i2s data format */
155 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
156 struct ldo_regulator *ldo;
157};
158
159/*
160 * mic_bias power on/off share the same register bits with
161 * output impedance of mic bias, when power on mic bias, we
162 * need reclaim it to impedance value.
163 * 0x0 = Powered off
164 * 0x1 = 2Kohm
165 * 0x2 = 4Kohm
166 * 0x3 = 8Kohm
167 */
168static int mic_bias_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event)
170{
171 switch (event) {
172 case SND_SOC_DAPM_POST_PMU:
173 /* change mic bias resistor to 4Kohm */
174 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
175 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k);
176 break;
177
178 case SND_SOC_DAPM_PRE_PMD:
179 /*
180 * SGTL5000_BIAS_R_8k as mask to clean the two bits
181 * of mic bias and output impedance
182 */
183 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
184 SGTL5000_BIAS_R_8k, 0);
185 break;
186 }
187 return 0;
188}
189
190/*
191 * using codec assist to small pop, hp_powerup or lineout_powerup
192 * should stay setting until vag_powerup is fully ramped down,
193 * vag fully ramped down require 400ms.
194 */
195static int small_pop_event(struct snd_soc_dapm_widget *w,
196 struct snd_kcontrol *kcontrol, int event)
197{
198 switch (event) {
199 case SND_SOC_DAPM_PRE_PMU:
200 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
201 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
202 break;
203
204 case SND_SOC_DAPM_PRE_PMD:
205 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
206 SGTL5000_VAG_POWERUP, 0);
207 msleep(400);
208 break;
209 default:
210 break;
211 }
212
213 return 0;
214}
215
216/* input sources for ADC */
217static const char *adc_mux_text[] = {
218 "MIC_IN", "LINE_IN"
219};
220
221static const struct soc_enum adc_enum =
222SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text);
223
224static const struct snd_kcontrol_new adc_mux =
225SOC_DAPM_ENUM("Capture Mux", adc_enum);
226
227/* input sources for DAC */
228static const char *dac_mux_text[] = {
229 "DAC", "LINE_IN"
230};
231
232static const struct soc_enum dac_enum =
233SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text);
234
235static const struct snd_kcontrol_new dac_mux =
236SOC_DAPM_ENUM("Headphone Mux", dac_enum);
237
238static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
239 SND_SOC_DAPM_INPUT("LINE_IN"),
240 SND_SOC_DAPM_INPUT("MIC_IN"),
241
242 SND_SOC_DAPM_OUTPUT("HP_OUT"),
243 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
244
245 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
246 mic_bias_event,
247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
248
249 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
250 small_pop_event,
251 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
252 SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0,
253 small_pop_event,
254 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
255
256 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
257 SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
258
259 /* aif for i2s input */
260 SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
261 0, SGTL5000_CHIP_DIG_POWER,
262 0, 0),
263
264 /* aif for i2s output */
265 SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture",
266 0, SGTL5000_CHIP_DIG_POWER,
267 1, 0),
268
269 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
270
271 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
272};
273
274/* routes for sgtl5000 */
275static const struct snd_soc_dapm_route audio_map[] = {
276 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
277 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
278
279 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
280 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
281
282 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
283 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
284 {"LO", NULL, "DAC"}, /* dac --> line_out */
285
286 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
287 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
288
289 {"LINE_OUT", NULL, "LO"},
290 {"HP_OUT", NULL, "HP"},
291};
292
293/* custom function to fetch info of PCM playback volume */
294static int dac_info_volsw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_info *uinfo)
296{
297 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
298 uinfo->count = 2;
299 uinfo->value.integer.min = 0;
300 uinfo->value.integer.max = 0xfc - 0x3c;
301 return 0;
302}
303
304/*
305 * custom function to get of PCM playback volume
306 *
307 * dac volume register
308 * 15-------------8-7--------------0
309 * | R channel vol | L channel vol |
310 * -------------------------------
311 *
312 * PCM volume with 0.5017 dB steps from 0 to -90 dB
313 *
314 * register values map to dB
315 * 0x3B and less = Reserved
316 * 0x3C = 0 dB
317 * 0x3D = -0.5 dB
318 * 0xF0 = -90 dB
319 * 0xFC and greater = Muted
320 *
321 * register value map to userspace value
322 *
323 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
324 * ------------------------------
325 * userspace value 0xc0 0
326 */
327static int dac_get_volsw(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol)
329{
330 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
331 int reg;
332 int l;
333 int r;
334
335 reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
336
337 /* get left channel volume */
338 l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
339
340 /* get right channel volume */
341 r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) >> SGTL5000_DAC_VOL_RIGHT_SHIFT;
342
343 /* make sure value fall in (0x3c,0xfc) */
344 l = clamp(l, 0x3c, 0xfc);
345 r = clamp(r, 0x3c, 0xfc);
346
347 /* invert it and map to userspace value */
348 l = 0xfc - l;
349 r = 0xfc - r;
350
351 ucontrol->value.integer.value[0] = l;
352 ucontrol->value.integer.value[1] = r;
353
354 return 0;
355}
356
357/*
358 * custom function to put of PCM playback volume
359 *
360 * dac volume register
361 * 15-------------8-7--------------0
362 * | R channel vol | L channel vol |
363 * -------------------------------
364 *
365 * PCM volume with 0.5017 dB steps from 0 to -90 dB
366 *
367 * register values map to dB
368 * 0x3B and less = Reserved
369 * 0x3C = 0 dB
370 * 0x3D = -0.5 dB
371 * 0xF0 = -90 dB
372 * 0xFC and greater = Muted
373 *
374 * userspace value map to register value
375 *
376 * userspace value 0xc0 0
377 * ------------------------------
378 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
379 */
380static int dac_put_volsw(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 int reg;
385 int l;
386 int r;
387
388 l = ucontrol->value.integer.value[0];
389 r = ucontrol->value.integer.value[1];
390
391 /* make sure userspace volume fall in (0, 0xfc-0x3c) */
392 l = clamp(l, 0, 0xfc - 0x3c);
393 r = clamp(r, 0, 0xfc - 0x3c);
394
395 /* invert it, get the value can be set to register */
396 l = 0xfc - l;
397 r = 0xfc - r;
398
399 /* shift to get the register value */
400 reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
401 r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
402
403 snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
404
405 return 0;
406}
407
408static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
409
410/* tlv for mic gain, 0db 20db 30db 40db */
411static const unsigned int mic_gain_tlv[] = {
412 TLV_DB_RANGE_HEAD(4),
413 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
414 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
415};
416
417/* tlv for hp volume, -51.5db to 12.0db, step .5db */
418static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
419
420static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
421 /* SOC_DOUBLE_S8_TLV with invert */
422 {
423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424 .name = "PCM Playback Volume",
425 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
426 SNDRV_CTL_ELEM_ACCESS_READWRITE,
427 .info = dac_info_volsw,
428 .get = dac_get_volsw,
429 .put = dac_put_volsw,
430 },
431
432 SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
433 SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
434 SGTL5000_CHIP_ANA_ADC_CTRL,
435 8, 2, 0, capture_6db_attenuate),
436 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
437
438 SOC_DOUBLE_TLV("Headphone Playback Volume",
439 SGTL5000_CHIP_ANA_HP_CTRL,
440 0, 8,
441 0x7f, 1,
442 headphone_volume),
443 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
444 5, 1, 0),
445
446 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
447 0, 4, 0, mic_gain_tlv),
448};
449
450/* mute the codec used by alsa core */
451static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
452{
453 struct snd_soc_codec *codec = codec_dai->codec;
454 u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
455
456 snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
457 adcdac_ctrl, mute ? adcdac_ctrl : 0);
458
459 return 0;
460}
461
462/* set codec format */
463static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
464{
465 struct snd_soc_codec *codec = codec_dai->codec;
466 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
467 u16 i2sctl = 0;
468
469 sgtl5000->master = 0;
470 /*
471 * i2s clock and frame master setting.
472 * ONLY support:
473 * - clock and frame slave,
474 * - clock and frame master
475 */
476 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
477 case SND_SOC_DAIFMT_CBS_CFS:
478 break;
479 case SND_SOC_DAIFMT_CBM_CFM:
480 i2sctl |= SGTL5000_I2S_MASTER;
481 sgtl5000->master = 1;
482 break;
483 default:
484 return -EINVAL;
485 }
486
487 /* setting i2s data format */
488 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
489 case SND_SOC_DAIFMT_DSP_A:
490 i2sctl |= SGTL5000_I2S_MODE_PCM;
491 break;
492 case SND_SOC_DAIFMT_DSP_B:
493 i2sctl |= SGTL5000_I2S_MODE_PCM;
494 i2sctl |= SGTL5000_I2S_LRALIGN;
495 break;
496 case SND_SOC_DAIFMT_I2S:
497 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
498 break;
499 case SND_SOC_DAIFMT_RIGHT_J:
500 i2sctl |= SGTL5000_I2S_MODE_RJ;
501 i2sctl |= SGTL5000_I2S_LRPOL;
502 break;
503 case SND_SOC_DAIFMT_LEFT_J:
504 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
505 i2sctl |= SGTL5000_I2S_LRALIGN;
506 break;
507 default:
508 return -EINVAL;
509 }
510
511 sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
512
513 /* Clock inversion */
514 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
515 case SND_SOC_DAIFMT_NB_NF:
516 break;
517 case SND_SOC_DAIFMT_IB_NF:
518 i2sctl |= SGTL5000_I2S_SCLK_INV;
519 break;
520 default:
521 return -EINVAL;
522 }
523
524 snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
525
526 return 0;
527}
528
529/* set codec sysclk */
530static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
531 int clk_id, unsigned int freq, int dir)
532{
533 struct snd_soc_codec *codec = codec_dai->codec;
534 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
535
536 switch (clk_id) {
537 case SGTL5000_SYSCLK:
538 sgtl5000->sysclk = freq;
539 break;
540 default:
541 return -EINVAL;
542 }
543
544 return 0;
545}
546
547/*
548 * set clock according to i2s frame clock,
549 * sgtl5000 provide 2 clock sources.
550 * 1. sys_mclk. sample freq can only configure to
551 * 1/256, 1/384, 1/512 of sys_mclk.
552 * 2. pll. can derive any audio clocks.
553 *
554 * clock setting rules:
555 * 1. in slave mode, only sys_mclk can use.
556 * 2. as constraint by sys_mclk, sample freq should
557 * set to 32k, 44.1k and above.
558 * 3. using sys_mclk prefer to pll to save power.
559 */
560static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
561{
562 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
563 int clk_ctl = 0;
564 int sys_fs; /* sample freq */
565
566 /*
567 * sample freq should be divided by frame clock,
568 * if frame clock lower than 44.1khz, sample feq should set to
569 * 32khz or 44.1khz.
570 */
571 switch (frame_rate) {
572 case 8000:
573 case 16000:
574 sys_fs = 32000;
575 break;
576 case 11025:
577 case 22050:
578 sys_fs = 44100;
579 break;
580 default:
581 sys_fs = frame_rate;
582 break;
583 }
584
585 /* set divided factor of frame clock */
586 switch (sys_fs / frame_rate) {
587 case 4:
588 clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT;
589 break;
590 case 2:
591 clk_ctl |= SGTL5000_RATE_MODE_DIV_2 << SGTL5000_RATE_MODE_SHIFT;
592 break;
593 case 1:
594 clk_ctl |= SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT;
595 break;
596 default:
597 return -EINVAL;
598 }
599
600 /* set the sys_fs according to frame rate */
601 switch (sys_fs) {
602 case 32000:
603 clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT;
604 break;
605 case 44100:
606 clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT;
607 break;
608 case 48000:
609 clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT;
610 break;
611 case 96000:
612 clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
613 break;
614 default:
615 dev_err(codec->dev, "frame rate %d not supported\n",
616 frame_rate);
617 return -EINVAL;
618 }
619
620 /*
621 * calculate the divider of mclk/sample_freq,
622 * factor of freq =96k can only be 256, since mclk in range (12m,27m)
623 */
624 switch (sgtl5000->sysclk / sys_fs) {
625 case 256:
626 clk_ctl |= SGTL5000_MCLK_FREQ_256FS <<
627 SGTL5000_MCLK_FREQ_SHIFT;
628 break;
629 case 384:
630 clk_ctl |= SGTL5000_MCLK_FREQ_384FS <<
631 SGTL5000_MCLK_FREQ_SHIFT;
632 break;
633 case 512:
634 clk_ctl |= SGTL5000_MCLK_FREQ_512FS <<
635 SGTL5000_MCLK_FREQ_SHIFT;
636 break;
637 default:
638 /* if mclk not satisify the divider, use pll */
639 if (sgtl5000->master) {
640 clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
641 SGTL5000_MCLK_FREQ_SHIFT;
642 } else {
643 dev_err(codec->dev,
644 "PLL not supported in slave mode\n");
645 return -EINVAL;
646 }
647 }
648
649 /* if using pll, please check manual 6.4.2 for detail */
650 if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
651 u64 out, t;
652 int div2;
653 int pll_ctl;
654 unsigned int in, int_div, frac_div;
655
656 if (sgtl5000->sysclk > 17000000) {
657 div2 = 1;
658 in = sgtl5000->sysclk / 2;
659 } else {
660 div2 = 0;
661 in = sgtl5000->sysclk;
662 }
663 if (sys_fs == 44100)
664 out = 180633600;
665 else
666 out = 196608000;
667 t = do_div(out, in);
668 int_div = out;
669 t *= 2048;
670 do_div(t, in);
671 frac_div = t;
672 pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
673 frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
674
675 snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
676 if (div2)
677 snd_soc_update_bits(codec,
678 SGTL5000_CHIP_CLK_TOP_CTRL,
679 SGTL5000_INPUT_FREQ_DIV2,
680 SGTL5000_INPUT_FREQ_DIV2);
681 else
682 snd_soc_update_bits(codec,
683 SGTL5000_CHIP_CLK_TOP_CTRL,
684 SGTL5000_INPUT_FREQ_DIV2,
685 0);
686
687 /* power up pll */
688 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
689 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
690 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
691 } else {
692 /* power down pll */
693 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
694 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
695 0);
696 }
697
698 /* if using pll, clk_ctrl must be set after pll power up */
699 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
700
701 return 0;
702}
703
704/*
705 * Set PCM DAI bit size and sample rate.
706 * input: params_rate, params_fmt
707 */
708static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
709 struct snd_pcm_hw_params *params,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_codec *codec = rtd->codec;
714 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
715 int channels = params_channels(params);
716 int i2s_ctl = 0;
717 int stereo;
718 int ret;
719
720 /* sysclk should already set */
721 if (!sgtl5000->sysclk) {
722 dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
723 return -EFAULT;
724 }
725
726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
727 stereo = SGTL5000_DAC_STEREO;
728 else
729 stereo = SGTL5000_ADC_STEREO;
730
731 /* set mono to save power */
732 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
733 channels == 1 ? 0 : stereo);
734
735 /* set codec clock base on lrclk */
736 ret = sgtl5000_set_clock(codec, params_rate(params));
737 if (ret)
738 return ret;
739
740 /* set i2s data format */
741 switch (params_format(params)) {
742 case SNDRV_PCM_FORMAT_S16_LE:
743 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
744 return -EINVAL;
745 i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT;
746 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS <<
747 SGTL5000_I2S_SCLKFREQ_SHIFT;
748 break;
749 case SNDRV_PCM_FORMAT_S20_3LE:
750 i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT;
751 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
752 SGTL5000_I2S_SCLKFREQ_SHIFT;
753 break;
754 case SNDRV_PCM_FORMAT_S24_LE:
755 i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT;
756 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
757 SGTL5000_I2S_SCLKFREQ_SHIFT;
758 break;
759 case SNDRV_PCM_FORMAT_S32_LE:
760 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
761 return -EINVAL;
762 i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT;
763 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
764 SGTL5000_I2S_SCLKFREQ_SHIFT;
765 break;
766 default:
767 return -EINVAL;
768 }
769
770 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl);
771
772 return 0;
773}
774
775static int ldo_regulator_is_enabled(struct regulator_dev *dev)
776{
777 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
778
779 return ldo->enabled;
780}
781
782static int ldo_regulator_enable(struct regulator_dev *dev)
783{
784 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
785 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
786 int reg;
787
788 if (ldo_regulator_is_enabled(dev))
789 return 0;
790
791 /* set regulator value firstly */
792 reg = (1600 - ldo->voltage / 1000) / 50;
793 reg = clamp(reg, 0x0, 0xf);
794
795 /* amend the voltage value, unit: uV */
796 ldo->voltage = (1600 - reg * 50) * 1000;
797
798 /* set voltage to register */
799 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
800 (0x1 << 4) - 1, reg);
801
802 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
803 SGTL5000_LINEREG_D_POWERUP,
804 SGTL5000_LINEREG_D_POWERUP);
805
806 /* when internal ldo enabled, simple digital power can be disabled */
807 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
808 SGTL5000_LINREG_SIMPLE_POWERUP,
809 0);
810
811 ldo->enabled = 1;
812 return 0;
813}
814
815static int ldo_regulator_disable(struct regulator_dev *dev)
816{
817 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
818 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
819
820 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
821 SGTL5000_LINEREG_D_POWERUP,
822 0);
823
824 /* clear voltage info */
825 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
826 (0x1 << 4) - 1, 0);
827
828 ldo->enabled = 0;
829
830 return 0;
831}
832
833static int ldo_regulator_get_voltage(struct regulator_dev *dev)
834{
835 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
836
837 return ldo->voltage;
838}
839
840static struct regulator_ops ldo_regulator_ops = {
841 .is_enabled = ldo_regulator_is_enabled,
842 .enable = ldo_regulator_enable,
843 .disable = ldo_regulator_disable,
844 .get_voltage = ldo_regulator_get_voltage,
845};
846
847static int ldo_regulator_register(struct snd_soc_codec *codec,
848 struct regulator_init_data *init_data,
849 int voltage)
850{
851 struct ldo_regulator *ldo;
852
853 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
854
855 if (!ldo) {
856 dev_err(codec->dev, "failed to allocate ldo_regulator\n");
857 return -ENOMEM;
858 }
859
860 ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
861 if (!ldo->desc.name) {
862 kfree(ldo);
863 dev_err(codec->dev, "failed to allocate decs name memory\n");
864 return -ENOMEM;
865 }
866
867 ldo->desc.type = REGULATOR_VOLTAGE;
868 ldo->desc.owner = THIS_MODULE;
869 ldo->desc.ops = &ldo_regulator_ops;
870 ldo->desc.n_voltages = 1;
871
872 ldo->codec_data = codec;
873 ldo->voltage = voltage;
874
875 ldo->dev = regulator_register(&ldo->desc, codec->dev,
876 init_data, ldo);
877 if (IS_ERR(ldo->dev)) {
878 int ret = PTR_ERR(ldo->dev);
879
880 dev_err(codec->dev, "failed to register regulator\n");
881 kfree(ldo->desc.name);
882 kfree(ldo);
883
884 return ret;
885 }
886
887 return 0;
888}
889
890static int ldo_regulator_remove(struct snd_soc_codec *codec)
891{
892 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
893 struct ldo_regulator *ldo = sgtl5000->ldo;
894
895 if (!ldo)
896 return 0;
897
898 regulator_unregister(ldo->dev);
899 kfree(ldo->desc.name);
900 kfree(ldo);
901
902 return 0;
903}
904
905/*
906 * set dac bias
907 * common state changes:
908 * startup:
909 * off --> standby --> prepare --> on
910 * standby --> prepare --> on
911 *
912 * stop:
913 * on --> prepare --> standby
914 */
915static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
916 enum snd_soc_bias_level level)
917{
918 int ret;
919 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
920
921 switch (level) {
922 case SND_SOC_BIAS_ON:
923 case SND_SOC_BIAS_PREPARE:
924 break;
925 case SND_SOC_BIAS_STANDBY:
926 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
927 ret = regulator_bulk_enable(
928 ARRAY_SIZE(sgtl5000->supplies),
929 sgtl5000->supplies);
930 if (ret)
931 return ret;
932 udelay(10);
933 }
934
935 break;
936 case SND_SOC_BIAS_OFF:
937 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
938 sgtl5000->supplies);
939 break;
940 }
941
942 codec->dapm.bias_level = level;
943 return 0;
944}
945
946#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
947 SNDRV_PCM_FMTBIT_S20_3LE |\
948 SNDRV_PCM_FMTBIT_S24_LE |\
949 SNDRV_PCM_FMTBIT_S32_LE)
950
951static struct snd_soc_dai_ops sgtl5000_ops = {
952 .hw_params = sgtl5000_pcm_hw_params,
953 .digital_mute = sgtl5000_digital_mute,
954 .set_fmt = sgtl5000_set_dai_fmt,
955 .set_sysclk = sgtl5000_set_dai_sysclk,
956};
957
958static struct snd_soc_dai_driver sgtl5000_dai = {
959 .name = "sgtl5000",
960 .playback = {
961 .stream_name = "Playback",
962 .channels_min = 1,
963 .channels_max = 2,
964 /*
965 * only support 8~48K + 96K,
966 * TODO modify hw_param to support more
967 */
968 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
969 .formats = SGTL5000_FORMATS,
970 },
971 .capture = {
972 .stream_name = "Capture",
973 .channels_min = 1,
974 .channels_max = 2,
975 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
976 .formats = SGTL5000_FORMATS,
977 },
978 .ops = &sgtl5000_ops,
979 .symmetric_rates = 1,
980};
981
982static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
983 unsigned int reg)
984{
985 switch (reg) {
986 case SGTL5000_CHIP_ID:
987 case SGTL5000_CHIP_ADCDAC_CTRL:
988 case SGTL5000_CHIP_ANA_STATUS:
989 return 1;
990 }
991
992 return 0;
993}
994
995#ifdef CONFIG_SUSPEND
996static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
997{
998 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
999
1000 return 0;
1001}
1002
1003/*
1004 * restore all sgtl5000 registers,
1005 * since a big hole between dap and regular registers,
1006 * we will restore them respectively.
1007 */
1008static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
1009{
1010 u16 *cache = codec->reg_cache;
1011 int i;
1012 int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1;
1013
1014 /* restore regular registers */
1015 for (i = 0; i < regular_regs; i++) {
1016 int reg = i << 1;
1017
1018 /* this regs depends on the others */
1019 if (reg == SGTL5000_CHIP_ANA_POWER ||
1020 reg == SGTL5000_CHIP_CLK_CTRL ||
1021 reg == SGTL5000_CHIP_LINREG_CTRL ||
1022 reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
1023 reg == SGTL5000_CHIP_CLK_CTRL)
1024 continue;
1025
1026 snd_soc_write(codec, reg, cache[i]);
1027 }
1028
1029 /* restore dap registers */
1030 for (i = SGTL5000_DAP_REG_OFFSET >> 1;
1031 i < SGTL5000_MAX_REG_OFFSET >> 1; i++) {
1032 int reg = i << 1;
1033
1034 snd_soc_write(codec, reg, cache[i]);
1035 }
1036
1037 /*
1038 * restore power and other regs according
1039 * to set_power() and set_clock()
1040 */
1041 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
1042 cache[SGTL5000_CHIP_LINREG_CTRL >> 1]);
1043
1044 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
1045 cache[SGTL5000_CHIP_ANA_POWER >> 1]);
1046
1047 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
1048 cache[SGTL5000_CHIP_CLK_CTRL >> 1]);
1049
1050 snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
1051 cache[SGTL5000_CHIP_REF_CTRL >> 1]);
1052
1053 snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1054 cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]);
1055 return 0;
1056}
1057
1058static int sgtl5000_resume(struct snd_soc_codec *codec)
1059{
1060 /* Bring the codec back up to standby to enable regulators */
1061 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1062
1063 /* Restore registers by cached in memory */
1064 sgtl5000_restore_regs(codec);
1065 return 0;
1066}
1067#else
1068#define sgtl5000_suspend NULL
1069#define sgtl5000_resume NULL
1070#endif /* CONFIG_SUSPEND */
1071
1072/*
1073 * sgtl5000 has 3 internal power supplies:
1074 * 1. VAG, normally set to vdda/2
1075 * 2. chargepump, set to different value
1076 * according to voltage of vdda and vddio
1077 * 3. line out VAG, normally set to vddio/2
1078 *
1079 * and should be set according to:
1080 * 1. vddd provided by external or not
1081 * 2. vdda and vddio voltage value. > 3.1v or not
1082 * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
1083 */
1084static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1085{
1086 int vddd;
1087 int vdda;
1088 int vddio;
1089 u16 ana_pwr;
1090 u16 lreg_ctrl;
1091 int vag;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093
1094 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
1095 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
1096 vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer);
1097
1098 vdda = vdda / 1000;
1099 vddio = vddio / 1000;
1100 vddd = vddd / 1000;
1101
1102 if (vdda <= 0 || vddio <= 0 || vddd < 0) {
1103 dev_err(codec->dev, "regulator voltage not set correctly\n");
1104
1105 return -EINVAL;
1106 }
1107
1108 /* according to datasheet, maximum voltage of supplies */
1109 if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
1110 dev_err(codec->dev,
1111 "exceed max voltage vdda %dmv vddio %dma vddd %dma\n",
1112 vdda, vddio, vddd);
1113
1114 return -EINVAL;
1115 }
1116
1117 /* reset value */
1118 ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
1119 ana_pwr |= SGTL5000_DAC_STEREO |
1120 SGTL5000_ADC_STEREO |
1121 SGTL5000_REFTOP_POWERUP;
1122 lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
1123
1124 if (vddio < 3100 && vdda < 3100) {
1125 /* enable internal oscillator used for charge pump */
1126 snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
1127 SGTL5000_INT_OSC_EN,
1128 SGTL5000_INT_OSC_EN);
1129 /* Enable VDDC charge pump */
1130 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
1131 } else if (vddio >= 3100 && vdda >= 3100) {
1132 /*
1133 * if vddio and vddd > 3.1v,
1134 * charge pump should be clean before set ana_pwr
1135 */
1136 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1137 SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
1138
1139 /* VDDC use VDDIO rail */
1140 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
1141 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
1142 SGTL5000_VDDC_MAN_ASSN_SHIFT;
1143 }
1144
1145 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
1146
1147 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1148
1149 /* set voltage to register */
1150 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1151 (0x1 << 4) - 1, 0x8);
1152
1153 /*
1154 * if vddd linear reg has been enabled,
1155 * simple digital supply should be clear to get
1156 * proper VDDD voltage.
1157 */
1158 if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
1159 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1160 SGTL5000_LINREG_SIMPLE_POWERUP,
1161 0);
1162 else
1163 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1164 SGTL5000_LINREG_SIMPLE_POWERUP |
1165 SGTL5000_STARTUP_POWERUP,
1166 0);
1167
1168 /*
1169 * set ADC/DAC VAG to vdda / 2,
1170 * should stay in range (0.8v, 1.575v)
1171 */
1172 vag = vdda / 2;
1173 if (vag <= SGTL5000_ANA_GND_BASE)
1174 vag = 0;
1175 else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
1176 (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT))
1177 vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT;
1178 else
1179 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1180
1181 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1182 vag << SGTL5000_ANA_GND_SHIFT,
1183 vag << SGTL5000_ANA_GND_SHIFT);
1184
1185 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1186 vag = vddio / 2;
1187 if (vag <= SGTL5000_LINE_OUT_GND_BASE)
1188 vag = 0;
1189 else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
1190 SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
1191 vag = SGTL5000_LINE_OUT_GND_MAX;
1192 else
1193 vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
1194 SGTL5000_LINE_OUT_GND_STP;
1195
1196 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1197 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1198 SGTL5000_LINE_OUT_CURRENT_360u <<
1199 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1200 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1201 SGTL5000_LINE_OUT_CURRENT_360u <<
1202 SGTL5000_LINE_OUT_CURRENT_SHIFT);
1203
1204 return 0;
1205}
1206
1207static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1208{
1209 u16 reg;
1210 int ret;
1211 int rev;
1212 int i;
1213 int external_vddd = 0;
1214 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1215
1216 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
1217 sgtl5000->supplies[i].supply = supply_names[i];
1218
1219 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
1220 sgtl5000->supplies);
1221 if (!ret)
1222 external_vddd = 1;
1223 else {
1224 /* set internal ldo to 1.2v */
1225 int voltage = LDO_VOLTAGE;
1226
1227 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1228 if (ret) {
1229 dev_err(codec->dev,
1230 "Failed to register vddd internal supplies: %d\n",
1231 ret);
1232 return ret;
1233 }
1234
1235 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1236
1237 ret = regulator_bulk_get(codec->dev,
1238 ARRAY_SIZE(sgtl5000->supplies),
1239 sgtl5000->supplies);
1240
1241 if (ret) {
1242 ldo_regulator_remove(codec);
1243 dev_err(codec->dev,
1244 "Failed to request supplies: %d\n", ret);
1245
1246 return ret;
1247 }
1248 }
1249
1250 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1251 sgtl5000->supplies);
1252 if (ret)
1253 goto err_regulator_free;
1254
1255 /* wait for all power rails bring up */
1256 udelay(10);
1257
1258 /* read chip information */
1259 reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
1260 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1261 SGTL5000_PARTID_PART_ID) {
1262 dev_err(codec->dev,
1263 "Device with ID register %x is not a sgtl5000\n", reg);
1264 ret = -ENODEV;
1265 goto err_regulator_disable;
1266 }
1267
1268 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1269 dev_info(codec->dev, "sgtl5000 revision %d\n", rev);
1270
1271 /*
1272 * workaround for revision 0x11 and later,
1273 * roll back to use internal LDO
1274 */
1275 if (external_vddd && rev >= 0x11) {
1276 int voltage = LDO_VOLTAGE;
1277 /* disable all regulator first */
1278 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1279 sgtl5000->supplies);
1280 /* free VDDD regulator */
1281 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1282 sgtl5000->supplies);
1283
1284 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1285 if (ret)
1286 return ret;
1287
1288 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1289
1290 ret = regulator_bulk_get(codec->dev,
1291 ARRAY_SIZE(sgtl5000->supplies),
1292 sgtl5000->supplies);
1293 if (ret) {
1294 ldo_regulator_remove(codec);
1295 dev_err(codec->dev,
1296 "Failed to request supplies: %d\n", ret);
1297
1298 return ret;
1299 }
1300
1301 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1302 sgtl5000->supplies);
1303 if (ret)
1304 goto err_regulator_free;
1305
1306 /* wait for all power rails bring up */
1307 udelay(10);
1308 }
1309
1310 return 0;
1311
1312err_regulator_disable:
1313 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1314 sgtl5000->supplies);
1315err_regulator_free:
1316 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1317 sgtl5000->supplies);
1318 if (external_vddd)
1319 ldo_regulator_remove(codec);
1320 return ret;
1321
1322}
1323
1324static int sgtl5000_probe(struct snd_soc_codec *codec)
1325{
1326 int ret;
1327 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1328
1329 /* setup i2c data ops */
1330 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
1331 if (ret < 0) {
1332 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1333 return ret;
1334 }
1335
1336 ret = sgtl5000_enable_regulators(codec);
1337 if (ret)
1338 return ret;
1339
1340 /* power up sgtl5000 */
1341 ret = sgtl5000_set_power_regs(codec);
1342 if (ret)
1343 goto err;
1344
1345 /* enable small pop, introduce 400ms delay in turning off */
1346 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1347 SGTL5000_SMALL_POP,
1348 SGTL5000_SMALL_POP);
1349
1350 /* disable short cut detector */
1351 snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
1352
1353 /*
1354 * set i2s as default input of sound switch
1355 * TODO: add sound switch to control and dapm widge.
1356 */
1357 snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
1358 SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
1359 snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
1360 SGTL5000_ADC_EN | SGTL5000_DAC_EN);
1361
1362 /* enable dac volume ramp by default */
1363 snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
1364 SGTL5000_DAC_VOL_RAMP_EN |
1365 SGTL5000_DAC_MUTE_RIGHT |
1366 SGTL5000_DAC_MUTE_LEFT);
1367
1368 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
1369
1370 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1371 SGTL5000_HP_ZCD_EN |
1372 SGTL5000_ADC_ZCD_EN);
1373
1374 snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);
1375
1376 /*
1377 * disable DAP
1378 * TODO:
1379 * Enable DAP in kcontrol and dapm.
1380 */
1381 snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
1382
1383 /* leading to standby state */
1384 ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1385 if (ret)
1386 goto err;
1387
1388 snd_soc_add_controls(codec, sgtl5000_snd_controls,
1389 ARRAY_SIZE(sgtl5000_snd_controls));
1390
1391 snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
1392 ARRAY_SIZE(sgtl5000_dapm_widgets));
1393
1394 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1395 ARRAY_SIZE(audio_map));
1396
1397 snd_soc_dapm_new_widgets(&codec->dapm);
1398
1399 return 0;
1400
1401err:
1402 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1403 sgtl5000->supplies);
1404 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1405 sgtl5000->supplies);
1406 ldo_regulator_remove(codec);
1407
1408 return ret;
1409}
1410
1411static int sgtl5000_remove(struct snd_soc_codec *codec)
1412{
1413 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1414
1415 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
1416
1417 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1418 sgtl5000->supplies);
1419 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1420 sgtl5000->supplies);
1421 ldo_regulator_remove(codec);
1422
1423 return 0;
1424}
1425
1426static struct snd_soc_codec_driver sgtl5000_driver = {
1427 .probe = sgtl5000_probe,
1428 .remove = sgtl5000_remove,
1429 .suspend = sgtl5000_suspend,
1430 .resume = sgtl5000_resume,
1431 .set_bias_level = sgtl5000_set_bias_level,
1432 .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
1433 .reg_word_size = sizeof(u16),
1434 .reg_cache_step = 2,
1435 .reg_cache_default = sgtl5000_regs,
1436 .volatile_register = sgtl5000_volatile_register,
1437};
1438
1439static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
1440 const struct i2c_device_id *id)
1441{
1442 struct sgtl5000_priv *sgtl5000;
1443 int ret;
1444
1445 sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL);
1446 if (!sgtl5000)
1447 return -ENOMEM;
1448
1449 /*
1450 * copy DAP default values to default value array.
1451 * sgtl5000 register space has a big hole, merge it
1452 * at init phase makes life easy.
1453 * FIXME: should we drop 'const' of sgtl5000_regs?
1454 */
1455 memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)),
1456 sgtl5000_dap_regs,
1457 SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET);
1458
1459 i2c_set_clientdata(client, sgtl5000);
1460
1461 ret = snd_soc_register_codec(&client->dev,
1462 &sgtl5000_driver, &sgtl5000_dai, 1);
1463 if (ret) {
1464 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1465 kfree(sgtl5000);
1466 return ret;
1467 }
1468
1469 return 0;
1470}
1471
1472static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
1473{
1474 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1475
1476 snd_soc_unregister_codec(&client->dev);
1477
1478 kfree(sgtl5000);
1479 return 0;
1480}
1481
1482static const struct i2c_device_id sgtl5000_id[] = {
1483 {"sgtl5000", 0},
1484 {},
1485};
1486
1487MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1488
1489static struct i2c_driver sgtl5000_i2c_driver = {
1490 .driver = {
1491 .name = "sgtl5000",
1492 .owner = THIS_MODULE,
1493 },
1494 .probe = sgtl5000_i2c_probe,
1495 .remove = __devexit_p(sgtl5000_i2c_remove),
1496 .id_table = sgtl5000_id,
1497};
1498
1499static int __init sgtl5000_modinit(void)
1500{
1501 return i2c_add_driver(&sgtl5000_i2c_driver);
1502}
1503module_init(sgtl5000_modinit);
1504
1505static void __exit sgtl5000_exit(void)
1506{
1507 i2c_del_driver(&sgtl5000_i2c_driver);
1508}
1509module_exit(sgtl5000_exit);
1510
1511MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1512MODULE_AUTHOR("Zeng Zhaoming <zhaoming.zeng@freescale.com>");
1513MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
new file mode 100644
index 000000000000..eec3ab368f39
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.h
@@ -0,0 +1,400 @@
1/*
2 * sgtl5000.h - SGTL5000 audio codec interface
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _SGTL5000_H
12#define _SGTL5000_H
13
14/*
15 * Register values.
16 */
17#define SGTL5000_CHIP_ID 0x0000
18#define SGTL5000_CHIP_DIG_POWER 0x0002
19#define SGTL5000_CHIP_CLK_CTRL 0x0004
20#define SGTL5000_CHIP_I2S_CTRL 0x0006
21#define SGTL5000_CHIP_SSS_CTRL 0x000a
22#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e
23#define SGTL5000_CHIP_DAC_VOL 0x0010
24#define SGTL5000_CHIP_PAD_STRENGTH 0x0014
25#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020
26#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022
27#define SGTL5000_CHIP_ANA_CTRL 0x0024
28#define SGTL5000_CHIP_LINREG_CTRL 0x0026
29#define SGTL5000_CHIP_REF_CTRL 0x0028
30#define SGTL5000_CHIP_MIC_CTRL 0x002a
31#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c
32#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e
33#define SGTL5000_CHIP_ANA_POWER 0x0030
34#define SGTL5000_CHIP_PLL_CTRL 0x0032
35#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034
36#define SGTL5000_CHIP_ANA_STATUS 0x0036
37#define SGTL5000_CHIP_SHORT_CTRL 0x003c
38#define SGTL5000_CHIP_ANA_TEST2 0x003a
39#define SGTL5000_DAP_CTRL 0x0100
40#define SGTL5000_DAP_PEQ 0x0102
41#define SGTL5000_DAP_BASS_ENHANCE 0x0104
42#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106
43#define SGTL5000_DAP_AUDIO_EQ 0x0108
44#define SGTL5000_DAP_SURROUND 0x010a
45#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c
46#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e
47#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110
48#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116
49#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118
50#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a
51#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c
52#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e
53#define SGTL5000_DAP_MAIN_CHAN 0x0120
54#define SGTL5000_DAP_MIX_CHAN 0x0122
55#define SGTL5000_DAP_AVC_CTRL 0x0124
56#define SGTL5000_DAP_AVC_THRESHOLD 0x0126
57#define SGTL5000_DAP_AVC_ATTACK 0x0128
58#define SGTL5000_DAP_AVC_DECAY 0x012a
59#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c
60#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e
61#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130
62#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132
63#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134
64#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136
65#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138
66#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a
67
68/*
69 * Field Definitions.
70 */
71
72/*
73 * SGTL5000_CHIP_ID
74 */
75#define SGTL5000_PARTID_MASK 0xff00
76#define SGTL5000_PARTID_SHIFT 8
77#define SGTL5000_PARTID_WIDTH 8
78#define SGTL5000_PARTID_PART_ID 0xa0
79#define SGTL5000_REVID_MASK 0x00ff
80#define SGTL5000_REVID_SHIFT 0
81#define SGTL5000_REVID_WIDTH 8
82
83/*
84 * SGTL5000_CHIP_DIG_POWER
85 */
86#define SGTL5000_ADC_EN 0x0040
87#define SGTL5000_DAC_EN 0x0020
88#define SGTL5000_DAP_POWERUP 0x0010
89#define SGTL5000_I2S_OUT_POWERUP 0x0002
90#define SGTL5000_I2S_IN_POWERUP 0x0001
91
92/*
93 * SGTL5000_CHIP_CLK_CTRL
94 */
95#define SGTL5000_RATE_MODE_MASK 0x0030
96#define SGTL5000_RATE_MODE_SHIFT 4
97#define SGTL5000_RATE_MODE_WIDTH 2
98#define SGTL5000_RATE_MODE_DIV_1 0
99#define SGTL5000_RATE_MODE_DIV_2 1
100#define SGTL5000_RATE_MODE_DIV_4 2
101#define SGTL5000_RATE_MODE_DIV_6 3
102#define SGTL5000_SYS_FS_MASK 0x000c
103#define SGTL5000_SYS_FS_SHIFT 2
104#define SGTL5000_SYS_FS_WIDTH 2
105#define SGTL5000_SYS_FS_32k 0x0
106#define SGTL5000_SYS_FS_44_1k 0x1
107#define SGTL5000_SYS_FS_48k 0x2
108#define SGTL5000_SYS_FS_96k 0x3
109#define SGTL5000_MCLK_FREQ_MASK 0x0003
110#define SGTL5000_MCLK_FREQ_SHIFT 0
111#define SGTL5000_MCLK_FREQ_WIDTH 2
112#define SGTL5000_MCLK_FREQ_256FS 0x0
113#define SGTL5000_MCLK_FREQ_384FS 0x1
114#define SGTL5000_MCLK_FREQ_512FS 0x2
115#define SGTL5000_MCLK_FREQ_PLL 0x3
116
117/*
118 * SGTL5000_CHIP_I2S_CTRL
119 */
120#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100
121#define SGTL5000_I2S_SCLKFREQ_SHIFT 8
122#define SGTL5000_I2S_SCLKFREQ_WIDTH 1
123#define SGTL5000_I2S_SCLKFREQ_64FS 0x0
124#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */
125#define SGTL5000_I2S_MASTER 0x0080
126#define SGTL5000_I2S_SCLK_INV 0x0040
127#define SGTL5000_I2S_DLEN_MASK 0x0030
128#define SGTL5000_I2S_DLEN_SHIFT 4
129#define SGTL5000_I2S_DLEN_WIDTH 2
130#define SGTL5000_I2S_DLEN_32 0x0
131#define SGTL5000_I2S_DLEN_24 0x1
132#define SGTL5000_I2S_DLEN_20 0x2
133#define SGTL5000_I2S_DLEN_16 0x3
134#define SGTL5000_I2S_MODE_MASK 0x000c
135#define SGTL5000_I2S_MODE_SHIFT 2
136#define SGTL5000_I2S_MODE_WIDTH 2
137#define SGTL5000_I2S_MODE_I2S_LJ 0x0
138#define SGTL5000_I2S_MODE_RJ 0x1
139#define SGTL5000_I2S_MODE_PCM 0x2
140#define SGTL5000_I2S_LRALIGN 0x0002
141#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */
142
143/*
144 * SGTL5000_CHIP_SSS_CTRL
145 */
146#define SGTL5000_DAP_MIX_LRSWAP 0x4000
147#define SGTL5000_DAP_LRSWAP 0x2000
148#define SGTL5000_DAC_LRSWAP 0x1000
149#define SGTL5000_I2S_OUT_LRSWAP 0x0400
150#define SGTL5000_DAP_MIX_SEL_MASK 0x0300
151#define SGTL5000_DAP_MIX_SEL_SHIFT 8
152#define SGTL5000_DAP_MIX_SEL_WIDTH 2
153#define SGTL5000_DAP_MIX_SEL_ADC 0x0
154#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1
155#define SGTL5000_DAP_SEL_MASK 0x00c0
156#define SGTL5000_DAP_SEL_SHIFT 6
157#define SGTL5000_DAP_SEL_WIDTH 2
158#define SGTL5000_DAP_SEL_ADC 0x0
159#define SGTL5000_DAP_SEL_I2S_IN 0x1
160#define SGTL5000_DAC_SEL_MASK 0x0030
161#define SGTL5000_DAC_SEL_SHIFT 4
162#define SGTL5000_DAC_SEL_WIDTH 2
163#define SGTL5000_DAC_SEL_ADC 0x0
164#define SGTL5000_DAC_SEL_I2S_IN 0x1
165#define SGTL5000_DAC_SEL_DAP 0x3
166#define SGTL5000_I2S_OUT_SEL_MASK 0x0003
167#define SGTL5000_I2S_OUT_SEL_SHIFT 0
168#define SGTL5000_I2S_OUT_SEL_WIDTH 2
169#define SGTL5000_I2S_OUT_SEL_ADC 0x0
170#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1
171#define SGTL5000_I2S_OUT_SEL_DAP 0x3
172
173/*
174 * SGTL5000_CHIP_ADCDAC_CTRL
175 */
176#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000
177#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000
178#define SGTL5000_DAC_VOL_RAMP_EN 0x0200
179#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100
180#define SGTL5000_DAC_MUTE_RIGHT 0x0008
181#define SGTL5000_DAC_MUTE_LEFT 0x0004
182#define SGTL5000_ADC_HPF_FREEZE 0x0002
183#define SGTL5000_ADC_HPF_BYPASS 0x0001
184
185/*
186 * SGTL5000_CHIP_DAC_VOL
187 */
188#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00
189#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8
190#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8
191#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff
192#define SGTL5000_DAC_VOL_LEFT_SHIFT 0
193#define SGTL5000_DAC_VOL_LEFT_WIDTH 8
194
195/*
196 * SGTL5000_CHIP_PAD_STRENGTH
197 */
198#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300
199#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8
200#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2
201#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0
202#define SGTL5000_PAD_I2S_SCLK_SHIFT 6
203#define SGTL5000_PAD_I2S_SCLK_WIDTH 2
204#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030
205#define SGTL5000_PAD_I2S_DOUT_SHIFT 4
206#define SGTL5000_PAD_I2S_DOUT_WIDTH 2
207#define SGTL5000_PAD_I2C_SDA_MASK 0x000c
208#define SGTL5000_PAD_I2C_SDA_SHIFT 2
209#define SGTL5000_PAD_I2C_SDA_WIDTH 2
210#define SGTL5000_PAD_I2C_SCL_MASK 0x0003
211#define SGTL5000_PAD_I2C_SCL_SHIFT 0
212#define SGTL5000_PAD_I2C_SCL_WIDTH 2
213
214/*
215 * SGTL5000_CHIP_ANA_ADC_CTRL
216 */
217#define SGTL5000_ADC_VOL_M6DB 0x0100
218#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0
219#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4
220#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4
221#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f
222#define SGTL5000_ADC_VOL_LEFT_SHIFT 0
223#define SGTL5000_ADC_VOL_LEFT_WIDTH 4
224
225/*
226 * SGTL5000_CHIP_ANA_HP_CTRL
227 */
228#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00
229#define SGTL5000_HP_VOL_RIGHT_SHIFT 8
230#define SGTL5000_HP_VOL_RIGHT_WIDTH 7
231#define SGTL5000_HP_VOL_LEFT_MASK 0x007f
232#define SGTL5000_HP_VOL_LEFT_SHIFT 0
233#define SGTL5000_HP_VOL_LEFT_WIDTH 7
234
235/*
236 * SGTL5000_CHIP_ANA_CTRL
237 */
238#define SGTL5000_LINE_OUT_MUTE 0x0100
239#define SGTL5000_HP_SEL_MASK 0x0040
240#define SGTL5000_HP_SEL_SHIFT 6
241#define SGTL5000_HP_SEL_WIDTH 1
242#define SGTL5000_HP_SEL_DAC 0x0
243#define SGTL5000_HP_SEL_LINE_IN 0x1
244#define SGTL5000_HP_ZCD_EN 0x0020
245#define SGTL5000_HP_MUTE 0x0010
246#define SGTL5000_ADC_SEL_MASK 0x0004
247#define SGTL5000_ADC_SEL_SHIFT 2
248#define SGTL5000_ADC_SEL_WIDTH 1
249#define SGTL5000_ADC_SEL_MIC 0x0
250#define SGTL5000_ADC_SEL_LINE_IN 0x1
251#define SGTL5000_ADC_ZCD_EN 0x0002
252#define SGTL5000_ADC_MUTE 0x0001
253
254/*
255 * SGTL5000_CHIP_LINREG_CTRL
256 */
257#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040
258#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6
259#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1
260#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0
261#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1
262#define SGTL5000_VDDC_ASSN_OVRD 0x0020
263#define SGTL5000_LINREG_VDDD_MASK 0x000f
264#define SGTL5000_LINREG_VDDD_SHIFT 0
265#define SGTL5000_LINREG_VDDD_WIDTH 4
266
267/*
268 * SGTL5000_CHIP_REF_CTRL
269 */
270#define SGTL5000_ANA_GND_MASK 0x01f0
271#define SGTL5000_ANA_GND_SHIFT 4
272#define SGTL5000_ANA_GND_WIDTH 5
273#define SGTL5000_ANA_GND_BASE 800 /* mv */
274#define SGTL5000_ANA_GND_STP 25 /*mv */
275#define SGTL5000_BIAS_CTRL_MASK 0x000e
276#define SGTL5000_BIAS_CTRL_SHIFT 1
277#define SGTL5000_BIAS_CTRL_WIDTH 3
278#define SGTL5000_SMALL_POP 0x0001
279
280/*
281 * SGTL5000_CHIP_MIC_CTRL
282 */
283#define SGTL5000_BIAS_R_MASK 0x0200
284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0
287#define SGTL5000_BIAS_R_2K 0x1
288#define SGTL5000_BIAS_R_4k 0x2
289#define SGTL5000_BIAS_R_8k 0x3
290#define SGTL5000_BIAS_VOLT_MASK 0x0070
291#define SGTL5000_BIAS_VOLT_SHIFT 4
292#define SGTL5000_BIAS_VOLT_WIDTH 3
293#define SGTL5000_MIC_GAIN_MASK 0x0003
294#define SGTL5000_MIC_GAIN_SHIFT 0
295#define SGTL5000_MIC_GAIN_WIDTH 2
296
297/*
298 * SGTL5000_CHIP_LINE_OUT_CTRL
299 */
300#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00
301#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8
302#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4
303#define SGTL5000_LINE_OUT_CURRENT_180u 0x0
304#define SGTL5000_LINE_OUT_CURRENT_270u 0x1
305#define SGTL5000_LINE_OUT_CURRENT_360u 0x3
306#define SGTL5000_LINE_OUT_CURRENT_450u 0x7
307#define SGTL5000_LINE_OUT_CURRENT_540u 0xf
308#define SGTL5000_LINE_OUT_GND_MASK 0x003f
309#define SGTL5000_LINE_OUT_GND_SHIFT 0
310#define SGTL5000_LINE_OUT_GND_WIDTH 6
311#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */
312#define SGTL5000_LINE_OUT_GND_STP 25
313#define SGTL5000_LINE_OUT_GND_MAX 0x23
314
315/*
316 * SGTL5000_CHIP_LINE_OUT_VOL
317 */
318#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00
319#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8
320#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5
321#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f
322#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0
323#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5
324
325/*
326 * SGTL5000_CHIP_ANA_POWER
327 */
328#define SGTL5000_DAC_STEREO 0x4000
329#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
330#define SGTL5000_STARTUP_POWERUP 0x1000
331#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800
332#define SGTL5000_PLL_POWERUP 0x0400
333#define SGTL5000_LINEREG_D_POWERUP 0x0200
334#define SGTL5000_VCOAMP_POWERUP 0x0100
335#define SGTL5000_VAG_POWERUP 0x0080
336#define SGTL5000_ADC_STEREO 0x0040
337#define SGTL5000_REFTOP_POWERUP 0x0020
338#define SGTL5000_HP_POWERUP 0x0010
339#define SGTL5000_DAC_POWERUP 0x0008
340#define SGTL5000_CAPLESS_HP_POWERUP 0x0004
341#define SGTL5000_ADC_POWERUP 0x0002
342#define SGTL5000_LINE_OUT_POWERUP 0x0001
343
344/*
345 * SGTL5000_CHIP_PLL_CTRL
346 */
347#define SGTL5000_PLL_INT_DIV_MASK 0xf800
348#define SGTL5000_PLL_INT_DIV_SHIFT 11
349#define SGTL5000_PLL_INT_DIV_WIDTH 5
350#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700
351#define SGTL5000_PLL_FRAC_DIV_SHIFT 0
352#define SGTL5000_PLL_FRAC_DIV_WIDTH 11
353
354/*
355 * SGTL5000_CHIP_CLK_TOP_CTRL
356 */
357#define SGTL5000_INT_OSC_EN 0x0800
358#define SGTL5000_INPUT_FREQ_DIV2 0x0008
359
360/*
361 * SGTL5000_CHIP_ANA_STATUS
362 */
363#define SGTL5000_HP_LRSHORT 0x0200
364#define SGTL5000_CAPLESS_SHORT 0x0100
365#define SGTL5000_PLL_LOCKED 0x0010
366
367/*
368 * SGTL5000_CHIP_SHORT_CTRL
369 */
370#define SGTL5000_LVLADJR_MASK 0x7000
371#define SGTL5000_LVLADJR_SHIFT 12
372#define SGTL5000_LVLADJR_WIDTH 3
373#define SGTL5000_LVLADJL_MASK 0x0700
374#define SGTL5000_LVLADJL_SHIFT 8
375#define SGTL5000_LVLADJL_WIDTH 3
376#define SGTL5000_LVLADJC_MASK 0x0070
377#define SGTL5000_LVLADJC_SHIFT 4
378#define SGTL5000_LVLADJC_WIDTH 3
379#define SGTL5000_LR_SHORT_MOD_MASK 0x000c
380#define SGTL5000_LR_SHORT_MOD_SHIFT 2
381#define SGTL5000_LR_SHORT_MOD_WIDTH 2
382#define SGTL5000_CM_SHORT_MOD_MASK 0x0003
383#define SGTL5000_CM_SHORT_MOD_SHIFT 0
384#define SGTL5000_CM_SHORT_MOD_WIDTH 2
385
386/*
387 *SGTL5000_CHIP_ANA_TEST2
388 */
389#define SGTL5000_MONO_DAC 0x1000
390
391/*
392 * SGTL5000_DAP_CTRL
393 */
394#define SGTL5000_DAP_MIX_EN 0x0010
395#define SGTL5000_DAP_EN 0x0001
396
397#define SGTL5000_SYSCLK 0x00
398#define SGTL5000_LRCLK 0x01
399
400#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
new file mode 100644
index 000000000000..2a30eae1881c
--- /dev/null
+++ b/sound/soc/codecs/sn95031.c
@@ -0,0 +1,949 @@
1/*
2 * sn95031.c - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <asm/intel_scu_ipc.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37#include <sound/jack.h>
38#include "sn95031.h"
39
40#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
41#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
42
43/* adc helper functions */
44
45/* enables mic bias voltage */
46static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
47{
48 snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
49 snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
50}
51
52/* Enable/Disable the ADC depending on the argument */
53static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
54{
55 int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
56
57 if (val) {
58 /* Enable and start the ADC */
59 value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
60 value &= (~SN95031_ADC_NO_LOOP);
61 } else {
62 /* Just stop the ADC */
63 value &= (~SN95031_ADC_START);
64 }
65 snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
66}
67
68/*
69 * finds an empty channel for conversion
70 * If the ADC is not enabled then start using 0th channel
71 * itself. Otherwise find an empty channel by looking for a
72 * channel in which the stopbit is set to 1. returns the index
73 * of the first free channel if succeeds or an error code.
74 *
75 * Context: can sleep
76 *
77 */
78static int find_free_channel(struct snd_soc_codec *sn95031_codec)
79{
80 int ret = 0, i, value;
81
82 /* check whether ADC is enabled */
83 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
84
85 if ((value & SN95031_ADC_ENBL) == 0)
86 return 0;
87
88 /* ADC is already enabled; Looking for an empty channel */
89 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
90 value = snd_soc_read(sn95031_codec,
91 SN95031_ADC_CHNL_START_ADDR + i);
92 if (value & SN95031_STOPBIT_MASK) {
93 ret = i;
94 break;
95 }
96 }
97 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret;
98}
99
100/* Initialize the ADC for reading micbias values. Can sleep. */
101static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
102{
103 int base_addr, chnl_addr;
104 int value;
105 static int channel_index;
106
107 /* Index of the first channel in which the stop bit is set */
108 channel_index = find_free_channel(sn95031_codec);
109 if (channel_index < 0) {
110 pr_err("No free ADC channels");
111 return channel_index;
112 }
113
114 base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
115
116 if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
117 /* Reset stop bit for channels other than 0 and 12 */
118 value = snd_soc_read(sn95031_codec, base_addr);
119 /* Set the stop bit to zero */
120 snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
121 /* Index of the first free channel */
122 base_addr++;
123 channel_index++;
124 }
125
126 /* Since this is the last channel, set the stop bit
127 to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
128 snd_soc_write(sn95031_codec, base_addr,
129 SN95031_AUDIO_DETECT_CODE | 0x10);
130
131 chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
132 pr_debug("mid_initialize : %x", chnl_addr);
133 configure_adc(sn95031_codec, 1);
134 return chnl_addr;
135}
136
137
138/* reads the ADC registers and gets the mic bias value in mV. */
139static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
140{
141 u16 adc_adr = sn95031_initialize_adc(codec);
142 u16 adc_val1, adc_val2;
143 unsigned int mic_bias;
144
145 sn95031_enable_mic_bias(codec);
146
147 /* Enable the sound card for conversion before reading */
148 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
149 /* Re-toggle the RRDATARD bit */
150 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
151
152 /* Read the higher bits of data */
153 msleep(1000);
154 adc_val1 = snd_soc_read(codec, adc_adr);
155 adc_adr++;
156 adc_val2 = snd_soc_read(codec, adc_adr);
157
158 /* Adding lower two bits to the higher bits */
159 mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
160 mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
161 pr_debug("mic bias = %dmV\n", mic_bias);
162 return mic_bias;
163}
164EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
165/*end - adc helper functions */
166
167static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
168 unsigned int reg)
169{
170 u8 value = 0;
171 int ret;
172
173 ret = intel_scu_ipc_ioread8(reg, &value);
174 if (ret)
175 pr_err("read of %x failed, err %d\n", reg, ret);
176 return value;
177
178}
179
180static inline int sn95031_write(struct snd_soc_codec *codec,
181 unsigned int reg, unsigned int value)
182{
183 int ret;
184
185 ret = intel_scu_ipc_iowrite8(reg, value);
186 if (ret)
187 pr_err("write of %x failed, err %d\n", reg, ret);
188 return ret;
189}
190
191static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
192 enum snd_soc_bias_level level)
193{
194 switch (level) {
195 case SND_SOC_BIAS_ON:
196 break;
197
198 case SND_SOC_BIAS_PREPARE:
199 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
200 pr_debug("vaud_bias powering up pll\n");
201 /* power up the pll */
202 snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
203 /* enable pcm 2 */
204 snd_soc_update_bits(codec, SN95031_PCM2C2,
205 BIT(0), BIT(0));
206 }
207 break;
208
209 case SND_SOC_BIAS_STANDBY:
210 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
211 pr_debug("vaud_bias power up rail\n");
212 /* power up the rail */
213 snd_soc_write(codec, SN95031_VAUD,
214 BIT(2)|BIT(1)|BIT(0));
215 msleep(1);
216 } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
217 /* turn off pcm */
218 pr_debug("vaud_bias power dn pcm\n");
219 snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
220 snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
221 }
222 break;
223
224
225 case SND_SOC_BIAS_OFF:
226 pr_debug("vaud_bias _OFF doing rail shutdown\n");
227 snd_soc_write(codec, SN95031_VAUD, BIT(3));
228 break;
229 }
230
231 codec->dapm.bias_level = level;
232 return 0;
233}
234
235static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
236 struct snd_kcontrol *kcontrol, int event)
237{
238 if (SND_SOC_DAPM_EVENT_ON(event)) {
239 pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
240 /* power up the rail */
241 snd_soc_write(w->codec, SN95031_VHSP, 0x3D);
242 snd_soc_write(w->codec, SN95031_VHSN, 0x3F);
243 msleep(1);
244 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
245 pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
246 snd_soc_write(w->codec, SN95031_VHSP, 0xC4);
247 snd_soc_write(w->codec, SN95031_VHSN, 0x04);
248 }
249 return 0;
250}
251
252static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
253 struct snd_kcontrol *kcontrol, int event)
254{
255 if (SND_SOC_DAPM_EVENT_ON(event)) {
256 pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
257 /* power up the rail */
258 snd_soc_write(w->codec, SN95031_VIHF, 0x27);
259 msleep(1);
260 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
261 pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
262 snd_soc_write(w->codec, SN95031_VIHF, 0x24);
263 }
264 return 0;
265}
266
267static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
268 struct snd_kcontrol *k, int event)
269{
270 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
271
272 if (SND_SOC_DAPM_EVENT_ON(event)) {
273 ldo = BIT(5)|BIT(4);
274 clk_dir = BIT(0);
275 data_dir = BIT(7);
276 }
277 /* program DMIC LDO, clock and set clock */
278 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
279 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
280 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
281 return 0;
282}
283
284static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
285 struct snd_kcontrol *k, int event)
286{
287 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
288
289 if (SND_SOC_DAPM_EVENT_ON(event)) {
290 ldo = BIT(5)|BIT(4);
291 clk_dir = BIT(2);
292 data_dir = BIT(1);
293 }
294 /* program DMIC LDO, clock and set clock */
295 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
296 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
297 snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
298 return 0;
299}
300
301static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
302 struct snd_kcontrol *k, int event)
303{
304 unsigned int ldo = 0;
305
306 if (SND_SOC_DAPM_EVENT_ON(event))
307 ldo = BIT(7)|BIT(6);
308
309 /* program DMIC LDO */
310 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
311 return 0;
312}
313
314/* mux controls */
315static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
316
317static const struct soc_enum sn95031_micl_enum =
318 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts);
319
320static const struct snd_kcontrol_new sn95031_micl_mux_control =
321 SOC_DAPM_ENUM("Route", sn95031_micl_enum);
322
323static const struct soc_enum sn95031_micr_enum =
324 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts);
325
326static const struct snd_kcontrol_new sn95031_micr_mux_control =
327 SOC_DAPM_ENUM("Route", sn95031_micr_enum);
328
329static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
330 "DMIC4", "DMIC5", "DMIC6",
331 "ADC Left", "ADC Right" };
332
333static const struct soc_enum sn95031_input1_enum =
334 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts);
335
336static const struct snd_kcontrol_new sn95031_input1_mux_control =
337 SOC_DAPM_ENUM("Route", sn95031_input1_enum);
338
339static const struct soc_enum sn95031_input2_enum =
340 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts);
341
342static const struct snd_kcontrol_new sn95031_input2_mux_control =
343 SOC_DAPM_ENUM("Route", sn95031_input2_enum);
344
345static const struct soc_enum sn95031_input3_enum =
346 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts);
347
348static const struct snd_kcontrol_new sn95031_input3_mux_control =
349 SOC_DAPM_ENUM("Route", sn95031_input3_enum);
350
351static const struct soc_enum sn95031_input4_enum =
352 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts);
353
354static const struct snd_kcontrol_new sn95031_input4_mux_control =
355 SOC_DAPM_ENUM("Route", sn95031_input4_enum);
356
357/* capture path controls */
358
359static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
360
361/* 0dB to 30dB in 10dB steps */
362static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
363
364static const struct soc_enum sn95031_micmode1_enum =
365 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
366static const struct soc_enum sn95031_micmode2_enum =
367 SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text);
368
369static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
370
371static const struct soc_enum sn95031_dmic12_cfg_enum =
372 SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text);
373static const struct soc_enum sn95031_dmic34_cfg_enum =
374 SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text);
375static const struct soc_enum sn95031_dmic56_cfg_enum =
376 SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text);
377
378static const struct snd_kcontrol_new sn95031_snd_controls[] = {
379 SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
380 SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
381 SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
382 SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
383 SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
384 SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
385 2, 4, 0, mic_tlv),
386 SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
387 2, 4, 0, mic_tlv),
388};
389
390/* DAPM widgets */
391static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
392
393 /* all end points mic, hs etc */
394 SND_SOC_DAPM_OUTPUT("HPOUTL"),
395 SND_SOC_DAPM_OUTPUT("HPOUTR"),
396 SND_SOC_DAPM_OUTPUT("EPOUT"),
397 SND_SOC_DAPM_OUTPUT("IHFOUTL"),
398 SND_SOC_DAPM_OUTPUT("IHFOUTR"),
399 SND_SOC_DAPM_OUTPUT("LINEOUTL"),
400 SND_SOC_DAPM_OUTPUT("LINEOUTR"),
401 SND_SOC_DAPM_OUTPUT("VIB1OUT"),
402 SND_SOC_DAPM_OUTPUT("VIB2OUT"),
403
404 SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
405 SND_SOC_DAPM_INPUT("AMIC2"),
406 SND_SOC_DAPM_INPUT("DMIC1"),
407 SND_SOC_DAPM_INPUT("DMIC2"),
408 SND_SOC_DAPM_INPUT("DMIC3"),
409 SND_SOC_DAPM_INPUT("DMIC4"),
410 SND_SOC_DAPM_INPUT("DMIC5"),
411 SND_SOC_DAPM_INPUT("DMIC6"),
412 SND_SOC_DAPM_INPUT("LINEINL"),
413 SND_SOC_DAPM_INPUT("LINEINR"),
414
415 SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
416 SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
417 SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
418 SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
419 SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
420
421 SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
422 sn95031_dmic12_event,
423 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
424 SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
425 sn95031_dmic34_event,
426 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
427 SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
428 sn95031_dmic56_event,
429 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
430
431 SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
432 SND_SOC_NOPM, 0, 0),
433
434 SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
435 sn95031_vhs_event,
436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
437 SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
438 sn95031_vihf_event,
439 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
440
441 /* playback path driver enables */
442 SND_SOC_DAPM_PGA("Headset Left Playback",
443 SN95031_DRIVEREN, 0, 0, NULL, 0),
444 SND_SOC_DAPM_PGA("Headset Right Playback",
445 SN95031_DRIVEREN, 1, 0, NULL, 0),
446 SND_SOC_DAPM_PGA("Speaker Left Playback",
447 SN95031_DRIVEREN, 2, 0, NULL, 0),
448 SND_SOC_DAPM_PGA("Speaker Right Playback",
449 SN95031_DRIVEREN, 3, 0, NULL, 0),
450 SND_SOC_DAPM_PGA("Vibra1 Playback",
451 SN95031_DRIVEREN, 4, 0, NULL, 0),
452 SND_SOC_DAPM_PGA("Vibra2 Playback",
453 SN95031_DRIVEREN, 5, 0, NULL, 0),
454 SND_SOC_DAPM_PGA("Earpiece Playback",
455 SN95031_DRIVEREN, 6, 0, NULL, 0),
456 SND_SOC_DAPM_PGA("Lineout Left Playback",
457 SN95031_LOCTL, 0, 0, NULL, 0),
458 SND_SOC_DAPM_PGA("Lineout Right Playback",
459 SN95031_LOCTL, 4, 0, NULL, 0),
460
461 /* playback path filter enable */
462 SND_SOC_DAPM_PGA("Headset Left Filter",
463 SN95031_HSEPRXCTRL, 4, 0, NULL, 0),
464 SND_SOC_DAPM_PGA("Headset Right Filter",
465 SN95031_HSEPRXCTRL, 5, 0, NULL, 0),
466 SND_SOC_DAPM_PGA("Speaker Left Filter",
467 SN95031_IHFRXCTRL, 0, 0, NULL, 0),
468 SND_SOC_DAPM_PGA("Speaker Right Filter",
469 SN95031_IHFRXCTRL, 1, 0, NULL, 0),
470
471 /* DACs */
472 SND_SOC_DAPM_DAC("HSDAC Left", "Headset",
473 SN95031_DACCONFIG, 0, 0),
474 SND_SOC_DAPM_DAC("HSDAC Right", "Headset",
475 SN95031_DACCONFIG, 1, 0),
476 SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
477 SN95031_DACCONFIG, 2, 0),
478 SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
479 SN95031_DACCONFIG, 3, 0),
480 SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
481 SN95031_VIB1C5, 1, 0),
482 SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
483 SN95031_VIB2C5, 1, 0),
484
485 /* capture widgets */
486 SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
487 7, 0, NULL, 0),
488 SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
489 7, 0, NULL, 0),
490
491 SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
492 SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
493 SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
494 SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
495 SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
496 SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
497
498 /* ADC have null stream as they will be turned ON by TX path */
499 SND_SOC_DAPM_ADC("ADC Left", NULL,
500 SN95031_ADCCONFIG, 0, 0),
501 SND_SOC_DAPM_ADC("ADC Right", NULL,
502 SN95031_ADCCONFIG, 2, 0),
503
504 SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
505 SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
506 SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
507 SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
508
509 SND_SOC_DAPM_MUX("Txpath1 Capture Route",
510 SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
511 SND_SOC_DAPM_MUX("Txpath2 Capture Route",
512 SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
513 SND_SOC_DAPM_MUX("Txpath3 Capture Route",
514 SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
515 SND_SOC_DAPM_MUX("Txpath4 Capture Route",
516 SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
517
518};
519
520static const struct snd_soc_dapm_route sn95031_audio_map[] = {
521 /* headset and earpiece map */
522 { "HPOUTL", NULL, "Headset Rail"},
523 { "HPOUTR", NULL, "Headset Rail"},
524 { "HPOUTL", NULL, "Headset Left Playback" },
525 { "HPOUTR", NULL, "Headset Right Playback" },
526 { "EPOUT", NULL, "Earpiece Playback" },
527 { "Headset Left Playback", NULL, "Headset Left Filter"},
528 { "Headset Right Playback", NULL, "Headset Right Filter"},
529 { "Earpiece Playback", NULL, "Headset Left Filter"},
530 { "Headset Left Filter", NULL, "HSDAC Left"},
531 { "Headset Right Filter", NULL, "HSDAC Right"},
532
533 /* speaker map */
534 { "IHFOUTL", NULL, "Speaker Rail"},
535 { "IHFOUTR", NULL, "Speaker Rail"},
536 { "IHFOUTL", "NULL", "Speaker Left Playback"},
537 { "IHFOUTR", "NULL", "Speaker Right Playback"},
538 { "Speaker Left Playback", NULL, "Speaker Left Filter"},
539 { "Speaker Right Playback", NULL, "Speaker Right Filter"},
540 { "Speaker Left Filter", NULL, "IHFDAC Left"},
541 { "Speaker Right Filter", NULL, "IHFDAC Right"},
542
543 /* vibra map */
544 { "VIB1OUT", NULL, "Vibra1 Playback"},
545 { "Vibra1 Playback", NULL, "Vibra1 DAC"},
546
547 { "VIB2OUT", NULL, "Vibra2 Playback"},
548 { "Vibra2 Playback", NULL, "Vibra2 DAC"},
549
550 /* lineout */
551 { "LINEOUTL", NULL, "Lineout Left Playback"},
552 { "LINEOUTR", NULL, "Lineout Right Playback"},
553 { "Lineout Left Playback", NULL, "Headset Left Filter"},
554 { "Lineout Left Playback", NULL, "Speaker Left Filter"},
555 { "Lineout Left Playback", NULL, "Vibra1 DAC"},
556 { "Lineout Right Playback", NULL, "Headset Right Filter"},
557 { "Lineout Right Playback", NULL, "Speaker Right Filter"},
558 { "Lineout Right Playback", NULL, "Vibra2 DAC"},
559
560 /* Headset (AMIC1) mic */
561 { "AMIC1Bias", NULL, "AMIC1"},
562 { "MIC1 Enable", NULL, "AMIC1Bias"},
563 { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
564
565 /* AMIC2 */
566 { "AMIC2Bias", NULL, "AMIC2"},
567 { "MIC2 Enable", NULL, "AMIC2Bias"},
568 { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
569
570
571 /* Linein */
572 { "LineIn Enable Left", NULL, "LINEINL"},
573 { "LineIn Enable Right", NULL, "LINEINR"},
574 { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
575 { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
576
577 /* ADC connection */
578 { "ADC Left", NULL, "Mic_InputL Capture Route"},
579 { "ADC Right", NULL, "Mic_InputR Capture Route"},
580
581 /*DMIC connections */
582 { "DMIC1", NULL, "DMIC12supply"},
583 { "DMIC2", NULL, "DMIC12supply"},
584 { "DMIC3", NULL, "DMIC34supply"},
585 { "DMIC4", NULL, "DMIC34supply"},
586 { "DMIC5", NULL, "DMIC56supply"},
587 { "DMIC6", NULL, "DMIC56supply"},
588
589 { "DMIC12Bias", NULL, "DMIC1"},
590 { "DMIC12Bias", NULL, "DMIC2"},
591 { "DMIC34Bias", NULL, "DMIC3"},
592 { "DMIC34Bias", NULL, "DMIC4"},
593 { "DMIC56Bias", NULL, "DMIC5"},
594 { "DMIC56Bias", NULL, "DMIC6"},
595
596 /*TX path inputs*/
597 { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
598 { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
599 { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
600 { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
601 { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
602 { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
603 { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
604 { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
605 { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
606 { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
607 { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
608 { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
609 { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
610 { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
611 { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
612 { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
613 { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
614 { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
615 { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
616 { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
617 { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
618 { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
619 { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
620 { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
621 { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
622 { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
623 { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
624 { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
625 { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
626 { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
627 { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
628 { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
629
630 /* tx path */
631 { "TX1 Enable", NULL, "Txpath1 Capture Route"},
632 { "TX2 Enable", NULL, "Txpath2 Capture Route"},
633 { "TX3 Enable", NULL, "Txpath3 Capture Route"},
634 { "TX4 Enable", NULL, "Txpath4 Capture Route"},
635 { "PCM_Out", NULL, "TX1 Enable"},
636 { "PCM_Out", NULL, "TX2 Enable"},
637 { "PCM_Out", NULL, "TX3 Enable"},
638 { "PCM_Out", NULL, "TX4 Enable"},
639
640};
641
642/* speaker and headset mutes, for audio pops and clicks */
643static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
644{
645 snd_soc_update_bits(dai->codec,
646 SN95031_HSLVOLCTRL, BIT(7), (!mute << 7));
647 snd_soc_update_bits(dai->codec,
648 SN95031_HSRVOLCTRL, BIT(7), (!mute << 7));
649 return 0;
650}
651
652static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
653{
654 snd_soc_update_bits(dai->codec,
655 SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7));
656 snd_soc_update_bits(dai->codec,
657 SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7));
658 return 0;
659}
660
661int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
662 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
663{
664 unsigned int format, rate;
665
666 switch (params_format(params)) {
667 case SNDRV_PCM_FORMAT_S16_LE:
668 format = BIT(4)|BIT(5);
669 break;
670
671 case SNDRV_PCM_FORMAT_S24_LE:
672 format = 0;
673 break;
674 default:
675 return -EINVAL;
676 }
677 snd_soc_update_bits(dai->codec, SN95031_PCM2C2,
678 BIT(4)|BIT(5), format);
679
680 switch (params_rate(params)) {
681 case 48000:
682 pr_debug("RATE_48000\n");
683 rate = 0;
684 break;
685
686 case 44100:
687 pr_debug("RATE_44100\n");
688 rate = BIT(7);
689 break;
690
691 default:
692 pr_err("ERR rate %d\n", params_rate(params));
693 return -EINVAL;
694 }
695 snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate);
696
697 return 0;
698}
699
700/* Codec DAI section */
701static struct snd_soc_dai_ops sn95031_headset_dai_ops = {
702 .digital_mute = sn95031_pcm_hs_mute,
703 .hw_params = sn95031_pcm_hw_params,
704};
705
706static struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
707 .digital_mute = sn95031_pcm_spkr_mute,
708 .hw_params = sn95031_pcm_hw_params,
709};
710
711static struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
712 .hw_params = sn95031_pcm_hw_params,
713};
714
715static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
716 .hw_params = sn95031_pcm_hw_params,
717};
718
719struct snd_soc_dai_driver sn95031_dais[] = {
720{
721 .name = "SN95031 Headset",
722 .playback = {
723 .stream_name = "Headset",
724 .channels_min = 2,
725 .channels_max = 2,
726 .rates = SN95031_RATES,
727 .formats = SN95031_FORMATS,
728 },
729 .capture = {
730 .stream_name = "Capture",
731 .channels_min = 1,
732 .channels_max = 5,
733 .rates = SN95031_RATES,
734 .formats = SN95031_FORMATS,
735 },
736 .ops = &sn95031_headset_dai_ops,
737},
738{ .name = "SN95031 Speaker",
739 .playback = {
740 .stream_name = "Speaker",
741 .channels_min = 2,
742 .channels_max = 2,
743 .rates = SN95031_RATES,
744 .formats = SN95031_FORMATS,
745 },
746 .ops = &sn95031_speaker_dai_ops,
747},
748{ .name = "SN95031 Vibra1",
749 .playback = {
750 .stream_name = "Vibra1",
751 .channels_min = 1,
752 .channels_max = 1,
753 .rates = SN95031_RATES,
754 .formats = SN95031_FORMATS,
755 },
756 .ops = &sn95031_vib1_dai_ops,
757},
758{ .name = "SN95031 Vibra2",
759 .playback = {
760 .stream_name = "Vibra2",
761 .channels_min = 1,
762 .channels_max = 1,
763 .rates = SN95031_RATES,
764 .formats = SN95031_FORMATS,
765 },
766 .ops = &sn95031_vib2_dai_ops,
767},
768};
769
770static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
771{
772 snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
773}
774
775static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
776{
777 snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
778 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
779}
780
781static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
782{
783 int micbias = sn95031_get_mic_bias(mfld_jack->codec);
784
785 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
786
787 pr_debug("jack type detected = %d\n", jack_type);
788 if (jack_type == SND_JACK_HEADSET)
789 sn95031_enable_jack_btn(mfld_jack->codec);
790 return jack_type;
791}
792
793void sn95031_jack_detection(struct mfld_jack_data *jack_data)
794{
795 unsigned int status;
796 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
797
798 pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
799 if (jack_data->intr_id & 0x1) {
800 pr_debug("short_push detected\n");
801 status = SND_JACK_HEADSET | SND_JACK_BTN_0;
802 } else if (jack_data->intr_id & 0x2) {
803 pr_debug("long_push detected\n");
804 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
805 } else if (jack_data->intr_id & 0x4) {
806 pr_debug("headset or headphones inserted\n");
807 status = sn95031_get_headset_state(jack_data->mfld_jack);
808 } else if (jack_data->intr_id & 0x8) {
809 pr_debug("headset or headphones removed\n");
810 status = 0;
811 sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
812 } else {
813 pr_err("unidentified interrupt\n");
814 return;
815 }
816
817 snd_soc_jack_report(jack_data->mfld_jack, status, mask);
818 /*button pressed and released so we send explicit button release */
819 if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
820 snd_soc_jack_report(jack_data->mfld_jack,
821 SND_JACK_HEADSET, mask);
822}
823EXPORT_SYMBOL_GPL(sn95031_jack_detection);
824
825/* codec registration */
826static int sn95031_codec_probe(struct snd_soc_codec *codec)
827{
828 int ret;
829
830 pr_debug("codec_probe called\n");
831
832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
833 codec->dapm.idle_bias_off = 1;
834
835 /* PCM interface config
836 * This sets the pcm rx slot conguration to max 6 slots
837 * for max 4 dais (2 stereo and 2 mono)
838 */
839 snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
840 snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
841 snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
842 snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
843 snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
844 /* pcm port setting
845 * This sets the pcm port to slave and clock at 19.2Mhz which
846 * can support 6slots, sampling rate set per stream in hw-params
847 */
848 snd_soc_write(codec, SN95031_PCM1C1, 0x00);
849 snd_soc_write(codec, SN95031_PCM2C1, 0x01);
850 snd_soc_write(codec, SN95031_PCM2C2, 0x0A);
851 snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4));
852 /* vendor vibra workround, the vibras are muted by
853 * custom register so unmute them
854 */
855 snd_soc_write(codec, SN95031_SSR5, 0x80);
856 snd_soc_write(codec, SN95031_SSR6, 0x80);
857 snd_soc_write(codec, SN95031_VIB1C5, 0x00);
858 snd_soc_write(codec, SN95031_VIB2C5, 0x00);
859 /* configure vibras for pcm port */
860 snd_soc_write(codec, SN95031_VIB1C3, 0x00);
861 snd_soc_write(codec, SN95031_VIB2C3, 0x00);
862
863 /* soft mute ramp time */
864 snd_soc_write(codec, SN95031_SOFTMUTE, 0x3);
865 /* fix the initial volume at 1dB,
866 * default in +9dB,
867 * 1dB give optimal swing on DAC, amps
868 */
869 snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08);
870 snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08);
871 snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08);
872 snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08);
873 /* dac mode and lineout workaround */
874 snd_soc_write(codec, SN95031_SSR2, 0x10);
875 snd_soc_write(codec, SN95031_SSR3, 0x40);
876
877 snd_soc_add_controls(codec, sn95031_snd_controls,
878 ARRAY_SIZE(sn95031_snd_controls));
879
880 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets,
881 ARRAY_SIZE(sn95031_dapm_widgets));
882 if (ret)
883 pr_err("soc_dapm_new_control failed %d", ret);
884 ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map,
885 ARRAY_SIZE(sn95031_audio_map));
886 if (ret)
887 pr_err("soc_dapm_add_routes failed %d", ret);
888
889 return ret;
890}
891
892static int sn95031_codec_remove(struct snd_soc_codec *codec)
893{
894 pr_debug("codec_remove called\n");
895 sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF);
896
897 return 0;
898}
899
900struct snd_soc_codec_driver sn95031_codec = {
901 .probe = sn95031_codec_probe,
902 .remove = sn95031_codec_remove,
903 .read = sn95031_read,
904 .write = sn95031_write,
905 .set_bias_level = sn95031_set_vaud_bias,
906};
907
908static int __devinit sn95031_device_probe(struct platform_device *pdev)
909{
910 pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
911 return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
912 sn95031_dais, ARRAY_SIZE(sn95031_dais));
913}
914
915static int __devexit sn95031_device_remove(struct platform_device *pdev)
916{
917 pr_debug("codec device remove called\n");
918 snd_soc_unregister_codec(&pdev->dev);
919 return 0;
920}
921
922static struct platform_driver sn95031_codec_driver = {
923 .driver = {
924 .name = "sn95031",
925 .owner = THIS_MODULE,
926 },
927 .probe = sn95031_device_probe,
928 .remove = sn95031_device_remove,
929};
930
931static int __init sn95031_init(void)
932{
933 pr_debug("driver init called\n");
934 return platform_driver_register(&sn95031_codec_driver);
935}
936module_init(sn95031_init);
937
938static void __exit sn95031_exit(void)
939{
940 pr_debug("driver exit called\n");
941 platform_driver_unregister(&sn95031_codec_driver);
942}
943module_exit(sn95031_exit);
944
945MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
946MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
947MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
948MODULE_LICENSE("GPL v2");
949MODULE_ALIAS("platform:sn95031");
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
new file mode 100644
index 000000000000..20376d234fb8
--- /dev/null
+++ b/sound/soc/codecs/sn95031.h
@@ -0,0 +1,132 @@
1/*
2 * sn95031.h - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#ifndef _SN95031_H
27#define _SN95031_H
28
29/*register map*/
30#define SN95031_VAUD 0xDB
31#define SN95031_VHSP 0xDC
32#define SN95031_VHSN 0xDD
33#define SN95031_VIHF 0xC9
34
35#define SN95031_AUDPLLCTRL 0x240
36#define SN95031_DMICBUF0123 0x241
37#define SN95031_DMICBUF45 0x242
38#define SN95031_DMICGPO 0x244
39#define SN95031_DMICMUX 0x245
40#define SN95031_DMICLK 0x246
41#define SN95031_MICBIAS 0x247
42#define SN95031_ADCCONFIG 0x248
43#define SN95031_MICAMP1 0x249
44#define SN95031_MICAMP2 0x24A
45#define SN95031_NOISEMUX 0x24B
46#define SN95031_AUDIOMUX12 0x24C
47#define SN95031_AUDIOMUX34 0x24D
48#define SN95031_AUDIOSINC 0x24E
49#define SN95031_AUDIOTXEN 0x24F
50#define SN95031_HSEPRXCTRL 0x250
51#define SN95031_IHFRXCTRL 0x251
52#define SN95031_HSMIXER 0x256
53#define SN95031_DACCONFIG 0x257
54#define SN95031_SOFTMUTE 0x258
55#define SN95031_HSLVOLCTRL 0x259
56#define SN95031_HSRVOLCTRL 0x25A
57#define SN95031_IHFLVOLCTRL 0x25B
58#define SN95031_IHFRVOLCTRL 0x25C
59#define SN95031_DRIVEREN 0x25D
60#define SN95031_LOCTL 0x25E
61#define SN95031_VIB1C1 0x25F
62#define SN95031_VIB1C2 0x260
63#define SN95031_VIB1C3 0x261
64#define SN95031_VIB1SPIPCM1 0x262
65#define SN95031_VIB1SPIPCM2 0x263
66#define SN95031_VIB1C5 0x264
67#define SN95031_VIB2C1 0x265
68#define SN95031_VIB2C2 0x266
69#define SN95031_VIB2C3 0x267
70#define SN95031_VIB2SPIPCM1 0x268
71#define SN95031_VIB2SPIPCM2 0x269
72#define SN95031_VIB2C5 0x26A
73#define SN95031_BTNCTRL1 0x26B
74#define SN95031_BTNCTRL2 0x26C
75#define SN95031_PCM1TXSLOT01 0x26D
76#define SN95031_PCM1TXSLOT23 0x26E
77#define SN95031_PCM1TXSLOT45 0x26F
78#define SN95031_PCM1RXSLOT0_3 0x270
79#define SN95031_PCM1RXSLOT45 0x271
80#define SN95031_PCM2TXSLOT01 0x272
81#define SN95031_PCM2TXSLOT23 0x273
82#define SN95031_PCM2TXSLOT45 0x274
83#define SN95031_PCM2RXSLOT01 0x275
84#define SN95031_PCM2RXSLOT23 0x276
85#define SN95031_PCM2RXSLOT45 0x277
86#define SN95031_PCM1C1 0x278
87#define SN95031_PCM1C2 0x279
88#define SN95031_PCM1C3 0x27A
89#define SN95031_PCM2C1 0x27B
90#define SN95031_PCM2C2 0x27C
91/*end codec register defn*/
92
93/*vendor defn these are not part of avp*/
94#define SN95031_SSR2 0x381
95#define SN95031_SSR3 0x382
96#define SN95031_SSR5 0x384
97#define SN95031_SSR6 0x385
98
99/* ADC registers */
100
101#define SN95031_ADC1CNTL1 0x1C0
102#define SN95031_ADC_ENBL 0x10
103#define SN95031_ADC_START 0x08
104#define SN95031_ADC1CNTL3 0x1C2
105#define SN95031_ADCTHERM_ENBL 0x04
106#define SN95031_ADCRRDATA_ENBL 0x05
107#define SN95031_STOPBIT_MASK 16
108#define SN95031_ADCTHERM_MASK 4
109#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
110#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
111#define SN95031_ADC_NO_LOOP 0x07
112#define SN95031_AUDIO_GPIO_CTRL 0x070
113
114/* ADC channel code values */
115#define SN95031_AUDIO_DETECT_CODE 0x06
116
117/* ADC base addresses */
118#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
119#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
120/* multipier to convert to mV */
121#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
122
123
124struct mfld_jack_data {
125 int intr_id;
126 int micbias_vol;
127 struct snd_soc_jack *mfld_jack;
128};
129
130extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
131
132#endif
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
new file mode 100644
index 000000000000..e93b9d1ae1dd
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -0,0 +1,794 @@
1/*
2 * linux/sound/soc/codecs/tlv320aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/cdev.h>
34#include <linux/slab.h>
35
36#include <sound/tlv320aic32x4.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h>
43#include <sound/tlv.h>
44
45#include "tlv320aic32x4.h"
46
47struct aic32x4_rate_divs {
48 u32 mclk;
49 u32 rate;
50 u8 p_val;
51 u8 pll_j;
52 u16 pll_d;
53 u16 dosr;
54 u8 ndac;
55 u8 mdac;
56 u8 aosr;
57 u8 nadc;
58 u8 madc;
59 u8 blck_N;
60};
61
62struct aic32x4_priv {
63 u32 sysclk;
64 s32 master;
65 u8 page_no;
66 void *control_data;
67 u32 power_cfg;
68 u32 micpga_routing;
69 bool swapdacs;
70};
71
72/* 0dB min, 1dB steps */
73static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
74/* 0dB min, 0.5dB steps */
75static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
76
77static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
78 SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
79 AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5),
80 SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
81 AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1),
82 SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
83 AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1),
84 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
85 AIC32X4_HPRGAIN, 6, 0x01, 1),
86 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
87 AIC32X4_LORGAIN, 6, 0x01, 1),
88 SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
89 AIC32X4_RMICPGAVOL, 7, 0x01, 1),
90
91 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
92 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
93
94 SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL,
95 AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5),
96 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
97 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
98
99 SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
100
101 SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
102 SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
103 SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
104 4, 0x07, 0),
105 SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
106 0, 0x03, 0),
107 SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
108 6, 0x03, 0),
109 SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
110 1, 0x1F, 0),
111 SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
112 0, 0x7F, 0),
113 SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
114 3, 0x1F, 0),
115 SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
116 3, 0x1F, 0),
117 SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
118 0, 0x1F, 0),
119 SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
120 0, 0x0F, 0),
121};
122
123static const struct aic32x4_rate_divs aic32x4_divs[] = {
124 /* 8k rate */
125 {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
126 {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
127 {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
128 /* 11.025k rate */
129 {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
130 {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
131 /* 16k rate */
132 {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
133 {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
134 {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
135 /* 22.05k rate */
136 {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
137 {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
138 {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
139 /* 32k rate */
140 {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
141 {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
142 /* 44.1k rate */
143 {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
144 {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
145 {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
146 /* 48k rate */
147 {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
148 {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
149 {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
150};
151
152static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
153 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
154 SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
155};
156
157static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
158 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
159 SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
160};
161
162static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
163 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
164};
165
166static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
167 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
168};
169
170static const struct snd_kcontrol_new left_input_mixer_controls[] = {
171 SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
172 SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
173 SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
174};
175
176static const struct snd_kcontrol_new right_input_mixer_controls[] = {
177 SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
178 SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
179 SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
180};
181
182static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
183 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
184 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
185 &hpl_output_mixer_controls[0],
186 ARRAY_SIZE(hpl_output_mixer_controls)),
187 SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
188
189 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
190 &lol_output_mixer_controls[0],
191 ARRAY_SIZE(lol_output_mixer_controls)),
192 SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
193
194 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
195 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
196 &hpr_output_mixer_controls[0],
197 ARRAY_SIZE(hpr_output_mixer_controls)),
198 SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
199 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
200 &lor_output_mixer_controls[0],
201 ARRAY_SIZE(lor_output_mixer_controls)),
202 SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
203 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
204 &left_input_mixer_controls[0],
205 ARRAY_SIZE(left_input_mixer_controls)),
206 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
207 &right_input_mixer_controls[0],
208 ARRAY_SIZE(right_input_mixer_controls)),
209 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
210 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
211 SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
212
213 SND_SOC_DAPM_OUTPUT("HPL"),
214 SND_SOC_DAPM_OUTPUT("HPR"),
215 SND_SOC_DAPM_OUTPUT("LOL"),
216 SND_SOC_DAPM_OUTPUT("LOR"),
217 SND_SOC_DAPM_INPUT("IN1_L"),
218 SND_SOC_DAPM_INPUT("IN1_R"),
219 SND_SOC_DAPM_INPUT("IN2_L"),
220 SND_SOC_DAPM_INPUT("IN2_R"),
221 SND_SOC_DAPM_INPUT("IN3_L"),
222 SND_SOC_DAPM_INPUT("IN3_R"),
223};
224
225static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
226 /* Left Output */
227 {"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
228 {"HPL Output Mixer", "IN1_L Switch", "IN1_L"},
229
230 {"HPL Power", NULL, "HPL Output Mixer"},
231 {"HPL", NULL, "HPL Power"},
232
233 {"LOL Output Mixer", "L_DAC Switch", "Left DAC"},
234
235 {"LOL Power", NULL, "LOL Output Mixer"},
236 {"LOL", NULL, "LOL Power"},
237
238 /* Right Output */
239 {"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
240 {"HPR Output Mixer", "IN1_R Switch", "IN1_R"},
241
242 {"HPR Power", NULL, "HPR Output Mixer"},
243 {"HPR", NULL, "HPR Power"},
244
245 {"LOR Output Mixer", "R_DAC Switch", "Right DAC"},
246
247 {"LOR Power", NULL, "LOR Output Mixer"},
248 {"LOR", NULL, "LOR Power"},
249
250 /* Left input */
251 {"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
252 {"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
253 {"Left Input Mixer", "IN3_L P Switch", "IN3_L"},
254
255 {"Left ADC", NULL, "Left Input Mixer"},
256
257 /* Right Input */
258 {"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
259 {"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
260 {"Right Input Mixer", "IN3_R P Switch", "IN3_R"},
261
262 {"Right ADC", NULL, "Right Input Mixer"},
263};
264
265static inline int aic32x4_change_page(struct snd_soc_codec *codec,
266 unsigned int new_page)
267{
268 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
269 u8 data[2];
270 int ret;
271
272 data[0] = 0x00;
273 data[1] = new_page & 0xff;
274
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret == 2) {
277 aic32x4->page_no = new_page;
278 return 0;
279 } else {
280 return ret;
281 }
282}
283
284static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
285 unsigned int val)
286{
287 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
288 unsigned int page = reg / 128;
289 unsigned int fixed_reg = reg % 128;
290 u8 data[2];
291 int ret;
292
293 /* A write to AIC32X4_PSEL is really a non-explicit page change */
294 if (reg == AIC32X4_PSEL)
295 return aic32x4_change_page(codec, val);
296
297 if (aic32x4->page_no != page) {
298 ret = aic32x4_change_page(codec, page);
299 if (ret != 0)
300 return ret;
301 }
302
303 data[0] = fixed_reg & 0xff;
304 data[1] = val & 0xff;
305
306 if (codec->hw_write(codec->control_data, data, 2) == 2)
307 return 0;
308 else
309 return -EIO;
310}
311
312static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
313{
314 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
315 unsigned int page = reg / 128;
316 unsigned int fixed_reg = reg % 128;
317 int ret;
318
319 if (aic32x4->page_no != page) {
320 ret = aic32x4_change_page(codec, page);
321 if (ret != 0)
322 return ret;
323 }
324 return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
325}
326
327static inline int aic32x4_get_divs(int mclk, int rate)
328{
329 int i;
330
331 for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
332 if ((aic32x4_divs[i].rate == rate)
333 && (aic32x4_divs[i].mclk == mclk)) {
334 return i;
335 }
336 }
337 printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
338 return -EINVAL;
339}
340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir)
355{
356 struct snd_soc_codec *codec = codec_dai->codec;
357 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
358
359 switch (freq) {
360 case AIC32X4_FREQ_12000000:
361 case AIC32X4_FREQ_24000000:
362 case AIC32X4_FREQ_25000000:
363 aic32x4->sysclk = freq;
364 return 0;
365 }
366 printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
367 return -EINVAL;
368}
369
370static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
371{
372 struct snd_soc_codec *codec = codec_dai->codec;
373 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
374 u8 iface_reg_1;
375 u8 iface_reg_2;
376 u8 iface_reg_3;
377
378 iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
379 iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
380 iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
381 iface_reg_2 = 0;
382 iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
383 iface_reg_3 = iface_reg_3 & ~(1 << 3);
384
385 /* set master/slave audio interface */
386 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
387 case SND_SOC_DAIFMT_CBM_CFM:
388 aic32x4->master = 1;
389 iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 aic32x4->master = 0;
393 break;
394 default:
395 printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
396 return -EINVAL;
397 }
398
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 break;
402 case SND_SOC_DAIFMT_DSP_A:
403 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
404 iface_reg_3 |= (1 << 3); /* invert bit clock */
405 iface_reg_2 = 0x01; /* add offset 1 */
406 break;
407 case SND_SOC_DAIFMT_DSP_B:
408 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
409 iface_reg_3 |= (1 << 3); /* invert bit clock */
410 break;
411 case SND_SOC_DAIFMT_RIGHT_J:
412 iface_reg_1 |=
413 (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
414 break;
415 case SND_SOC_DAIFMT_LEFT_J:
416 iface_reg_1 |=
417 (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
418 break;
419 default:
420 printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
421 return -EINVAL;
422 }
423
424 snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
425 snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
426 snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
427 return 0;
428}
429
430static int aic32x4_hw_params(struct snd_pcm_substream *substream,
431 struct snd_pcm_hw_params *params,
432 struct snd_soc_dai *dai)
433{
434 struct snd_soc_codec *codec = dai->codec;
435 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
436 u8 data;
437 int i;
438
439 i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
440 if (i < 0) {
441 printk(KERN_ERR "aic32x4: sampling rate not supported\n");
442 return i;
443 }
444
445 /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
446 snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
447 snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
448
449 /* We will fix R value to 1 and will make P & J=K.D as varialble */
450 data = snd_soc_read(codec, AIC32X4_PLLPR);
451 data &= ~(7 << 4);
452 snd_soc_write(codec, AIC32X4_PLLPR,
453 (data | (aic32x4_divs[i].p_val << 4) | 0x01));
454
455 snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
456
457 snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
458 snd_soc_write(codec, AIC32X4_PLLDLSB,
459 (aic32x4_divs[i].pll_d & 0xff));
460
461 /* NDAC divider value */
462 data = snd_soc_read(codec, AIC32X4_NDAC);
463 data &= ~(0x7f);
464 snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
465
466 /* MDAC divider value */
467 data = snd_soc_read(codec, AIC32X4_MDAC);
468 data &= ~(0x7f);
469 snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
470
471 /* DOSR MSB & LSB values */
472 snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
473 snd_soc_write(codec, AIC32X4_DOSRLSB,
474 (aic32x4_divs[i].dosr & 0xff));
475
476 /* NADC divider value */
477 data = snd_soc_read(codec, AIC32X4_NADC);
478 data &= ~(0x7f);
479 snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
480
481 /* MADC divider value */
482 data = snd_soc_read(codec, AIC32X4_MADC);
483 data &= ~(0x7f);
484 snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
485
486 /* AOSR value */
487 snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
488
489 /* BCLK N divider */
490 data = snd_soc_read(codec, AIC32X4_BCLKN);
491 data &= ~(0x7f);
492 snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
493
494 data = snd_soc_read(codec, AIC32X4_IFACE1);
495 data = data & ~(3 << 4);
496 switch (params_format(params)) {
497 case SNDRV_PCM_FORMAT_S16_LE:
498 break;
499 case SNDRV_PCM_FORMAT_S20_3LE:
500 data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
501 break;
502 case SNDRV_PCM_FORMAT_S24_LE:
503 data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
504 break;
505 case SNDRV_PCM_FORMAT_S32_LE:
506 data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
507 break;
508 }
509 snd_soc_write(codec, AIC32X4_IFACE1, data);
510
511 return 0;
512}
513
514static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
515{
516 struct snd_soc_codec *codec = dai->codec;
517 u8 dac_reg;
518
519 dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
520 if (mute)
521 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
522 else
523 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
524 return 0;
525}
526
527static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level)
529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532
533 switch (level) {
534 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) {
536 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR);
538 snd_soc_write(codec, AIC32X4_PLLPR,
539 (value | AIC32X4_PLLEN));
540
541 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC);
543 snd_soc_write(codec, AIC32X4_NDAC,
544 value | AIC32X4_NDACEN);
545
546 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC);
548 snd_soc_write(codec, AIC32X4_MDAC,
549 value | AIC32X4_MDACEN);
550
551 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC);
553 snd_soc_write(codec, AIC32X4_NADC,
554 value | AIC32X4_MDACEN);
555
556 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC);
558 snd_soc_write(codec, AIC32X4_MADC,
559 value | AIC32X4_MDACEN);
560
561 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN);
563 snd_soc_write(codec, AIC32X4_BCLKN,
564 value | AIC32X4_BCLKEN);
565 }
566 break;
567 case SND_SOC_BIAS_PREPARE:
568 break;
569 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) {
571 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR);
573 snd_soc_write(codec, AIC32X4_PLLPR,
574 (value & ~AIC32X4_PLLEN));
575
576 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC);
578 snd_soc_write(codec, AIC32X4_NDAC,
579 value & ~AIC32X4_NDACEN);
580
581 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC);
583 snd_soc_write(codec, AIC32X4_MDAC,
584 value & ~AIC32X4_MDACEN);
585
586 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC);
588 snd_soc_write(codec, AIC32X4_NADC,
589 value & ~AIC32X4_NDACEN);
590
591 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC);
593 snd_soc_write(codec, AIC32X4_MADC,
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596
597 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN);
600 }
601 break;
602 case SND_SOC_BIAS_OFF:
603 break;
604 }
605 codec->dapm.bias_level = level;
606 return 0;
607}
608
609#define AIC32X4_RATES SNDRV_PCM_RATE_8000_48000
610#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
611 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
612
613static struct snd_soc_dai_ops aic32x4_ops = {
614 .hw_params = aic32x4_hw_params,
615 .digital_mute = aic32x4_mute,
616 .set_fmt = aic32x4_set_dai_fmt,
617 .set_sysclk = aic32x4_set_dai_sysclk,
618};
619
620static struct snd_soc_dai_driver aic32x4_dai = {
621 .name = "tlv320aic32x4-hifi",
622 .playback = {
623 .stream_name = "Playback",
624 .channels_min = 1,
625 .channels_max = 2,
626 .rates = AIC32X4_RATES,
627 .formats = AIC32X4_FORMATS,},
628 .capture = {
629 .stream_name = "Capture",
630 .channels_min = 1,
631 .channels_max = 2,
632 .rates = AIC32X4_RATES,
633 .formats = AIC32X4_FORMATS,},
634 .ops = &aic32x4_ops,
635 .symmetric_rates = 1,
636};
637
638static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
639{
640 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
641 return 0;
642}
643
644static int aic32x4_resume(struct snd_soc_codec *codec)
645{
646 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
647 return 0;
648}
649
650static int aic32x4_probe(struct snd_soc_codec *codec)
651{
652 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
653 u32 tmp_reg;
654
655 codec->hw_write = (hw_write_t) i2c_master_send;
656 codec->control_data = aic32x4->control_data;
657
658 snd_soc_write(codec, AIC32X4_RESET, 0x01);
659
660 /* Power platform configuration */
661 if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
662 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
663 AIC32X4_MICBIAS_2075V);
664 }
665 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
666 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
667 }
668 if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
669 snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
670 }
671 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
672 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
673 tmp_reg |= AIC32X4_LDOIN_18_36;
674 }
675 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
676 tmp_reg |= AIC32X4_LDOIN2HP;
677 }
678 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
679
680 /* Do DACs need to be swapped? */
681 if (aic32x4->swapdacs) {
682 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2RCHN | AIC32X4_RDAC2LCHN);
683 } else {
684 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN);
685 }
686
687 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 }
694
695 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
696 snd_soc_add_controls(codec, aic32x4_snd_controls,
697 ARRAY_SIZE(aic32x4_snd_controls));
698 aic32x4_add_widgets(codec);
699
700 return 0;
701}
702
703static int aic32x4_remove(struct snd_soc_codec *codec)
704{
705 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
706 return 0;
707}
708
709static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
710 .read = aic32x4_read,
711 .write = aic32x4_write,
712 .probe = aic32x4_probe,
713 .remove = aic32x4_remove,
714 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level,
717};
718
719static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
720 const struct i2c_device_id *id)
721{
722 struct aic32x4_pdata *pdata = i2c->dev.platform_data;
723 struct aic32x4_priv *aic32x4;
724 int ret;
725
726 aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
727 if (aic32x4 == NULL)
728 return -ENOMEM;
729
730 aic32x4->control_data = i2c;
731 i2c_set_clientdata(i2c, aic32x4);
732
733 if (pdata) {
734 aic32x4->power_cfg = pdata->power_cfg;
735 aic32x4->swapdacs = pdata->swapdacs;
736 aic32x4->micpga_routing = pdata->micpga_routing;
737 } else {
738 aic32x4->power_cfg = 0;
739 aic32x4->swapdacs = false;
740 aic32x4->micpga_routing = 0;
741 }
742
743 ret = snd_soc_register_codec(&i2c->dev,
744 &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
745 if (ret < 0)
746 kfree(aic32x4);
747 return ret;
748}
749
750static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
751{
752 snd_soc_unregister_codec(&client->dev);
753 kfree(i2c_get_clientdata(client));
754 return 0;
755}
756
757static const struct i2c_device_id aic32x4_i2c_id[] = {
758 { "tlv320aic32x4", 0 },
759 { }
760};
761MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
762
763static struct i2c_driver aic32x4_i2c_driver = {
764 .driver = {
765 .name = "tlv320aic32x4",
766 .owner = THIS_MODULE,
767 },
768 .probe = aic32x4_i2c_probe,
769 .remove = __devexit_p(aic32x4_i2c_remove),
770 .id_table = aic32x4_i2c_id,
771};
772
773static int __init aic32x4_modinit(void)
774{
775 int ret = 0;
776
777 ret = i2c_add_driver(&aic32x4_i2c_driver);
778 if (ret != 0) {
779 printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
780 ret);
781 }
782 return ret;
783}
784module_init(aic32x4_modinit);
785
786static void __exit aic32x4_exit(void)
787{
788 i2c_del_driver(&aic32x4_i2c_driver);
789}
790module_exit(aic32x4_exit);
791
792MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
793MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
794MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
new file mode 100644
index 000000000000..aae2b2440398
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -0,0 +1,143 @@
1/*
2 * tlv320aic32x4.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9
10#ifndef _TLV320AIC32X4_H
11#define _TLV320AIC32X4_H
12
13/* tlv320aic32x4 register space (in decimal to match datasheet) */
14
15#define AIC32X4_PAGE1 128
16
17#define AIC32X4_PSEL 0
18#define AIC32X4_RESET 1
19#define AIC32X4_CLKMUX 4
20#define AIC32X4_PLLPR 5
21#define AIC32X4_PLLJ 6
22#define AIC32X4_PLLDMSB 7
23#define AIC32X4_PLLDLSB 8
24#define AIC32X4_NDAC 11
25#define AIC32X4_MDAC 12
26#define AIC32X4_DOSRMSB 13
27#define AIC32X4_DOSRLSB 14
28#define AIC32X4_NADC 18
29#define AIC32X4_MADC 19
30#define AIC32X4_AOSR 20
31#define AIC32X4_CLKMUX2 25
32#define AIC32X4_CLKOUTM 26
33#define AIC32X4_IFACE1 27
34#define AIC32X4_IFACE2 28
35#define AIC32X4_IFACE3 29
36#define AIC32X4_BCLKN 30
37#define AIC32X4_IFACE4 31
38#define AIC32X4_IFACE5 32
39#define AIC32X4_IFACE6 33
40#define AIC32X4_DOUTCTL 53
41#define AIC32X4_DINCTL 54
42#define AIC32X4_DACSPB 60
43#define AIC32X4_ADCSPB 61
44#define AIC32X4_DACSETUP 63
45#define AIC32X4_DACMUTE 64
46#define AIC32X4_LDACVOL 65
47#define AIC32X4_RDACVOL 66
48#define AIC32X4_ADCSETUP 81
49#define AIC32X4_ADCFGA 82
50#define AIC32X4_LADCVOL 83
51#define AIC32X4_RADCVOL 84
52#define AIC32X4_LAGC1 86
53#define AIC32X4_LAGC2 87
54#define AIC32X4_LAGC3 88
55#define AIC32X4_LAGC4 89
56#define AIC32X4_LAGC5 90
57#define AIC32X4_LAGC6 91
58#define AIC32X4_LAGC7 92
59#define AIC32X4_RAGC1 94
60#define AIC32X4_RAGC2 95
61#define AIC32X4_RAGC3 96
62#define AIC32X4_RAGC4 97
63#define AIC32X4_RAGC5 98
64#define AIC32X4_RAGC6 99
65#define AIC32X4_RAGC7 100
66#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1)
67#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
68#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9)
69#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10)
70#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12)
71#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13)
72#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14)
73#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15)
74#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16)
75#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17)
76#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18)
77#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19)
78#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20)
79#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51)
80#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52)
81#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54)
82#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55)
83#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57)
84#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58)
85#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59)
86#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60)
87
88#define AIC32X4_FREQ_12000000 12000000
89#define AIC32X4_FREQ_24000000 24000000
90#define AIC32X4_FREQ_25000000 25000000
91
92#define AIC32X4_WORD_LEN_16BITS 0x00
93#define AIC32X4_WORD_LEN_20BITS 0x01
94#define AIC32X4_WORD_LEN_24BITS 0x02
95#define AIC32X4_WORD_LEN_32BITS 0x03
96
97#define AIC32X4_I2S_MODE 0x00
98#define AIC32X4_DSP_MODE 0x01
99#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02
100#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03
101
102#define AIC32X4_AVDDWEAKDISABLE 0x08
103#define AIC32X4_LDOCTLEN 0x01
104
105#define AIC32X4_LDOIN_18_36 0x01
106#define AIC32X4_LDOIN2HP 0x02
107
108#define AIC32X4_DACSPBLOCK_MASK 0x1f
109#define AIC32X4_ADCSPBLOCK_MASK 0x1f
110
111#define AIC32X4_PLLJ_SHIFT 6
112#define AIC32X4_DOSRMSB_SHIFT 4
113
114#define AIC32X4_PLLCLKIN 0x03
115
116#define AIC32X4_MICBIAS_LDOIN 0x08
117#define AIC32X4_MICBIAS_2075V 0x60
118
119#define AIC32X4_LMICPGANIN_IN2R_10K 0x10
120#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
121
122#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
123#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
124
125#define AIC32X4_BCLKMASTER 0x08
126#define AIC32X4_WCLKMASTER 0x04
127#define AIC32X4_PLLEN (0x01 << 7)
128#define AIC32X4_NDACEN (0x01 << 7)
129#define AIC32X4_MDACEN (0x01 << 7)
130#define AIC32X4_NADCEN (0x01 << 7)
131#define AIC32X4_MADCEN (0x01 << 7)
132#define AIC32X4_BCLKEN (0x01 << 7)
133#define AIC32X4_DACEN (0x03 << 6)
134#define AIC32X4_RDAC2LCHN (0x02 << 2)
135#define AIC32X4_LDAC2RCHN (0x02 << 4)
136#define AIC32X4_LDAC2LCHN (0x01 << 4)
137#define AIC32X4_RDAC2RCHN (0x01 << 2)
138
139#define AIC32X4_SSTEP2WCLK 0x01
140#define AIC32X4_MUTEON 0x0C
141#define AIC32X4_DACMOD2BCLK 0x01
142
143#endif /* _TLV320AIC32X4_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 71d7be8ac488..00b6d87e7bdb 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1615,6 +1615,7 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1615 }, 1615 },
1616 { }, 1616 { },
1617}; 1617};
1618MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
1618 1619
1619static struct i2c_driver tlv320dac33_i2c_driver = { 1620static struct i2c_driver tlv320dac33_i2c_driver = {
1620 .driver = { 1621 .driver = {
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 4bbf1b15a493..482fcdb59bfa 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -724,8 +724,8 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
724 return 0; 724 return 0;
725} 725}
726 726
727void twl6040_hs_jack_report(struct snd_soc_codec *codec, 727static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
728 struct snd_soc_jack *jack, int report) 728 struct snd_soc_jack *jack, int report)
729{ 729{
730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
731 int status; 731 int status;
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 80ddf4fd23db..a3b9cbb20ee9 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -836,24 +836,25 @@ static void wm2000_i2c_shutdown(struct i2c_client *i2c)
836} 836}
837 837
838#ifdef CONFIG_PM 838#ifdef CONFIG_PM
839static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) 839static int wm2000_i2c_suspend(struct device *dev)
840{ 840{
841 struct i2c_client *i2c = to_i2c_client(dev);
841 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 842 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
842 843
843 return wm2000_anc_transition(wm2000, ANC_OFF); 844 return wm2000_anc_transition(wm2000, ANC_OFF);
844} 845}
845 846
846static int wm2000_i2c_resume(struct i2c_client *i2c) 847static int wm2000_i2c_resume(struct device *dev)
847{ 848{
849 struct i2c_client *i2c = to_i2c_client(dev);
848 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 850 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
849 851
850 return wm2000_anc_set_mode(wm2000); 852 return wm2000_anc_set_mode(wm2000);
851} 853}
852#else
853#define wm2000_i2c_suspend NULL
854#define wm2000_i2c_resume NULL
855#endif 854#endif
856 855
856static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume);
857
857static const struct i2c_device_id wm2000_i2c_id[] = { 858static const struct i2c_device_id wm2000_i2c_id[] = {
858 { "wm2000", 0 }, 859 { "wm2000", 0 },
859 { } 860 { }
@@ -864,11 +865,10 @@ static struct i2c_driver wm2000_i2c_driver = {
864 .driver = { 865 .driver = {
865 .name = "wm2000", 866 .name = "wm2000",
866 .owner = THIS_MODULE, 867 .owner = THIS_MODULE,
868 .pm = &wm2000_pm,
867 }, 869 },
868 .probe = wm2000_i2c_probe, 870 .probe = wm2000_i2c_probe,
869 .remove = __devexit_p(wm2000_i2c_remove), 871 .remove = __devexit_p(wm2000_i2c_remove),
870 .suspend = wm2000_i2c_suspend,
871 .resume = wm2000_i2c_resume,
872 .shutdown = wm2000_i2c_shutdown, 872 .shutdown = wm2000_i2c_shutdown,
873 .id_table = wm2000_i2c_id, 873 .id_table = wm2000_i2c_id,
874}; 874};
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 5eb2f501ce32..4fd4d8dca0fc 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -58,7 +58,7 @@ static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
58 0x0000, /* R8 - ZERO_DETECT */ 58 0x0000, /* R8 - ZERO_DETECT */
59}; 59};
60 60
61static int wm8523_volatile_register(unsigned int reg) 61static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
62{ 62{
63 switch (reg) { 63 switch (reg) {
64 case WM8523_DEVICE_ID: 64 case WM8523_DEVICE_ID:
@@ -414,7 +414,6 @@ static int wm8523_resume(struct snd_soc_codec *codec)
414static int wm8523_probe(struct snd_soc_codec *codec) 414static int wm8523_probe(struct snd_soc_codec *codec)
415{ 415{
416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
417 u16 *reg_cache = codec->reg_cache;
418 int ret, i; 417 int ret, i;
419 418
420 codec->hw_write = (hw_write_t)i2c_master_send; 419 codec->hw_write = (hw_write_t)i2c_master_send;
@@ -471,8 +470,9 @@ static int wm8523_probe(struct snd_soc_codec *codec)
471 } 470 }
472 471
473 /* Change some default settings - latch VU and enable ZC */ 472 /* Change some default settings - latch VU and enable ZC */
474 reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; 473 snd_soc_update_bits(codec, WM8523_DAC_GAINR,
475 reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; 474 WM8523_DACR_VU, WM8523_DACR_VU);
475 snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
476 476
477 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 477 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
478 478
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 494f2d31d75b..25af901fe813 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -421,7 +421,6 @@ static int wm8741_resume(struct snd_soc_codec *codec)
421static int wm8741_probe(struct snd_soc_codec *codec) 421static int wm8741_probe(struct snd_soc_codec *codec)
422{ 422{
423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
424 u16 *reg_cache = codec->reg_cache;
425 int ret = 0; 424 int ret = 0;
426 425
427 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); 426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +436,14 @@ static int wm8741_probe(struct snd_soc_codec *codec)
437 } 436 }
438 437
439 /* Change some default settings - latch VU */ 438 /* Change some default settings - latch VU */
440 reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; 439 snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
441 reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; 440 WM8741_UPDATELL, WM8741_UPDATELL);
442 reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; 441 snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
443 reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; 442 WM8741_UPDATELM, WM8741_UPDATELM);
443 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
444 WM8741_UPDATERL, WM8741_UPDATERL);
445 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
446 WM8741_UPDATERM, WM8741_UPDATERM);
444 447
445 snd_soc_add_controls(codec, wm8741_snd_controls, 448 snd_soc_add_controls(codec, wm8741_snd_controls,
446 ARRAY_SIZE(wm8741_snd_controls)); 449 ARRAY_SIZE(wm8741_snd_controls));
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 79b02ae125c5..3f09deea8d9d 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -55,8 +55,10 @@ static int caps_charge = 2000;
55module_param(caps_charge, int, 0); 55module_param(caps_charge, int, 0);
56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
57 57
58static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 58static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
59 struct snd_soc_dai *dai, unsigned int hifi); 59 unsigned int fmt);
60static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
61 unsigned int fmt);
60 62
61/* 63/*
62 * wm8753 register cache 64 * wm8753 register cache
@@ -87,6 +89,10 @@ struct wm8753_priv {
87 enum snd_soc_control_type control_type; 89 enum snd_soc_control_type control_type;
88 unsigned int sysclk; 90 unsigned int sysclk;
89 unsigned int pcmclk; 91 unsigned int pcmclk;
92
93 unsigned int voice_fmt;
94 unsigned int hifi_fmt;
95
90 int dai_func; 96 int dai_func;
91}; 97};
92 98
@@ -170,9 +176,9 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
170 struct snd_ctl_elem_value *ucontrol) 176 struct snd_ctl_elem_value *ucontrol)
171{ 177{
172 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 178 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
173 int mode = snd_soc_read(codec, WM8753_IOCTL); 179 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
174 180
175 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; 181 ucontrol->value.integer.value[0] = wm8753->dai_func;
176 return 0; 182 return 0;
177} 183}
178 184
@@ -180,16 +186,26 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
181{ 187{
182 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
183 int mode = snd_soc_read(codec, WM8753_IOCTL);
184 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 189 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
190 u16 ioctl;
191
192 if (codec->active)
193 return -EBUSY;
194
195 ioctl = snd_soc_read(codec, WM8753_IOCTL);
196
197 wm8753->dai_func = ucontrol->value.integer.value[0];
198
199 if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
200 return 1;
201
202 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
203 snd_soc_write(codec, WM8753_IOCTL, ioctl);
185 204
186 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
187 return 0;
188 205
189 mode &= 0xfff3; 206 wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
190 mode |= (ucontrol->value.integer.value[0] << 2); 207 wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
191 208
192 wm8753->dai_func = ucontrol->value.integer.value[0];
193 return 1; 209 return 1;
194} 210}
195 211
@@ -828,10 +844,9 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
828/* 844/*
829 * Set's ADC and Voice DAC format. 845 * Set's ADC and Voice DAC format.
830 */ 846 */
831static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, 847static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
832 unsigned int fmt) 848 unsigned int fmt)
833{ 849{
834 struct snd_soc_codec *codec = codec_dai->codec;
835 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec; 850 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
836 851
837 /* interface format */ 852 /* interface format */
@@ -858,13 +873,6 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
858 return 0; 873 return 0;
859} 874}
860 875
861static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
862 struct snd_soc_dai *dai)
863{
864 wm8753_set_dai_mode(dai->codec, dai, 0);
865 return 0;
866}
867
868/* 876/*
869 * Set PCM DAI bit size and sample rate. 877 * Set PCM DAI bit size and sample rate.
870 */ 878 */
@@ -905,10 +913,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
905/* 913/*
906 * Set's PCM dai fmt and BCLK. 914 * Set's PCM dai fmt and BCLK.
907 */ 915 */
908static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, 916static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
909 unsigned int fmt) 917 unsigned int fmt)
910{ 918{
911 struct snd_soc_codec *codec = codec_dai->codec;
912 u16 voice, ioctl; 919 u16 voice, ioctl;
913 920
914 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f; 921 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
@@ -999,10 +1006,9 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
999/* 1006/*
1000 * Set's HiFi DAC format. 1007 * Set's HiFi DAC format.
1001 */ 1008 */
1002static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, 1009static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
1003 unsigned int fmt) 1010 unsigned int fmt)
1004{ 1011{
1005 struct snd_soc_codec *codec = codec_dai->codec;
1006 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0; 1012 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1007 1013
1008 /* interface format */ 1014 /* interface format */
@@ -1032,10 +1038,9 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1032/* 1038/*
1033 * Set's I2S DAI format. 1039 * Set's I2S DAI format.
1034 */ 1040 */
1035static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, 1041static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
1036 unsigned int fmt) 1042 unsigned int fmt)
1037{ 1043{
1038 struct snd_soc_codec *codec = codec_dai->codec;
1039 u16 ioctl, hifi; 1044 u16 ioctl, hifi;
1040 1045
1041 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; 1046 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
@@ -1098,13 +1103,6 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1098 return 0; 1103 return 0;
1099} 1104}
1100 1105
1101static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1102 struct snd_soc_dai *dai)
1103{
1104 wm8753_set_dai_mode(dai->codec, dai, 1);
1105 return 0;
1106}
1107
1108/* 1106/*
1109 * Set PCM DAI bit size and sample rate. 1107 * Set PCM DAI bit size and sample rate.
1110 */ 1108 */
@@ -1147,61 +1145,117 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1147 return 0; 1145 return 0;
1148} 1146}
1149 1147
1150static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, 1148static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
1151 unsigned int fmt) 1149 unsigned int fmt)
1152{ 1150{
1153 struct snd_soc_codec *codec = codec_dai->codec;
1154 u16 clock; 1151 u16 clock;
1155 1152
1156 /* set clk source as pcmclk */ 1153 /* set clk source as pcmclk */
1157 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1154 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1158 snd_soc_write(codec, WM8753_CLOCK, clock); 1155 snd_soc_write(codec, WM8753_CLOCK, clock);
1159 1156
1160 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1157 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1161 return -EINVAL;
1162 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1163} 1158}
1164 1159
1165static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai, 1160static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
1166 unsigned int fmt) 1161 unsigned int fmt)
1167{ 1162{
1168 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1163 return wm8753_hdac_set_dai_fmt(codec, fmt);
1169 return -EINVAL;
1170 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1171} 1164}
1172 1165
1173static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, 1166static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
1174 unsigned int fmt) 1167 unsigned int fmt)
1175{ 1168{
1176 struct snd_soc_codec *codec = codec_dai->codec;
1177 u16 clock; 1169 u16 clock;
1178 1170
1179 /* set clk source as pcmclk */ 1171 /* set clk source as pcmclk */
1180 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1172 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1181 snd_soc_write(codec, WM8753_CLOCK, clock); 1173 snd_soc_write(codec, WM8753_CLOCK, clock);
1182 1174
1183 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1175 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1184 return -EINVAL;
1185 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1186} 1176}
1187 1177
1188static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, 1178static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
1189 unsigned int fmt) 1179 unsigned int fmt)
1190{ 1180{
1191 struct snd_soc_codec *codec = codec_dai->codec;
1192 u16 clock; 1181 u16 clock;
1193 1182
1194 /* set clk source as mclk */ 1183 /* set clk source as mclk */
1195 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1184 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1196 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4); 1185 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1197 1186
1198 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1187 if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
1199 return -EINVAL; 1188 return -EINVAL;
1200 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1189 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1201 return -EINVAL;
1202 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1203} 1190}
1204 1191
1192static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
1193 unsigned int fmt)
1194{
1195 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1196 int ret = 0;
1197
1198 switch (wm8753->dai_func) {
1199 case 0:
1200 ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
1201 break;
1202 case 1:
1203 ret = wm8753_mode2_set_dai_fmt(codec, fmt);
1204 break;
1205 case 2:
1206 case 3:
1207 ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
1208 break;
1209 default:
1210 break;
1211 }
1212 if (ret)
1213 return ret;
1214
1215 return wm8753_i2s_set_dai_fmt(codec, fmt);
1216}
1217
1218static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1219 unsigned int fmt)
1220{
1221 struct snd_soc_codec *codec = codec_dai->codec;
1222 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1223
1224 wm8753->hifi_fmt = fmt;
1225
1226 return wm8753_hifi_write_dai_fmt(codec, fmt);
1227};
1228
1229static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
1230 unsigned int fmt)
1231{
1232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1233 int ret = 0;
1234
1235 if (wm8753->dai_func != 0)
1236 return 0;
1237
1238 ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
1239 if (ret)
1240 return ret;
1241 ret = wm8753_pcm_set_dai_fmt(codec, fmt);
1242 if (ret)
1243 return ret;
1244
1245 return 0;
1246};
1247
1248static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1249 unsigned int fmt)
1250{
1251 struct snd_soc_codec *codec = codec_dai->codec;
1252 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1253
1254 wm8753->voice_fmt = fmt;
1255
1256 return wm8753_voice_write_dai_fmt(codec, fmt);
1257};
1258
1205static int wm8753_mute(struct snd_soc_dai *dai, int mute) 1259static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1206{ 1260{
1207 struct snd_soc_codec *codec = dai->codec; 1261 struct snd_soc_codec *codec = dai->codec;
@@ -1268,57 +1322,25 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1268 * 3. Voice disabled - HIFI over HIFI 1322 * 3. Voice disabled - HIFI over HIFI
1269 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1323 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1270 */ 1324 */
1271static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1325static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
1272 .startup = wm8753_i2s_startup,
1273 .hw_params = wm8753_i2s_hw_params, 1326 .hw_params = wm8753_i2s_hw_params,
1274 .digital_mute = wm8753_mute, 1327 .digital_mute = wm8753_mute,
1275 .set_fmt = wm8753_mode1h_set_dai_fmt, 1328 .set_fmt = wm8753_hifi_set_dai_fmt,
1276 .set_clkdiv = wm8753_set_dai_clkdiv,
1277 .set_pll = wm8753_set_dai_pll,
1278 .set_sysclk = wm8753_set_dai_sysclk,
1279};
1280
1281static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1282 .startup = wm8753_pcm_startup,
1283 .hw_params = wm8753_pcm_hw_params,
1284 .digital_mute = wm8753_mute,
1285 .set_fmt = wm8753_mode1v_set_dai_fmt,
1286 .set_clkdiv = wm8753_set_dai_clkdiv, 1329 .set_clkdiv = wm8753_set_dai_clkdiv,
1287 .set_pll = wm8753_set_dai_pll, 1330 .set_pll = wm8753_set_dai_pll,
1288 .set_sysclk = wm8753_set_dai_sysclk, 1331 .set_sysclk = wm8753_set_dai_sysclk,
1289}; 1332};
1290 1333
1291static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1334static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
1292 .startup = wm8753_pcm_startup,
1293 .hw_params = wm8753_pcm_hw_params, 1335 .hw_params = wm8753_pcm_hw_params,
1294 .digital_mute = wm8753_mute, 1336 .digital_mute = wm8753_mute,
1295 .set_fmt = wm8753_mode2_set_dai_fmt, 1337 .set_fmt = wm8753_voice_set_dai_fmt,
1296 .set_clkdiv = wm8753_set_dai_clkdiv,
1297 .set_pll = wm8753_set_dai_pll,
1298 .set_sysclk = wm8753_set_dai_sysclk,
1299};
1300
1301static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1302 .startup = wm8753_i2s_startup,
1303 .hw_params = wm8753_i2s_hw_params,
1304 .digital_mute = wm8753_mute,
1305 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1306 .set_clkdiv = wm8753_set_dai_clkdiv,
1307 .set_pll = wm8753_set_dai_pll,
1308 .set_sysclk = wm8753_set_dai_sysclk,
1309};
1310
1311static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1312 .startup = wm8753_i2s_startup,
1313 .hw_params = wm8753_i2s_hw_params,
1314 .digital_mute = wm8753_mute,
1315 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1316 .set_clkdiv = wm8753_set_dai_clkdiv, 1338 .set_clkdiv = wm8753_set_dai_clkdiv,
1317 .set_pll = wm8753_set_dai_pll, 1339 .set_pll = wm8753_set_dai_pll,
1318 .set_sysclk = wm8753_set_dai_sysclk, 1340 .set_sysclk = wm8753_set_dai_sysclk,
1319}; 1341};
1320 1342
1321static struct snd_soc_dai_driver wm8753_all_dai[] = { 1343static struct snd_soc_dai_driver wm8753_dai[] = {
1322/* DAI HiFi mode 1 */ 1344/* DAI HiFi mode 1 */
1323{ .name = "wm8753-hifi", 1345{ .name = "wm8753-hifi",
1324 .playback = { 1346 .playback = {
@@ -1326,14 +1348,16 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1326 .channels_min = 1, 1348 .channels_min = 1,
1327 .channels_max = 2, 1349 .channels_max = 2,
1328 .rates = WM8753_RATES, 1350 .rates = WM8753_RATES,
1329 .formats = WM8753_FORMATS}, 1351 .formats = WM8753_FORMATS
1352 },
1330 .capture = { /* dummy for fast DAI switching */ 1353 .capture = { /* dummy for fast DAI switching */
1331 .stream_name = "Capture", 1354 .stream_name = "Capture",
1332 .channels_min = 1, 1355 .channels_min = 1,
1333 .channels_max = 2, 1356 .channels_max = 2,
1334 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1335 .formats = WM8753_FORMATS}, 1358 .formats = WM8753_FORMATS
1336 .ops = &wm8753_dai_ops_hifi_mode1, 1359 },
1360 .ops = &wm8753_dai_ops_hifi_mode,
1337}, 1361},
1338/* DAI Voice mode 1 */ 1362/* DAI Voice mode 1 */
1339{ .name = "wm8753-voice", 1363{ .name = "wm8753-voice",
@@ -1342,97 +1366,19 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1342 .channels_min = 1, 1366 .channels_min = 1,
1343 .channels_max = 1, 1367 .channels_max = 1,
1344 .rates = WM8753_RATES, 1368 .rates = WM8753_RATES,
1345 .formats = WM8753_FORMATS,}, 1369 .formats = WM8753_FORMATS,
1346 .capture = { 1370 },
1347 .stream_name = "Capture",
1348 .channels_min = 1,
1349 .channels_max = 2,
1350 .rates = WM8753_RATES,
1351 .formats = WM8753_FORMATS,},
1352 .ops = &wm8753_dai_ops_voice_mode1,
1353},
1354/* DAI HiFi mode 2 - dummy */
1355{ .name = "wm8753-hifi",
1356},
1357/* DAI Voice mode 2 */
1358{ .name = "wm8753-voice",
1359 .playback = {
1360 .stream_name = "Voice Playback",
1361 .channels_min = 1,
1362 .channels_max = 1,
1363 .rates = WM8753_RATES,
1364 .formats = WM8753_FORMATS,},
1365 .capture = {
1366 .stream_name = "Capture",
1367 .channels_min = 1,
1368 .channels_max = 2,
1369 .rates = WM8753_RATES,
1370 .formats = WM8753_FORMATS,},
1371 .ops = &wm8753_dai_ops_voice_mode2,
1372},
1373/* DAI HiFi mode 3 */
1374{ .name = "wm8753-hifi",
1375 .playback = {
1376 .stream_name = "HiFi Playback",
1377 .channels_min = 1,
1378 .channels_max = 2,
1379 .rates = WM8753_RATES,
1380 .formats = WM8753_FORMATS,},
1381 .capture = {
1382 .stream_name = "Capture",
1383 .channels_min = 1,
1384 .channels_max = 2,
1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,},
1387 .ops = &wm8753_dai_ops_hifi_mode3,
1388},
1389/* DAI Voice mode 3 - dummy */
1390{ .name = "wm8753-voice",
1391},
1392/* DAI HiFi mode 4 */
1393{ .name = "wm8753-hifi",
1394 .playback = {
1395 .stream_name = "HiFi Playback",
1396 .channels_min = 1,
1397 .channels_max = 2,
1398 .rates = WM8753_RATES,
1399 .formats = WM8753_FORMATS,},
1400 .capture = { 1371 .capture = {
1401 .stream_name = "Capture", 1372 .stream_name = "Capture",
1402 .channels_min = 1, 1373 .channels_min = 1,
1403 .channels_max = 2, 1374 .channels_max = 2,
1404 .rates = WM8753_RATES, 1375 .rates = WM8753_RATES,
1405 .formats = WM8753_FORMATS,}, 1376 .formats = WM8753_FORMATS,
1406 .ops = &wm8753_dai_ops_hifi_mode4,
1407},
1408/* DAI Voice mode 4 - dummy */
1409{ .name = "wm8753-voice",
1410},
1411};
1412
1413static struct snd_soc_dai_driver wm8753_dai[] = {
1414 {
1415 .name = "wm8753-aif0",
1416 },
1417 {
1418 .name = "wm8753-aif1",
1419 }, 1377 },
1378 .ops = &wm8753_dai_ops_voice_mode,
1379},
1420}; 1380};
1421 1381
1422static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1423 struct snd_soc_dai *dai, unsigned int hifi)
1424{
1425 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1426
1427 if (wm8753->dai_func < 4) {
1428 if (hifi)
1429 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1430 else
1431 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1432 }
1433 snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
1434}
1435
1436static void wm8753_work(struct work_struct *work) 1382static void wm8753_work(struct work_struct *work)
1437{ 1383{
1438 struct snd_soc_dapm_context *dapm = 1384 struct snd_soc_dapm_context *dapm =
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 6dae1b40c9f7..6785688f8806 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -175,7 +175,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
175 return 0; 175 return 0;
176} 176}
177 177
178static int wm8804_volatile(unsigned int reg) 178static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
179{ 179{
180 switch (reg) { 180 switch (reg) {
181 case WM8804_RST_DEVID1: 181 case WM8804_RST_DEVID1:
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index cd0959926d12..449ea09a193d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -180,7 +180,7 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
180 /* Remaining registers all zero */ 180 /* Remaining registers all zero */
181}; 181};
182 182
183static int wm8900_volatile_register(unsigned int reg) 183static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
184{ 184{
185 switch (reg) { 185 switch (reg) {
186 case WM8900_REG_ID: 186 case WM8900_REG_ID:
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 017d99ceb42e..ae1cadfae84c 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2,6 +2,7 @@
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc.
5 * 6 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 8 *
@@ -19,6 +20,7 @@
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/completion.h> 21#include <linux/completion.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/gpio.h>
22#include <linux/pm.h> 24#include <linux/pm.h>
23#include <linux/i2c.h> 25#include <linux/i2c.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -213,6 +215,7 @@ static u16 wm8903_reg_defaults[] = {
213}; 215};
214 216
215struct wm8903_priv { 217struct wm8903_priv {
218 struct snd_soc_codec *codec;
216 219
217 int sysclk; 220 int sysclk;
218 int irq; 221 int irq;
@@ -220,25 +223,36 @@ struct wm8903_priv {
220 int fs; 223 int fs;
221 int deemph; 224 int deemph;
222 225
226 int dcs_pending;
227 int dcs_cache[4];
228
223 /* Reference count */ 229 /* Reference count */
224 int class_w_users; 230 int class_w_users;
225 231
226 struct completion wseq;
227
228 struct snd_soc_jack *mic_jack; 232 struct snd_soc_jack *mic_jack;
229 int mic_det; 233 int mic_det;
230 int mic_short; 234 int mic_short;
231 int mic_last_report; 235 int mic_last_report;
232 int mic_delay; 236 int mic_delay;
237
238#ifdef CONFIG_GPIOLIB
239 struct gpio_chip gpio_chip;
240#endif
233}; 241};
234 242
235static int wm8903_volatile_register(unsigned int reg) 243static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
236{ 244{
237 switch (reg) { 245 switch (reg) {
238 case WM8903_SW_RESET_AND_ID: 246 case WM8903_SW_RESET_AND_ID:
239 case WM8903_REVISION_NUMBER: 247 case WM8903_REVISION_NUMBER:
240 case WM8903_INTERRUPT_STATUS_1: 248 case WM8903_INTERRUPT_STATUS_1:
241 case WM8903_WRITE_SEQUENCER_4: 249 case WM8903_WRITE_SEQUENCER_4:
250 case WM8903_POWER_MANAGEMENT_3:
251 case WM8903_POWER_MANAGEMENT_2:
252 case WM8903_DC_SERVO_READBACK_1:
253 case WM8903_DC_SERVO_READBACK_2:
254 case WM8903_DC_SERVO_READBACK_3:
255 case WM8903_DC_SERVO_READBACK_4:
242 return 1; 256 return 1;
243 257
244 default: 258 default:
@@ -246,50 +260,6 @@ static int wm8903_volatile_register(unsigned int reg)
246 } 260 }
247} 261}
248 262
249static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
250{
251 u16 reg[5];
252 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
253
254 BUG_ON(start > 48);
255
256 /* Enable the sequencer if it's not already on */
257 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
258 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
259 reg[0] | WM8903_WSEQ_ENA);
260
261 dev_dbg(codec->dev, "Starting sequence at %d\n", start);
262
263 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
264 start | WM8903_WSEQ_START);
265
266 /* Wait for it to complete. If we have the interrupt wired up then
267 * that will break us out of the poll early.
268 */
269 do {
270 wait_for_completion_timeout(&wm8903->wseq,
271 msecs_to_jiffies(10));
272
273 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
274 } while (reg[4] & WM8903_WSEQ_BUSY);
275
276 dev_dbg(codec->dev, "Sequence complete\n");
277
278 /* Disable the sequencer again if we enabled it */
279 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
280
281 return 0;
282}
283
284static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
285{
286 int i;
287
288 /* There really ought to be something better we can do here :/ */
289 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
290 cache[i] = codec->hw_read(codec, i);
291}
292
293static void wm8903_reset(struct snd_soc_codec *codec) 263static void wm8903_reset(struct snd_soc_codec *codec)
294{ 264{
295 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); 265 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
@@ -297,11 +267,6 @@ static void wm8903_reset(struct snd_soc_codec *codec)
297 sizeof(wm8903_reg_defaults)); 267 sizeof(wm8903_reg_defaults));
298} 268}
299 269
300#define WM8903_OUTPUT_SHORT 0x8
301#define WM8903_OUTPUT_OUT 0x4
302#define WM8903_OUTPUT_INT 0x2
303#define WM8903_OUTPUT_IN 0x1
304
305static int wm8903_cp_event(struct snd_soc_dapm_widget *w, 270static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
306 struct snd_kcontrol *kcontrol, int event) 271 struct snd_kcontrol *kcontrol, int event)
307{ 272{
@@ -311,97 +276,101 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
311 return 0; 276 return 0;
312} 277}
313 278
314/* 279static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
315 * Event for headphone and line out amplifier power changes. Special 280 struct snd_kcontrol *kcontrol, int event)
316 * power up/down sequences are required in order to maximise pop/click
317 * performance.
318 */
319static int wm8903_output_event(struct snd_soc_dapm_widget *w,
320 struct snd_kcontrol *kcontrol, int event)
321{ 281{
322 struct snd_soc_codec *codec = w->codec; 282 struct snd_soc_codec *codec = w->codec;
323 u16 val; 283 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
324 u16 reg;
325 u16 dcs_reg;
326 u16 dcs_bit;
327 int shift;
328 284
329 switch (w->reg) { 285 switch (event) {
330 case WM8903_POWER_MANAGEMENT_2: 286 case SND_SOC_DAPM_POST_PMU:
331 reg = WM8903_ANALOGUE_HP_0; 287 wm8903->dcs_pending |= 1 << w->shift;
332 dcs_bit = 0 + w->shift;
333 break; 288 break;
334 case WM8903_POWER_MANAGEMENT_3: 289 case SND_SOC_DAPM_PRE_PMD:
335 reg = WM8903_ANALOGUE_LINEOUT_0; 290 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
336 dcs_bit = 2 + w->shift; 291 1 << w->shift, 0);
337 break; 292 break;
338 default:
339 BUG();
340 return -EINVAL; /* Spurious warning from some compilers */
341 } 293 }
342 294
343 switch (w->shift) { 295 return 0;
344 case 0: 296}
345 shift = 0;
346 break;
347 case 1:
348 shift = 4;
349 break;
350 default:
351 BUG();
352 return -EINVAL; /* Spurious warning from some compilers */
353 }
354 297
355 if (event & SND_SOC_DAPM_PRE_PMU) { 298#define WM8903_DCS_MODE_WRITE_STOP 0
356 val = snd_soc_read(codec, reg); 299#define WM8903_DCS_MODE_START_STOP 2
357 300
358 /* Short the output */ 301static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
359 val &= ~(WM8903_OUTPUT_SHORT << shift); 302 enum snd_soc_dapm_type event, int subseq)
360 snd_soc_write(codec, reg, val); 303{
361 } 304 struct snd_soc_codec *codec = container_of(dapm,
305 struct snd_soc_codec, dapm);
306 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
307 int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
308 int i, val;
362 309
363 if (event & SND_SOC_DAPM_POST_PMU) { 310 /* Complete any pending DC servo starts */
364 val = snd_soc_read(codec, reg); 311 if (wm8903->dcs_pending) {
312 dev_dbg(codec->dev, "Starting DC servo for %x\n",
313 wm8903->dcs_pending);
365 314
366 val |= (WM8903_OUTPUT_IN << shift); 315 /* If we've no cached values then we need to do startup */
367 snd_soc_write(codec, reg, val); 316 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
317 if (!(wm8903->dcs_pending & (1 << i)))
318 continue;
368 319
369 val |= (WM8903_OUTPUT_INT << shift); 320 if (wm8903->dcs_cache[i]) {
370 snd_soc_write(codec, reg, val); 321 dev_dbg(codec->dev,
322 "Restore DC servo %d value %x\n",
323 3 - i, wm8903->dcs_cache[i]);
324
325 snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
326 wm8903->dcs_cache[i] & 0xff);
327 } else {
328 dev_dbg(codec->dev,
329 "Calibrate DC servo %d\n", 3 - i);
330 dcs_mode = WM8903_DCS_MODE_START_STOP;
331 }
332 }
371 333
372 /* Turn on the output ENA_OUTP */ 334 /* Don't trust the cache for analogue */
373 val |= (WM8903_OUTPUT_OUT << shift); 335 if (wm8903->class_w_users)
374 snd_soc_write(codec, reg, val); 336 dcs_mode = WM8903_DCS_MODE_START_STOP;
375 337
376 /* Enable the DC servo */ 338 snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
377 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 339 WM8903_DCS_MODE_MASK, dcs_mode);
378 dcs_reg |= dcs_bit;
379 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
380 340
381 /* Remove the short */ 341 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
382 val |= (WM8903_OUTPUT_SHORT << shift); 342 WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
383 snd_soc_write(codec, reg, val);
384 }
385 343
386 if (event & SND_SOC_DAPM_PRE_PMD) { 344 switch (dcs_mode) {
387 val = snd_soc_read(codec, reg); 345 case WM8903_DCS_MODE_WRITE_STOP:
346 break;
388 347
389 /* Short the output */ 348 case WM8903_DCS_MODE_START_STOP:
390 val &= ~(WM8903_OUTPUT_SHORT << shift); 349 msleep(270);
391 snd_soc_write(codec, reg, val);
392 350
393 /* Disable the DC servo */ 351 /* Cache the measured offsets for digital */
394 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 352 if (wm8903->class_w_users)
395 dcs_reg &= ~dcs_bit; 353 break;
396 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
397 354
398 /* Then disable the intermediate and output stages */ 355 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
399 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 356 if (!(wm8903->dcs_pending & (1 << i)))
400 WM8903_OUTPUT_IN) << shift); 357 continue;
401 snd_soc_write(codec, reg, val);
402 }
403 358
404 return 0; 359 val = snd_soc_read(codec,
360 WM8903_DC_SERVO_READBACK_1 + i);
361 dev_dbg(codec->dev, "DC servo %d: %x\n",
362 3 - i, val);
363 wm8903->dcs_cache[i] = val;
364 }
365 break;
366
367 default:
368 pr_warn("DCS mode %d delay not set\n", dcs_mode);
369 break;
370 }
371
372 wm8903->dcs_pending = 0;
373 }
405} 374}
406 375
407/* 376/*
@@ -667,6 +636,22 @@ static const struct soc_enum lsidetone_enum =
667static const struct soc_enum rsidetone_enum = 636static const struct soc_enum rsidetone_enum =
668 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 637 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
669 638
639static const char *aif_text[] = {
640 "Left", "Right"
641};
642
643static const struct soc_enum lcapture_enum =
644 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text);
645
646static const struct soc_enum rcapture_enum =
647 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text);
648
649static const struct soc_enum lplay_enum =
650 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text);
651
652static const struct soc_enum rplay_enum =
653 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text);
654
670static const struct snd_kcontrol_new wm8903_snd_controls[] = { 655static const struct snd_kcontrol_new wm8903_snd_controls[] = {
671 656
672/* Input PGAs - No TLV since the scale depends on PGA mode */ 657/* Input PGAs - No TLV since the scale depends on PGA mode */
@@ -784,6 +769,18 @@ static const struct snd_kcontrol_new lsidetone_mux =
784static const struct snd_kcontrol_new rsidetone_mux = 769static const struct snd_kcontrol_new rsidetone_mux =
785 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 770 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
786 771
772static const struct snd_kcontrol_new lcapture_mux =
773 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
774
775static const struct snd_kcontrol_new rcapture_mux =
776 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
777
778static const struct snd_kcontrol_new lplay_mux =
779 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
780
781static const struct snd_kcontrol_new rplay_mux =
782 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
783
787static const struct snd_kcontrol_new left_output_mixer[] = { 784static const struct snd_kcontrol_new left_output_mixer[] = {
788SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 785SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
789SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 786SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
@@ -847,14 +844,26 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
847SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 844SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
848SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 845SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
849 846
850SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), 847SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
851SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), 848SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
849
850SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
851SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
852
853SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
854SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
852 855
853SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), 856SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
854SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), 857SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
855 858
856SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), 859SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0),
857SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), 860SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0),
861
862SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
863SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
864
865SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0),
866SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0),
858 867
859SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, 868SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
860 left_output_mixer, ARRAY_SIZE(left_output_mixer)), 869 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
@@ -866,23 +875,45 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
866SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, 875SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
867 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 876 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
868 877
869SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 878SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
870 1, 0, NULL, 0, wm8903_output_event, 879 4, 0, NULL, 0),
871 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 880SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
872 SND_SOC_DAPM_PRE_PMD), 881 0, 0, NULL, 0),
873SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 882
874 0, 0, NULL, 0, wm8903_output_event, 883SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 4, 0,
875 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 884 NULL, 0),
876 SND_SOC_DAPM_PRE_PMD), 885SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 0, 0,
877 886 NULL, 0),
878SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, 887
879 NULL, 0, wm8903_output_event, 888SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0),
880 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 889SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0),
881 SND_SOC_DAPM_PRE_PMD), 890SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0),
882SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, 891SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0),
883 NULL, 0, wm8903_output_event, 892SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0),
884 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 893SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0),
885 SND_SOC_DAPM_PRE_PMD), 894
895SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0,
896 NULL, 0),
897SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0,
898 NULL, 0),
899SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 5, 0,
900 NULL, 0),
901SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0,
902 NULL, 0),
903SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0,
904 NULL, 0),
905SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 1, 0,
906 NULL, 0),
907
908SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0),
909SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event,
910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
911SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event,
912 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
913SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event,
914 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
915SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event,
916 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
886 917
887SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, 918SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
888 NULL, 0), 919 NULL, 0),
@@ -892,10 +923,18 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
892SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, 923SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
893 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), 924 wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
894SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), 925SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
926SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
895}; 927};
896 928
897static const struct snd_soc_dapm_route intercon[] = { 929static const struct snd_soc_dapm_route intercon[] = {
898 930
931 { "CLK_DSP", NULL, "CLK_SYS" },
932 { "Mic Bias", NULL, "CLK_SYS" },
933 { "HPL_DCS", NULL, "CLK_SYS" },
934 { "HPR_DCS", NULL, "CLK_SYS" },
935 { "LINEOUTL_DCS", NULL, "CLK_SYS" },
936 { "LINEOUTR_DCS", NULL, "CLK_SYS" },
937
899 { "Left Input Mux", "IN1L", "IN1L" }, 938 { "Left Input Mux", "IN1L", "IN1L" },
900 { "Left Input Mux", "IN2L", "IN2L" }, 939 { "Left Input Mux", "IN2L", "IN2L" },
901 { "Left Input Mux", "IN3L", "IN3L" }, 940 { "Left Input Mux", "IN3L", "IN3L" },
@@ -936,18 +975,36 @@ static const struct snd_soc_dapm_route intercon[] = {
936 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 975 { "Left Input PGA", NULL, "Left Input Mode Mux" },
937 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 976 { "Right Input PGA", NULL, "Right Input Mode Mux" },
938 977
978 { "Left Capture Mux", "Left", "ADCL" },
979 { "Left Capture Mux", "Right", "ADCR" },
980
981 { "Right Capture Mux", "Left", "ADCL" },
982 { "Right Capture Mux", "Right", "ADCR" },
983
984 { "AIFTXL", NULL, "Left Capture Mux" },
985 { "AIFTXR", NULL, "Right Capture Mux" },
986
939 { "ADCL", NULL, "Left Input PGA" }, 987 { "ADCL", NULL, "Left Input PGA" },
940 { "ADCL", NULL, "CLK_DSP" }, 988 { "ADCL", NULL, "CLK_DSP" },
941 { "ADCR", NULL, "Right Input PGA" }, 989 { "ADCR", NULL, "Right Input PGA" },
942 { "ADCR", NULL, "CLK_DSP" }, 990 { "ADCR", NULL, "CLK_DSP" },
943 991
992 { "Left Playback Mux", "Left", "AIFRXL" },
993 { "Left Playback Mux", "Right", "AIFRXR" },
994
995 { "Right Playback Mux", "Left", "AIFRXL" },
996 { "Right Playback Mux", "Right", "AIFRXR" },
997
944 { "DACL Sidetone", "Left", "ADCL" }, 998 { "DACL Sidetone", "Left", "ADCL" },
945 { "DACL Sidetone", "Right", "ADCR" }, 999 { "DACL Sidetone", "Right", "ADCR" },
946 { "DACR Sidetone", "Left", "ADCL" }, 1000 { "DACR Sidetone", "Left", "ADCL" },
947 { "DACR Sidetone", "Right", "ADCR" }, 1001 { "DACR Sidetone", "Right", "ADCR" },
948 1002
1003 { "DACL", NULL, "Left Playback Mux" },
949 { "DACL", NULL, "DACL Sidetone" }, 1004 { "DACL", NULL, "DACL Sidetone" },
950 { "DACL", NULL, "CLK_DSP" }, 1005 { "DACL", NULL, "CLK_DSP" },
1006
1007 { "DACR", NULL, "Right Playback Mux" },
951 { "DACR", NULL, "DACR Sidetone" }, 1008 { "DACR", NULL, "DACR Sidetone" },
952 { "DACR", NULL, "CLK_DSP" }, 1009 { "DACR", NULL, "CLK_DSP" },
953 1010
@@ -980,11 +1037,35 @@ static const struct snd_soc_dapm_route intercon[] = {
980 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, 1037 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
981 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, 1038 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
982 1039
983 { "HPOUTL", NULL, "Left Headphone Output PGA" }, 1040 { "HPL_ENA_DLY", NULL, "Left Headphone Output PGA" },
984 { "HPOUTR", NULL, "Right Headphone Output PGA" }, 1041 { "HPR_ENA_DLY", NULL, "Right Headphone Output PGA" },
1042 { "LINEOUTL_ENA_DLY", NULL, "Left Line Output PGA" },
1043 { "LINEOUTR_ENA_DLY", NULL, "Right Line Output PGA" },
1044
1045 { "HPL_DCS", NULL, "DCS Master" },
1046 { "HPR_DCS", NULL, "DCS Master" },
1047 { "LINEOUTL_DCS", NULL, "DCS Master" },
1048 { "LINEOUTR_DCS", NULL, "DCS Master" },
1049
1050 { "HPL_DCS", NULL, "HPL_ENA_DLY" },
1051 { "HPR_DCS", NULL, "HPR_ENA_DLY" },
1052 { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" },
1053 { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" },
985 1054
986 { "LINEOUTL", NULL, "Left Line Output PGA" }, 1055 { "HPL_ENA_OUTP", NULL, "HPL_DCS" },
987 { "LINEOUTR", NULL, "Right Line Output PGA" }, 1056 { "HPR_ENA_OUTP", NULL, "HPR_DCS" },
1057 { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" },
1058 { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" },
1059
1060 { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" },
1061 { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" },
1062 { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" },
1063 { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" },
1064
1065 { "HPOUTL", NULL, "HPL_RMV_SHORT" },
1066 { "HPOUTR", NULL, "HPR_RMV_SHORT" },
1067 { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" },
1068 { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" },
988 1069
989 { "LOP", NULL, "Left Speaker PGA" }, 1070 { "LOP", NULL, "Left Speaker PGA" },
990 { "LON", NULL, "Left Speaker PGA" }, 1071 { "LON", NULL, "Left Speaker PGA" },
@@ -1012,29 +1093,71 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
1012static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1093static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1013 enum snd_soc_bias_level level) 1094 enum snd_soc_bias_level level)
1014{ 1095{
1015 u16 reg;
1016
1017 switch (level) { 1096 switch (level) {
1018 case SND_SOC_BIAS_ON: 1097 case SND_SOC_BIAS_ON:
1098 break;
1099
1019 case SND_SOC_BIAS_PREPARE: 1100 case SND_SOC_BIAS_PREPARE:
1020 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1101 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1021 reg &= ~(WM8903_VMID_RES_MASK); 1102 WM8903_VMID_RES_MASK,
1022 reg |= WM8903_VMID_RES_50K; 1103 WM8903_VMID_RES_50K);
1023 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1024 break; 1104 break;
1025 1105
1026 case SND_SOC_BIAS_STANDBY: 1106 case SND_SOC_BIAS_STANDBY:
1027 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1107 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1028 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1108 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1029 WM8903_CLK_SYS_ENA); 1109 WM8903_POBCTRL | WM8903_ISEL_MASK |
1030 1110 WM8903_STARTUP_BIAS_ENA |
1031 /* Change DC servo dither level in startup sequence */ 1111 WM8903_BIAS_ENA,
1032 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 1112 WM8903_POBCTRL |
1033 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 1113 (2 << WM8903_ISEL_SHIFT) |
1034 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 1114 WM8903_STARTUP_BIAS_ENA);
1035 1115
1036 wm8903_run_sequence(codec, 0); 1116 snd_soc_update_bits(codec,
1037 wm8903_sync_reg_cache(codec, codec->reg_cache); 1117 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1118 WM8903_SPK_DISCHARGE,
1119 WM8903_SPK_DISCHARGE);
1120
1121 msleep(33);
1122
1123 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1124 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1125 WM8903_SPKL_ENA | WM8903_SPKR_ENA);
1126
1127 snd_soc_update_bits(codec,
1128 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1129 WM8903_SPK_DISCHARGE, 0);
1130
1131 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1132 WM8903_VMID_TIE_ENA |
1133 WM8903_BUFIO_ENA |
1134 WM8903_VMID_IO_ENA |
1135 WM8903_VMID_SOFT_MASK |
1136 WM8903_VMID_RES_MASK |
1137 WM8903_VMID_BUF_ENA,
1138 WM8903_VMID_TIE_ENA |
1139 WM8903_BUFIO_ENA |
1140 WM8903_VMID_IO_ENA |
1141 (2 << WM8903_VMID_SOFT_SHIFT) |
1142 WM8903_VMID_RES_250K |
1143 WM8903_VMID_BUF_ENA);
1144
1145 msleep(129);
1146
1147 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1148 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1149 0);
1150
1151 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1152 WM8903_VMID_SOFT_MASK, 0);
1153
1154 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1155 WM8903_VMID_RES_MASK,
1156 WM8903_VMID_RES_50K);
1157
1158 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1159 WM8903_BIAS_ENA | WM8903_POBCTRL,
1160 WM8903_BIAS_ENA);
1038 1161
1039 /* By default no bypass paths are enabled so 1162 /* By default no bypass paths are enabled so
1040 * enable Class W support. 1163 * enable Class W support.
@@ -1047,17 +1170,32 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1047 WM8903_CP_DYN_V); 1170 WM8903_CP_DYN_V);
1048 } 1171 }
1049 1172
1050 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1173 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1051 reg &= ~(WM8903_VMID_RES_MASK); 1174 WM8903_VMID_RES_MASK,
1052 reg |= WM8903_VMID_RES_250K; 1175 WM8903_VMID_RES_250K);
1053 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1054 break; 1176 break;
1055 1177
1056 case SND_SOC_BIAS_OFF: 1178 case SND_SOC_BIAS_OFF:
1057 wm8903_run_sequence(codec, 32); 1179 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1058 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); 1180 WM8903_BIAS_ENA, 0);
1059 reg &= ~WM8903_CLK_SYS_ENA; 1181
1060 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); 1182 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1183 WM8903_VMID_SOFT_MASK,
1184 2 << WM8903_VMID_SOFT_SHIFT);
1185
1186 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1187 WM8903_VMID_BUF_ENA, 0);
1188
1189 msleep(290);
1190
1191 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1192 WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
1193 WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
1194 WM8903_VMID_SOFT_MASK |
1195 WM8903_VMID_BUF_ENA, 0);
1196
1197 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1198 WM8903_STARTUP_BIAS_ENA, 0);
1061 break; 1199 break;
1062 } 1200 }
1063 1201
@@ -1510,8 +1648,7 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1510 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1648 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1511 1649
1512 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1650 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1513 dev_dbg(codec->dev, "Write sequencer done\n"); 1651 dev_warn(codec->dev, "Write sequencer done\n");
1514 complete(&wm8903->wseq);
1515 } 1652 }
1516 1653
1517 /* 1654 /*
@@ -1635,6 +1772,120 @@ static int wm8903_resume(struct snd_soc_codec *codec)
1635 return 0; 1772 return 0;
1636} 1773}
1637 1774
1775#ifdef CONFIG_GPIOLIB
1776static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip)
1777{
1778 return container_of(chip, struct wm8903_priv, gpio_chip);
1779}
1780
1781static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1782{
1783 if (offset >= WM8903_NUM_GPIO)
1784 return -EINVAL;
1785
1786 return 0;
1787}
1788
1789static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1790{
1791 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1792 struct snd_soc_codec *codec = wm8903->codec;
1793 unsigned int mask, val;
1794
1795 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
1796 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1797 WM8903_GP1_DIR;
1798
1799 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1800 mask, val);
1801}
1802
1803static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1804{
1805 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1806 struct snd_soc_codec *codec = wm8903->codec;
1807 int reg;
1808
1809 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
1810
1811 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1812}
1813
1814static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1815 unsigned offset, int value)
1816{
1817 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1818 struct snd_soc_codec *codec = wm8903->codec;
1819 unsigned int mask, val;
1820
1821 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
1822 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1823 (value << WM8903_GP2_LVL_SHIFT);
1824
1825 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1826 mask, val);
1827}
1828
1829static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1830{
1831 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1832 struct snd_soc_codec *codec = wm8903->codec;
1833
1834 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1835 WM8903_GP1_LVL_MASK,
1836 !!value << WM8903_GP1_LVL_SHIFT);
1837}
1838
1839static struct gpio_chip wm8903_template_chip = {
1840 .label = "wm8903",
1841 .owner = THIS_MODULE,
1842 .request = wm8903_gpio_request,
1843 .direction_input = wm8903_gpio_direction_in,
1844 .get = wm8903_gpio_get,
1845 .direction_output = wm8903_gpio_direction_out,
1846 .set = wm8903_gpio_set,
1847 .can_sleep = 1,
1848};
1849
1850static void wm8903_init_gpio(struct snd_soc_codec *codec)
1851{
1852 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1853 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1854 int ret;
1855
1856 wm8903->gpio_chip = wm8903_template_chip;
1857 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1858 wm8903->gpio_chip.dev = codec->dev;
1859
1860 if (pdata && pdata->gpio_base)
1861 wm8903->gpio_chip.base = pdata->gpio_base;
1862 else
1863 wm8903->gpio_chip.base = -1;
1864
1865 ret = gpiochip_add(&wm8903->gpio_chip);
1866 if (ret != 0)
1867 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
1868}
1869
1870static void wm8903_free_gpio(struct snd_soc_codec *codec)
1871{
1872 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1873 int ret;
1874
1875 ret = gpiochip_remove(&wm8903->gpio_chip);
1876 if (ret != 0)
1877 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
1878}
1879#else
1880static void wm8903_init_gpio(struct snd_soc_codec *codec)
1881{
1882}
1883
1884static void wm8903_free_gpio(struct snd_soc_codec *codec)
1885{
1886}
1887#endif
1888
1638static int wm8903_probe(struct snd_soc_codec *codec) 1889static int wm8903_probe(struct snd_soc_codec *codec)
1639{ 1890{
1640 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); 1891 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
@@ -1643,7 +1894,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1643 int trigger, irq_pol; 1894 int trigger, irq_pol;
1644 u16 val; 1895 u16 val;
1645 1896
1646 init_completion(&wm8903->wseq); 1897 wm8903->codec = codec;
1647 1898
1648 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1899 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1649 if (ret != 0) { 1900 if (ret != 0) {
@@ -1659,19 +1910,33 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1659 } 1910 }
1660 1911
1661 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1912 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1662 dev_info(codec->dev, "WM8903 revision %d\n", 1913 dev_info(codec->dev, "WM8903 revision %c\n",
1663 val & WM8903_CHIP_REV_MASK); 1914 (val & WM8903_CHIP_REV_MASK) + 'A');
1664 1915
1665 wm8903_reset(codec); 1916 wm8903_reset(codec);
1666 1917
1667 /* Set up GPIOs and microphone detection */ 1918 /* Set up GPIOs and microphone detection */
1668 if (pdata) { 1919 if (pdata) {
1920 bool mic_gpio = false;
1921
1669 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { 1922 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1670 if (!pdata->gpio_cfg[i]) 1923 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
1671 continue; 1924 continue;
1672 1925
1673 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, 1926 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1674 pdata->gpio_cfg[i] & 0xffff); 1927 pdata->gpio_cfg[i] & 0xffff);
1928
1929 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1930 >> WM8903_GP1_FN_SHIFT;
1931
1932 switch (val) {
1933 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1934 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1935 mic_gpio = true;
1936 break;
1937 default:
1938 break;
1939 }
1675 } 1940 }
1676 1941
1677 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, 1942 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
@@ -1682,6 +1947,14 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1682 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1947 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1683 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); 1948 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1684 1949
1950 /* If microphone detection is enabled by pdata but
1951 * detected via IRQ then interrupts can be lost before
1952 * the machine driver has set up microphone detection
1953 * IRQs as the IRQs are clear on read. The detection
1954 * will be enabled when the machine driver configures.
1955 */
1956 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1957
1685 wm8903->mic_delay = pdata->micdet_delay; 1958 wm8903->mic_delay = pdata->micdet_delay;
1686 } 1959 }
1687 1960
@@ -1741,20 +2014,23 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1741 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 2014 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1742 2015
1743 /* Enable DAC soft mute by default */ 2016 /* Enable DAC soft mute by default */
1744 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 2017 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
1745 val |= WM8903_DAC_MUTEMODE; 2018 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
1746 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 2019 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
1747 2020
1748 snd_soc_add_controls(codec, wm8903_snd_controls, 2021 snd_soc_add_controls(codec, wm8903_snd_controls,
1749 ARRAY_SIZE(wm8903_snd_controls)); 2022 ARRAY_SIZE(wm8903_snd_controls));
1750 wm8903_add_widgets(codec); 2023 wm8903_add_widgets(codec);
1751 2024
2025 wm8903_init_gpio(codec);
2026
1752 return ret; 2027 return ret;
1753} 2028}
1754 2029
1755/* power down chip */ 2030/* power down chip */
1756static int wm8903_remove(struct snd_soc_codec *codec) 2031static int wm8903_remove(struct snd_soc_codec *codec)
1757{ 2032{
2033 wm8903_free_gpio(codec);
1758 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 2034 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1759 return 0; 2035 return 0;
1760} 2036}
@@ -1769,6 +2045,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1769 .reg_word_size = sizeof(u16), 2045 .reg_word_size = sizeof(u16),
1770 .reg_cache_default = wm8903_reg_defaults, 2046 .reg_cache_default = wm8903_reg_defaults,
1771 .volatile_register = wm8903_volatile_register, 2047 .volatile_register = wm8903_volatile_register,
2048 .seq_notifier = wm8903_seq_notifier,
1772}; 2049};
1773 2050
1774#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1807,7 +2084,7 @@ MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1807 2084
1808static struct i2c_driver wm8903_i2c_driver = { 2085static struct i2c_driver wm8903_i2c_driver = {
1809 .driver = { 2086 .driver = {
1810 .name = "wm8903-codec", 2087 .name = "wm8903",
1811 .owner = THIS_MODULE, 2088 .owner = THIS_MODULE,
1812 }, 2089 },
1813 .probe = wm8903_i2c_probe, 2090 .probe = wm8903_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index e3ec2433b215..db949311c0f2 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -75,6 +75,14 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41 75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
76#define WM8903_DC_SERVO_0 0x43 76#define WM8903_DC_SERVO_0 0x43
77#define WM8903_DC_SERVO_2 0x45 77#define WM8903_DC_SERVO_2 0x45
78#define WM8903_DC_SERVO_4 0x47
79#define WM8903_DC_SERVO_5 0x48
80#define WM8903_DC_SERVO_6 0x49
81#define WM8903_DC_SERVO_7 0x4A
82#define WM8903_DC_SERVO_READBACK_1 0x51
83#define WM8903_DC_SERVO_READBACK_2 0x52
84#define WM8903_DC_SERVO_READBACK_3 0x53
85#define WM8903_DC_SERVO_READBACK_4 0x54
78#define WM8903_ANALOGUE_HP_0 0x5A 86#define WM8903_ANALOGUE_HP_0 0x5A
79#define WM8903_ANALOGUE_LINEOUT_0 0x5E 87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
80#define WM8903_CHARGE_PUMP_0 0x62 88#define WM8903_CHARGE_PUMP_0 0x62
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 9de44a4c05c0..443ae580445c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -596,7 +596,7 @@ static struct {
596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ 596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
597}; 597};
598 598
599static int wm8904_volatile_register(unsigned int reg) 599static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
600{ 600{
601 return wm8904_access[reg].vol; 601 return wm8904_access[reg].vol;
602} 602}
@@ -2436,19 +2436,28 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2436 } 2436 }
2437 2437
2438 /* Change some default settings - latch VU and enable ZC */ 2438 /* Change some default settings - latch VU and enable ZC */
2439 reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; 2439 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2440 reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; 2440 WM8904_ADC_VU, WM8904_ADC_VU);
2441 reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; 2441 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2442 reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; 2442 WM8904_ADC_VU, WM8904_ADC_VU);
2443 reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | 2443 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2444 WM8904_HPOUTLZC; 2444 WM8904_DAC_VU, WM8904_DAC_VU);
2445 reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | 2445 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2446 WM8904_HPOUTRZC; 2446 WM8904_DAC_VU, WM8904_DAC_VU);
2447 reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | 2447 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2448 WM8904_LINEOUTLZC; 2448 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2449 reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | 2449 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2450 WM8904_LINEOUTRZC; 2450 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2451 reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2451 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2452 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2453 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2454 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2455 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2456 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2457 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2458 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2459 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2460 WM8904_SR_MODE, 0);
2452 2461
2453 /* Apply configuration from the platform data. */ 2462 /* Apply configuration from the platform data. */
2454 if (wm8904->pdata) { 2463 if (wm8904->pdata) {
@@ -2469,10 +2478,12 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2469 /* Set Class W by default - this will be managed by the Class 2478 /* Set Class W by default - this will be managed by the Class
2470 * G widget at runtime where bypass paths are available. 2479 * G widget at runtime where bypass paths are available.
2471 */ 2480 */
2472 reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; 2481 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2482 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2473 2483
2474 /* Use normal bias source */ 2484 /* Use normal bias source */
2475 reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; 2485 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2486 WM8904_POBCTRL, 0);
2476 2487
2477 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2488 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2478 2489
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 7167dfc96aa7..5e0214d6293e 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -934,16 +934,27 @@ static int wm8955_probe(struct snd_soc_codec *codec)
934 } 934 }
935 935
936 /* Change some default settings - latch VU and enable ZC */ 936 /* Change some default settings - latch VU and enable ZC */
937 reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; 937 snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME,
938 reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; 938 WM8955_LDVU, WM8955_LDVU);
939 reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; 939 snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME,
940 reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; 940 WM8955_RDVU, WM8955_RDVU);
941 reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; 941 snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME,
942 reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; 942 WM8955_LO1VU | WM8955_LO1ZC,
943 reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; 943 WM8955_LO1VU | WM8955_LO1ZC);
944 snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME,
945 WM8955_RO1VU | WM8955_RO1ZC,
946 WM8955_RO1VU | WM8955_RO1ZC);
947 snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME,
948 WM8955_LO2VU | WM8955_LO2ZC,
949 WM8955_LO2VU | WM8955_LO2ZC);
950 snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME,
951 WM8955_RO2VU | WM8955_RO2ZC,
952 WM8955_RO2VU | WM8955_RO2ZC);
953 snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME,
954 WM8955_MOZC, WM8955_MOZC);
944 955
945 /* Also enable adaptive bass boost by default */ 956 /* Also enable adaptive bass boost by default */
946 reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; 957 snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
947 958
948 /* Set platform data values */ 959 /* Set platform data values */
949 if (pdata) { 960 if (pdata) {
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 55252e7d02c9..cdee8103d09b 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -291,7 +291,7 @@ struct wm8961_priv {
291 int sysclk; 291 int sysclk;
292}; 292};
293 293
294static int wm8961_volatile_register(unsigned int reg) 294static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
295{ 295{
296 switch (reg) { 296 switch (reg) {
297 case WM8961_SOFTWARE_RESET: 297 case WM8961_SOFTWARE_RESET:
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index b9cb1fcf8c92..3b71dd65c966 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1938,7 +1938,7 @@ static const struct wm8962_reg_access {
1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ 1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
1939}; 1939};
1940 1940
1941static int wm8962_volatile_register(unsigned int reg) 1941static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
1942{ 1942{
1943 if (wm8962_reg_access[reg].vol) 1943 if (wm8962_reg_access[reg].vol)
1944 return 1; 1944 return 1;
@@ -1946,7 +1946,7 @@ static int wm8962_volatile_register(unsigned int reg)
1946 return 0; 1946 return 0;
1947} 1947}
1948 1948
1949static int wm8962_readable_register(unsigned int reg) 1949static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg)
1950{ 1950{
1951 if (wm8962_reg_access[reg].read) 1951 if (wm8962_reg_access[reg].read)
1952 return 1; 1952 return 1;
@@ -3635,7 +3635,7 @@ static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
3635 struct snd_soc_codec *codec = wm8962->codec; 3635 struct snd_soc_codec *codec = wm8962->codec;
3636 3636
3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, 3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
3638 WM8962_GP2_LVL, value << WM8962_GP2_LVL_SHIFT); 3638 WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
3639} 3639}
3640 3640
3641static int wm8962_gpio_direction_out(struct gpio_chip *chip, 3641static int wm8962_gpio_direction_out(struct gpio_chip *chip,
@@ -3822,16 +3822,26 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3822 } 3822 }
3823 3823
3824 /* Latch volume update bits */ 3824 /* Latch volume update bits */
3825 reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; 3825 snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
3826 reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; 3826 WM8962_IN_VU, WM8962_IN_VU);
3827 reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; 3827 snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
3828 reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; 3828 WM8962_IN_VU, WM8962_IN_VU);
3829 reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; 3829 snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
3830 reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; 3830 WM8962_ADC_VU, WM8962_ADC_VU);
3831 reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; 3831 snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
3832 reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; 3832 WM8962_ADC_VU, WM8962_ADC_VU);
3833 reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; 3833 snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME,
3834 reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; 3834 WM8962_DAC_VU, WM8962_DAC_VU);
3835 snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME,
3836 WM8962_DAC_VU, WM8962_DAC_VU);
3837 snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
3838 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3839 snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
3840 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3841 snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
3842 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3843 snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
3844 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3835 3845
3836 wm8962_add_widgets(codec); 3846 wm8962_add_widgets(codec);
3837 3847
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 8dfb0a0da673..85e3e630e763 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -93,6 +93,7 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); 93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); 94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1); 95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
96static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
96 97
97static const struct snd_kcontrol_new wm8978_snd_controls[] = { 98static const struct snd_kcontrol_new wm8978_snd_controls[] = {
98 99
@@ -144,8 +145,8 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
144 145
145 SOC_SINGLE("DAC Playback Limiter Threshold", 146 SOC_SINGLE("DAC Playback Limiter Threshold",
146 WM8978_DAC_LIMITER_2, 4, 7, 0), 147 WM8978_DAC_LIMITER_2, 4, 7, 0),
147 SOC_SINGLE("DAC Playback Limiter Boost", 148 SOC_SINGLE_TLV("DAC Playback Limiter Volume",
148 WM8978_DAC_LIMITER_2, 0, 12, 0), 149 WM8978_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
149 150
150 SOC_ENUM("ALC Enable Switch", alc1), 151 SOC_ENUM("ALC Enable Switch", alc1),
151 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0), 152 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
@@ -967,7 +968,7 @@ static int wm8978_probe(struct snd_soc_codec *codec)
967 * written. 968 * written.
968 */ 969 */
969 for (i = 0; i < ARRAY_SIZE(update_reg); i++) 970 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
970 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100; 971 snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
971 972
972 /* Reset the codec */ 973 /* Reset the codec */
973 ret = snd_soc_write(codec, WM8978_RESET, 0); 974 ret = snd_soc_write(codec, WM8978_RESET, 0);
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
new file mode 100644
index 000000000000..28fdfd66661d
--- /dev/null
+++ b/sound/soc/codecs/wm8991.c
@@ -0,0 +1,1427 @@
1/*
2 * wm8991.c -- WM8991 ALSA Soc Audio driver
3 *
4 * Copyright 2007-2010 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31#include <asm/div64.h>
32
33#include "wm8991.h"
34
35struct wm8991_priv {
36 enum snd_soc_control_type control_type;
37 unsigned int pcmclk;
38};
39
40static const u16 wm8991_reg_defs[] = {
41 0x8991, /* R0 - Reset */
42 0x0000, /* R1 - Power Management (1) */
43 0x6000, /* R2 - Power Management (2) */
44 0x0000, /* R3 - Power Management (3) */
45 0x4050, /* R4 - Audio Interface (1) */
46 0x4000, /* R5 - Audio Interface (2) */
47 0x01C8, /* R6 - Clocking (1) */
48 0x0000, /* R7 - Clocking (2) */
49 0x0040, /* R8 - Audio Interface (3) */
50 0x0040, /* R9 - Audio Interface (4) */
51 0x0004, /* R10 - DAC CTRL */
52 0x00C0, /* R11 - Left DAC Digital Volume */
53 0x00C0, /* R12 - Right DAC Digital Volume */
54 0x0000, /* R13 - Digital Side Tone */
55 0x0100, /* R14 - ADC CTRL */
56 0x00C0, /* R15 - Left ADC Digital Volume */
57 0x00C0, /* R16 - Right ADC Digital Volume */
58 0x0000, /* R17 */
59 0x0000, /* R18 - GPIO CTRL 1 */
60 0x1000, /* R19 - GPIO1 & GPIO2 */
61 0x1010, /* R20 - GPIO3 & GPIO4 */
62 0x1010, /* R21 - GPIO5 & GPIO6 */
63 0x8000, /* R22 - GPIOCTRL 2 */
64 0x0800, /* R23 - GPIO_POL */
65 0x008B, /* R24 - Left Line Input 1&2 Volume */
66 0x008B, /* R25 - Left Line Input 3&4 Volume */
67 0x008B, /* R26 - Right Line Input 1&2 Volume */
68 0x008B, /* R27 - Right Line Input 3&4 Volume */
69 0x0000, /* R28 - Left Output Volume */
70 0x0000, /* R29 - Right Output Volume */
71 0x0066, /* R30 - Line Outputs Volume */
72 0x0022, /* R31 - Out3/4 Volume */
73 0x0079, /* R32 - Left OPGA Volume */
74 0x0079, /* R33 - Right OPGA Volume */
75 0x0003, /* R34 - Speaker Volume */
76 0x0003, /* R35 - ClassD1 */
77 0x0000, /* R36 */
78 0x0100, /* R37 - ClassD3 */
79 0x0000, /* R38 */
80 0x0000, /* R39 - Input Mixer1 */
81 0x0000, /* R40 - Input Mixer2 */
82 0x0000, /* R41 - Input Mixer3 */
83 0x0000, /* R42 - Input Mixer4 */
84 0x0000, /* R43 - Input Mixer5 */
85 0x0000, /* R44 - Input Mixer6 */
86 0x0000, /* R45 - Output Mixer1 */
87 0x0000, /* R46 - Output Mixer2 */
88 0x0000, /* R47 - Output Mixer3 */
89 0x0000, /* R48 - Output Mixer4 */
90 0x0000, /* R49 - Output Mixer5 */
91 0x0000, /* R50 - Output Mixer6 */
92 0x0180, /* R51 - Out3/4 Mixer */
93 0x0000, /* R52 - Line Mixer1 */
94 0x0000, /* R53 - Line Mixer2 */
95 0x0000, /* R54 - Speaker Mixer */
96 0x0000, /* R55 - Additional Control */
97 0x0000, /* R56 - AntiPOP1 */
98 0x0000, /* R57 - AntiPOP2 */
99 0x0000, /* R58 - MICBIAS */
100 0x0000, /* R59 */
101 0x0008, /* R60 - PLL1 */
102 0x0031, /* R61 - PLL2 */
103 0x0026, /* R62 - PLL3 */
104};
105
106#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
107
108static const unsigned int rec_mix_tlv[] = {
109 TLV_DB_RANGE_HEAD(1),
110 0, 7, TLV_DB_LINEAR_ITEM(-1500, 600),
111};
112
113static const unsigned int in_pga_tlv[] = {
114 TLV_DB_RANGE_HEAD(1),
115 0, 0x1F, TLV_DB_LINEAR_ITEM(-1650, 3000),
116};
117
118static const unsigned int out_mix_tlv[] = {
119 TLV_DB_RANGE_HEAD(1),
120 0, 7, TLV_DB_LINEAR_ITEM(0, -2100),
121};
122
123static const unsigned int out_pga_tlv[] = {
124 TLV_DB_RANGE_HEAD(1),
125 0, 127, TLV_DB_LINEAR_ITEM(-7300, 600),
126};
127
128static const unsigned int out_omix_tlv[] = {
129 TLV_DB_RANGE_HEAD(1),
130 0, 7, TLV_DB_LINEAR_ITEM(-600, 0),
131};
132
133static const unsigned int out_dac_tlv[] = {
134 TLV_DB_RANGE_HEAD(1),
135 0, 255, TLV_DB_LINEAR_ITEM(-7163, 0),
136};
137
138static const unsigned int in_adc_tlv[] = {
139 TLV_DB_RANGE_HEAD(1),
140 0, 255, TLV_DB_LINEAR_ITEM(-7163, 1763),
141};
142
143static const unsigned int out_sidetone_tlv[] = {
144 TLV_DB_RANGE_HEAD(1),
145 0, 31, TLV_DB_LINEAR_ITEM(-3600, 0),
146};
147
148static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol)
150{
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 int reg = kcontrol->private_value & 0xff;
153 int ret;
154 u16 val;
155
156 ret = snd_soc_put_volsw(kcontrol, ucontrol);
157 if (ret < 0)
158 return ret;
159
160 /* now hit the volume update bits (always bit 8) */
161 val = snd_soc_read(codec, reg);
162 return snd_soc_write(codec, reg, val | 0x0100);
163}
164
165static const char *wm8991_digital_sidetone[] =
166{"None", "Left ADC", "Right ADC", "Reserved"};
167
168static const struct soc_enum wm8991_left_digital_sidetone_enum =
169 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
170 WM8991_ADC_TO_DACL_SHIFT,
171 WM8991_ADC_TO_DACL_MASK,
172 wm8991_digital_sidetone);
173
174static const struct soc_enum wm8991_right_digital_sidetone_enum =
175 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
176 WM8991_ADC_TO_DACR_SHIFT,
177 WM8991_ADC_TO_DACR_MASK,
178 wm8991_digital_sidetone);
179
180static const char *wm8991_adcmode[] =
181{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
182
183static const struct soc_enum wm8991_right_adcmode_enum =
184 SOC_ENUM_SINGLE(WM8991_ADC_CTRL,
185 WM8991_ADC_HPF_CUT_SHIFT,
186 WM8991_ADC_HPF_CUT_MASK,
187 wm8991_adcmode);
188
189static const struct snd_kcontrol_new wm8991_snd_controls[] = {
190 /* INMIXL */
191 SOC_SINGLE("LIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L12MNBST_BIT, 1, 0),
192 SOC_SINGLE("LIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L34MNBST_BIT, 1, 0),
193 /* INMIXR */
194 SOC_SINGLE("RIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R12MNBST_BIT, 1, 0),
195 SOC_SINGLE("RIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R34MNBST_BIT, 1, 0),
196
197 /* LOMIX */
198 SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER3,
199 WM8991_LLI3LOVOL_SHIFT, WM8991_LLI3LOVOL_MASK, 1, out_mix_tlv),
200 SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
201 WM8991_LR12LOVOL_SHIFT, WM8991_LR12LOVOL_MASK, 1, out_mix_tlv),
202 SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
203 WM8991_LL12LOVOL_SHIFT, WM8991_LL12LOVOL_MASK, 1, out_mix_tlv),
204 SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER5,
205 WM8991_LRI3LOVOL_SHIFT, WM8991_LRI3LOVOL_MASK, 1, out_mix_tlv),
206 SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
207 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
208 SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
209 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
210
211 /* ROMIX */
212 SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER4,
213 WM8991_RRI3ROVOL_SHIFT, WM8991_RRI3ROVOL_MASK, 1, out_mix_tlv),
214 SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
215 WM8991_RL12ROVOL_SHIFT, WM8991_RL12ROVOL_MASK, 1, out_mix_tlv),
216 SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
217 WM8991_RR12ROVOL_SHIFT, WM8991_RR12ROVOL_MASK, 1, out_mix_tlv),
218 SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER6,
219 WM8991_RLI3ROVOL_SHIFT, WM8991_RLI3ROVOL_MASK, 1, out_mix_tlv),
220 SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
221 WM8991_RLBROVOL_SHIFT, WM8991_RLBROVOL_MASK, 1, out_mix_tlv),
222 SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
223 WM8991_RRBROVOL_SHIFT, WM8991_RRBROVOL_MASK, 1, out_mix_tlv),
224
225 /* LOUT */
226 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8991_LEFT_OUTPUT_VOLUME,
227 WM8991_LOUTVOL_SHIFT, WM8991_LOUTVOL_MASK, 0, out_pga_tlv),
228 SOC_SINGLE("LOUT ZC", WM8991_LEFT_OUTPUT_VOLUME, WM8991_LOZC_BIT, 1, 0),
229
230 /* ROUT */
231 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8991_RIGHT_OUTPUT_VOLUME,
232 WM8991_ROUTVOL_SHIFT, WM8991_ROUTVOL_MASK, 0, out_pga_tlv),
233 SOC_SINGLE("ROUT ZC", WM8991_RIGHT_OUTPUT_VOLUME, WM8991_ROZC_BIT, 1, 0),
234
235 /* LOPGA */
236 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8991_LEFT_OPGA_VOLUME,
237 WM8991_LOPGAVOL_SHIFT, WM8991_LOPGAVOL_MASK, 0, out_pga_tlv),
238 SOC_SINGLE("LOPGA ZC Switch", WM8991_LEFT_OPGA_VOLUME,
239 WM8991_LOPGAZC_BIT, 1, 0),
240
241 /* ROPGA */
242 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8991_RIGHT_OPGA_VOLUME,
243 WM8991_ROPGAVOL_SHIFT, WM8991_ROPGAVOL_MASK, 0, out_pga_tlv),
244 SOC_SINGLE("ROPGA ZC Switch", WM8991_RIGHT_OPGA_VOLUME,
245 WM8991_ROPGAZC_BIT, 1, 0),
246
247 SOC_SINGLE("LON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
248 WM8991_LONMUTE_BIT, 1, 0),
249 SOC_SINGLE("LOP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
250 WM8991_LOPMUTE_BIT, 1, 0),
251 SOC_SINGLE("LOP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
252 WM8991_LOATTN_BIT, 1, 0),
253 SOC_SINGLE("RON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
254 WM8991_RONMUTE_BIT, 1, 0),
255 SOC_SINGLE("ROP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
256 WM8991_ROPMUTE_BIT, 1, 0),
257 SOC_SINGLE("ROP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
258 WM8991_ROATTN_BIT, 1, 0),
259
260 SOC_SINGLE("OUT3 Mute Switch", WM8991_OUT3_4_VOLUME,
261 WM8991_OUT3MUTE_BIT, 1, 0),
262 SOC_SINGLE("OUT3 Attenuation Switch", WM8991_OUT3_4_VOLUME,
263 WM8991_OUT3ATTN_BIT, 1, 0),
264
265 SOC_SINGLE("OUT4 Mute Switch", WM8991_OUT3_4_VOLUME,
266 WM8991_OUT4MUTE_BIT, 1, 0),
267 SOC_SINGLE("OUT4 Attenuation Switch", WM8991_OUT3_4_VOLUME,
268 WM8991_OUT4ATTN_BIT, 1, 0),
269
270 SOC_SINGLE("Speaker Mode Switch", WM8991_CLASSD1,
271 WM8991_CDMODE_BIT, 1, 0),
272
273 SOC_SINGLE("Speaker Output Attenuation Volume", WM8991_SPEAKER_VOLUME,
274 WM8991_SPKVOL_SHIFT, WM8991_SPKVOL_MASK, 0),
275 SOC_SINGLE("Speaker DC Boost Volume", WM8991_CLASSD3,
276 WM8991_DCGAIN_SHIFT, WM8991_DCGAIN_MASK, 0),
277 SOC_SINGLE("Speaker AC Boost Volume", WM8991_CLASSD3,
278 WM8991_ACGAIN_SHIFT, WM8991_ACGAIN_MASK, 0),
279
280 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
281 WM8991_LEFT_DAC_DIGITAL_VOLUME,
282 WM8991_DACL_VOL_SHIFT,
283 WM8991_DACL_VOL_MASK,
284 0,
285 out_dac_tlv),
286
287 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
288 WM8991_RIGHT_DAC_DIGITAL_VOLUME,
289 WM8991_DACR_VOL_SHIFT,
290 WM8991_DACR_VOL_MASK,
291 0,
292 out_dac_tlv),
293
294 SOC_ENUM("Left Digital Sidetone", wm8991_left_digital_sidetone_enum),
295 SOC_ENUM("Right Digital Sidetone", wm8991_right_digital_sidetone_enum),
296
297 SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
298 WM8991_ADCL_DAC_SVOL_SHIFT, WM8991_ADCL_DAC_SVOL_MASK, 0,
299 out_sidetone_tlv),
300 SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
301 WM8991_ADCR_DAC_SVOL_SHIFT, WM8991_ADCR_DAC_SVOL_MASK, 0,
302 out_sidetone_tlv),
303
304 SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8991_ADC_CTRL,
305 WM8991_ADC_HPF_ENA_BIT, 1, 0),
306
307 SOC_ENUM("ADC HPF Mode", wm8991_right_adcmode_enum),
308
309 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
310 WM8991_LEFT_ADC_DIGITAL_VOLUME,
311 WM8991_ADCL_VOL_SHIFT,
312 WM8991_ADCL_VOL_MASK,
313 0,
314 in_adc_tlv),
315
316 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
317 WM8991_RIGHT_ADC_DIGITAL_VOLUME,
318 WM8991_ADCR_VOL_SHIFT,
319 WM8991_ADCR_VOL_MASK,
320 0,
321 in_adc_tlv),
322
323 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
324 WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
325 WM8991_LIN12VOL_SHIFT,
326 WM8991_LIN12VOL_MASK,
327 0,
328 in_pga_tlv),
329
330 SOC_SINGLE("LIN12 ZC Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
331 WM8991_LI12ZC_BIT, 1, 0),
332
333 SOC_SINGLE("LIN12 Mute Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
334 WM8991_LI12MUTE_BIT, 1, 0),
335
336 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
337 WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
338 WM8991_LIN34VOL_SHIFT,
339 WM8991_LIN34VOL_MASK,
340 0,
341 in_pga_tlv),
342
343 SOC_SINGLE("LIN34 ZC Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
344 WM8991_LI34ZC_BIT, 1, 0),
345
346 SOC_SINGLE("LIN34 Mute Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
347 WM8991_LI34MUTE_BIT, 1, 0),
348
349 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
350 WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
351 WM8991_RIN12VOL_SHIFT,
352 WM8991_RIN12VOL_MASK,
353 0,
354 in_pga_tlv),
355
356 SOC_SINGLE("RIN12 ZC Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
357 WM8991_RI12ZC_BIT, 1, 0),
358
359 SOC_SINGLE("RIN12 Mute Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
360 WM8991_RI12MUTE_BIT, 1, 0),
361
362 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
363 WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
364 WM8991_RIN34VOL_SHIFT,
365 WM8991_RIN34VOL_MASK,
366 0,
367 in_pga_tlv),
368
369 SOC_SINGLE("RIN34 ZC Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
370 WM8991_RI34ZC_BIT, 1, 0),
371
372 SOC_SINGLE("RIN34 Mute Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
373 WM8991_RI34MUTE_BIT, 1, 0),
374};
375
376/*
377 * _DAPM_ Controls
378 */
379static int inmixer_event(struct snd_soc_dapm_widget *w,
380 struct snd_kcontrol *kcontrol, int event)
381{
382 u16 reg, fakepower;
383
384 reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
385 fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
386
387 if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
388 (1 << WM8991_AINLMUX_PWR_BIT)))
389 reg |= WM8991_AINL_ENA;
390 else
391 reg &= ~WM8991_AINL_ENA;
392
393 if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
394 (1 << WM8991_AINRMUX_PWR_BIT)))
395 reg |= WM8991_AINR_ENA;
396 else
397 reg &= ~WM8991_AINL_ENA;
398
399 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
400 return 0;
401}
402
403static int outmixer_event(struct snd_soc_dapm_widget *w,
404 struct snd_kcontrol *kcontrol, int event)
405{
406 u32 reg_shift = kcontrol->private_value & 0xfff;
407 int ret = 0;
408 u16 reg;
409
410 switch (reg_shift) {
411 case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
412 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1);
413 if (reg & WM8991_LDLO) {
414 printk(KERN_WARNING
415 "Cannot set as Output Mixer 1 LDLO Set\n");
416 ret = -1;
417 }
418 break;
419
420 case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
421 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2);
422 if (reg & WM8991_RDRO) {
423 printk(KERN_WARNING
424 "Cannot set as Output Mixer 2 RDRO Set\n");
425 ret = -1;
426 }
427 break;
428
429 case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
430 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
431 if (reg & WM8991_LDSPK) {
432 printk(KERN_WARNING
433 "Cannot set as Speaker Mixer LDSPK Set\n");
434 ret = -1;
435 }
436 break;
437
438 case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
439 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
440 if (reg & WM8991_RDSPK) {
441 printk(KERN_WARNING
442 "Cannot set as Speaker Mixer RDSPK Set\n");
443 ret = -1;
444 }
445 break;
446 }
447
448 return ret;
449}
450
451/* INMIX dB values */
452static const unsigned int in_mix_tlv[] = {
453 TLV_DB_RANGE_HEAD(1),
454 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600),
455};
456
457/* Left In PGA Connections */
458static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = {
459 SOC_DAPM_SINGLE("LIN1 Switch", WM8991_INPUT_MIXER2, WM8991_LMN1_BIT, 1, 0),
460 SOC_DAPM_SINGLE("LIN2 Switch", WM8991_INPUT_MIXER2, WM8991_LMP2_BIT, 1, 0),
461};
462
463static const struct snd_kcontrol_new wm8991_dapm_lin34_pga_controls[] = {
464 SOC_DAPM_SINGLE("LIN3 Switch", WM8991_INPUT_MIXER2, WM8991_LMN3_BIT, 1, 0),
465 SOC_DAPM_SINGLE("LIN4 Switch", WM8991_INPUT_MIXER2, WM8991_LMP4_BIT, 1, 0),
466};
467
468/* Right In PGA Connections */
469static const struct snd_kcontrol_new wm8991_dapm_rin12_pga_controls[] = {
470 SOC_DAPM_SINGLE("RIN1 Switch", WM8991_INPUT_MIXER2, WM8991_RMN1_BIT, 1, 0),
471 SOC_DAPM_SINGLE("RIN2 Switch", WM8991_INPUT_MIXER2, WM8991_RMP2_BIT, 1, 0),
472};
473
474static const struct snd_kcontrol_new wm8991_dapm_rin34_pga_controls[] = {
475 SOC_DAPM_SINGLE("RIN3 Switch", WM8991_INPUT_MIXER2, WM8991_RMN3_BIT, 1, 0),
476 SOC_DAPM_SINGLE("RIN4 Switch", WM8991_INPUT_MIXER2, WM8991_RMP4_BIT, 1, 0),
477};
478
479/* INMIXL */
480static const struct snd_kcontrol_new wm8991_dapm_inmixl_controls[] = {
481 SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8991_INPUT_MIXER3,
482 WM8991_LDBVOL_SHIFT, WM8991_LDBVOL_MASK, 0, in_mix_tlv),
483 SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8991_INPUT_MIXER5, WM8991_LI2BVOL_SHIFT,
484 7, 0, in_mix_tlv),
485 SOC_DAPM_SINGLE("LINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
486 1, 0),
487 SOC_DAPM_SINGLE("LINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
488 1, 0),
489};
490
491/* INMIXR */
492static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = {
493 SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8991_INPUT_MIXER4,
494 WM8991_RDBVOL_SHIFT, WM8991_RDBVOL_MASK, 0, in_mix_tlv),
495 SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8991_INPUT_MIXER6, WM8991_RI2BVOL_SHIFT,
496 7, 0, in_mix_tlv),
497 SOC_DAPM_SINGLE("RINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
498 1, 0),
499 SOC_DAPM_SINGLE("RINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
500 1, 0),
501};
502
503/* AINLMUX */
504static const char *wm8991_ainlmux[] =
505{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
506
507static const struct soc_enum wm8991_ainlmux_enum =
508 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT,
509 ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux);
510
511static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
512 SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum);
513
514/* DIFFINL */
515
516/* AINRMUX */
517static const char *wm8991_ainrmux[] =
518{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
519
520static const struct soc_enum wm8991_ainrmux_enum =
521 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT,
522 ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux);
523
524static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls =
525 SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum);
526
527/* RXVOICE */
528static const struct snd_kcontrol_new wm8991_dapm_rxvoice_controls[] = {
529 SOC_DAPM_SINGLE_TLV("LIN4RXN", WM8991_INPUT_MIXER5, WM8991_LR4BVOL_SHIFT,
530 WM8991_LR4BVOL_MASK, 0, in_mix_tlv),
531 SOC_DAPM_SINGLE_TLV("RIN4RXP", WM8991_INPUT_MIXER6, WM8991_RL4BVOL_SHIFT,
532 WM8991_RL4BVOL_MASK, 0, in_mix_tlv),
533};
534
535/* LOMIX */
536static const struct snd_kcontrol_new wm8991_dapm_lomix_controls[] = {
537 SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
538 WM8991_LRBLO_BIT, 1, 0),
539 SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
540 WM8991_LLBLO_BIT, 1, 0),
541 SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
542 WM8991_LRI3LO_BIT, 1, 0),
543 SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
544 WM8991_LLI3LO_BIT, 1, 0),
545 SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
546 WM8991_LR12LO_BIT, 1, 0),
547 SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
548 WM8991_LL12LO_BIT, 1, 0),
549 SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8991_OUTPUT_MIXER1,
550 WM8991_LDLO_BIT, 1, 0),
551};
552
553/* ROMIX */
554static const struct snd_kcontrol_new wm8991_dapm_romix_controls[] = {
555 SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
556 WM8991_RLBRO_BIT, 1, 0),
557 SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
558 WM8991_RRBRO_BIT, 1, 0),
559 SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
560 WM8991_RLI3RO_BIT, 1, 0),
561 SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
562 WM8991_RRI3RO_BIT, 1, 0),
563 SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
564 WM8991_RL12RO_BIT, 1, 0),
565 SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
566 WM8991_RR12RO_BIT, 1, 0),
567 SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8991_OUTPUT_MIXER2,
568 WM8991_RDRO_BIT, 1, 0),
569};
570
571/* LONMIX */
572static const struct snd_kcontrol_new wm8991_dapm_lonmix_controls[] = {
573 SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
574 WM8991_LLOPGALON_BIT, 1, 0),
575 SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER1,
576 WM8991_LROPGALON_BIT, 1, 0),
577 SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8991_LINE_MIXER1,
578 WM8991_LOPLON_BIT, 1, 0),
579};
580
581/* LOPMIX */
582static const struct snd_kcontrol_new wm8991_dapm_lopmix_controls[] = {
583 SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER1,
584 WM8991_LR12LOP_BIT, 1, 0),
585 SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER1,
586 WM8991_LL12LOP_BIT, 1, 0),
587 SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
588 WM8991_LLOPGALOP_BIT, 1, 0),
589};
590
591/* RONMIX */
592static const struct snd_kcontrol_new wm8991_dapm_ronmix_controls[] = {
593 SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
594 WM8991_RROPGARON_BIT, 1, 0),
595 SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER2,
596 WM8991_RLOPGARON_BIT, 1, 0),
597 SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8991_LINE_MIXER2,
598 WM8991_ROPRON_BIT, 1, 0),
599};
600
601/* ROPMIX */
602static const struct snd_kcontrol_new wm8991_dapm_ropmix_controls[] = {
603 SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER2,
604 WM8991_RL12ROP_BIT, 1, 0),
605 SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER2,
606 WM8991_RR12ROP_BIT, 1, 0),
607 SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
608 WM8991_RROPGAROP_BIT, 1, 0),
609};
610
611/* OUT3MIX */
612static const struct snd_kcontrol_new wm8991_dapm_out3mix_controls[] = {
613 SOC_DAPM_SINGLE("OUT3MIX LIN4RXN Bypass Switch", WM8991_OUT3_4_MIXER,
614 WM8991_LI4O3_BIT, 1, 0),
615 SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8991_OUT3_4_MIXER,
616 WM8991_LPGAO3_BIT, 1, 0),
617};
618
619/* OUT4MIX */
620static const struct snd_kcontrol_new wm8991_dapm_out4mix_controls[] = {
621 SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8991_OUT3_4_MIXER,
622 WM8991_RPGAO4_BIT, 1, 0),
623 SOC_DAPM_SINGLE("OUT4MIX RIN4RXP Bypass Switch", WM8991_OUT3_4_MIXER,
624 WM8991_RI4O4_BIT, 1, 0),
625};
626
627/* SPKMIX */
628static const struct snd_kcontrol_new wm8991_dapm_spkmix_controls[] = {
629 SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
630 WM8991_LI2SPK_BIT, 1, 0),
631 SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8991_SPEAKER_MIXER,
632 WM8991_LB2SPK_BIT, 1, 0),
633 SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8991_SPEAKER_MIXER,
634 WM8991_LOPGASPK_BIT, 1, 0),
635 SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8991_SPEAKER_MIXER,
636 WM8991_LDSPK_BIT, 1, 0),
637 SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8991_SPEAKER_MIXER,
638 WM8991_RDSPK_BIT, 1, 0),
639 SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8991_SPEAKER_MIXER,
640 WM8991_ROPGASPK_BIT, 1, 0),
641 SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8991_SPEAKER_MIXER,
642 WM8991_RL12ROP_BIT, 1, 0),
643 SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
644 WM8991_RI2SPK_BIT, 1, 0),
645};
646
647static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
648 /* Input Side */
649 /* Input Lines */
650 SND_SOC_DAPM_INPUT("LIN1"),
651 SND_SOC_DAPM_INPUT("LIN2"),
652 SND_SOC_DAPM_INPUT("LIN3"),
653 SND_SOC_DAPM_INPUT("LIN4RXN"),
654 SND_SOC_DAPM_INPUT("RIN3"),
655 SND_SOC_DAPM_INPUT("RIN4RXP"),
656 SND_SOC_DAPM_INPUT("RIN1"),
657 SND_SOC_DAPM_INPUT("RIN2"),
658 SND_SOC_DAPM_INPUT("Internal ADC Source"),
659
660 /* DACs */
661 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
662 WM8991_ADCL_ENA_BIT, 0),
663 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8991_POWER_MANAGEMENT_2,
664 WM8991_ADCR_ENA_BIT, 0),
665
666 /* Input PGAs */
667 SND_SOC_DAPM_MIXER("LIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN12_ENA_BIT,
668 0, &wm8991_dapm_lin12_pga_controls[0],
669 ARRAY_SIZE(wm8991_dapm_lin12_pga_controls)),
670 SND_SOC_DAPM_MIXER("LIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN34_ENA_BIT,
671 0, &wm8991_dapm_lin34_pga_controls[0],
672 ARRAY_SIZE(wm8991_dapm_lin34_pga_controls)),
673 SND_SOC_DAPM_MIXER("RIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN12_ENA_BIT,
674 0, &wm8991_dapm_rin12_pga_controls[0],
675 ARRAY_SIZE(wm8991_dapm_rin12_pga_controls)),
676 SND_SOC_DAPM_MIXER("RIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN34_ENA_BIT,
677 0, &wm8991_dapm_rin34_pga_controls[0],
678 ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
679
680 /* INMIXL */
681 SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0,
682 &wm8991_dapm_inmixl_controls[0],
683 ARRAY_SIZE(wm8991_dapm_inmixl_controls),
684 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
685
686 /* AINLMUX */
687 SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0,
688 &wm8991_dapm_ainlmux_controls, inmixer_event,
689 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
690
691 /* INMIXR */
692 SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0,
693 &wm8991_dapm_inmixr_controls[0],
694 ARRAY_SIZE(wm8991_dapm_inmixr_controls),
695 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
696
697 /* AINRMUX */
698 SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0,
699 &wm8991_dapm_ainrmux_controls, inmixer_event,
700 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
701
702 /* Output Side */
703 /* DACs */
704 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8991_POWER_MANAGEMENT_3,
705 WM8991_DACL_ENA_BIT, 0),
706 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8991_POWER_MANAGEMENT_3,
707 WM8991_DACR_ENA_BIT, 0),
708
709 /* LOMIX */
710 SND_SOC_DAPM_MIXER_E("LOMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOMIX_ENA_BIT,
711 0, &wm8991_dapm_lomix_controls[0],
712 ARRAY_SIZE(wm8991_dapm_lomix_controls),
713 outmixer_event, SND_SOC_DAPM_PRE_REG),
714
715 /* LONMIX */
716 SND_SOC_DAPM_MIXER("LONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LON_ENA_BIT, 0,
717 &wm8991_dapm_lonmix_controls[0],
718 ARRAY_SIZE(wm8991_dapm_lonmix_controls)),
719
720 /* LOPMIX */
721 SND_SOC_DAPM_MIXER("LOPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOP_ENA_BIT, 0,
722 &wm8991_dapm_lopmix_controls[0],
723 ARRAY_SIZE(wm8991_dapm_lopmix_controls)),
724
725 /* OUT3MIX */
726 SND_SOC_DAPM_MIXER("OUT3MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT3_ENA_BIT, 0,
727 &wm8991_dapm_out3mix_controls[0],
728 ARRAY_SIZE(wm8991_dapm_out3mix_controls)),
729
730 /* SPKMIX */
731 SND_SOC_DAPM_MIXER_E("SPKMIX", WM8991_POWER_MANAGEMENT_1, WM8991_SPK_ENA_BIT, 0,
732 &wm8991_dapm_spkmix_controls[0],
733 ARRAY_SIZE(wm8991_dapm_spkmix_controls), outmixer_event,
734 SND_SOC_DAPM_PRE_REG),
735
736 /* OUT4MIX */
737 SND_SOC_DAPM_MIXER("OUT4MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT4_ENA_BIT, 0,
738 &wm8991_dapm_out4mix_controls[0],
739 ARRAY_SIZE(wm8991_dapm_out4mix_controls)),
740
741 /* ROPMIX */
742 SND_SOC_DAPM_MIXER("ROPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROP_ENA_BIT, 0,
743 &wm8991_dapm_ropmix_controls[0],
744 ARRAY_SIZE(wm8991_dapm_ropmix_controls)),
745
746 /* RONMIX */
747 SND_SOC_DAPM_MIXER("RONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_RON_ENA_BIT, 0,
748 &wm8991_dapm_ronmix_controls[0],
749 ARRAY_SIZE(wm8991_dapm_ronmix_controls)),
750
751 /* ROMIX */
752 SND_SOC_DAPM_MIXER_E("ROMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROMIX_ENA_BIT,
753 0, &wm8991_dapm_romix_controls[0],
754 ARRAY_SIZE(wm8991_dapm_romix_controls),
755 outmixer_event, SND_SOC_DAPM_PRE_REG),
756
757 /* LOUT PGA */
758 SND_SOC_DAPM_PGA("LOUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_LOUT_ENA_BIT, 0,
759 NULL, 0),
760
761 /* ROUT PGA */
762 SND_SOC_DAPM_PGA("ROUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_ROUT_ENA_BIT, 0,
763 NULL, 0),
764
765 /* LOPGA */
766 SND_SOC_DAPM_PGA("LOPGA", WM8991_POWER_MANAGEMENT_3, WM8991_LOPGA_ENA_BIT, 0,
767 NULL, 0),
768
769 /* ROPGA */
770 SND_SOC_DAPM_PGA("ROPGA", WM8991_POWER_MANAGEMENT_3, WM8991_ROPGA_ENA_BIT, 0,
771 NULL, 0),
772
773 /* MICBIAS */
774 SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1,
775 WM8991_MICBIAS_ENA_BIT, 0),
776
777 SND_SOC_DAPM_OUTPUT("LON"),
778 SND_SOC_DAPM_OUTPUT("LOP"),
779 SND_SOC_DAPM_OUTPUT("OUT3"),
780 SND_SOC_DAPM_OUTPUT("LOUT"),
781 SND_SOC_DAPM_OUTPUT("SPKN"),
782 SND_SOC_DAPM_OUTPUT("SPKP"),
783 SND_SOC_DAPM_OUTPUT("ROUT"),
784 SND_SOC_DAPM_OUTPUT("OUT4"),
785 SND_SOC_DAPM_OUTPUT("ROP"),
786 SND_SOC_DAPM_OUTPUT("RON"),
787 SND_SOC_DAPM_OUTPUT("OUT"),
788
789 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
790};
791
792static const struct snd_soc_dapm_route audio_map[] = {
793 /* Make DACs turn on when playing even if not mixed into any outputs */
794 {"Internal DAC Sink", NULL, "Left DAC"},
795 {"Internal DAC Sink", NULL, "Right DAC"},
796
797 /* Make ADCs turn on when recording even if not mixed from any inputs */
798 {"Left ADC", NULL, "Internal ADC Source"},
799 {"Right ADC", NULL, "Internal ADC Source"},
800
801 /* Input Side */
802 /* LIN12 PGA */
803 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
804 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
805 /* LIN34 PGA */
806 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
807 {"LIN34 PGA", "LIN4 Switch", "LIN4RXN"},
808 /* INMIXL */
809 {"INMIXL", "Record Left Volume", "LOMIX"},
810 {"INMIXL", "LIN2 Volume", "LIN2"},
811 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
812 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
813 /* AINLMUX */
814 {"AINLMUX", "INMIXL Mix", "INMIXL"},
815 {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
816 {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
817 {"AINLMUX", "RXVOICE Mix", "LIN4RXN"},
818 {"AINLMUX", "RXVOICE Mix", "RIN4RXP"},
819 /* ADC */
820 {"Left ADC", NULL, "AINLMUX"},
821
822 /* RIN12 PGA */
823 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
824 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
825 /* RIN34 PGA */
826 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
827 {"RIN34 PGA", "RIN4 Switch", "RIN4RXP"},
828 /* INMIXL */
829 {"INMIXR", "Record Right Volume", "ROMIX"},
830 {"INMIXR", "RIN2 Volume", "RIN2"},
831 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
832 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
833 /* AINRMUX */
834 {"AINRMUX", "INMIXR Mix", "INMIXR"},
835 {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
836 {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
837 {"AINRMUX", "RXVOICE Mix", "LIN4RXN"},
838 {"AINRMUX", "RXVOICE Mix", "RIN4RXP"},
839 /* ADC */
840 {"Right ADC", NULL, "AINRMUX"},
841
842 /* LOMIX */
843 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
844 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
845 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
846 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
847 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
848 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
849 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
850
851 /* ROMIX */
852 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
853 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
854 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
855 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
856 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
857 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
858 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
859
860 /* SPKMIX */
861 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
862 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
863 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
864 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
865 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
866 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
867 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
868 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
869
870 /* LONMIX */
871 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
872 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
873 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
874
875 /* LOPMIX */
876 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
877 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
878 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
879
880 /* OUT3MIX */
881 {"OUT3MIX", "OUT3MIX LIN4RXN Bypass Switch", "LIN4RXN"},
882 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
883
884 /* OUT4MIX */
885 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
886 {"OUT4MIX", "OUT4MIX RIN4RXP Bypass Switch", "RIN4RXP"},
887
888 /* RONMIX */
889 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
890 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
891 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
892
893 /* ROPMIX */
894 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
895 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
896 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
897
898 /* Out Mixer PGAs */
899 {"LOPGA", NULL, "LOMIX"},
900 {"ROPGA", NULL, "ROMIX"},
901
902 {"LOUT PGA", NULL, "LOMIX"},
903 {"ROUT PGA", NULL, "ROMIX"},
904
905 /* Output Pins */
906 {"LON", NULL, "LONMIX"},
907 {"LOP", NULL, "LOPMIX"},
908 {"OUT", NULL, "OUT3MIX"},
909 {"LOUT", NULL, "LOUT PGA"},
910 {"SPKN", NULL, "SPKMIX"},
911 {"ROUT", NULL, "ROUT PGA"},
912 {"OUT4", NULL, "OUT4MIX"},
913 {"ROP", NULL, "ROPMIX"},
914 {"RON", NULL, "RONMIX"},
915};
916
917/* PLL divisors */
918struct _pll_div {
919 u32 div2;
920 u32 n;
921 u32 k;
922};
923
924/* The size in bits of the pll divide multiplied by 10
925 * to allow rounding later */
926#define FIXED_PLL_SIZE ((1 << 16) * 10)
927
928static void pll_factors(struct _pll_div *pll_div, unsigned int target,
929 unsigned int source)
930{
931 u64 Kpart;
932 unsigned int K, Ndiv, Nmod;
933
934
935 Ndiv = target / source;
936 if (Ndiv < 6) {
937 source >>= 1;
938 pll_div->div2 = 1;
939 Ndiv = target / source;
940 } else
941 pll_div->div2 = 0;
942
943 if ((Ndiv < 6) || (Ndiv > 12))
944 printk(KERN_WARNING
945 "WM8991 N value outwith recommended range! N = %d\n", Ndiv);
946
947 pll_div->n = Ndiv;
948 Nmod = target % source;
949 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
950
951 do_div(Kpart, source);
952
953 K = Kpart & 0xFFFFFFFF;
954
955 /* Check if we need to round */
956 if ((K % 10) >= 5)
957 K += 5;
958
959 /* Move down to proper range now rounding is done */
960 K /= 10;
961
962 pll_div->k = K;
963}
964
965static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
966 int pll_id, int src, unsigned int freq_in, unsigned int freq_out)
967{
968 u16 reg;
969 struct snd_soc_codec *codec = codec_dai->codec;
970 struct _pll_div pll_div;
971
972 if (freq_in && freq_out) {
973 pll_factors(&pll_div, freq_out * 4, freq_in);
974
975 /* Turn on PLL */
976 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
977 reg |= WM8991_PLL_ENA;
978 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
979
980 /* sysclk comes from PLL */
981 reg = snd_soc_read(codec, WM8991_CLOCKING_2);
982 snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
983
984 /* set up N , fractional mode and pre-divisor if neccessary */
985 snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM |
986 (pll_div.div2 ? WM8991_PRESCALE : 0));
987 snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8));
988 snd_soc_write(codec, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
989 } else {
990 /* Turn on PLL */
991 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
992 reg &= ~WM8991_PLL_ENA;
993 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
994 }
995 return 0;
996}
997
998/*
999 * Set's ADC and Voice DAC format.
1000 */
1001static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
1002 unsigned int fmt)
1003{
1004 struct snd_soc_codec *codec = codec_dai->codec;
1005 u16 audio1, audio3;
1006
1007 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1008 audio3 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_3);
1009
1010 /* set master/slave audio interface */
1011 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1012 case SND_SOC_DAIFMT_CBS_CFS:
1013 audio3 &= ~WM8991_AIF_MSTR1;
1014 break;
1015 case SND_SOC_DAIFMT_CBM_CFM:
1016 audio3 |= WM8991_AIF_MSTR1;
1017 break;
1018 default:
1019 return -EINVAL;
1020 }
1021
1022 audio1 &= ~WM8991_AIF_FMT_MASK;
1023
1024 /* interface format */
1025 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1026 case SND_SOC_DAIFMT_I2S:
1027 audio1 |= WM8991_AIF_TMF_I2S;
1028 audio1 &= ~WM8991_AIF_LRCLK_INV;
1029 break;
1030 case SND_SOC_DAIFMT_RIGHT_J:
1031 audio1 |= WM8991_AIF_TMF_RIGHTJ;
1032 audio1 &= ~WM8991_AIF_LRCLK_INV;
1033 break;
1034 case SND_SOC_DAIFMT_LEFT_J:
1035 audio1 |= WM8991_AIF_TMF_LEFTJ;
1036 audio1 &= ~WM8991_AIF_LRCLK_INV;
1037 break;
1038 case SND_SOC_DAIFMT_DSP_A:
1039 audio1 |= WM8991_AIF_TMF_DSP;
1040 audio1 &= ~WM8991_AIF_LRCLK_INV;
1041 break;
1042 case SND_SOC_DAIFMT_DSP_B:
1043 audio1 |= WM8991_AIF_TMF_DSP | WM8991_AIF_LRCLK_INV;
1044 break;
1045 default:
1046 return -EINVAL;
1047 }
1048
1049 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1050 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_3, audio3);
1051 return 0;
1052}
1053
1054static int wm8991_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1055 int div_id, int div)
1056{
1057 struct snd_soc_codec *codec = codec_dai->codec;
1058 u16 reg;
1059
1060 switch (div_id) {
1061 case WM8991_MCLK_DIV:
1062 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1063 ~WM8991_MCLK_DIV_MASK;
1064 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1065 break;
1066 case WM8991_DACCLK_DIV:
1067 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1068 ~WM8991_DAC_CLKDIV_MASK;
1069 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1070 break;
1071 case WM8991_ADCCLK_DIV:
1072 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1073 ~WM8991_ADC_CLKDIV_MASK;
1074 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1075 break;
1076 case WM8991_BCLK_DIV:
1077 reg = snd_soc_read(codec, WM8991_CLOCKING_1) &
1078 ~WM8991_BCLK_DIV_MASK;
1079 snd_soc_write(codec, WM8991_CLOCKING_1, reg | div);
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 return 0;
1086}
1087
1088/*
1089 * Set PCM DAI bit size and sample rate.
1090 */
1091static int wm8991_hw_params(struct snd_pcm_substream *substream,
1092 struct snd_pcm_hw_params *params,
1093 struct snd_soc_dai *dai)
1094{
1095 struct snd_soc_codec *codec = dai->codec;
1096 u16 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1097
1098 audio1 &= ~WM8991_AIF_WL_MASK;
1099 /* bit size */
1100 switch (params_format(params)) {
1101 case SNDRV_PCM_FORMAT_S16_LE:
1102 break;
1103 case SNDRV_PCM_FORMAT_S20_3LE:
1104 audio1 |= WM8991_AIF_WL_20BITS;
1105 break;
1106 case SNDRV_PCM_FORMAT_S24_LE:
1107 audio1 |= WM8991_AIF_WL_24BITS;
1108 break;
1109 case SNDRV_PCM_FORMAT_S32_LE:
1110 audio1 |= WM8991_AIF_WL_32BITS;
1111 break;
1112 }
1113
1114 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1115 return 0;
1116}
1117
1118static int wm8991_mute(struct snd_soc_dai *dai, int mute)
1119{
1120 struct snd_soc_codec *codec = dai->codec;
1121 u16 val;
1122
1123 val = snd_soc_read(codec, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
1124 if (mute)
1125 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1126 else
1127 snd_soc_write(codec, WM8991_DAC_CTRL, val);
1128 return 0;
1129}
1130
1131static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1132 enum snd_soc_bias_level level)
1133{
1134 u16 val;
1135
1136 switch (level) {
1137 case SND_SOC_BIAS_ON:
1138 break;
1139
1140 case SND_SOC_BIAS_PREPARE:
1141 /* VMID=2*50k */
1142 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1143 ~WM8991_VMID_MODE_MASK;
1144 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x2);
1145 break;
1146
1147 case SND_SOC_BIAS_STANDBY:
1148 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1149 snd_soc_cache_sync(codec);
1150 /* Enable all output discharge bits */
1151 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1152 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1153 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1154 WM8991_DIS_ROUT);
1155
1156 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1157 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1158 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1159 WM8991_VMIDTOG);
1160
1161 /* Delay to allow output caps to discharge */
1162 msleep(300);
1163
1164 /* Disable VMIDTOG */
1165 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1166 WM8991_BUFDCOPEN | WM8991_POBCTRL);
1167
1168 /* disable all output discharge bits */
1169 snd_soc_write(codec, WM8991_ANTIPOP1, 0);
1170
1171 /* Enable outputs */
1172 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1b00);
1173
1174 msleep(50);
1175
1176 /* Enable VMID at 2x50k */
1177 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f02);
1178
1179 msleep(100);
1180
1181 /* Enable VREF */
1182 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1183
1184 msleep(600);
1185
1186 /* Enable BUFIOEN */
1187 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1188 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1189 WM8991_BUFIOEN);
1190
1191 /* Disable outputs */
1192 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x3);
1193
1194 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1195 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_BUFIOEN);
1196 }
1197
1198 /* VMID=2*250k */
1199 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1200 ~WM8991_VMID_MODE_MASK;
1201 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x4);
1202 break;
1203
1204 case SND_SOC_BIAS_OFF:
1205 /* Enable POBCTRL and SOFT_ST */
1206 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1207 WM8991_POBCTRL | WM8991_BUFIOEN);
1208
1209 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1210 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1211 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1212 WM8991_BUFIOEN);
1213
1214 /* mute DAC */
1215 val = snd_soc_read(codec, WM8991_DAC_CTRL);
1216 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1217
1218 /* Enable any disabled outputs */
1219 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1220
1221 /* Disable VMID */
1222 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f01);
1223
1224 msleep(300);
1225
1226 /* Enable all output discharge bits */
1227 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1228 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1229 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1230 WM8991_DIS_ROUT);
1231
1232 /* Disable VREF */
1233 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x0);
1234
1235 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1236 snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
1237 codec->cache_sync = 1;
1238 break;
1239 }
1240
1241 codec->dapm.bias_level = level;
1242 return 0;
1243}
1244
1245static int wm8991_suspend(struct snd_soc_codec *codec, pm_message_t state)
1246{
1247 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1248 return 0;
1249}
1250
1251static int wm8991_resume(struct snd_soc_codec *codec)
1252{
1253 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1254 return 0;
1255}
1256
1257/* power down chip */
1258static int wm8991_remove(struct snd_soc_codec *codec)
1259{
1260 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1261 return 0;
1262}
1263
1264static int wm8991_probe(struct snd_soc_codec *codec)
1265{
1266 struct wm8991_priv *wm8991;
1267 int ret;
1268 unsigned int reg;
1269
1270 wm8991 = snd_soc_codec_get_drvdata(codec);
1271
1272 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type);
1273 if (ret < 0) {
1274 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1275 return ret;
1276 }
1277
1278 ret = wm8991_reset(codec);
1279 if (ret < 0) {
1280 dev_err(codec->dev, "Failed to issue reset\n");
1281 return ret;
1282 }
1283
1284 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1285
1286 reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4);
1287 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1);
1288
1289 reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) &
1290 ~WM8991_GPIO1_SEL_MASK;
1291 snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1);
1292
1293 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1);
1294 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA|
1295 WM8991_VMID_MODE_MASK);
1296
1297 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
1298 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA);
1299
1300 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1301 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1302 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1303
1304 snd_soc_add_controls(codec, wm8991_snd_controls,
1305 ARRAY_SIZE(wm8991_snd_controls));
1306
1307 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
1308 ARRAY_SIZE(wm8991_dapm_widgets));
1309 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1310 ARRAY_SIZE(audio_map));
1311 return 0;
1312}
1313
1314#define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1315 SNDRV_PCM_FMTBIT_S24_LE)
1316
1317static struct snd_soc_dai_ops wm8991_ops = {
1318 .hw_params = wm8991_hw_params,
1319 .digital_mute = wm8991_mute,
1320 .set_fmt = wm8991_set_dai_fmt,
1321 .set_clkdiv = wm8991_set_dai_clkdiv,
1322 .set_pll = wm8991_set_dai_pll
1323};
1324
1325/*
1326 * The WM8991 supports 2 different and mutually exclusive DAI
1327 * configurations.
1328 *
1329 * 1. ADC/DAC on Primary Interface
1330 * 2. ADC on Primary Interface/DAC on secondary
1331 */
1332static struct snd_soc_dai_driver wm8991_dai = {
1333 /* ADC/DAC on primary */
1334 .name = "wm8991",
1335 .id = 1,
1336 .playback = {
1337 .stream_name = "Playback",
1338 .channels_min = 1,
1339 .channels_max = 2,
1340 .rates = SNDRV_PCM_RATE_8000_96000,
1341 .formats = WM8991_FORMATS
1342 },
1343 .capture = {
1344 .stream_name = "Capture",
1345 .channels_min = 1,
1346 .channels_max = 2,
1347 .rates = SNDRV_PCM_RATE_8000_96000,
1348 .formats = WM8991_FORMATS
1349 },
1350 .ops = &wm8991_ops
1351};
1352
1353static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
1354 .probe = wm8991_probe,
1355 .remove = wm8991_remove,
1356 .suspend = wm8991_suspend,
1357 .resume = wm8991_resume,
1358 .set_bias_level = wm8991_set_bias_level,
1359 .reg_cache_size = WM8991_MAX_REGISTER + 1,
1360 .reg_word_size = sizeof(u16),
1361 .reg_cache_default = wm8991_reg_defs
1362};
1363
1364static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
1365 const struct i2c_device_id *id)
1366{
1367 struct wm8991_priv *wm8991;
1368 int ret;
1369
1370 wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
1371 if (!wm8991)
1372 return -ENOMEM;
1373
1374 wm8991->control_type = SND_SOC_I2C;
1375 i2c_set_clientdata(i2c, wm8991);
1376
1377 ret = snd_soc_register_codec(&i2c->dev,
1378 &soc_codec_dev_wm8991, &wm8991_dai, 1);
1379 if (ret < 0)
1380 kfree(wm8991);
1381 return ret;
1382}
1383
1384static __devexit int wm8991_i2c_remove(struct i2c_client *client)
1385{
1386 snd_soc_unregister_codec(&client->dev);
1387 kfree(i2c_get_clientdata(client));
1388 return 0;
1389}
1390
1391static const struct i2c_device_id wm8991_i2c_id[] = {
1392 { "wm8991", 0 },
1393 { }
1394};
1395MODULE_DEVICE_TABLE(i2c, wm8991_i2c_id);
1396
1397static struct i2c_driver wm8991_i2c_driver = {
1398 .driver = {
1399 .name = "wm8991",
1400 .owner = THIS_MODULE,
1401 },
1402 .probe = wm8991_i2c_probe,
1403 .remove = __devexit_p(wm8991_i2c_remove),
1404 .id_table = wm8991_i2c_id,
1405};
1406
1407static int __init wm8991_modinit(void)
1408{
1409 int ret;
1410 ret = i2c_add_driver(&wm8991_i2c_driver);
1411 if (ret != 0) {
1412 printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
1413 ret);
1414 }
1415 return 0;
1416}
1417module_init(wm8991_modinit);
1418
1419static void __exit wm8991_exit(void)
1420{
1421 i2c_del_driver(&wm8991_i2c_driver);
1422}
1423module_exit(wm8991_exit);
1424
1425MODULE_DESCRIPTION("ASoC WM8991 driver");
1426MODULE_AUTHOR("Graeme Gregory");
1427MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
new file mode 100644
index 000000000000..8a942efd18a5
--- /dev/null
+++ b/sound/soc/codecs/wm8991.h
@@ -0,0 +1,833 @@
1/*
2 * wm8991.h -- audio driver for WM8991
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef _WM8991_H
15#define _WM8991_H
16
17/*
18 * Register values.
19 */
20#define WM8991_RESET 0x00
21#define WM8991_POWER_MANAGEMENT_1 0x01
22#define WM8991_POWER_MANAGEMENT_2 0x02
23#define WM8991_POWER_MANAGEMENT_3 0x03
24#define WM8991_AUDIO_INTERFACE_1 0x04
25#define WM8991_AUDIO_INTERFACE_2 0x05
26#define WM8991_CLOCKING_1 0x06
27#define WM8991_CLOCKING_2 0x07
28#define WM8991_AUDIO_INTERFACE_3 0x08
29#define WM8991_AUDIO_INTERFACE_4 0x09
30#define WM8991_DAC_CTRL 0x0A
31#define WM8991_LEFT_DAC_DIGITAL_VOLUME 0x0B
32#define WM8991_RIGHT_DAC_DIGITAL_VOLUME 0x0C
33#define WM8991_DIGITAL_SIDE_TONE 0x0D
34#define WM8991_ADC_CTRL 0x0E
35#define WM8991_LEFT_ADC_DIGITAL_VOLUME 0x0F
36#define WM8991_RIGHT_ADC_DIGITAL_VOLUME 0x10
37#define WM8991_GPIO_CTRL_1 0x12
38#define WM8991_GPIO1_GPIO2 0x13
39#define WM8991_GPIO3_GPIO4 0x14
40#define WM8991_GPIO5_GPIO6 0x15
41#define WM8991_GPIOCTRL_2 0x16
42#define WM8991_GPIO_POL 0x17
43#define WM8991_LEFT_LINE_INPUT_1_2_VOLUME 0x18
44#define WM8991_LEFT_LINE_INPUT_3_4_VOLUME 0x19
45#define WM8991_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
46#define WM8991_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
47#define WM8991_LEFT_OUTPUT_VOLUME 0x1C
48#define WM8991_RIGHT_OUTPUT_VOLUME 0x1D
49#define WM8991_LINE_OUTPUTS_VOLUME 0x1E
50#define WM8991_OUT3_4_VOLUME 0x1F
51#define WM8991_LEFT_OPGA_VOLUME 0x20
52#define WM8991_RIGHT_OPGA_VOLUME 0x21
53#define WM8991_SPEAKER_VOLUME 0x22
54#define WM8991_CLASSD1 0x23
55#define WM8991_CLASSD3 0x25
56#define WM8991_INPUT_MIXER1 0x27
57#define WM8991_INPUT_MIXER2 0x28
58#define WM8991_INPUT_MIXER3 0x29
59#define WM8991_INPUT_MIXER4 0x2A
60#define WM8991_INPUT_MIXER5 0x2B
61#define WM8991_INPUT_MIXER6 0x2C
62#define WM8991_OUTPUT_MIXER1 0x2D
63#define WM8991_OUTPUT_MIXER2 0x2E
64#define WM8991_OUTPUT_MIXER3 0x2F
65#define WM8991_OUTPUT_MIXER4 0x30
66#define WM8991_OUTPUT_MIXER5 0x31
67#define WM8991_OUTPUT_MIXER6 0x32
68#define WM8991_OUT3_4_MIXER 0x33
69#define WM8991_LINE_MIXER1 0x34
70#define WM8991_LINE_MIXER2 0x35
71#define WM8991_SPEAKER_MIXER 0x36
72#define WM8991_ADDITIONAL_CONTROL 0x37
73#define WM8991_ANTIPOP1 0x38
74#define WM8991_ANTIPOP2 0x39
75#define WM8991_MICBIAS 0x3A
76#define WM8991_PLL1 0x3C
77#define WM8991_PLL2 0x3D
78#define WM8991_PLL3 0x3E
79#define WM8991_INTDRIVBITS 0x3F
80
81#define WM8991_REGISTER_COUNT 60
82#define WM8991_MAX_REGISTER 0x3F
83
84/*
85 * Field Definitions.
86 */
87
88/*
89 * R0 (0x00) - Reset
90 */
91#define WM8991_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID - [15:0] */
92
93/*
94 * R1 (0x01) - Power Management (1)
95 */
96#define WM8991_SPK_ENA 0x1000 /* SPK_ENA */
97#define WM8991_SPK_ENA_BIT 12
98#define WM8991_OUT3_ENA 0x0800 /* OUT3_ENA */
99#define WM8991_OUT3_ENA_BIT 11
100#define WM8991_OUT4_ENA 0x0400 /* OUT4_ENA */
101#define WM8991_OUT4_ENA_BIT 10
102#define WM8991_LOUT_ENA 0x0200 /* LOUT_ENA */
103#define WM8991_LOUT_ENA_BIT 9
104#define WM8991_ROUT_ENA 0x0100 /* ROUT_ENA */
105#define WM8991_ROUT_ENA_BIT 8
106#define WM8991_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
107#define WM8991_MICBIAS_ENA_BIT 4
108#define WM8991_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
109#define WM8991_VREF_ENA 0x0001 /* VREF_ENA */
110#define WM8991_VREF_ENA_BIT 0
111
112/*
113 * R2 (0x02) - Power Management (2)
114 */
115#define WM8991_PLL_ENA 0x8000 /* PLL_ENA */
116#define WM8991_PLL_ENA_BIT 15
117#define WM8991_TSHUT_ENA 0x4000 /* TSHUT_ENA */
118#define WM8991_TSHUT_ENA_BIT 14
119#define WM8991_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
120#define WM8991_TSHUT_OPDIS_BIT 13
121#define WM8991_OPCLK_ENA 0x0800 /* OPCLK_ENA */
122#define WM8991_OPCLK_ENA_BIT 11
123#define WM8991_AINL_ENA 0x0200 /* AINL_ENA */
124#define WM8991_AINL_ENA_BIT 9
125#define WM8991_AINR_ENA 0x0100 /* AINR_ENA */
126#define WM8991_AINR_ENA_BIT 8
127#define WM8991_LIN34_ENA 0x0080 /* LIN34_ENA */
128#define WM8991_LIN34_ENA_BIT 7
129#define WM8991_LIN12_ENA 0x0040 /* LIN12_ENA */
130#define WM8991_LIN12_ENA_BIT 6
131#define WM8991_RIN34_ENA 0x0020 /* RIN34_ENA */
132#define WM8991_RIN34_ENA_BIT 5
133#define WM8991_RIN12_ENA 0x0010 /* RIN12_ENA */
134#define WM8991_RIN12_ENA_BIT 4
135#define WM8991_ADCL_ENA 0x0002 /* ADCL_ENA */
136#define WM8991_ADCL_ENA_BIT 1
137#define WM8991_ADCR_ENA 0x0001 /* ADCR_ENA */
138#define WM8991_ADCR_ENA_BIT 0
139
140/*
141 * R3 (0x03) - Power Management (3)
142 */
143#define WM8991_LON_ENA 0x2000 /* LON_ENA */
144#define WM8991_LON_ENA_BIT 13
145#define WM8991_LOP_ENA 0x1000 /* LOP_ENA */
146#define WM8991_LOP_ENA_BIT 12
147#define WM8991_RON_ENA 0x0800 /* RON_ENA */
148#define WM8991_RON_ENA_BIT 11
149#define WM8991_ROP_ENA 0x0400 /* ROP_ENA */
150#define WM8991_ROP_ENA_BIT 10
151#define WM8991_LOPGA_ENA 0x0080 /* LOPGA_ENA */
152#define WM8991_LOPGA_ENA_BIT 7
153#define WM8991_ROPGA_ENA 0x0040 /* ROPGA_ENA */
154#define WM8991_ROPGA_ENA_BIT 6
155#define WM8991_LOMIX_ENA 0x0020 /* LOMIX_ENA */
156#define WM8991_LOMIX_ENA_BIT 5
157#define WM8991_ROMIX_ENA 0x0010 /* ROMIX_ENA */
158#define WM8991_ROMIX_ENA_BIT 4
159#define WM8991_DACL_ENA 0x0002 /* DACL_ENA */
160#define WM8991_DACL_ENA_BIT 1
161#define WM8991_DACR_ENA 0x0001 /* DACR_ENA */
162#define WM8991_DACR_ENA_BIT 0
163
164/*
165 * R4 (0x04) - Audio Interface (1)
166 */
167#define WM8991_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
168#define WM8991_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
169#define WM8991_AIFADC_TDM 0x2000 /* AIFADC_TDM */
170#define WM8991_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
171#define WM8991_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
172#define WM8991_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
173#define WM8991_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
174#define WM8991_AIF_WL_16BITS (0 << 5)
175#define WM8991_AIF_WL_20BITS (1 << 5)
176#define WM8991_AIF_WL_24BITS (2 << 5)
177#define WM8991_AIF_WL_32BITS (3 << 5)
178#define WM8991_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
179#define WM8991_AIF_TMF_RIGHTJ (0 << 3)
180#define WM8991_AIF_TMF_LEFTJ (1 << 3)
181#define WM8991_AIF_TMF_I2S (2 << 3)
182#define WM8991_AIF_TMF_DSP (3 << 3)
183
184/*
185 * R5 (0x05) - Audio Interface (2)
186 */
187#define WM8991_DACL_SRC 0x8000 /* DACL_SRC */
188#define WM8991_DACR_SRC 0x4000 /* DACR_SRC */
189#define WM8991_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
190#define WM8991_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
191#define WM8991_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
192#define WM8991_DAC_COMP 0x0010 /* DAC_COMP */
193#define WM8991_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
194#define WM8991_ADC_COMP 0x0004 /* ADC_COMP */
195#define WM8991_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
196#define WM8991_LOOPBACK 0x0001 /* LOOPBACK */
197
198/*
199 * R6 (0x06) - Clocking (1)
200 */
201#define WM8991_TOCLK_RATE 0x8000 /* TOCLK_RATE */
202#define WM8991_TOCLK_ENA 0x4000 /* TOCLK_ENA */
203#define WM8991_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
204#define WM8991_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
205#define WM8991_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
206#define WM8991_BCLK_DIV_1 (0x0 << 1)
207#define WM8991_BCLK_DIV_1_5 (0x1 << 1)
208#define WM8991_BCLK_DIV_2 (0x2 << 1)
209#define WM8991_BCLK_DIV_3 (0x3 << 1)
210#define WM8991_BCLK_DIV_4 (0x4 << 1)
211#define WM8991_BCLK_DIV_5_5 (0x5 << 1)
212#define WM8991_BCLK_DIV_6 (0x6 << 1)
213#define WM8991_BCLK_DIV_8 (0x7 << 1)
214#define WM8991_BCLK_DIV_11 (0x8 << 1)
215#define WM8991_BCLK_DIV_12 (0x9 << 1)
216#define WM8991_BCLK_DIV_16 (0xA << 1)
217#define WM8991_BCLK_DIV_22 (0xB << 1)
218#define WM8991_BCLK_DIV_24 (0xC << 1)
219#define WM8991_BCLK_DIV_32 (0xD << 1)
220#define WM8991_BCLK_DIV_44 (0xE << 1)
221#define WM8991_BCLK_DIV_48 (0xF << 1)
222
223/*
224 * R7 (0x07) - Clocking (2)
225 */
226#define WM8991_MCLK_SRC 0x8000 /* MCLK_SRC */
227#define WM8991_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
228#define WM8991_CLK_FORCE 0x2000 /* CLK_FORCE */
229#define WM8991_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
230#define WM8991_MCLK_DIV_1 (0 << 11)
231#define WM8991_MCLK_DIV_2 ( 2 << 11)
232#define WM8991_MCLK_INV 0x0400 /* MCLK_INV */
233#define WM8991_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */
234#define WM8991_ADC_CLKDIV_1 (0 << 5)
235#define WM8991_ADC_CLKDIV_1_5 (1 << 5)
236#define WM8991_ADC_CLKDIV_2 (2 << 5)
237#define WM8991_ADC_CLKDIV_3 (3 << 5)
238#define WM8991_ADC_CLKDIV_4 (4 << 5)
239#define WM8991_ADC_CLKDIV_5_5 (5 << 5)
240#define WM8991_ADC_CLKDIV_6 (6 << 5)
241#define WM8991_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
242#define WM8991_DAC_CLKDIV_1 (0 << 2)
243#define WM8991_DAC_CLKDIV_1_5 (1 << 2)
244#define WM8991_DAC_CLKDIV_2 (2 << 2)
245#define WM8991_DAC_CLKDIV_3 (3 << 2)
246#define WM8991_DAC_CLKDIV_4 (4 << 2)
247#define WM8991_DAC_CLKDIV_5_5 (5 << 2)
248#define WM8991_DAC_CLKDIV_6 (6 << 2)
249
250/*
251 * R8 (0x08) - Audio Interface (3)
252 */
253#define WM8991_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
254#define WM8991_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
255#define WM8991_AIF_SEL 0x2000 /* AIF_SEL */
256#define WM8991_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
257#define WM8991_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */
258
259/*
260 * R9 (0x09) - Audio Interface (4)
261 */
262#define WM8991_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
263#define WM8991_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
264#define WM8991_AIF_TRIS 0x2000 /* AIF_TRIS */
265#define WM8991_DACLRC_DIR 0x0800 /* DACLRC_DIR */
266#define WM8991_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */
267
268/*
269 * R10 (0x0A) - DAC CTRL
270 */
271#define WM8991_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
272#define WM8991_DAC_MONO 0x0200 /* DAC_MONO */
273#define WM8991_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
274#define WM8991_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
275#define WM8991_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
276#define WM8991_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
277#define WM8991_DAC_MUTE 0x0004 /* DAC_MUTE */
278#define WM8991_DACL_DATINV 0x0002 /* DACL_DATINV */
279#define WM8991_DACR_DATINV 0x0001 /* DACR_DATINV */
280
281/*
282 * R11 (0x0B) - Left DAC Digital Volume
283 */
284#define WM8991_DAC_VU 0x0100 /* DAC_VU */
285#define WM8991_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
286#define WM8991_DACL_VOL_SHIFT 0
287/*
288 * R12 (0x0C) - Right DAC Digital Volume
289 */
290#define WM8991_DAC_VU 0x0100 /* DAC_VU */
291#define WM8991_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
292#define WM8991_DACR_VOL_SHIFT 0
293/*
294 * R13 (0x0D) - Digital Side Tone
295 */
296#define WM8991_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL - [12:9] */
297#define WM8991_ADCL_DAC_SVOL_SHIFT 9
298#define WM8991_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL - [8:5] */
299#define WM8991_ADCR_DAC_SVOL_SHIFT 5
300#define WM8991_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
301#define WM8991_ADC_TO_DACL_SHIFT 2
302#define WM8991_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
303#define WM8991_ADC_TO_DACR_SHIFT 0
304
305/*
306 * R14 (0x0E) - ADC CTRL
307 */
308#define WM8991_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
309#define WM8991_ADC_HPF_ENA_BIT 8
310#define WM8991_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
311#define WM8991_ADC_HPF_CUT_SHIFT 5
312#define WM8991_ADCL_DATINV 0x0002 /* ADCL_DATINV */
313#define WM8991_ADCL_DATINV_BIT 1
314#define WM8991_ADCR_DATINV 0x0001 /* ADCR_DATINV */
315#define WM8991_ADCR_DATINV_BIT 0
316
317/*
318 * R15 (0x0F) - Left ADC Digital Volume
319 */
320#define WM8991_ADC_VU 0x0100 /* ADC_VU */
321#define WM8991_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
322#define WM8991_ADCL_VOL_SHIFT 0
323
324/*
325 * R16 (0x10) - Right ADC Digital Volume
326 */
327#define WM8991_ADC_VU 0x0100 /* ADC_VU */
328#define WM8991_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
329#define WM8991_ADCR_VOL_SHIFT 0
330
331/*
332 * R18 (0x12) - GPIO CTRL 1
333 */
334#define WM8991_IRQ 0x1000 /* IRQ */
335#define WM8991_TEMPOK 0x0800 /* TEMPOK */
336#define WM8991_MICSHRT 0x0400 /* MICSHRT */
337#define WM8991_MICDET 0x0200 /* MICDET */
338#define WM8991_PLL_LCK 0x0100 /* PLL_LCK */
339#define WM8991_GPI8_STATUS 0x0080 /* GPI8_STATUS */
340#define WM8991_GPI7_STATUS 0x0040 /* GPI7_STATUS */
341#define WM8991_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
342#define WM8991_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
343#define WM8991_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
344#define WM8991_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
345#define WM8991_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
346#define WM8991_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
347
348/*
349 * R19 (0x13) - GPIO1 & GPIO2
350 */
351#define WM8991_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
352#define WM8991_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
353#define WM8991_GPIO2_PU 0x2000 /* GPIO2_PU */
354#define WM8991_GPIO2_PD 0x1000 /* GPIO2_PD */
355#define WM8991_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
356#define WM8991_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
357#define WM8991_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
358#define WM8991_GPIO1_PU 0x0020 /* GPIO1_PU */
359#define WM8991_GPIO1_PD 0x0010 /* GPIO1_PD */
360#define WM8991_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
361
362/*
363 * R20 (0x14) - GPIO3 & GPIO4
364 */
365#define WM8991_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
366#define WM8991_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
367#define WM8991_GPIO4_PU 0x2000 /* GPIO4_PU */
368#define WM8991_GPIO4_PD 0x1000 /* GPIO4_PD */
369#define WM8991_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
370#define WM8991_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
371#define WM8991_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
372#define WM8991_GPIO3_PU 0x0020 /* GPIO3_PU */
373#define WM8991_GPIO3_PD 0x0010 /* GPIO3_PD */
374#define WM8991_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
375
376/*
377 * R21 (0x15) - GPIO5 & GPIO6
378 */
379#define WM8991_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
380#define WM8991_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
381#define WM8991_GPIO6_PU 0x2000 /* GPIO6_PU */
382#define WM8991_GPIO6_PD 0x1000 /* GPIO6_PD */
383#define WM8991_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
384#define WM8991_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
385#define WM8991_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
386#define WM8991_GPIO5_PU 0x0020 /* GPIO5_PU */
387#define WM8991_GPIO5_PD 0x0010 /* GPIO5_PD */
388#define WM8991_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
389
390/*
391 * R22 (0x16) - GPIOCTRL 2
392 */
393#define WM8991_RD_3W_ENA 0x8000 /* RD_3W_ENA */
394#define WM8991_MODE_3W4W 0x4000 /* MODE_3W4W */
395#define WM8991_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
396#define WM8991_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
397#define WM8991_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
398#define WM8991_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
399#define WM8991_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
400#define WM8991_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
401#define WM8991_GPI8_ENA 0x0010 /* GPI8_ENA */
402#define WM8991_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
403#define WM8991_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
404#define WM8991_GPI7_ENA 0x0001 /* GPI7_ENA */
405
406/*
407 * R23 (0x17) - GPIO_POL
408 */
409#define WM8991_IRQ_INV 0x1000 /* IRQ_INV */
410#define WM8991_TEMPOK_POL 0x0800 /* TEMPOK_POL */
411#define WM8991_MICSHRT_POL 0x0400 /* MICSHRT_POL */
412#define WM8991_MICDET_POL 0x0200 /* MICDET_POL */
413#define WM8991_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
414#define WM8991_GPI8_POL 0x0080 /* GPI8_POL */
415#define WM8991_GPI7_POL 0x0040 /* GPI7_POL */
416#define WM8991_GPIO6_POL 0x0020 /* GPIO6_POL */
417#define WM8991_GPIO5_POL 0x0010 /* GPIO5_POL */
418#define WM8991_GPIO4_POL 0x0008 /* GPIO4_POL */
419#define WM8991_GPIO3_POL 0x0004 /* GPIO3_POL */
420#define WM8991_GPIO2_POL 0x0002 /* GPIO2_POL */
421#define WM8991_GPIO1_POL 0x0001 /* GPIO1_POL */
422
423/*
424 * R24 (0x18) - Left Line Input 1&2 Volume
425 */
426#define WM8991_IPVU 0x0100 /* IPVU */
427#define WM8991_LI12MUTE 0x0080 /* LI12MUTE */
428#define WM8991_LI12MUTE_BIT 7
429#define WM8991_LI12ZC 0x0040 /* LI12ZC */
430#define WM8991_LI12ZC_BIT 6
431#define WM8991_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
432#define WM8991_LIN12VOL_SHIFT 0
433/*
434 * R25 (0x19) - Left Line Input 3&4 Volume
435 */
436#define WM8991_IPVU 0x0100 /* IPVU */
437#define WM8991_LI34MUTE 0x0080 /* LI34MUTE */
438#define WM8991_LI34MUTE_BIT 7
439#define WM8991_LI34ZC 0x0040 /* LI34ZC */
440#define WM8991_LI34ZC_BIT 6
441#define WM8991_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
442#define WM8991_LIN34VOL_SHIFT 0
443
444/*
445 * R26 (0x1A) - Right Line Input 1&2 Volume
446 */
447#define WM8991_IPVU 0x0100 /* IPVU */
448#define WM8991_RI12MUTE 0x0080 /* RI12MUTE */
449#define WM8991_RI12MUTE_BIT 7
450#define WM8991_RI12ZC 0x0040 /* RI12ZC */
451#define WM8991_RI12ZC_BIT 6
452#define WM8991_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
453#define WM8991_RIN12VOL_SHIFT 0
454
455/*
456 * R27 (0x1B) - Right Line Input 3&4 Volume
457 */
458#define WM8991_IPVU 0x0100 /* IPVU */
459#define WM8991_RI34MUTE 0x0080 /* RI34MUTE */
460#define WM8991_RI34MUTE_BIT 7
461#define WM8991_RI34ZC 0x0040 /* RI34ZC */
462#define WM8991_RI34ZC_BIT 6
463#define WM8991_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
464#define WM8991_RIN34VOL_SHIFT 0
465
466/*
467 * R28 (0x1C) - Left Output Volume
468 */
469#define WM8991_OPVU 0x0100 /* OPVU */
470#define WM8991_LOZC 0x0080 /* LOZC */
471#define WM8991_LOZC_BIT 7
472#define WM8991_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
473#define WM8991_LOUTVOL_SHIFT 0
474/*
475 * R29 (0x1D) - Right Output Volume
476 */
477#define WM8991_OPVU 0x0100 /* OPVU */
478#define WM8991_ROZC 0x0080 /* ROZC */
479#define WM8991_ROZC_BIT 7
480#define WM8991_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
481#define WM8991_ROUTVOL_SHIFT 0
482/*
483 * R30 (0x1E) - Line Outputs Volume
484 */
485#define WM8991_LONMUTE 0x0040 /* LONMUTE */
486#define WM8991_LONMUTE_BIT 6
487#define WM8991_LOPMUTE 0x0020 /* LOPMUTE */
488#define WM8991_LOPMUTE_BIT 5
489#define WM8991_LOATTN 0x0010 /* LOATTN */
490#define WM8991_LOATTN_BIT 4
491#define WM8991_RONMUTE 0x0004 /* RONMUTE */
492#define WM8991_RONMUTE_BIT 2
493#define WM8991_ROPMUTE 0x0002 /* ROPMUTE */
494#define WM8991_ROPMUTE_BIT 1
495#define WM8991_ROATTN 0x0001 /* ROATTN */
496#define WM8991_ROATTN_BIT 0
497
498/*
499 * R31 (0x1F) - Out3/4 Volume
500 */
501#define WM8991_OUT3MUTE 0x0020 /* OUT3MUTE */
502#define WM8991_OUT3MUTE_BIT 5
503#define WM8991_OUT3ATTN 0x0010 /* OUT3ATTN */
504#define WM8991_OUT3ATTN_BIT 4
505#define WM8991_OUT4MUTE 0x0002 /* OUT4MUTE */
506#define WM8991_OUT4MUTE_BIT 1
507#define WM8991_OUT4ATTN 0x0001 /* OUT4ATTN */
508#define WM8991_OUT4ATTN_BIT 0
509
510/*
511 * R32 (0x20) - Left OPGA Volume
512 */
513#define WM8991_OPVU 0x0100 /* OPVU */
514#define WM8991_LOPGAZC 0x0080 /* LOPGAZC */
515#define WM8991_LOPGAZC_BIT 7
516#define WM8991_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
517#define WM8991_LOPGAVOL_SHIFT 0
518
519/*
520 * R33 (0x21) - Right OPGA Volume
521 */
522#define WM8991_OPVU 0x0100 /* OPVU */
523#define WM8991_ROPGAZC 0x0080 /* ROPGAZC */
524#define WM8991_ROPGAZC_BIT 7
525#define WM8991_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
526#define WM8991_ROPGAVOL_SHIFT 0
527/*
528 * R34 (0x22) - Speaker Volume
529 */
530#define WM8991_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
531#define WM8991_SPKVOL_SHIFT 0
532
533/*
534 * R35 (0x23) - ClassD1
535 */
536#define WM8991_CDMODE 0x0100 /* CDMODE */
537#define WM8991_CDMODE_BIT 8
538
539/*
540 * R37 (0x25) - ClassD3
541 */
542#define WM8991_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
543#define WM8991_DCGAIN_SHIFT 3
544#define WM8991_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
545#define WM8991_ACGAIN_SHIFT 0
546/*
547 * R39 (0x27) - Input Mixer1
548 */
549#define WM8991_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
550#define WM8991_AINLMODE_SHIFT 2
551#define WM8991_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
552#define WM8991_AINRMODE_SHIFT 0
553
554/*
555 * R40 (0x28) - Input Mixer2
556 */
557#define WM8991_LMP4 0x0080 /* LMP4 */
558#define WM8991_LMP4_BIT 7 /* LMP4 */
559#define WM8991_LMN3 0x0040 /* LMN3 */
560#define WM8991_LMN3_BIT 6 /* LMN3 */
561#define WM8991_LMP2 0x0020 /* LMP2 */
562#define WM8991_LMP2_BIT 5 /* LMP2 */
563#define WM8991_LMN1 0x0010 /* LMN1 */
564#define WM8991_LMN1_BIT 4 /* LMN1 */
565#define WM8991_RMP4 0x0008 /* RMP4 */
566#define WM8991_RMP4_BIT 3 /* RMP4 */
567#define WM8991_RMN3 0x0004 /* RMN3 */
568#define WM8991_RMN3_BIT 2 /* RMN3 */
569#define WM8991_RMP2 0x0002 /* RMP2 */
570#define WM8991_RMP2_BIT 1 /* RMP2 */
571#define WM8991_RMN1 0x0001 /* RMN1 */
572#define WM8991_RMN1_BIT 0 /* RMN1 */
573
574/*
575 * R41 (0x29) - Input Mixer3
576 */
577#define WM8991_L34MNB 0x0100 /* L34MNB */
578#define WM8991_L34MNB_BIT 8
579#define WM8991_L34MNBST 0x0080 /* L34MNBST */
580#define WM8991_L34MNBST_BIT 7
581#define WM8991_L12MNB 0x0020 /* L12MNB */
582#define WM8991_L12MNB_BIT 5
583#define WM8991_L12MNBST 0x0010 /* L12MNBST */
584#define WM8991_L12MNBST_BIT 4
585#define WM8991_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
586#define WM8991_LDBVOL_SHIFT 0
587
588/*
589 * R42 (0x2A) - Input Mixer4
590 */
591#define WM8991_R34MNB 0x0100 /* R34MNB */
592#define WM8991_R34MNB_BIT 8
593#define WM8991_R34MNBST 0x0080 /* R34MNBST */
594#define WM8991_R34MNBST_BIT 7
595#define WM8991_R12MNB 0x0020 /* R12MNB */
596#define WM8991_R12MNB_BIT 5
597#define WM8991_R12MNBST 0x0010 /* R12MNBST */
598#define WM8991_R12MNBST_BIT 4
599#define WM8991_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
600#define WM8991_RDBVOL_SHIFT 0
601
602/*
603 * R43 (0x2B) - Input Mixer5
604 */
605#define WM8991_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
606#define WM8991_LI2BVOL_SHIFT 6
607#define WM8991_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
608#define WM8991_LR4BVOL_SHIFT 3
609#define WM8991_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
610#define WM8991_LL4BVOL_SHIFT 0
611
612/*
613 * R44 (0x2C) - Input Mixer6
614 */
615#define WM8991_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
616#define WM8991_RI2BVOL_SHIFT 6
617#define WM8991_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
618#define WM8991_RL4BVOL_SHIFT 3
619#define WM8991_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
620#define WM8991_RR4BVOL_SHIFT 0
621
622/*
623 * R45 (0x2D) - Output Mixer1
624 */
625#define WM8991_LRBLO 0x0080 /* LRBLO */
626#define WM8991_LRBLO_BIT 7
627#define WM8991_LLBLO 0x0040 /* LLBLO */
628#define WM8991_LLBLO_BIT 6
629#define WM8991_LRI3LO 0x0020 /* LRI3LO */
630#define WM8991_LRI3LO_BIT 5
631#define WM8991_LLI3LO 0x0010 /* LLI3LO */
632#define WM8991_LLI3LO_BIT 4
633#define WM8991_LR12LO 0x0008 /* LR12LO */
634#define WM8991_LR12LO_BIT 3
635#define WM8991_LL12LO 0x0004 /* LL12LO */
636#define WM8991_LL12LO_BIT 2
637#define WM8991_LDLO 0x0001 /* LDLO */
638#define WM8991_LDLO_BIT 0
639
640/*
641 * R46 (0x2E) - Output Mixer2
642 */
643#define WM8991_RLBRO 0x0080 /* RLBRO */
644#define WM8991_RLBRO_BIT 7
645#define WM8991_RRBRO 0x0040 /* RRBRO */
646#define WM8991_RRBRO_BIT 6
647#define WM8991_RLI3RO 0x0020 /* RLI3RO */
648#define WM8991_RLI3RO_BIT 5
649#define WM8991_RRI3RO 0x0010 /* RRI3RO */
650#define WM8991_RRI3RO_BIT 4
651#define WM8991_RL12RO 0x0008 /* RL12RO */
652#define WM8991_RL12RO_BIT 3
653#define WM8991_RR12RO 0x0004 /* RR12RO */
654#define WM8991_RR12RO_BIT 2
655#define WM8991_RDRO 0x0001 /* RDRO */
656#define WM8991_RDRO_BIT 0
657
658/*
659 * R47 (0x2F) - Output Mixer3
660 */
661#define WM8991_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
662#define WM8991_LLI3LOVOL_SHIFT 6
663#define WM8991_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
664#define WM8991_LR12LOVOL_SHIFT 3
665#define WM8991_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
666#define WM8991_LL12LOVOL_SHIFT 0
667
668/*
669 * R48 (0x30) - Output Mixer4
670 */
671#define WM8991_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
672#define WM8991_RRI3ROVOL_SHIFT 6
673#define WM8991_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
674#define WM8991_RL12ROVOL_SHIFT 3
675#define WM8991_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
676#define WM8991_RR12ROVOL_SHIFT 0
677
678/*
679 * R49 (0x31) - Output Mixer5
680 */
681#define WM8991_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
682#define WM8991_LRI3LOVOL_SHIFT 6
683#define WM8991_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
684#define WM8991_LRBLOVOL_SHIFT 3
685#define WM8991_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
686#define WM8991_LLBLOVOL_SHIFT 0
687
688/*
689 * R50 (0x32) - Output Mixer6
690 */
691#define WM8991_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
692#define WM8991_RLI3ROVOL_SHIFT 6
693#define WM8991_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
694#define WM8991_RLBROVOL_SHIFT 3
695#define WM8991_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
696#define WM8991_RRBROVOL_SHIFT 0
697
698/*
699 * R51 (0x33) - Out3/4 Mixer
700 */
701#define WM8991_VSEL_MASK 0x0180 /* VSEL - [8:7] */
702#define WM8991_LI4O3 0x0020 /* LI4O3 */
703#define WM8991_LI4O3_BIT 5
704#define WM8991_LPGAO3 0x0010 /* LPGAO3 */
705#define WM8991_LPGAO3_BIT 4
706#define WM8991_RI4O4 0x0002 /* RI4O4 */
707#define WM8991_RI4O4_BIT 1
708#define WM8991_RPGAO4 0x0001 /* RPGAO4 */
709#define WM8991_RPGAO4_BIT 0
710/*
711 * R52 (0x34) - Line Mixer1
712 */
713#define WM8991_LLOPGALON 0x0040 /* LLOPGALON */
714#define WM8991_LLOPGALON_BIT 6
715#define WM8991_LROPGALON 0x0020 /* LROPGALON */
716#define WM8991_LROPGALON_BIT 5
717#define WM8991_LOPLON 0x0010 /* LOPLON */
718#define WM8991_LOPLON_BIT 4
719#define WM8991_LR12LOP 0x0004 /* LR12LOP */
720#define WM8991_LR12LOP_BIT 2
721#define WM8991_LL12LOP 0x0002 /* LL12LOP */
722#define WM8991_LL12LOP_BIT 1
723#define WM8991_LLOPGALOP 0x0001 /* LLOPGALOP */
724#define WM8991_LLOPGALOP_BIT 0
725/*
726 * R53 (0x35) - Line Mixer2
727 */
728#define WM8991_RROPGARON 0x0040 /* RROPGARON */
729#define WM8991_RROPGARON_BIT 6
730#define WM8991_RLOPGARON 0x0020 /* RLOPGARON */
731#define WM8991_RLOPGARON_BIT 5
732#define WM8991_ROPRON 0x0010 /* ROPRON */
733#define WM8991_ROPRON_BIT 4
734#define WM8991_RL12ROP 0x0004 /* RL12ROP */
735#define WM8991_RL12ROP_BIT 2
736#define WM8991_RR12ROP 0x0002 /* RR12ROP */
737#define WM8991_RR12ROP_BIT 1
738#define WM8991_RROPGAROP 0x0001 /* RROPGAROP */
739#define WM8991_RROPGAROP_BIT 0
740
741/*
742 * R54 (0x36) - Speaker Mixer
743 */
744#define WM8991_LB2SPK 0x0080 /* LB2SPK */
745#define WM8991_LB2SPK_BIT 7
746#define WM8991_RB2SPK 0x0040 /* RB2SPK */
747#define WM8991_RB2SPK_BIT 6
748#define WM8991_LI2SPK 0x0020 /* LI2SPK */
749#define WM8991_LI2SPK_BIT 5
750#define WM8991_RI2SPK 0x0010 /* RI2SPK */
751#define WM8991_RI2SPK_BIT 4
752#define WM8991_LOPGASPK 0x0008 /* LOPGASPK */
753#define WM8991_LOPGASPK_BIT 3
754#define WM8991_ROPGASPK 0x0004 /* ROPGASPK */
755#define WM8991_ROPGASPK_BIT 2
756#define WM8991_LDSPK 0x0002 /* LDSPK */
757#define WM8991_LDSPK_BIT 1
758#define WM8991_RDSPK 0x0001 /* RDSPK */
759#define WM8991_RDSPK_BIT 0
760
761/*
762 * R55 (0x37) - Additional Control
763 */
764#define WM8991_VROI 0x0001 /* VROI */
765
766/*
767 * R56 (0x38) - AntiPOP1
768 */
769#define WM8991_DIS_LLINE 0x0020 /* DIS_LLINE */
770#define WM8991_DIS_RLINE 0x0010 /* DIS_RLINE */
771#define WM8991_DIS_OUT3 0x0008 /* DIS_OUT3 */
772#define WM8991_DIS_OUT4 0x0004 /* DIS_OUT4 */
773#define WM8991_DIS_LOUT 0x0002 /* DIS_LOUT */
774#define WM8991_DIS_ROUT 0x0001 /* DIS_ROUT */
775
776/*
777 * R57 (0x39) - AntiPOP2
778 */
779#define WM8991_SOFTST 0x0040 /* SOFTST */
780#define WM8991_BUFIOEN 0x0008 /* BUFIOEN */
781#define WM8991_BUFDCOPEN 0x0004 /* BUFDCOPEN */
782#define WM8991_POBCTRL 0x0002 /* POBCTRL */
783#define WM8991_VMIDTOG 0x0001 /* VMIDTOG */
784
785/*
786 * R58 (0x3A) - MICBIAS
787 */
788#define WM8991_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
789#define WM8991_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
790#define WM8991_MCD 0x0004 /* MCD */
791#define WM8991_MBSEL 0x0001 /* MBSEL */
792
793/*
794 * R60 (0x3C) - PLL1
795 */
796#define WM8991_SDM 0x0080 /* SDM */
797#define WM8991_PRESCALE 0x0040 /* PRESCALE */
798#define WM8991_PLLN_MASK 0x000F /* PLLN - [3:0] */
799
800/*
801 * R61 (0x3D) - PLL2
802 */
803#define WM8991_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
804
805/*
806 * R62 (0x3E) - PLL3
807 */
808#define WM8991_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
809
810/*
811 * R63 (0x3F) - Internal Driver Bits
812 */
813#define WM8991_INMIXL_PWR_BIT 0
814#define WM8991_AINLMUX_PWR_BIT 1
815#define WM8991_INMIXR_PWR_BIT 2
816#define WM8991_AINRMUX_PWR_BIT 3
817
818#define WM8991_MCLK_DIV 0
819#define WM8991_DACCLK_DIV 1
820#define WM8991_ADCCLK_DIV 2
821#define WM8991_BCLK_DIV 3
822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832
833#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 18c0d9ce7c32..379fa22c5b6c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -242,7 +242,7 @@ struct wm8993_priv {
242 int fll_src; 242 int fll_src;
243}; 243};
244 244
245static int wm8993_volatile(unsigned int reg) 245static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg)
246{ 246{
247 switch (reg) { 247 switch (reg) {
248 case WM8993_SOFTWARE_RESET: 248 case WM8993_SOFTWARE_RESET:
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index 68e9b024dd48..a87adbd05ee1 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -62,8 +62,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ 62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
63 { 0x000F, 0x000F }, /* R59 - LDO 1 */ 63 { 0x000F, 0x000F }, /* R59 - LDO 1 */
64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */ 64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
65 { 0x0000, 0x0000 }, /* R61 */ 65 { 0xFFFF, 0xFFFF }, /* R61 */
66 { 0x0000, 0x0000 }, /* R62 */ 66 { 0xFFFF, 0xFFFF }, /* R62 */
67 { 0x0000, 0x0000 }, /* R63 */ 67 { 0x0000, 0x0000 }, /* R63 */
68 { 0x0000, 0x0000 }, /* R64 */ 68 { 0x0000, 0x0000 }, /* R64 */
69 { 0x0000, 0x0000 }, /* R65 */ 69 { 0x0000, 0x0000 }, /* R65 */
@@ -209,9 +209,9 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
209 { 0x0000, 0x0000 }, /* R205 */ 209 { 0x0000, 0x0000 }, /* R205 */
210 { 0x0000, 0x0000 }, /* R206 */ 210 { 0x0000, 0x0000 }, /* R206 */
211 { 0x0000, 0x0000 }, /* R207 */ 211 { 0x0000, 0x0000 }, /* R207 */
212 { 0x0000, 0x0000 }, /* R208 */ 212 { 0xFFFF, 0xFFFF }, /* R208 */
213 { 0x0000, 0x0000 }, /* R209 */ 213 { 0xFFFF, 0xFFFF }, /* R209 */
214 { 0x0000, 0x0000 }, /* R210 */ 214 { 0xFFFF, 0xFFFF }, /* R210 */
215 { 0x0000, 0x0000 }, /* R211 */ 215 { 0x0000, 0x0000 }, /* R211 */
216 { 0x0000, 0x0000 }, /* R212 */ 216 { 0x0000, 0x0000 }, /* R212 */
217 { 0x0000, 0x0000 }, /* R213 */ 217 { 0x0000, 0x0000 }, /* R213 */
@@ -1573,7 +1573,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ 1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1574}; 1574};
1575 1575
1576const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { 1576const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1577 0x8994, /* R0 - Software Reset */ 1577 0x8994, /* R0 - Software Reset */
1578 0x0000, /* R1 - Power Management (1) */ 1578 0x0000, /* R1 - Power Management (1) */
1579 0x6000, /* R2 - Power Management (2) */ 1579 0x6000, /* R2 - Power Management (2) */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index c6c958ee5d59..3dc64c8b6a5c 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -102,8 +102,7 @@ struct wm8994_priv {
102 102
103 wm8958_micdet_cb jack_cb; 103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data; 104 void *jack_cb_data;
105 bool jack_is_mic; 105 int micdet_irq;
106 bool jack_is_video;
107 106
108 int revision; 107 int revision;
109 struct wm8994_pdata *pdata; 108 struct wm8994_pdata *pdata;
@@ -115,7 +114,7 @@ struct wm8994_priv {
115 unsigned int aif2clk_disable:1; 114 unsigned int aif2clk_disable:1;
116}; 115};
117 116
118static int wm8994_readable(unsigned int reg) 117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
119{ 118{
120 switch (reg) { 119 switch (reg) {
121 case WM8994_GPIO_1: 120 case WM8994_GPIO_1:
@@ -142,7 +141,7 @@ static int wm8994_readable(unsigned int reg)
142 return wm8994_access_masks[reg].readable != 0; 141 return wm8994_access_masks[reg].readable != 0;
143} 142}
144 143
145static int wm8994_volatile(unsigned int reg) 144static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
146{ 145{
147 if (reg >= WM8994_CACHE_SIZE) 146 if (reg >= WM8994_CACHE_SIZE)
148 return 1; 147 return 1;
@@ -170,7 +169,7 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
170 169
171 BUG_ON(reg > WM8994_MAX_REGISTER); 170 BUG_ON(reg > WM8994_MAX_REGISTER);
172 171
173 if (!wm8994_volatile(reg)) { 172 if (!wm8994_volatile(codec, reg)) {
174 ret = snd_soc_cache_write(codec, reg, value); 173 ret = snd_soc_cache_write(codec, reg, value);
175 if (ret != 0) 174 if (ret != 0)
176 dev_err(codec->dev, "Cache write to %x failed: %d\n", 175 dev_err(codec->dev, "Cache write to %x failed: %d\n",
@@ -188,7 +187,7 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
188 187
189 BUG_ON(reg > WM8994_MAX_REGISTER); 188 BUG_ON(reg > WM8994_MAX_REGISTER);
190 189
191 if (!wm8994_volatile(reg) && wm8994_readable(reg) && 190 if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) &&
192 reg < codec->driver->reg_cache_size) { 191 reg < codec->driver->reg_cache_size) {
193 ret = snd_soc_cache_read(codec, reg, &val); 192 ret = snd_soc_cache_read(codec, reg, &val);
194 if (ret >= 0) 193 if (ret >= 0)
@@ -529,7 +528,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol) 528 struct snd_ctl_elem_value *ucontrol)
530{ 529{
531 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 530 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
532 struct wm8994_priv *wm8994 =snd_soc_codec_get_drvdata(codec); 531 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
533 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 532 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
534 533
535 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 534 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -1103,6 +1102,13 @@ static int adc_mux_ev(struct snd_soc_dapm_widget *w,
1103 return 0; 1102 return 0;
1104} 1103}
1105 1104
1105static int micbias_ev(struct snd_soc_dapm_widget *w,
1106 struct snd_kcontrol *kcontrol, int event)
1107{
1108 late_enable_ev(w, kcontrol, event);
1109 return 0;
1110}
1111
1106static int dac_ev(struct snd_soc_dapm_widget *w, 1112static int dac_ev(struct snd_soc_dapm_widget *w,
1107 struct snd_kcontrol *kcontrol, int event) 1113 struct snd_kcontrol *kcontrol, int event)
1108{ 1114{
@@ -1440,6 +1446,10 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"),
1440SND_SOC_DAPM_INPUT("DMIC2DAT"), 1446SND_SOC_DAPM_INPUT("DMIC2DAT"),
1441SND_SOC_DAPM_INPUT("Clock"), 1447SND_SOC_DAPM_INPUT("Clock"),
1442 1448
1449SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
1450SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1451 SND_SOC_DAPM_PRE_PMU),
1452
1443SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1453SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1444 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1454 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1445 1455
@@ -1755,6 +1765,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1755 { "AIF2DACDAT", NULL, "AIF1DACDAT" }, 1765 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
1756 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, 1766 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
1757 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, 1767 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
1768 { "MICBIAS", NULL, "CLK_SYS" },
1769 { "MICBIAS", NULL, "MICBIAS Supply" },
1758}; 1770};
1759 1771
1760static const struct snd_soc_dapm_route wm8994_intercon[] = { 1772static const struct snd_soc_dapm_route wm8994_intercon[] = {
@@ -2883,6 +2895,13 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2883 else 2895 else
2884 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 2896 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
2885 ARRAY_SIZE(wm8994_eq_controls)); 2897 ARRAY_SIZE(wm8994_eq_controls));
2898
2899 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
2900 if (pdata->micbias[i]) {
2901 snd_soc_write(codec, WM8958_MICBIAS1 + i,
2902 pdata->micbias[i] & 0xffff);
2903 }
2904 }
2886} 2905}
2887 2906
2888/** 2907/**
@@ -2993,46 +3012,18 @@ static void wm8958_default_micdet(u16 status, void *data)
2993 int report = 0; 3012 int report = 0;
2994 3013
2995 /* If nothing present then clear our statuses */ 3014 /* If nothing present then clear our statuses */
2996 if (!(status & WM8958_MICD_STS)) { 3015 if (!(status & WM8958_MICD_STS))
2997 wm8994->jack_is_video = false;
2998 wm8994->jack_is_mic = false;
2999 goto done; 3016 goto done;
3000 }
3001 3017
3002 /* Assume anything over 475 ohms is a microphone and remember 3018 report = SND_JACK_MICROPHONE;
3003 * that we've seen one (since buttons override it) */
3004 if (status & 0x600)
3005 wm8994->jack_is_mic = true;
3006 if (wm8994->jack_is_mic)
3007 report |= SND_JACK_MICROPHONE;
3008
3009 /* Video has an impedence of approximately 75 ohms; assume
3010 * this isn't used as a button and remember it since buttons
3011 * override it. */
3012 if (status & 0x40)
3013 wm8994->jack_is_video = true;
3014 if (wm8994->jack_is_video)
3015 report |= SND_JACK_VIDEOOUT;
3016 3019
3017 /* Everything else is buttons; just assign slots */ 3020 /* Everything else is buttons; just assign slots */
3018 if (status & 0x4) 3021 if (status & 0x1c0)
3019 report |= SND_JACK_BTN_0; 3022 report |= SND_JACK_BTN_0;
3020 if (status & 0x8)
3021 report |= SND_JACK_BTN_1;
3022 if (status & 0x10)
3023 report |= SND_JACK_BTN_2;
3024 if (status & 0x20)
3025 report |= SND_JACK_BTN_3;
3026 if (status & 0x80)
3027 report |= SND_JACK_BTN_4;
3028 if (status & 0x100)
3029 report |= SND_JACK_BTN_5;
3030 3023
3031done: 3024done:
3032 snd_soc_jack_report(wm8994->micdet[0].jack, report, 3025 snd_soc_jack_report(wm8994->micdet[0].jack, report,
3033 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | 3026 SND_JACK_BTN_0 | SND_JACK_MICROPHONE);
3034 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
3035 SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT);
3036} 3027}
3037 3028
3038/** 3029/**
@@ -3131,13 +3122,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3131 wm8994->pdata = dev_get_platdata(codec->dev->parent); 3122 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3132 wm8994->codec = codec; 3123 wm8994->codec = codec;
3133 3124
3125 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3126 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3127 else if (wm8994->pdata && wm8994->pdata->irq_base)
3128 wm8994->micdet_irq = wm8994->pdata->irq_base +
3129 WM8994_IRQ_MIC1_DET;
3130
3134 pm_runtime_enable(codec->dev); 3131 pm_runtime_enable(codec->dev);
3135 pm_runtime_resume(codec->dev); 3132 pm_runtime_resume(codec->dev);
3136 3133
3137 /* Read our current status back from the chip - we don't want to 3134 /* Read our current status back from the chip - we don't want to
3138 * reset as this may interfere with the GPIO or LDO operation. */ 3135 * reset as this may interfere with the GPIO or LDO operation. */
3139 for (i = 0; i < WM8994_CACHE_SIZE; i++) { 3136 for (i = 0; i < WM8994_CACHE_SIZE; i++) {
3140 if (!wm8994_readable(i) || wm8994_volatile(i)) 3137 if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i))
3141 continue; 3138 continue;
3142 3139
3143 ret = wm8994_reg_read(codec->control_data, i); 3140 ret = wm8994_reg_read(codec->control_data, i);
@@ -3179,14 +3176,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3179 3176
3180 switch (control->type) { 3177 switch (control->type) {
3181 case WM8994: 3178 case WM8994:
3182 ret = wm8994_request_irq(codec->control_data, 3179 if (wm8994->micdet_irq) {
3183 WM8994_IRQ_MIC1_DET, 3180 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3184 wm8994_mic_irq, "Mic 1 detect", 3181 wm8994_mic_irq,
3185 wm8994); 3182 IRQF_TRIGGER_RISING,
3186 if (ret != 0) 3183 "Mic1 detect",
3187 dev_warn(codec->dev, 3184 wm8994);
3188 "Failed to request Mic1 detect IRQ: %d\n", 3185 if (ret != 0)
3189 ret); 3186 dev_warn(codec->dev,
3187 "Failed to request Mic1 detect IRQ: %d\n",
3188 ret);
3189 }
3190 3190
3191 ret = wm8994_request_irq(codec->control_data, 3191 ret = wm8994_request_irq(codec->control_data,
3192 WM8994_IRQ_MIC1_SHRT, 3192 WM8994_IRQ_MIC1_SHRT,
@@ -3217,15 +3217,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3217 break; 3217 break;
3218 3218
3219 case WM8958: 3219 case WM8958:
3220 ret = wm8994_request_irq(codec->control_data, 3220 if (wm8994->micdet_irq) {
3221 WM8994_IRQ_MIC1_DET, 3221 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3222 wm8958_mic_irq, "Mic detect", 3222 wm8958_mic_irq,
3223 wm8994); 3223 IRQF_TRIGGER_RISING,
3224 if (ret != 0) 3224 "Mic detect",
3225 dev_warn(codec->dev, 3225 wm8994);
3226 "Failed to request Mic detect IRQ: %d\n", 3226 if (ret != 0)
3227 ret); 3227 dev_warn(codec->dev,
3228 break; 3228 "Failed to request Mic detect IRQ: %d\n",
3229 ret);
3230 }
3229 } 3231 }
3230 3232
3231 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3233 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
@@ -3369,7 +3371,8 @@ err_irq:
3369 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3371 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
3370 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3372 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
3371 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3373 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
3372 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3374 if (wm8994->micdet_irq)
3375 free_irq(wm8994->micdet_irq, wm8994);
3373err: 3376err:
3374 kfree(wm8994); 3377 kfree(wm8994);
3375 return ret; 3378 return ret;
@@ -3386,8 +3389,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3386 3389
3387 switch (control->type) { 3390 switch (control->type) {
3388 case WM8994: 3391 case WM8994:
3389 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 3392 if (wm8994->micdet_irq)
3390 wm8994); 3393 free_irq(wm8994->micdet_irq, wm8994);
3391 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 3394 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3392 wm8994); 3395 wm8994);
3393 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 3396 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
@@ -3397,8 +3400,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3397 break; 3400 break;
3398 3401
3399 case WM8958: 3402 case WM8958:
3400 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 3403 if (wm8994->micdet_irq)
3401 wm8994); 3404 free_irq(wm8994->micdet_irq, wm8994);
3402 break; 3405 break;
3403 } 3406 }
3404 kfree(wm8994->retune_mobile_texts); 3407 kfree(wm8994->retune_mobile_texts);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0c355bfc88f1..999b8851226b 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -43,6 +43,6 @@ struct wm8994_access_mask {
43}; 43};
44 44
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 47
48#endif 48#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 608c84c5aa8e..67eaaecbb42e 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -30,6 +31,18 @@
30 31
31#include "wm8995.h" 32#include "wm8995.h"
32 33
34#define WM8995_NUM_SUPPLIES 8
35static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD1",
38 "DBVDD2",
39 "DBVDD3",
40 "AVDD1",
41 "AVDD2",
42 "CPVDD",
43 "MICVDD"
44};
45
33static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = { 46static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
34 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b, 47 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
35 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0, 48 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
@@ -126,8 +139,37 @@ struct wm8995_priv {
126 int mclk[2]; 139 int mclk[2];
127 int aifclk[2]; 140 int aifclk[2];
128 struct fll_config fll[2], fll_suspend[2]; 141 struct fll_config fll[2], fll_suspend[2];
142 struct regulator_bulk_data supplies[WM8995_NUM_SUPPLIES];
143 struct notifier_block disable_nb[WM8995_NUM_SUPPLIES];
144 struct snd_soc_codec *codec;
129}; 145};
130 146
147/*
148 * We can't use the same notifier block for more than one supply and
149 * there's no way I can see to get from a callback to the caller
150 * except container_of().
151 */
152#define WM8995_REGULATOR_EVENT(n) \
153static int wm8995_regulator_event_##n(struct notifier_block *nb, \
154 unsigned long event, void *data) \
155{ \
156 struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
157 disable_nb[n]); \
158 if (event & REGULATOR_EVENT_DISABLE) { \
159 wm8995->codec->cache_sync = 1; \
160 } \
161 return 0; \
162}
163
164WM8995_REGULATOR_EVENT(0)
165WM8995_REGULATOR_EVENT(1)
166WM8995_REGULATOR_EVENT(2)
167WM8995_REGULATOR_EVENT(3)
168WM8995_REGULATOR_EVENT(4)
169WM8995_REGULATOR_EVENT(5)
170WM8995_REGULATOR_EVENT(6)
171WM8995_REGULATOR_EVENT(7)
172
131static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 173static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
132static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0); 174static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
133static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0); 175static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
@@ -909,7 +951,7 @@ static const struct snd_soc_dapm_route wm8995_intercon[] = {
909 { "SPK2R", NULL, "SPK2R Driver" } 951 { "SPK2R", NULL, "SPK2R Driver" }
910}; 952};
911 953
912static int wm8995_volatile(unsigned int reg) 954static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg)
913{ 955{
914 /* out of bounds registers are generally considered 956 /* out of bounds registers are generally considered
915 * volatile to support register banks that are partially 957 * volatile to support register banks that are partially
@@ -1483,6 +1525,11 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1483 break; 1525 break;
1484 case SND_SOC_BIAS_STANDBY: 1526 case SND_SOC_BIAS_STANDBY:
1485 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1527 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1528 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1529 wm8995->supplies);
1530 if (ret)
1531 return ret;
1532
1486 ret = snd_soc_cache_sync(codec); 1533 ret = snd_soc_cache_sync(codec);
1487 if (ret) { 1534 if (ret) {
1488 dev_err(codec->dev, 1535 dev_err(codec->dev,
@@ -1492,12 +1539,13 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1492 1539
1493 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, 1540 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1494 WM8995_BG_ENA_MASK, WM8995_BG_ENA); 1541 WM8995_BG_ENA_MASK, WM8995_BG_ENA);
1495
1496 } 1542 }
1497 break; 1543 break;
1498 case SND_SOC_BIAS_OFF: 1544 case SND_SOC_BIAS_OFF:
1499 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, 1545 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1500 WM8995_BG_ENA_MASK, 0); 1546 WM8995_BG_ENA_MASK, 0);
1547 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies),
1548 wm8995->supplies);
1501 break; 1549 break;
1502 } 1550 }
1503 1551
@@ -1536,10 +1584,12 @@ static int wm8995_remove(struct snd_soc_codec *codec)
1536static int wm8995_probe(struct snd_soc_codec *codec) 1584static int wm8995_probe(struct snd_soc_codec *codec)
1537{ 1585{
1538 struct wm8995_priv *wm8995; 1586 struct wm8995_priv *wm8995;
1587 int i;
1539 int ret; 1588 int ret;
1540 1589
1541 codec->dapm.idle_bias_off = 1; 1590 codec->dapm.idle_bias_off = 1;
1542 wm8995 = snd_soc_codec_get_drvdata(codec); 1591 wm8995 = snd_soc_codec_get_drvdata(codec);
1592 wm8995->codec = codec;
1543 1593
1544 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type); 1594 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
1545 if (ret < 0) { 1595 if (ret < 0) {
@@ -1547,21 +1597,58 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1547 return ret; 1597 return ret;
1548 } 1598 }
1549 1599
1600 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
1601 wm8995->supplies[i].supply = wm8995_supply_names[i];
1602
1603 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8995->supplies),
1604 wm8995->supplies);
1605 if (ret) {
1606 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1607 return ret;
1608 }
1609
1610 wm8995->disable_nb[0].notifier_call = wm8995_regulator_event_0;
1611 wm8995->disable_nb[1].notifier_call = wm8995_regulator_event_1;
1612 wm8995->disable_nb[2].notifier_call = wm8995_regulator_event_2;
1613 wm8995->disable_nb[3].notifier_call = wm8995_regulator_event_3;
1614 wm8995->disable_nb[4].notifier_call = wm8995_regulator_event_4;
1615 wm8995->disable_nb[5].notifier_call = wm8995_regulator_event_5;
1616 wm8995->disable_nb[6].notifier_call = wm8995_regulator_event_6;
1617 wm8995->disable_nb[7].notifier_call = wm8995_regulator_event_7;
1618
1619 /* This should really be moved into the regulator core */
1620 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) {
1621 ret = regulator_register_notifier(wm8995->supplies[i].consumer,
1622 &wm8995->disable_nb[i]);
1623 if (ret) {
1624 dev_err(codec->dev,
1625 "Failed to register regulator notifier: %d\n",
1626 ret);
1627 }
1628 }
1629
1630 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1631 wm8995->supplies);
1632 if (ret) {
1633 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1634 goto err_reg_get;
1635 }
1636
1550 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET); 1637 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
1551 if (ret < 0) { 1638 if (ret < 0) {
1552 dev_err(codec->dev, "Failed to read device ID: %d\n", ret); 1639 dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
1553 return ret; 1640 goto err_reg_enable;
1554 } 1641 }
1555 1642
1556 if (ret != 0x8995) { 1643 if (ret != 0x8995) {
1557 dev_err(codec->dev, "Invalid device ID: %#x\n", ret); 1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1558 return -EINVAL; 1645 goto err_reg_enable;
1559 } 1646 }
1560 1647
1561 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0); 1648 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
1562 if (ret < 0) { 1649 if (ret < 0) {
1563 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1650 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1564 return ret; 1651 goto err_reg_enable;
1565 } 1652 }
1566 1653
1567 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1654 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1596,6 +1683,12 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1596 ARRAY_SIZE(wm8995_intercon)); 1683 ARRAY_SIZE(wm8995_intercon));
1597 1684
1598 return 0; 1685 return 0;
1686
1687err_reg_enable:
1688 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1689err_reg_get:
1690 regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1691 return ret;
1599} 1692}
1600 1693
1601#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1694#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index cce704c275c6..55cdf2982020 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -167,10 +167,10 @@ struct wm9081_priv {
167 int fll_fref; 167 int fll_fref;
168 int fll_fout; 168 int fll_fout;
169 int tdm_width; 169 int tdm_width;
170 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
171}; 171};
172 172
173static int wm9081_volatile_register(unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
174{ 174{
175 switch (reg) { 175 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 176 case WM9081_SOFTWARE_RESET:
@@ -389,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
390}; 390};
391 391
392static int speaker_event(struct snd_soc_dapm_widget *w,
393 struct snd_kcontrol *kcontrol, int event)
394{
395 struct snd_soc_codec *codec = w->codec;
396 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
397
398 switch (event) {
399 case SND_SOC_DAPM_POST_PMU:
400 reg |= WM9081_SPK_ENA;
401 break;
402
403 case SND_SOC_DAPM_PRE_PMD:
404 reg &= ~WM9081_SPK_ENA;
405 break;
406 }
407
408 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
409
410 return 0;
411}
412
413struct _fll_div { 392struct _fll_div {
414 u16 fll_fratio; 393 u16 fll_fratio;
415 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -747,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
747 726
748SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
749 728
750SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
751 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
752 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
753 731
754SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
755SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -762,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
762}; 740};
763 741
764 742
765static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
766 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
767 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
768 746
@@ -780,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
780 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
781 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
782 760
783 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
784 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
785}; 765};
786 766
787static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -1082,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1082 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1083 1063
1084 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1085 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1086 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1087 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1088 int eq1; 1068 int eq1;
1089 1069
1090 best = 0; 1070 best = 0;
1091 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1092 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1093 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1094 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1095 best_val = cur_val; 1076 best_val = cur_val;
1096 best = i; 1077 best = i;
1097 } 1078 }
1098 } 1079 }
1099 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1100 1081
1101 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1102 s->name, s->rate); 1083 s->name, s->rate);
@@ -1139,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1139 return 0; 1120 return 0;
1140} 1121}
1141 1122
1142static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1143 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1144{ 1125{
1145 struct snd_soc_codec *codec = codec_dai->codec;
1146 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1147 1127
1148 switch (clk_id) { 1128 switch (clk_id) {
@@ -1207,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1207 1187
1208static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1209 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1210 .set_sysclk = wm9081_set_sysclk,
1211 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1212 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1213 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1231,7 +1210,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
1231static int wm9081_probe(struct snd_soc_codec *codec) 1210static int wm9081_probe(struct snd_soc_codec *codec)
1232{ 1211{
1233 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1212 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_dapm_context *dapm = &codec->dapm;
1235 int ret; 1213 int ret;
1236 u16 reg; 1214 u16 reg;
1237 1215
@@ -1255,6 +1233,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1255 return ret; 1233 return ret;
1256 } 1234 }
1257 1235
1236 reg = 0;
1237 if (wm9081->pdata.irq_high)
1238 reg |= WM9081_IRQ_POL;
1239 if (!wm9081->pdata.irq_cmos)
1240 reg |= WM9081_IRQ_OP_CTRL;
1241 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1242 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1243
1258 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1259 1245
1260 /* Enable zero cross by default */ 1246 /* Enable zero cross by default */
@@ -1266,17 +1252,13 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1266 1252
1267 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1268 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1269 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1270 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1271 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1272 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1273 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1274 } 1260 }
1275 1261
1276 snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
1277 ARRAY_SIZE(wm9081_dapm_widgets));
1278 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1279
1280 return ret; 1262 return ret;
1281} 1263}
1282 1264
@@ -1320,11 +1302,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1320 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1321 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1322 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1305
1306 .set_sysclk = wm9081_set_sysclk,
1323 .set_bias_level = wm9081_set_bias_level, 1307 .set_bias_level = wm9081_set_bias_level,
1308
1324 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1325 .reg_word_size = sizeof(u16), 1310 .reg_word_size = sizeof(u16),
1326 .reg_cache_default = wm9081_reg_defaults, 1311 .reg_cache_default = wm9081_reg_defaults,
1327 .volatile_register = wm9081_volatile_register, 1312 .volatile_register = wm9081_volatile_register,
1313
1314 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths,
1317 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1328}; 1318};
1329 1319
1330#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1343,8 +1333,8 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1343 wm9081->control_data = i2c; 1333 wm9081->control_data = i2c;
1344 1334
1345 if (dev_get_platdata(&i2c->dev)) 1335 if (dev_get_platdata(&i2c->dev))
1346 memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), 1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1347 sizeof(wm9081->retune)); 1337 sizeof(wm9081->pdata));
1348 1338
1349 ret = snd_soc_register_codec(&i2c->dev, 1339 ret = snd_soc_register_codec(&i2c->dev,
1350 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
@@ -1368,7 +1358,7 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1368 1358
1369static struct i2c_driver wm9081_i2c_driver = { 1359static struct i2c_driver wm9081_i2c_driver = {
1370 .driver = { 1360 .driver = {
1371 .name = "wm9081-codec", 1361 .name = "wm9081",
1372 .owner = THIS_MODULE, 1362 .owner = THIS_MODULE,
1373 }, 1363 },
1374 .probe = wm9081_i2c_probe, 1364 .probe = wm9081_i2c_probe,
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index a788c4297046..4de12203e611 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -144,7 +144,7 @@ struct wm9090_priv {
144 void *control_data; 144 void *control_data;
145}; 145};
146 146
147static int wm9090_volatile(unsigned int reg) 147static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
148{ 148{
149 switch (reg) { 149 switch (reg) {
150 case WM9090_SOFTWARE_RESET: 150 case WM9090_SOFTWARE_RESET:
@@ -518,7 +518,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
518 for (i = 1; i < codec->driver->reg_cache_size; i++) { 518 for (i = 1; i < codec->driver->reg_cache_size; i++) {
519 if (reg_cache[i] == wm9090_reg_defaults[i]) 519 if (reg_cache[i] == wm9090_reg_defaults[i])
520 continue; 520 continue;
521 if (wm9090_volatile(i)) 521 if (wm9090_volatile(codec, i))
522 continue; 522 continue;
523 523
524 ret = snd_soc_write(codec, i, reg_cache[i]); 524 ret = snd_soc_write(codec, i, reg_cache[i]);
@@ -551,7 +551,6 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
551static int wm9090_probe(struct snd_soc_codec *codec) 551static int wm9090_probe(struct snd_soc_codec *codec)
552{ 552{
553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); 553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
554 u16 *reg_cache = codec->reg_cache;
555 int ret; 554 int ret;
556 555
557 codec->control_data = wm9090->control_data; 556 codec->control_data = wm9090->control_data;
@@ -576,22 +575,30 @@ static int wm9090_probe(struct snd_soc_codec *codec)
576 /* Configure some defaults; they will be written out when we 575 /* Configure some defaults; they will be written out when we
577 * bring the bias up. 576 * bring the bias up.
578 */ 577 */
579 reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU 578 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_A_VOLUME,
580 | WM9090_IN1A_ZC; 579 WM9090_IN1_VU | WM9090_IN1A_ZC,
581 reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU 580 WM9090_IN1_VU | WM9090_IN1A_ZC);
582 | WM9090_IN1B_ZC; 581 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_B_VOLUME,
583 reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU 582 WM9090_IN1_VU | WM9090_IN1B_ZC,
584 | WM9090_IN2A_ZC; 583 WM9090_IN1_VU | WM9090_IN1B_ZC);
585 reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU 584 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_A_VOLUME,
586 | WM9090_IN2B_ZC; 585 WM9090_IN2_VU | WM9090_IN2A_ZC,
587 reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= 586 WM9090_IN2_VU | WM9090_IN2A_ZC);
588 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC; 587 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_B_VOLUME,
589 reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= 588 WM9090_IN2_VU | WM9090_IN2B_ZC,
590 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC; 589 WM9090_IN2_VU | WM9090_IN2B_ZC);
591 reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= 590 snd_soc_update_bits(codec, WM9090_SPEAKER_VOLUME_LEFT,
592 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC; 591 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
593 592 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
594 reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; 593 snd_soc_update_bits(codec, WM9090_LEFT_OUTPUT_VOLUME,
594 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
595 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
596 snd_soc_update_bits(codec, WM9090_RIGHT_OUTPUT_VOLUME,
597 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
598 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
599
600 snd_soc_update_bits(codec, WM9090_CLOCKING_1,
601 WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
595 602
596 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 603 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 604
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 516892706063..7b6b3c18e299 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -82,7 +82,8 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
82 } while (reg & op && count < 400); 82 } while (reg & op && count < 400);
83 83
84 if (reg & op) 84 if (reg & op)
85 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 85 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
86 op);
86} 87}
87 88
88/* 89/*
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 9e0e565e6ed9..d0d60b8a54d4 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -658,7 +658,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
658 return -ENODEV; 658 return -ENODEV;
659 } 659 }
660 660
661 ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, 661 ioarea = request_mem_region(mem->start, resource_size(mem),
662 pdev->name); 662 pdev->name);
663 if (!ioarea) { 663 if (!ioarea) {
664 dev_err(&pdev->dev, "McBSP region already claimed\n"); 664 dev_err(&pdev->dev, "McBSP region already claimed\n");
@@ -694,20 +694,25 @@ static int davinci_i2s_probe(struct platform_device *pdev)
694 } 694 }
695 clk_enable(dev->clk); 695 clk_enable(dev->clk);
696 696
697 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 697 dev->base = ioremap(mem->start, resource_size(mem));
698 if (!dev->base) {
699 dev_err(&pdev->dev, "ioremap failed\n");
700 ret = -ENOMEM;
701 goto err_release_clk;
702 }
698 703
699 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 704 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
700 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 705 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
701 706
702 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 707 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
703 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 708 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
704 709
705 /* first TX, then RX */ 710 /* first TX, then RX */
706 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 711 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
707 if (!res) { 712 if (!res) {
708 dev_err(&pdev->dev, "no DMA resource\n"); 713 dev_err(&pdev->dev, "no DMA resource\n");
709 ret = -ENXIO; 714 ret = -ENXIO;
710 goto err_free_mem; 715 goto err_iounmap;
711 } 716 }
712 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; 717 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
713 718
@@ -715,7 +720,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
715 if (!res) { 720 if (!res) {
716 dev_err(&pdev->dev, "no DMA resource\n"); 721 dev_err(&pdev->dev, "no DMA resource\n");
717 ret = -ENXIO; 722 ret = -ENXIO;
718 goto err_free_mem; 723 goto err_iounmap;
719 } 724 }
720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 725 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev; 726 dev->dev = &pdev->dev;
@@ -724,14 +729,19 @@ static int davinci_i2s_probe(struct platform_device *pdev)
724 729
725 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); 730 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
726 if (ret != 0) 731 if (ret != 0)
727 goto err_free_mem; 732 goto err_iounmap;
728 733
729 return 0; 734 return 0;
730 735
736err_iounmap:
737 iounmap(dev->base);
738err_release_clk:
739 clk_disable(dev->clk);
740 clk_put(dev->clk);
731err_free_mem: 741err_free_mem:
732 kfree(dev); 742 kfree(dev);
733err_release_region: 743err_release_region:
734 release_mem_region(mem->start, (mem->end - mem->start) + 1); 744 release_mem_region(mem->start, resource_size(mem));
735 745
736 return ret; 746 return ret;
737} 747}
@@ -747,7 +757,7 @@ static int davinci_i2s_remove(struct platform_device *pdev)
747 dev->clk = NULL; 757 dev->clk = NULL;
748 kfree(dev); 758 kfree(dev);
749 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
750 release_mem_region(mem->start, (mem->end - mem->start) + 1); 760 release_mem_region(mem->start, resource_size(mem));
751 761
752 return 0; 762 return 0;
753} 763}
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index fb55d2c5d704..a5af834c8ef5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -868,7 +868,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
868 } 868 }
869 869
870 ioarea = request_mem_region(mem->start, 870 ioarea = request_mem_region(mem->start,
871 (mem->end - mem->start) + 1, pdev->name); 871 resource_size(mem), pdev->name);
872 if (!ioarea) { 872 if (!ioarea) {
873 dev_err(&pdev->dev, "Audio region already claimed\n"); 873 dev_err(&pdev->dev, "Audio region already claimed\n");
874 ret = -EBUSY; 874 ret = -EBUSY;
@@ -885,7 +885,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
885 clk_enable(dev->clk); 885 clk_enable(dev->clk);
886 dev->clk_active = 1; 886 dev->clk_active = 1;
887 887
888 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 888 dev->base = ioremap(mem->start, resource_size(mem));
889 if (!dev->base) {
890 dev_err(&pdev->dev, "ioremap failed\n");
891 ret = -ENOMEM;
892 goto err_release_clk;
893 }
894
889 dev->op_mode = pdata->op_mode; 895 dev->op_mode = pdata->op_mode;
890 dev->tdm_slots = pdata->tdm_slots; 896 dev->tdm_slots = pdata->tdm_slots;
891 dev->num_serializer = pdata->num_serializer; 897 dev->num_serializer = pdata->num_serializer;
@@ -899,14 +905,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
899 dma_data->asp_chan_q = pdata->asp_chan_q; 905 dma_data->asp_chan_q = pdata->asp_chan_q;
900 dma_data->ram_chan_q = pdata->ram_chan_q; 906 dma_data->ram_chan_q = pdata->ram_chan_q;
901 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 907 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
902 io_v2p(dev->base)); 908 mem->start);
903 909
904 /* first TX, then RX */ 910 /* first TX, then RX */
905 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 911 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
906 if (!res) { 912 if (!res) {
907 dev_err(&pdev->dev, "no DMA resource\n"); 913 dev_err(&pdev->dev, "no DMA resource\n");
908 ret = -ENODEV; 914 ret = -ENODEV;
909 goto err_release_region; 915 goto err_iounmap;
910 } 916 }
911 917
912 dma_data->channel = res->start; 918 dma_data->channel = res->start;
@@ -915,13 +921,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
915 dma_data->asp_chan_q = pdata->asp_chan_q; 921 dma_data->asp_chan_q = pdata->asp_chan_q;
916 dma_data->ram_chan_q = pdata->ram_chan_q; 922 dma_data->ram_chan_q = pdata->ram_chan_q;
917 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 923 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
918 io_v2p(dev->base)); 924 mem->start);
919 925
920 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 926 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
921 if (!res) { 927 if (!res) {
922 dev_err(&pdev->dev, "no DMA resource\n"); 928 dev_err(&pdev->dev, "no DMA resource\n");
923 ret = -ENODEV; 929 ret = -ENODEV;
924 goto err_release_region; 930 goto err_iounmap;
925 } 931 }
926 932
927 dma_data->channel = res->start; 933 dma_data->channel = res->start;
@@ -929,11 +935,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
929 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); 935 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
930 936
931 if (ret != 0) 937 if (ret != 0)
932 goto err_release_region; 938 goto err_iounmap;
933 return 0; 939 return 0;
934 940
941err_iounmap:
942 iounmap(dev->base);
943err_release_clk:
944 clk_disable(dev->clk);
945 clk_put(dev->clk);
935err_release_region: 946err_release_region:
936 release_mem_region(mem->start, (mem->end - mem->start) + 1); 947 release_mem_region(mem->start, resource_size(mem));
937err_release_data: 948err_release_data:
938 kfree(dev); 949 kfree(dev);
939 950
@@ -951,7 +962,7 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
951 dev->clk = NULL; 962 dev->clk = NULL;
952 963
953 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 964 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
954 release_mem_region(mem->start, (mem->end - mem->start) + 1); 965 release_mem_region(mem->start, resource_size(mem));
955 966
956 kfree(dev); 967 kfree(dev);
957 968
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
index 57429041189c..91a28de94109 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/ep93xx/Kconfig
@@ -30,3 +30,12 @@ config SND_EP93XX_SOC_SIMONE
30 help 30 help
31 Say Y or M here if you want to add support for AC97 audio on the 31 Say Y or M here if you want to add support for AC97 audio on the
32 Simplemachines Sim.One board. 32 Simplemachines Sim.One board.
33
34config SND_EP93XX_SOC_EDB93XX
35 tristate "SoC Audio support for Cirrus Logic EDB93xx boards"
36 depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A)
37 select SND_EP93XX_SOC_I2S
38 select SND_SOC_CS4271
39 help
40 Say Y or M here if you want to add support for I2S audio on the
41 Cirrus Logic EDB93xx boards.
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/ep93xx/Makefile
index 8e7977fb6b7d..5514146cbdf0 100644
--- a/sound/soc/ep93xx/Makefile
+++ b/sound/soc/ep93xx/Makefile
@@ -10,6 +10,8 @@ obj-$(CONFIG_SND_EP93XX_SOC_AC97) += snd-soc-ep93xx-ac97.o
10# EP93XX Machine Support 10# EP93XX Machine Support
11snd-soc-snappercl15-objs := snappercl15.o 11snd-soc-snappercl15-objs := snappercl15.o
12snd-soc-simone-objs := simone.o 12snd-soc-simone-objs := simone.o
13snd-soc-edb93xx-objs := edb93xx.o
13 14
14obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o 15obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
15obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o 16obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o
17obj-$(CONFIG_SND_EP93XX_SOC_EDB93XX) += snd-soc-edb93xx.o
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
new file mode 100644
index 000000000000..d3aa15119d26
--- /dev/null
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -0,0 +1,142 @@
1/*
2 * SoC audio for EDB93xx
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include "ep93xx-pcm.h"
30
31#define edb93xx_has_audio() (machine_is_edb9301() || \
32 machine_is_edb9302() || \
33 machine_is_edb9302a() || \
34 machine_is_edb9307a() || \
35 machine_is_edb9315a())
36
37static int edb93xx_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 int err;
44 unsigned int mclk_rate;
45 unsigned int rate = params_rate(params);
46
47 /*
48 * According to CS4271 datasheet we use MCLK/LRCK=256 for
49 * rates below 50kHz and 128 for higher sample rates
50 */
51 if (rate < 50000)
52 mclk_rate = rate * 64 * 4;
53 else
54 mclk_rate = rate * 64 * 2;
55
56 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_IF |
58 SND_SOC_DAIFMT_CBS_CFS);
59 if (err)
60 return err;
61
62 err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_IF |
64 SND_SOC_DAIFMT_CBS_CFS);
65 if (err)
66 return err;
67
68 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
69 SND_SOC_CLOCK_IN);
70 if (err)
71 return err;
72
73 return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate,
74 SND_SOC_CLOCK_OUT);
75}
76
77static struct snd_soc_ops edb93xx_ops = {
78 .hw_params = edb93xx_hw_params,
79};
80
81static struct snd_soc_dai_link edb93xx_dai = {
82 .name = "CS4271",
83 .stream_name = "CS4271 HiFi",
84 .platform_name = "ep93xx-pcm-audio",
85 .cpu_dai_name = "ep93xx-i2s",
86 .codec_name = "spi0.0",
87 .codec_dai_name = "cs4271-hifi",
88 .ops = &edb93xx_ops,
89};
90
91static struct snd_soc_card snd_soc_edb93xx = {
92 .name = "EDB93XX",
93 .dai_link = &edb93xx_dai,
94 .num_links = 1,
95};
96
97static struct platform_device *edb93xx_snd_device;
98
99static int __init edb93xx_init(void)
100{
101 int ret;
102
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret)
110 return ret;
111
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1);
113 if (!edb93xx_snd_device) {
114 ret = -ENOMEM;
115 goto free_i2s;
116 }
117
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx);
119 ret = platform_device_add(edb93xx_snd_device);
120 if (ret)
121 goto device_put;
122
123 return 0;
124
125device_put:
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release();
129 return ret;
130}
131module_init(edb93xx_init);
132
133static void __exit edb93xx_exit(void)
134{
135 platform_device_unregister(edb93xx_snd_device);
136 ep93xx_i2s_release();
137}
138module_exit(edb93xx_exit);
139
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 68a0bae1208a..104e95cda0ad 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -253,7 +253,6 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); 253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
254 unsigned v = 0; 254 unsigned v = 0;
255 255
256
257 switch (cmd) { 256 switch (cmd) {
258 case SNDRV_PCM_TRIGGER_START: 257 case SNDRV_PCM_TRIGGER_START:
259 case SNDRV_PCM_TRIGGER_RESUME: 258 case SNDRV_PCM_TRIGGER_RESUME:
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index fff579a1c134..042f4e93746f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -242,7 +242,7 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
242{ 242{
243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
244 unsigned word_len, div, sdiv, lrdiv; 244 unsigned word_len, div, sdiv, lrdiv;
245 int found = 0, err; 245 int err;
246 246
247 switch (params_format(params)) { 247 switch (params_format(params)) {
248 case SNDRV_PCM_FORMAT_S16_LE: 248 case SNDRV_PCM_FORMAT_S16_LE:
@@ -275,15 +275,14 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
275 * the codec uses. 275 * the codec uses.
276 */ 276 */
277 div = clk_get_rate(info->mclk) / params_rate(params); 277 div = clk_get_rate(info->mclk) / params_rate(params);
278 for (sdiv = 2; sdiv <= 4; sdiv += 2) 278 sdiv = 4;
279 for (lrdiv = 64; lrdiv <= 128; lrdiv <<= 1) 279 if (div > (256 + 512) / 2) {
280 if (sdiv * lrdiv == div) { 280 lrdiv = 128;
281 found = 1; 281 } else {
282 goto out; 282 lrdiv = 64;
283 } 283 if (div < (128 + 256) / 2)
284out: 284 sdiv = 2;
285 if (!found) 285 }
286 return -EINVAL;
287 286
288 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv); 287 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
289 if (err) 288 if (err)
@@ -314,10 +313,12 @@ static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
314 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 313 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
315 314
316 if (!dai->active) 315 if (!dai->active)
317 return; 316 return 0;
318 317
319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK); 318 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
320 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE); 319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
320
321 return 0;
321} 322}
322 323
323static int ep93xx_i2s_resume(struct snd_soc_dai *dai) 324static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
@@ -325,10 +326,12 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
325 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 326 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
326 327
327 if (!dai->active) 328 if (!dai->active)
328 return; 329 return 0;
329 330
330 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK); 331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE); 332 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
333
334 return 0;
332} 335}
333#else 336#else
334#define ep93xx_i2s_suspend NULL 337#define ep93xx_i2s_suspend NULL
@@ -352,13 +355,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
352 .playback = { 355 .playback = {
353 .channels_min = 2, 356 .channels_min = 2,
354 .channels_max = 2, 357 .channels_max = 2,
355 .rates = SNDRV_PCM_RATE_8000_96000, 358 .rates = SNDRV_PCM_RATE_8000_192000,
356 .formats = EP93XX_I2S_FORMATS, 359 .formats = EP93XX_I2S_FORMATS,
357 }, 360 },
358 .capture = { 361 .capture = {
359 .channels_min = 2, 362 .channels_min = 2,
360 .channels_max = 2, 363 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_96000, 364 .rates = SNDRV_PCM_RATE_8000_192000,
362 .formats = EP93XX_I2S_FORMATS, 365 .formats = EP93XX_I2S_FORMATS,
363 }, 366 },
364 .ops = &ep93xx_i2s_dai_ops, 367 .ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 06670776f649..a456e491155f 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 = {
35 SNDRV_PCM_INFO_INTERLEAVED | 35 SNDRV_PCM_INFO_INTERLEAVED |
36 SNDRV_PCM_INFO_BLOCK_TRANSFER), 36 SNDRV_PCM_INFO_BLOCK_TRANSFER),
37 37
38 .rates = SNDRV_PCM_RATE_8000_96000, 38 .rates = SNDRV_PCM_RATE_8000_192000,
39 .rate_min = SNDRV_PCM_RATE_8000, 39 .rate_min = SNDRV_PCM_RATE_8000,
40 .rate_max = SNDRV_PCM_RATE_96000, 40 .rate_max = SNDRV_PCM_RATE_192000,
41 41
42 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
43 SNDRV_PCM_FMTBIT_S24_LE | 43 SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 7d7847a1e66b..c16c6b2eff95 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -53,9 +53,8 @@ struct mpc8610_hpcd_data {
53 * 53 *
54 * Here we program the DMACR and PMUXCR registers. 54 * Here we program the DMACR and PMUXCR registers.
55 */ 55 */
56static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device) 56static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
57{ 57{
58 struct snd_soc_card *card = platform_get_drvdata(sound_device);
59 struct mpc8610_hpcd_data *machine_data = 58 struct mpc8610_hpcd_data *machine_data =
60 container_of(card, struct mpc8610_hpcd_data, card); 59 container_of(card, struct mpc8610_hpcd_data, card);
61 struct ccsr_guts_86xx __iomem *guts; 60 struct ccsr_guts_86xx __iomem *guts;
@@ -138,9 +137,8 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
138 * This function is called to remove the sound device for one SSI. We 137 * This function is called to remove the sound device for one SSI. We
139 * de-program the DMACR and PMUXCR register. 138 * de-program the DMACR and PMUXCR register.
140 */ 139 */
141static int mpc8610_hpcd_machine_remove(struct platform_device *sound_device) 140static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
142{ 141{
143 struct snd_soc_card *card = platform_get_drvdata(sound_device);
144 struct mpc8610_hpcd_data *machine_data = 142 struct mpc8610_hpcd_data *machine_data =
145 container_of(card, struct mpc8610_hpcd_data, card); 143 container_of(card, struct mpc8610_hpcd_data, card);
146 struct ccsr_guts_86xx __iomem *guts; 144 struct ccsr_guts_86xx __iomem *guts;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 026b756961e0..66e0b68af147 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -85,9 +85,8 @@ struct machine_data {
85 * 85 *
86 * Here we program the DMACR and PMUXCR registers. 86 * Here we program the DMACR and PMUXCR registers.
87 */ 87 */
88static int p1022_ds_machine_probe(struct platform_device *sound_device) 88static int p1022_ds_machine_probe(struct snd_soc_card *card)
89{ 89{
90 struct snd_soc_card *card = platform_get_drvdata(sound_device);
91 struct machine_data *mdata = 90 struct machine_data *mdata =
92 container_of(card, struct machine_data, card); 91 container_of(card, struct machine_data, card);
93 struct ccsr_guts_85xx __iomem *guts; 92 struct ccsr_guts_85xx __iomem *guts;
@@ -160,9 +159,8 @@ static int p1022_ds_startup(struct snd_pcm_substream *substream)
160 * This function is called to remove the sound device for one SSI. We 159 * This function is called to remove the sound device for one SSI. We
161 * de-program the DMACR and PMUXCR register. 160 * de-program the DMACR and PMUXCR register.
162 */ 161 */
163static int p1022_ds_machine_remove(struct platform_device *sound_device) 162static int p1022_ds_machine_remove(struct snd_soc_card *card)
164{ 163{
165 struct snd_soc_card *card = platform_get_drvdata(sound_device);
166 struct machine_data *mdata = 164 struct machine_data *mdata =
167 container_of(card, struct machine_data, card); 165 container_of(card, struct machine_data, card);
168 struct ccsr_guts_85xx __iomem *guts; 166 struct ccsr_guts_85xx __iomem *guts;
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 9eeb8f0d67e9..d8f130d39dd9 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -30,6 +30,16 @@ config SND_MXC_SOC_WM1133_EV1
30 Enable support for audio on the i.MX31ADS with the WM1133-EV1 30 Enable support for audio on the i.MX31ADS with the WM1133-EV1
31 PMIC board with WM8835x fitted. 31 PMIC board with WM8835x fitted.
32 32
33config SND_SOC_MX27VIS_AIC32X4
34 tristate "SoC audio support for Visstrim M10 boards"
35 depends on MACH_IMX27_VISSTRIM_M10
36 select SND_SOC_TVL320AIC32X4
37 select SND_MXC_SOC_SSI
38 select SND_MXC_SOC_MX2
39 help
40 Say Y if you want to add support for SoC audio on Visstrim SM10
41 board with TLV320AIC32X4 codec.
42
33config SND_SOC_PHYCORE_AC97 43config SND_SOC_PHYCORE_AC97
34 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 44 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
35 depends on MACH_PCM043 || MACH_PCA100 45 depends on MACH_PCM043 || MACH_PCA100
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index b67fc02a4ecc..d6d609ba7e24 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -10,8 +10,10 @@ obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
12snd-soc-phycore-ac97-objs := phycore-ac97.o 12snd-soc-phycore-ac97-objs := phycore-ac97.o
13snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
13snd-soc-wm1133-ev1-objs := wm1133-ev1.o 14snd-soc-wm1133-ev1-objs := wm1133-ev1.o
14 15
15obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 16obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
16obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 17obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
18obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
17obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 19obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 30894ea7f333..bc92ec620004 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -108,7 +108,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
108 break; 108 break;
109 case SND_SOC_DAIFMT_DSP_B: 109 case SND_SOC_DAIFMT_DSP_B:
110 /* data on rising edge of bclk, frame high with data */ 110 /* data on rising edge of bclk, frame high with data */
111 strcr |= SSI_STCR_TFSL; 111 strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
112 break; 112 break;
113 case SND_SOC_DAIFMT_DSP_A: 113 case SND_SOC_DAIFMT_DSP_A:
114 /* data on rising edge of bclk, frame high 1clk before data */ 114 /* data on rising edge of bclk, frame high 1clk before data */
@@ -656,6 +656,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
658 658
659 ssi->dma_params_tx.burstsize = 4;
660 ssi->dma_params_rx.burstsize = 4;
661
659 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 662 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
660 if (res) 663 if (res)
661 ssi->dma_params_tx.dma = res->start; 664 ssi->dma_params_tx.dma = res->start;
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
new file mode 100644
index 000000000000..054110b91d42
--- /dev/null
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -0,0 +1,137 @@
1/*
2 * mx27vis-aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/device.h>
27#include <linux/i2c.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <asm/mach-types.h>
33#include <mach/audmux.h>
34
35#include "../codecs/tlv320aic32x4.h"
36#include "imx-ssi.h"
37
38static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret;
45 u32 dai_format;
46
47 dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM;
49
50 /* set codec DAI configuration */
51 snd_soc_dai_set_fmt(codec_dai, dai_format);
52
53 /* set cpu DAI configuration */
54 snd_soc_dai_set_fmt(cpu_dai, dai_format);
55
56 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
57 25000000, SND_SOC_CLOCK_OUT);
58 if (ret) {
59 pr_err("%s: failed setting codec sysclk\n", __func__);
60 return ret;
61 }
62
63 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
64 SND_SOC_CLOCK_IN);
65 if (ret) {
66 pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
67 return ret;
68 }
69
70 return 0;
71}
72
73static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
74 .hw_params = mx27vis_aic32x4_hw_params,
75};
76
77static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
78 .name = "tlv320aic32x4",
79 .stream_name = "TLV320AIC32X4",
80 .codec_dai_name = "tlv320aic32x4-hifi",
81 .platform_name = "imx-pcm-audio.0",
82 .codec_name = "tlv320aic32x4.0-0018",
83 .cpu_dai_name = "imx-ssi.0",
84 .ops = &mx27vis_aic32x4_snd_ops,
85};
86
87static struct snd_soc_card mx27vis_aic32x4 = {
88 .name = "visstrim_m10-audio",
89 .dai_link = &mx27vis_aic32x4_dai,
90 .num_links = 1,
91};
92
93static struct platform_device *mx27vis_aic32x4_snd_device;
94
95static int __init mx27vis_aic32x4_init(void)
96{
97 int ret;
98
99 mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1);
100 if (!mx27vis_aic32x4_snd_device)
101 return -ENOMEM;
102
103 platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
104 ret = platform_device_add(mx27vis_aic32x4_snd_device);
105
106 if (ret) {
107 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
108 platform_device_put(mx27vis_aic32x4_snd_device);
109 }
110
111 /* Connect SSI0 as clock slave to SSI1 external pins */
112 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
113 MXC_AUDMUX_V1_PCR_SYN |
114 MXC_AUDMUX_V1_PCR_TFSDIR |
115 MXC_AUDMUX_V1_PCR_TCLKDIR |
116 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
117 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
118 );
119 mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
120 MXC_AUDMUX_V1_PCR_SYN |
121 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
122 );
123
124 return ret;
125}
126
127static void __exit mx27vis_aic32x4_exit(void)
128{
129 platform_device_unregister(mx27vis_aic32x4_snd_device);
130}
131
132module_init(mx27vis_aic32x4_init);
133module_exit(mx27vis_aic32x4_exit);
134
135MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
136MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
137MODULE_LICENSE("GPL");
diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig
new file mode 100644
index 000000000000..29350428f1c2
--- /dev/null
+++ b/sound/soc/mid-x86/Kconfig
@@ -0,0 +1,14 @@
1config SND_MFLD_MACHINE
2 tristate "SOC Machine Audio driver for Intel Medfield MID platform"
3 depends on INTEL_SCU_IPC
4 depends on SND_INTEL_SST
5 select SND_SOC_SN95031
6 select SND_SST_PLATFORM
7 help
8 This adds support for ASoC machine driver for Intel(R) MID Medfield platform
9 used as alsa device in audio substem in Intel(R) MID devices
10 Say Y if you have such a device
11 If unsure select "N".
12
13config SND_SST_PLATFORM
14 tristate
diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile
new file mode 100644
index 000000000000..639883339465
--- /dev/null
+++ b/sound/soc/mid-x86/Makefile
@@ -0,0 +1,5 @@
1snd-soc-sst-platform-objs := sst_platform.o
2snd-soc-mfld-machine-objs := mfld_machine.o
3
4obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o
5obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
new file mode 100644
index 000000000000..429aa1be2cff
--- /dev/null
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -0,0 +1,452 @@
1/*
2 * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24
25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/jack.h>
35#include "../codecs/sn95031.h"
36
37#define MID_MONO 1
38#define MID_STEREO 2
39#define MID_MAX_CAP 5
40#define MFLD_JACK_INSERT 0x04
41
42enum soc_mic_bias_zones {
43 MFLD_MV_START = 0,
44 /* mic bias volutage range for Headphones*/
45 MFLD_MV_HP = 400,
46 /* mic bias volutage range for American Headset*/
47 MFLD_MV_AM_HS = 650,
48 /* mic bias volutage range for Headset*/
49 MFLD_MV_HS = 2000,
50 MFLD_MV_UNDEFINED,
51};
52
53static unsigned int hs_switch;
54static unsigned int lo_dac;
55
56struct mfld_mc_private {
57 struct platform_device *socdev;
58 void __iomem *int_base;
59 struct snd_soc_codec *codec;
60 u8 interrupt_status;
61};
62
63struct snd_soc_jack mfld_jack;
64
65/*Headset jack detection DAPM pins */
66static struct snd_soc_jack_pin mfld_jack_pins[] = {
67 {
68 .pin = "Headphones",
69 .mask = SND_JACK_HEADPHONE,
70 },
71 {
72 .pin = "AMIC1",
73 .mask = SND_JACK_MICROPHONE,
74 },
75};
76
77/* jack detection voltage zones */
78static struct snd_soc_jack_zone mfld_zones[] = {
79 {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE},
80 {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET},
81};
82
83/* sound card controls */
84static const char *headset_switch_text[] = {"Earpiece", "Headset"};
85
86static const char *lo_text[] = {"Vibra", "Headset", "IHF", "None"};
87
88static const struct soc_enum headset_enum =
89 SOC_ENUM_SINGLE_EXT(2, headset_switch_text);
90
91static const struct soc_enum lo_enum =
92 SOC_ENUM_SINGLE_EXT(4, lo_text);
93
94static int headset_get_switch(struct snd_kcontrol *kcontrol,
95 struct snd_ctl_elem_value *ucontrol)
96{
97 ucontrol->value.integer.value[0] = hs_switch;
98 return 0;
99}
100
101static int headset_set_switch(struct snd_kcontrol *kcontrol,
102 struct snd_ctl_elem_value *ucontrol)
103{
104 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
105
106 if (ucontrol->value.integer.value[0] == hs_switch)
107 return 0;
108
109 if (ucontrol->value.integer.value[0]) {
110 pr_debug("hs_set HS path\n");
111 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
112 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
113 } else {
114 pr_debug("hs_set EP path\n");
115 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
116 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
117 }
118 snd_soc_dapm_sync(&codec->dapm);
119 hs_switch = ucontrol->value.integer.value[0];
120
121 return 0;
122}
123
124static void lo_enable_out_pins(struct snd_soc_codec *codec)
125{
126 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL");
127 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR");
128 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL");
129 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR");
130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT");
131 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT");
132 if (hs_switch) {
133 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
134 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
135 } else {
136 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
137 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
138 }
139}
140
141static int lo_get_switch(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 ucontrol->value.integer.value[0] = lo_dac;
145 return 0;
146}
147
148static int lo_set_switch(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol)
150{
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152
153 if (ucontrol->value.integer.value[0] == lo_dac)
154 return 0;
155
156 /* we dont want to work with last state of lineout so just enable all
157 * pins and then disable pins not required
158 */
159 lo_enable_out_pins(codec);
160 switch (ucontrol->value.integer.value[0]) {
161 case 0:
162 pr_debug("set vibra path\n");
163 snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT");
164 snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT");
165 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0);
166 break;
167
168 case 1:
169 pr_debug("set hs path\n");
170 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
171 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
172 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
173 break;
174
175 case 2:
176 pr_debug("set spkr path\n");
177 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL");
178 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR");
179 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44);
180 break;
181
182 case 3:
183 pr_debug("set null path\n");
184 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL");
185 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR");
186 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66);
187 break;
188 }
189 snd_soc_dapm_sync(&codec->dapm);
190 lo_dac = ucontrol->value.integer.value[0];
191 return 0;
192}
193
194static const struct snd_kcontrol_new mfld_snd_controls[] = {
195 SOC_ENUM_EXT("Playback Switch", headset_enum,
196 headset_get_switch, headset_set_switch),
197 SOC_ENUM_EXT("Lineout Mux", lo_enum,
198 lo_get_switch, lo_set_switch),
199};
200
201static const struct snd_soc_dapm_widget mfld_widgets[] = {
202 SND_SOC_DAPM_HP("Headphones", NULL),
203 SND_SOC_DAPM_MIC("Mic", NULL),
204};
205
206static const struct snd_soc_dapm_route mfld_map[] = {
207 {"Headphones", NULL, "HPOUTR"},
208 {"Headphones", NULL, "HPOUTL"},
209 {"Mic", NULL, "AMIC1"},
210};
211
212static void mfld_jack_check(unsigned int intr_status)
213{
214 struct mfld_jack_data jack_data;
215
216 jack_data.mfld_jack = &mfld_jack;
217 jack_data.intr_id = intr_status;
218
219 sn95031_jack_detection(&jack_data);
220 /* TODO: add american headset detection post gpiolib support */
221}
222
223static int mfld_init(struct snd_soc_pcm_runtime *runtime)
224{
225 struct snd_soc_codec *codec = runtime->codec;
226 struct snd_soc_dapm_context *dapm = &codec->dapm;
227 int ret_val;
228
229 /* Add jack sense widgets */
230 snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
231
232 /* Set up the map */
233 snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
234
235 /* always connected */
236 snd_soc_dapm_enable_pin(dapm, "Headphones");
237 snd_soc_dapm_enable_pin(dapm, "Mic");
238 snd_soc_dapm_sync(dapm);
239
240 ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
241 ARRAY_SIZE(mfld_snd_controls));
242 if (ret_val) {
243 pr_err("soc_add_controls failed %d", ret_val);
244 return ret_val;
245 }
246 /* default is earpiece pin, userspace sets it explcitly */
247 snd_soc_dapm_disable_pin(dapm, "Headphones");
248 /* default is lineout NC, userspace sets it explcitly */
249 snd_soc_dapm_disable_pin(dapm, "LINEOUTL");
250 snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
251 lo_dac = 3;
252 hs_switch = 0;
253 /* we dont use linein in this so set to NC */
254 snd_soc_dapm_disable_pin(dapm, "LINEINL");
255 snd_soc_dapm_disable_pin(dapm, "LINEINR");
256 snd_soc_dapm_sync(dapm);
257
258 /* Headset and button jack detection */
259 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
260 SND_JACK_HEADSET | SND_JACK_BTN_0 |
261 SND_JACK_BTN_1, &mfld_jack);
262 if (ret_val) {
263 pr_err("jack creation failed\n");
264 return ret_val;
265 }
266
267 ret_val = snd_soc_jack_add_pins(&mfld_jack,
268 ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins);
269 if (ret_val) {
270 pr_err("adding jack pins failed\n");
271 return ret_val;
272 }
273 ret_val = snd_soc_jack_add_zones(&mfld_jack,
274 ARRAY_SIZE(mfld_zones), mfld_zones);
275 if (ret_val) {
276 pr_err("adding jack zones failed\n");
277 return ret_val;
278 }
279
280 /* we want to check if anything is inserted at boot,
281 * so send a fake event to codec and it will read adc
282 * to find if anything is there or not */
283 mfld_jack_check(MFLD_JACK_INSERT);
284 return ret_val;
285}
286
287struct snd_soc_dai_link mfld_msic_dailink[] = {
288 {
289 .name = "Medfield Headset",
290 .stream_name = "Headset",
291 .cpu_dai_name = "Headset-cpu-dai",
292 .codec_dai_name = "SN95031 Headset",
293 .codec_name = "sn95031",
294 .platform_name = "sst-platform",
295 .init = mfld_init,
296 },
297 {
298 .name = "Medfield Speaker",
299 .stream_name = "Speaker",
300 .cpu_dai_name = "Speaker-cpu-dai",
301 .codec_dai_name = "SN95031 Speaker",
302 .codec_name = "sn95031",
303 .platform_name = "sst-platform",
304 .init = NULL,
305 },
306 {
307 .name = "Medfield Vibra",
308 .stream_name = "Vibra1",
309 .cpu_dai_name = "Vibra1-cpu-dai",
310 .codec_dai_name = "SN95031 Vibra1",
311 .codec_name = "sn95031",
312 .platform_name = "sst-platform",
313 .init = NULL,
314 },
315 {
316 .name = "Medfield Haptics",
317 .stream_name = "Vibra2",
318 .cpu_dai_name = "Vibra2-cpu-dai",
319 .codec_dai_name = "SN95031 Vibra2",
320 .codec_name = "sn95031",
321 .platform_name = "sst-platform",
322 .init = NULL,
323 },
324};
325
326/* SoC card */
327static struct snd_soc_card snd_soc_card_mfld = {
328 .name = "medfield_audio",
329 .dai_link = mfld_msic_dailink,
330 .num_links = ARRAY_SIZE(mfld_msic_dailink),
331};
332
333static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
334{
335 struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev;
336
337 memcpy_fromio(&mc_private->interrupt_status,
338 ((void *)(mc_private->int_base)),
339 sizeof(u8));
340 return IRQ_WAKE_THREAD;
341}
342
343static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
344{
345 struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
346
347 if (mfld_jack.codec == NULL)
348 return IRQ_HANDLED;
349 mfld_jack_check(mc_drv_ctx->interrupt_status);
350
351 return IRQ_HANDLED;
352}
353
354static int __devinit snd_mfld_mc_probe(struct platform_device *pdev)
355{
356 int ret_val = 0, irq;
357 struct mfld_mc_private *mc_drv_ctx;
358 struct resource *irq_mem;
359
360 pr_debug("snd_mfld_mc_probe called\n");
361
362 /* retrive the irq number */
363 irq = platform_get_irq(pdev, 0);
364
365 /* audio interrupt base of SRAM location where
366 * interrupts are stored by System FW */
367 mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC);
368 if (!mc_drv_ctx) {
369 pr_err("allocation failed\n");
370 return -ENOMEM;
371 }
372
373 irq_mem = platform_get_resource_byname(
374 pdev, IORESOURCE_MEM, "IRQ_BASE");
375 if (!irq_mem) {
376 pr_err("no mem resource given\n");
377 ret_val = -ENODEV;
378 goto unalloc;
379 }
380 mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start,
381 resource_size(irq_mem));
382 if (!mc_drv_ctx->int_base) {
383 pr_err("Mapping of cache failed\n");
384 ret_val = -ENOMEM;
385 goto unalloc;
386 }
387 /* register for interrupt */
388 ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler,
389 snd_mfld_jack_detection,
390 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
391 if (ret_val) {
392 pr_err("cannot register IRQ\n");
393 goto unalloc;
394 }
395 /* register the soc card */
396 snd_soc_card_mfld.dev = &pdev->dev;
397 ret_val = snd_soc_register_card(&snd_soc_card_mfld);
398 if (ret_val) {
399 pr_debug("snd_soc_register_card failed %d\n", ret_val);
400 goto freeirq;
401 }
402 platform_set_drvdata(pdev, mc_drv_ctx);
403 pr_debug("successfully exited probe\n");
404 return ret_val;
405
406freeirq:
407 free_irq(irq, mc_drv_ctx);
408unalloc:
409 kfree(mc_drv_ctx);
410 return ret_val;
411}
412
413static int __devexit snd_mfld_mc_remove(struct platform_device *pdev)
414{
415 struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
416
417 pr_debug("snd_mfld_mc_remove called\n");
418 free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
419 snd_soc_unregister_card(&snd_soc_card_mfld);
420 kfree(mc_drv_ctx);
421 platform_set_drvdata(pdev, NULL);
422 return 0;
423}
424
425static struct platform_driver snd_mfld_mc_driver = {
426 .driver = {
427 .owner = THIS_MODULE,
428 .name = "msic_audio",
429 },
430 .probe = snd_mfld_mc_probe,
431 .remove = __devexit_p(snd_mfld_mc_remove),
432};
433
434static int __init snd_mfld_driver_init(void)
435{
436 pr_debug("snd_mfld_driver_init called\n");
437 return platform_driver_register(&snd_mfld_mc_driver);
438}
439module_init(snd_mfld_driver_init);
440
441static void __exit snd_mfld_driver_exit(void)
442{
443 pr_debug("snd_mfld_driver_exit called\n");
444 platform_driver_unregister(&snd_mfld_mc_driver);
445}
446module_exit(snd_mfld_driver_exit);
447
448MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
449MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
450MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
451MODULE_LICENSE("GPL v2");
452MODULE_ALIAS("platform:msic-audio");
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
new file mode 100644
index 000000000000..ee2c22475a76
--- /dev/null
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -0,0 +1,474 @@
1/*
2 * sst_platform.c - Intel MID Platform driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h"
35#include "../../../drivers/staging/intel_sst/intel_sst.h"
36#include "sst_platform.h"
37
38static struct snd_pcm_hardware sst_platform_pcm_hw = {
39 .info = (SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_DOUBLE |
41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME |
43 SNDRV_PCM_INFO_MMAP|
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_BLOCK_TRANSFER |
46 SNDRV_PCM_INFO_SYNC_START),
47 .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
48 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
49 SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
50 .rates = (SNDRV_PCM_RATE_8000|
51 SNDRV_PCM_RATE_44100 |
52 SNDRV_PCM_RATE_48000),
53 .rate_min = SST_MIN_RATE,
54 .rate_max = SST_MAX_RATE,
55 .channels_min = SST_MIN_CHANNEL,
56 .channels_max = SST_MAX_CHANNEL,
57 .buffer_bytes_max = SST_MAX_BUFFER,
58 .period_bytes_min = SST_MIN_PERIOD_BYTES,
59 .period_bytes_max = SST_MAX_PERIOD_BYTES,
60 .periods_min = SST_MIN_PERIODS,
61 .periods_max = SST_MAX_PERIODS,
62 .fifo_size = SST_FIFO_SIZE,
63};
64
65/* MFLD - MSIC */
66struct snd_soc_dai_driver sst_platform_dai[] = {
67{
68 .name = "Headset-cpu-dai",
69 .id = 0,
70 .playback = {
71 .channels_min = SST_STEREO,
72 .channels_max = SST_STEREO,
73 .rates = SNDRV_PCM_RATE_48000,
74 .formats = SNDRV_PCM_FMTBIT_S24_LE,
75 },
76 .capture = {
77 .channels_min = 1,
78 .channels_max = 5,
79 .rates = SNDRV_PCM_RATE_48000,
80 .formats = SNDRV_PCM_FMTBIT_S24_LE,
81 },
82},
83{
84 .name = "Speaker-cpu-dai",
85 .id = 1,
86 .playback = {
87 .channels_min = SST_MONO,
88 .channels_max = SST_STEREO,
89 .rates = SNDRV_PCM_RATE_48000,
90 .formats = SNDRV_PCM_FMTBIT_S24_LE,
91 },
92},
93{
94 .name = "Vibra1-cpu-dai",
95 .id = 2,
96 .playback = {
97 .channels_min = SST_MONO,
98 .channels_max = SST_MONO,
99 .rates = SNDRV_PCM_RATE_48000,
100 .formats = SNDRV_PCM_FMTBIT_S24_LE,
101 },
102},
103{
104 .name = "Vibra2-cpu-dai",
105 .id = 3,
106 .playback = {
107 .channels_min = SST_MONO,
108 .channels_max = SST_STEREO,
109 .rates = SNDRV_PCM_RATE_48000,
110 .formats = SNDRV_PCM_FMTBIT_S24_LE,
111 },
112},
113};
114
115/* helper functions */
116static inline void sst_set_stream_status(struct sst_runtime_stream *stream,
117 int state)
118{
119 spin_lock(&stream->status_lock);
120 stream->stream_status = state;
121 spin_unlock(&stream->status_lock);
122}
123
124static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
125{
126 int state;
127
128 spin_lock(&stream->status_lock);
129 state = stream->stream_status;
130 spin_unlock(&stream->status_lock);
131 return state;
132}
133
134static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
135 struct snd_sst_stream_params *param)
136{
137
138 param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
139 param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
140 param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
141 param->uc.pcm_params.reserved = 0;
142 param->uc.pcm_params.sfreq = substream->runtime->rate;
143 param->uc.pcm_params.ring_buffer_size =
144 snd_pcm_lib_buffer_bytes(substream);
145 param->uc.pcm_params.period_count = substream->runtime->period_size;
146 param->uc.pcm_params.ring_buffer_addr =
147 virt_to_phys(substream->dma_buffer.area);
148 pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count);
149 pr_debug("sfreq= %d, wd_sz = %d\n",
150 param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz);
151}
152
153static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
154{
155 struct sst_runtime_stream *stream =
156 substream->runtime->private_data;
157 struct snd_sst_stream_params param = {{{0,},},};
158 struct snd_sst_params str_params = {0};
159 int ret_val;
160
161 /* set codec params and inform SST driver the same */
162 sst_fill_pcm_params(substream, &param);
163 substream->runtime->dma_area = substream->dma_buffer.area;
164 str_params.sparams = param;
165 str_params.codec = param.uc.pcm_params.codec;
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
167 str_params.ops = STREAM_OPS_PLAYBACK;
168 str_params.device_type = substream->pcm->device + 1;
169 pr_debug("Playbck stream,Device %d\n",
170 substream->pcm->device);
171 } else {
172 str_params.ops = STREAM_OPS_CAPTURE;
173 str_params.device_type = SND_SST_DEVICE_CAPTURE;
174 pr_debug("Capture stream,Device %d\n",
175 substream->pcm->device);
176 }
177 ret_val = stream->sstdrv_ops->pcm_control->open(&str_params);
178 pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
179 if (ret_val < 0)
180 return ret_val;
181
182 stream->stream_info.str_id = ret_val;
183 pr_debug("str id : %d\n", stream->stream_info.str_id);
184 return ret_val;
185}
186
187static void sst_period_elapsed(void *mad_substream)
188{
189 struct snd_pcm_substream *substream = mad_substream;
190 struct sst_runtime_stream *stream;
191 int status;
192
193 if (!substream || !substream->runtime)
194 return;
195 stream = substream->runtime->private_data;
196 if (!stream)
197 return;
198 status = sst_get_stream_status(stream);
199 if (status != SST_PLATFORM_RUNNING)
200 return;
201 snd_pcm_period_elapsed(substream);
202}
203
204static int sst_platform_init_stream(struct snd_pcm_substream *substream)
205{
206 struct sst_runtime_stream *stream =
207 substream->runtime->private_data;
208 int ret_val;
209
210 pr_debug("setting buffer ptr param\n");
211 sst_set_stream_status(stream, SST_PLATFORM_INIT);
212 stream->stream_info.period_elapsed = sst_period_elapsed;
213 stream->stream_info.mad_substream = substream;
214 stream->stream_info.buffer_ptr = 0;
215 stream->stream_info.sfreq = substream->runtime->rate;
216 ret_val = stream->sstdrv_ops->pcm_control->device_control(
217 SST_SND_STREAM_INIT, &stream->stream_info);
218 if (ret_val)
219 pr_err("control_set ret error %d\n", ret_val);
220 return ret_val;
221
222}
223/* end -- helper functions */
224
225static int sst_platform_open(struct snd_pcm_substream *substream)
226{
227 struct snd_pcm_runtime *runtime;
228 struct sst_runtime_stream *stream;
229 int ret_val = 0;
230
231 pr_debug("sst_platform_open called\n");
232 runtime = substream->runtime;
233 runtime->hw = sst_platform_pcm_hw;
234 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
235 if (!stream)
236 return -ENOMEM;
237 spin_lock_init(&stream->status_lock);
238 stream->stream_info.str_id = 0;
239 sst_set_stream_status(stream, SST_PLATFORM_INIT);
240 stream->stream_info.mad_substream = substream;
241 /* allocate memory for SST API set */
242 stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops),
243 GFP_KERNEL);
244 if (!stream->sstdrv_ops) {
245 pr_err("sst: mem allocation for ops fail\n");
246 kfree(stream);
247 return -ENOMEM;
248 }
249 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
250 /* registering with SST driver to get access to SST APIs to use */
251 ret_val = register_sst_card(stream->sstdrv_ops);
252 if (ret_val) {
253 pr_err("sst: sst card registration failed\n");
254 return ret_val;
255 }
256 runtime->private_data = stream;
257 return snd_pcm_hw_constraint_integer(runtime,
258 SNDRV_PCM_HW_PARAM_PERIODS);
259}
260
261static int sst_platform_close(struct snd_pcm_substream *substream)
262{
263 struct sst_runtime_stream *stream;
264 int ret_val = 0, str_id;
265
266 pr_debug("sst_platform_close called\n");
267 stream = substream->runtime->private_data;
268 str_id = stream->stream_info.str_id;
269 if (str_id)
270 ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
271 kfree(stream->sstdrv_ops);
272 kfree(stream);
273 return ret_val;
274}
275
276static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
277{
278 struct sst_runtime_stream *stream;
279 int ret_val = 0, str_id;
280
281 pr_debug("sst_platform_pcm_prepare called\n");
282 stream = substream->runtime->private_data;
283 str_id = stream->stream_info.str_id;
284 if (stream->stream_info.str_id) {
285 ret_val = stream->sstdrv_ops->pcm_control->device_control(
286 SST_SND_DROP, &str_id);
287 return ret_val;
288 }
289
290 ret_val = sst_platform_alloc_stream(substream);
291 if (ret_val < 0)
292 return ret_val;
293 snprintf(substream->pcm->id, sizeof(substream->pcm->id),
294 "%d", stream->stream_info.str_id);
295
296 ret_val = sst_platform_init_stream(substream);
297 if (ret_val)
298 return ret_val;
299 substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
300 return ret_val;
301}
302
303static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
304 int cmd)
305{
306 int ret_val = 0, str_id;
307 struct sst_runtime_stream *stream;
308 int str_cmd, status;
309
310 pr_debug("sst_platform_pcm_trigger called\n");
311 stream = substream->runtime->private_data;
312 str_id = stream->stream_info.str_id;
313 switch (cmd) {
314 case SNDRV_PCM_TRIGGER_START:
315 pr_debug("sst: Trigger Start\n");
316 str_cmd = SST_SND_START;
317 status = SST_PLATFORM_RUNNING;
318 stream->stream_info.mad_substream = substream;
319 break;
320 case SNDRV_PCM_TRIGGER_STOP:
321 pr_debug("sst: in stop\n");
322 str_cmd = SST_SND_DROP;
323 status = SST_PLATFORM_DROPPED;
324 break;
325 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
326 pr_debug("sst: in pause\n");
327 str_cmd = SST_SND_PAUSE;
328 status = SST_PLATFORM_PAUSED;
329 break;
330 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
331 pr_debug("sst: in pause release\n");
332 str_cmd = SST_SND_RESUME;
333 status = SST_PLATFORM_RUNNING;
334 break;
335 default:
336 return -EINVAL;
337 }
338 ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd,
339 &str_id);
340 if (!ret_val)
341 sst_set_stream_status(stream, status);
342
343 return ret_val;
344}
345
346
347static snd_pcm_uframes_t sst_platform_pcm_pointer
348 (struct snd_pcm_substream *substream)
349{
350 struct sst_runtime_stream *stream;
351 int ret_val, status;
352 struct pcm_stream_info *str_info;
353
354 stream = substream->runtime->private_data;
355 status = sst_get_stream_status(stream);
356 if (status == SST_PLATFORM_INIT)
357 return 0;
358 str_info = &stream->stream_info;
359 ret_val = stream->sstdrv_ops->pcm_control->device_control(
360 SST_SND_BUFFER_POINTER, str_info);
361 if (ret_val) {
362 pr_err("sst: error code = %d\n", ret_val);
363 return ret_val;
364 }
365 return stream->stream_info.buffer_ptr;
366}
367
368static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params)
370{
371 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
372 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
373
374 return 0;
375}
376
377static struct snd_pcm_ops sst_platform_ops = {
378 .open = sst_platform_open,
379 .close = sst_platform_close,
380 .ioctl = snd_pcm_lib_ioctl,
381 .prepare = sst_platform_pcm_prepare,
382 .trigger = sst_platform_pcm_trigger,
383 .pointer = sst_platform_pcm_pointer,
384 .hw_params = sst_platform_pcm_hw_params,
385};
386
387static void sst_pcm_free(struct snd_pcm *pcm)
388{
389 pr_debug("sst_pcm_free called\n");
390 snd_pcm_lib_preallocate_free_for_all(pcm);
391}
392
393int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
394 struct snd_pcm *pcm)
395{
396 int retval = 0;
397
398 pr_debug("sst_pcm_new called\n");
399 if (dai->driver->playback.channels_min ||
400 dai->driver->capture.channels_min) {
401 retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
402 SNDRV_DMA_TYPE_CONTINUOUS,
403 snd_dma_continuous_data(GFP_KERNEL),
404 SST_MIN_BUFFER, SST_MAX_BUFFER);
405 if (retval) {
406 pr_err("dma buffer allocationf fail\n");
407 return retval;
408 }
409 }
410 return retval;
411}
412struct snd_soc_platform_driver sst_soc_platform_drv = {
413 .ops = &sst_platform_ops,
414 .pcm_new = sst_pcm_new,
415 .pcm_free = sst_pcm_free,
416};
417
418static int sst_platform_probe(struct platform_device *pdev)
419{
420 int ret;
421
422 pr_debug("sst_platform_probe called\n");
423 ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
424 if (ret) {
425 pr_err("registering soc platform failed\n");
426 return ret;
427 }
428
429 ret = snd_soc_register_dais(&pdev->dev,
430 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
431 if (ret) {
432 pr_err("registering cpu dais failed\n");
433 snd_soc_unregister_platform(&pdev->dev);
434 }
435 return ret;
436}
437
438static int sst_platform_remove(struct platform_device *pdev)
439{
440
441 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai));
442 snd_soc_unregister_platform(&pdev->dev);
443 pr_debug("sst_platform_remove sucess\n");
444 return 0;
445}
446
447static struct platform_driver sst_platform_driver = {
448 .driver = {
449 .name = "sst-platform",
450 .owner = THIS_MODULE,
451 },
452 .probe = sst_platform_probe,
453 .remove = sst_platform_remove,
454};
455
456static int __init sst_soc_platform_init(void)
457{
458 pr_debug("sst_soc_platform_init called\n");
459 return platform_driver_register(&sst_platform_driver);
460}
461module_init(sst_soc_platform_init);
462
463static void __exit sst_soc_platform_exit(void)
464{
465 platform_driver_unregister(&sst_platform_driver);
466 pr_debug("sst_soc_platform_exit sucess\n");
467}
468module_exit(sst_soc_platform_exit);
469
470MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
471MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
472MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
473MODULE_LICENSE("GPL v2");
474MODULE_ALIAS("platform:sst-platform");
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
new file mode 100644
index 000000000000..df370286694f
--- /dev/null
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -0,0 +1,63 @@
1/*
2 * sst_platform.h - Intel MID Platform driver header file
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26
27#ifndef __SST_PLATFORMDRV_H__
28#define __SST_PLATFORMDRV_H__
29
30#define SST_MONO 1
31#define SST_STEREO 2
32#define SST_MAX_CAP 5
33
34#define SST_MIN_RATE 8000
35#define SST_MAX_RATE 48000
36#define SST_MIN_CHANNEL 1
37#define SST_MAX_CHANNEL 5
38#define SST_MAX_BUFFER (800*1024)
39#define SST_MIN_BUFFER (800*1024)
40#define SST_MIN_PERIOD_BYTES 32
41#define SST_MAX_PERIOD_BYTES SST_MAX_BUFFER
42#define SST_MIN_PERIODS 2
43#define SST_MAX_PERIODS (1024*2)
44#define SST_FIFO_SIZE 0
45#define SST_CARD_NAMES "intel_mid_card"
46#define MSIC_VENDOR_ID 3
47
48struct sst_runtime_stream {
49 int stream_status;
50 struct pcm_stream_info stream_info;
51 struct intel_sst_card_ops *sstdrv_ops;
52 spinlock_t status_lock;
53};
54
55enum sst_drv_status {
56 SST_PLATFORM_INIT = 1,
57 SST_PLATFORM_STARTED,
58 SST_PLATFORM_RUNNING,
59 SST_PLATFORM_PAUSED,
60 SST_PLATFORM_DROPPED,
61};
62
63#endif
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index a088db6d5091..b5922984eac6 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -24,6 +24,7 @@ config SND_OMAP_SOC_RX51
24 select OMAP_MCBSP 24 select OMAP_MCBSP
25 select SND_OMAP_SOC_MCBSP 25 select SND_OMAP_SOC_MCBSP
26 select SND_SOC_TLV320AIC3X 26 select SND_SOC_TLV320AIC3X
27 select SND_SOC_TPA6130A2
27 help 28 help
28 Say Y if you want to add support for SoC audio on Nokia RX-51 29 Say Y if you want to add support for SoC audio on Nokia RX-51
29 hardware. This is also known as Nokia N900 product. 30 hardware. This is also known as Nokia N900 product.
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 09fb0df8d416..d0986220eff9 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -31,6 +31,7 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <plat/mcbsp.h> 33#include <plat/mcbsp.h>
34#include "../codecs/tpa6130a2.h"
34 35
35#include <asm/mach-types.h> 36#include <asm/mach-types.h>
36 37
@@ -39,6 +40,7 @@
39 40
40#define RX51_TVOUT_SEL_GPIO 40 41#define RX51_TVOUT_SEL_GPIO 40
41#define RX51_JACK_DETECT_GPIO 177 42#define RX51_JACK_DETECT_GPIO 177
43#define RX51_ECI_SW_GPIO 182
42/* 44/*
43 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This 45 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
44 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c 46 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -47,7 +49,9 @@
47 49
48enum { 50enum {
49 RX51_JACK_DISABLED, 51 RX51_JACK_DISABLED,
50 RX51_JACK_TVOUT, /* tv-out */ 52 RX51_JACK_TVOUT, /* tv-out with stereo output */
53 RX51_JACK_HP, /* headphone: stereo output, no mic */
54 RX51_JACK_HS, /* headset: stereo output with mic */
51}; 55};
52 56
53static int rx51_spk_func; 57static int rx51_spk_func;
@@ -57,6 +61,19 @@ static int rx51_jack_func;
57static void rx51_ext_control(struct snd_soc_codec *codec) 61static void rx51_ext_control(struct snd_soc_codec *codec)
58{ 62{
59 struct snd_soc_dapm_context *dapm = &codec->dapm; 63 struct snd_soc_dapm_context *dapm = &codec->dapm;
64 int hp = 0, hs = 0, tvout = 0;
65
66 switch (rx51_jack_func) {
67 case RX51_JACK_TVOUT:
68 tvout = 1;
69 hp = 1;
70 break;
71 case RX51_JACK_HS:
72 hs = 1;
73 case RX51_JACK_HP:
74 hp = 1;
75 break;
76 }
60 77
61 if (rx51_spk_func) 78 if (rx51_spk_func)
62 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 79 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
@@ -66,9 +83,16 @@ static void rx51_ext_control(struct snd_soc_codec *codec)
66 snd_soc_dapm_enable_pin(dapm, "DMic"); 83 snd_soc_dapm_enable_pin(dapm, "DMic");
67 else 84 else
68 snd_soc_dapm_disable_pin(dapm, "DMic"); 85 snd_soc_dapm_disable_pin(dapm, "DMic");
86 if (hp)
87 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
88 else
89 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
90 if (hs)
91 snd_soc_dapm_enable_pin(dapm, "HS Mic");
92 else
93 snd_soc_dapm_disable_pin(dapm, "HS Mic");
69 94
70 gpio_set_value(RX51_TVOUT_SEL_GPIO, 95 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
71 rx51_jack_func == RX51_JACK_TVOUT);
72 96
73 snd_soc_dapm_sync(dapm); 97 snd_soc_dapm_sync(dapm);
74} 98}
@@ -153,6 +177,19 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
153 return 0; 177 return 0;
154} 178}
155 179
180static int rx51_hp_event(struct snd_soc_dapm_widget *w,
181 struct snd_kcontrol *k, int event)
182{
183 struct snd_soc_codec *codec = w->dapm->codec;
184
185 if (SND_SOC_DAPM_EVENT_ON(event))
186 tpa6130a2_stereo_enable(codec, 1);
187 else
188 tpa6130a2_stereo_enable(codec, 0);
189
190 return 0;
191}
192
156static int rx51_get_input(struct snd_kcontrol *kcontrol, 193static int rx51_get_input(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol) 194 struct snd_ctl_elem_value *ucontrol)
158{ 195{
@@ -203,7 +240,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
203 { 240 {
204 .gpio = RX51_JACK_DETECT_GPIO, 241 .gpio = RX51_JACK_DETECT_GPIO,
205 .name = "avdet-gpio", 242 .name = "avdet-gpio",
206 .report = SND_JACK_VIDEOOUT, 243 .report = SND_JACK_HEADSET,
207 .invert = 1, 244 .invert = 1,
208 .debounce_time = 200, 245 .debounce_time = 200,
209 }, 246 },
@@ -212,19 +249,38 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
212static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { 249static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
213 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), 250 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
214 SND_SOC_DAPM_MIC("DMic", NULL), 251 SND_SOC_DAPM_MIC("DMic", NULL),
252 SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
253 SND_SOC_DAPM_MIC("HS Mic", NULL),
254 SND_SOC_DAPM_LINE("FM Transmitter", NULL),
255};
256
257static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = {
258 SND_SOC_DAPM_SPK("Earphone", NULL),
215}; 259};
216 260
217static const struct snd_soc_dapm_route audio_map[] = { 261static const struct snd_soc_dapm_route audio_map[] = {
218 {"Ext Spk", NULL, "HPLOUT"}, 262 {"Ext Spk", NULL, "HPLOUT"},
219 {"Ext Spk", NULL, "HPROUT"}, 263 {"Ext Spk", NULL, "HPROUT"},
264 {"Headphone Jack", NULL, "LLOUT"},
265 {"Headphone Jack", NULL, "RLOUT"},
266 {"FM Transmitter", NULL, "LLOUT"},
267 {"FM Transmitter", NULL, "RLOUT"},
220 268
221 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 269 {"DMic Rate 64", NULL, "Mic Bias 2V"},
222 {"Mic Bias 2V", NULL, "DMic"}, 270 {"Mic Bias 2V", NULL, "DMic"},
223}; 271};
224 272
273static const struct snd_soc_dapm_route audio_mapb[] = {
274 {"b LINE2R", NULL, "MONO_LOUT"},
275 {"Earphone", NULL, "b HPLOUT"},
276
277 {"LINE1L", NULL, "b Mic Bias 2.5V"},
278 {"b Mic Bias 2.5V", NULL, "HS Mic"}
279};
280
225static const char *spk_function[] = {"Off", "On"}; 281static const char *spk_function[] = {"Off", "On"};
226static const char *input_function[] = {"ADC", "Digital Mic"}; 282static const char *input_function[] = {"ADC", "Digital Mic"};
227static const char *jack_function[] = {"Off", "TV-OUT"}; 283static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"};
228 284
229static const struct soc_enum rx51_enum[] = { 285static const struct soc_enum rx51_enum[] = {
230 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), 286 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
@@ -239,6 +295,11 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
239 rx51_get_input, rx51_set_input), 295 rx51_get_input, rx51_set_input),
240 SOC_ENUM_EXT("Jack Function", rx51_enum[2], 296 SOC_ENUM_EXT("Jack Function", rx51_enum[2],
241 rx51_get_jack, rx51_set_jack), 297 rx51_get_jack, rx51_set_jack),
298 SOC_DAPM_PIN_SWITCH("FM Transmitter"),
299};
300
301static const struct snd_kcontrol_new aic34_rx51_controlsb[] = {
302 SOC_DAPM_PIN_SWITCH("Earphone"),
242}; 303};
243 304
244static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) 305static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
@@ -265,11 +326,21 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
265 /* Set up RX-51 specific audio path audio_map */ 326 /* Set up RX-51 specific audio path audio_map */
266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 327 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
267 328
329 err = tpa6130a2_add_controls(codec);
330 if (err < 0)
331 return err;
332 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
333
334 err = omap_mcbsp_st_add_controls(codec, 1);
335 if (err < 0)
336 return err;
337
268 snd_soc_dapm_sync(dapm); 338 snd_soc_dapm_sync(dapm);
269 339
270 /* AV jack detection */ 340 /* AV jack detection */
271 err = snd_soc_jack_new(codec, "AV Jack", 341 err = snd_soc_jack_new(codec, "AV Jack",
272 SND_JACK_VIDEOOUT, &rx51_av_jack); 342 SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
343 &rx51_av_jack);
273 if (err) 344 if (err)
274 return err; 345 return err;
275 err = snd_soc_jack_add_gpios(&rx51_av_jack, 346 err = snd_soc_jack_add_gpios(&rx51_av_jack,
@@ -279,6 +350,24 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
279 return err; 350 return err;
280} 351}
281 352
353static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
354{
355 int err;
356
357 err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb,
358 ARRAY_SIZE(aic34_rx51_controlsb));
359 if (err < 0)
360 return err;
361
362 err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb,
363 ARRAY_SIZE(aic34_dapm_widgetsb));
364 if (err < 0)
365 return 0;
366
367 return snd_soc_dapm_add_routes(dapm, audio_mapb,
368 ARRAY_SIZE(audio_mapb));
369}
370
282/* Digital audio interface glue - connects codec <--> CPU */ 371/* Digital audio interface glue - connects codec <--> CPU */
283static struct snd_soc_dai_link rx51_dai[] = { 372static struct snd_soc_dai_link rx51_dai[] = {
284 { 373 {
@@ -293,11 +382,30 @@ static struct snd_soc_dai_link rx51_dai[] = {
293 }, 382 },
294}; 383};
295 384
385struct snd_soc_aux_dev rx51_aux_dev[] = {
386 {
387 .name = "TLV320AIC34b",
388 .codec_name = "tlv320aic3x-codec.2-0019",
389 .init = rx51_aic34b_init,
390 },
391};
392
393static struct snd_soc_codec_conf rx51_codec_conf[] = {
394 {
395 .dev_name = "tlv320aic3x-codec.2-0019",
396 .name_prefix = "b",
397 },
398};
399
296/* Audio card */ 400/* Audio card */
297static struct snd_soc_card rx51_sound_card = { 401static struct snd_soc_card rx51_sound_card = {
298 .name = "RX-51", 402 .name = "RX-51",
299 .dai_link = rx51_dai, 403 .dai_link = rx51_dai,
300 .num_links = ARRAY_SIZE(rx51_dai), 404 .num_links = ARRAY_SIZE(rx51_dai),
405 .aux_dev = rx51_aux_dev,
406 .num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
407 .codec_conf = rx51_codec_conf,
408 .num_configs = ARRAY_SIZE(rx51_codec_conf),
301}; 409};
302 410
303static struct platform_device *rx51_snd_device; 411static struct platform_device *rx51_snd_device;
@@ -309,10 +417,14 @@ static int __init rx51_soc_init(void)
309 if (!machine_is_nokia_rx51()) 417 if (!machine_is_nokia_rx51())
310 return -ENODEV; 418 return -ENODEV;
311 419
312 err = gpio_request(RX51_TVOUT_SEL_GPIO, "tvout_sel"); 420 err = gpio_request_one(RX51_TVOUT_SEL_GPIO,
421 GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel");
313 if (err) 422 if (err)
314 goto err_gpio_tvout_sel; 423 goto err_gpio_tvout_sel;
315 gpio_direction_output(RX51_TVOUT_SEL_GPIO, 0); 424 err = gpio_request_one(RX51_ECI_SW_GPIO,
425 GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw");
426 if (err)
427 goto err_gpio_eci_sw;
316 428
317 rx51_snd_device = platform_device_alloc("soc-audio", -1); 429 rx51_snd_device = platform_device_alloc("soc-audio", -1);
318 if (!rx51_snd_device) { 430 if (!rx51_snd_device) {
@@ -330,6 +442,8 @@ static int __init rx51_soc_init(void)
330err2: 442err2:
331 platform_device_put(rx51_snd_device); 443 platform_device_put(rx51_snd_device);
332err1: 444err1:
445 gpio_free(RX51_ECI_SW_GPIO);
446err_gpio_eci_sw:
333 gpio_free(RX51_TVOUT_SEL_GPIO); 447 gpio_free(RX51_TVOUT_SEL_GPIO);
334err_gpio_tvout_sel: 448err_gpio_tvout_sel:
335 449
@@ -342,6 +456,7 @@ static void __exit rx51_soc_exit(void)
342 rx51_av_jack_gpios); 456 rx51_av_jack_gpios);
343 457
344 platform_device_unregister(rx51_snd_device); 458 platform_device_unregister(rx51_snd_device);
459 gpio_free(RX51_ECI_SW_GPIO);
345 gpio_free(RX51_TVOUT_SEL_GPIO); 460 gpio_free(RX51_TVOUT_SEL_GPIO);
346} 461}
347 462
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 0fd60f423036..2afabaf59491 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = {
151 .hw_params = raumfeld_cs4270_hw_params, 151 .hw_params = raumfeld_cs4270_hw_params,
152}; 152};
153 153
154static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state) 154static int raumfeld_line_suspend(struct snd_soc_card *card)
155{ 155{
156 raumfeld_enable_audio(false); 156 raumfeld_enable_audio(false);
157 return 0; 157 return 0;
158} 158}
159 159
160static int raumfeld_line_resume(struct platform_device *pdev) 160static int raumfeld_line_resume(struct snd_soc_card *card)
161{ 161{
162 raumfeld_enable_audio(true); 162 raumfeld_enable_audio(true);
163 return 0; 163 return 0;
@@ -229,19 +229,19 @@ static struct snd_soc_dai_link raumfeld_dai[] = {
229{ 229{
230 .name = "ak4104", 230 .name = "ak4104",
231 .stream_name = "Playback", 231 .stream_name = "Playback",
232 .cpu_dai_name = "pxa-ssp-dai.1", 232 .cpu_dai_name = "pxa-ssp-dai.1",
233 .codec_dai_name = "ak4104-hifi", 233 .codec_dai_name = "ak4104-hifi",
234 .platform_name = "pxa-pcm-audio", 234 .platform_name = "pxa-pcm-audio",
235 .ops = &raumfeld_ak4104_ops, 235 .ops = &raumfeld_ak4104_ops,
236 .codec_name = "ak4104-codec.0", 236 .codec_name = "ak4104-codec.0",
237}, 237},
238{ 238{
239 .name = "CS4270", 239 .name = "CS4270",
240 .stream_name = "CS4270", 240 .stream_name = "CS4270",
241 .cpu_dai_name = "pxa-ssp-dai.0", 241 .cpu_dai_name = "pxa-ssp-dai.0",
242 .platform_name = "pxa-pcm-audio", 242 .platform_name = "pxa-pcm-audio",
243 .codec_dai_name = "cs4270-hifi", 243 .codec_dai_name = "cs4270-hifi",
244 .codec_name = "cs4270-codec.0-0048", 244 .codec_name = "cs4270-codec.0-0048",
245 .ops = &raumfeld_cs4270_ops, 245 .ops = &raumfeld_cs4270_ops,
246},}; 246},};
247 247
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 4b6e5d608b42..9a2351366957 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -237,7 +237,7 @@ static struct snd_soc_dai_link tosa_dai[] = {
237}, 237},
238}; 238};
239 239
240static int tosa_probe(struct platform_device *dev) 240static int tosa_probe(struct snd_soc_card *card)
241{ 241{
242 int ret; 242 int ret;
243 243
@@ -251,7 +251,7 @@ static int tosa_probe(struct platform_device *dev)
251 return ret; 251 return ret;
252} 252}
253 253
254static int tosa_remove(struct platform_device *dev) 254static int tosa_remove(struct snd_soc_card *card)
255{ 255{
256 gpio_free(TOSA_GPIO_L_MUTE); 256 gpio_free(TOSA_GPIO_L_MUTE);
257 return 0; 257 return 0;
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 3ceaef68e01d..d69d9fc32233 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -95,6 +95,11 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
95 .pin = "Headphone Jack", 95 .pin = "Headphone Jack",
96 .mask = SND_JACK_HEADPHONE, 96 .mask = SND_JACK_HEADPHONE,
97 }, 97 },
98 {
99 .pin = "Ext Spk",
100 .mask = SND_JACK_HEADPHONE,
101 .invert = 1
102 },
98}; 103};
99 104
100/* Headset jack detection gpios */ 105/* Headset jack detection gpios */
@@ -147,7 +152,7 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
147 snd_soc_dapm_disable_pin(dapm, "LINPUT3"); 152 snd_soc_dapm_disable_pin(dapm, "LINPUT3");
148 snd_soc_dapm_disable_pin(dapm, "RINPUT3"); 153 snd_soc_dapm_disable_pin(dapm, "RINPUT3");
149 snd_soc_dapm_disable_pin(dapm, "OUT3"); 154 snd_soc_dapm_disable_pin(dapm, "OUT3");
150 snd_soc_dapm_disable_pin(dapm, "MONO"); 155 snd_soc_dapm_disable_pin(dapm, "MONO1");
151 156
152 /* Add z2 specific widgets */ 157 /* Add z2 specific widgets */
153 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, 158 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 25bba108fea3..ac577263b3e3 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -189,7 +189,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
189}, 189},
190}; 190};
191 191
192static int zylonite_probe(struct platform_device *pdev) 192static int zylonite_probe(struct snd_soc_card *card)
193{ 193{
194 int ret; 194 int ret;
195 195
@@ -216,7 +216,7 @@ static int zylonite_probe(struct platform_device *pdev)
216 return 0; 216 return 0;
217} 217}
218 218
219static int zylonite_remove(struct platform_device *pdev) 219static int zylonite_remove(struct snd_soc_card *card)
220{ 220{
221 if (clk_pout) { 221 if (clk_pout) {
222 clk_disable(pout); 222 clk_disable(pout);
@@ -226,8 +226,7 @@ static int zylonite_remove(struct platform_device *pdev)
226 return 0; 226 return 0;
227} 227}
228 228
229static int zylonite_suspend_post(struct platform_device *pdev, 229static int zylonite_suspend_post(struct snd_soc_card *card)
230 pm_message_t state)
231{ 230{
232 if (clk_pout) 231 if (clk_pout)
233 clk_disable(pout); 232 clk_disable(pout);
@@ -235,7 +234,7 @@ static int zylonite_suspend_post(struct platform_device *pdev,
235 return 0; 234 return 0;
236} 235}
237 236
238static int zylonite_resume_pre(struct platform_device *pdev) 237static int zylonite_resume_pre(struct snd_soc_card *card)
239{ 238{
240 int ret = 0; 239 int ret = 0;
241 240
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index d6713d5a90e7..a3fdfb631469 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -35,23 +35,16 @@ config SND_SAMSUNG_I2S
35 tristate 35 tristate
36 36
37config SND_SOC_SAMSUNG_NEO1973_WM8753 37config SND_SOC_SAMSUNG_NEO1973_WM8753
38 tristate "SoC I2S Audio support for NEO1973 - WM8753" 38 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)"
39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA01 39 depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02)
40 select SND_S3C24XX_I2S 40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753 41 select SND_SOC_WM8753
42 select SND_SOC_LM4857 if MACH_NEO1973_GTA01
43 select SND_SOC_DFBMCS320
42 help 44 help
43 Say Y if you want to add support for SoC audio on smdk2440 45 Say Y here to enable audio support for the Openmoko Neo1973
44 with the WM8753. 46 Smartphones.
45 47
46config SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753
47 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
48 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
49 select SND_S3C24XX_I2S
50 select SND_SOC_WM8753
51 help
52 This driver provides audio support for the Openmoko Neo FreeRunner
53 smartphone.
54
55config SND_SOC_SAMSUNG_JIVE_WM8750 48config SND_SOC_SAMSUNG_JIVE_WM8750
56 tristate "SoC I2S Audio support for Jive" 49 tristate "SoC I2S Audio support for Jive"
57 depends on SND_SOC_SAMSUNG && MACH_JIVE 50 depends on SND_SOC_SAMSUNG && MACH_JIVE
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 705d4e8a6724..294dec05c26d 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
20# S3C24XX Machine Support 20# S3C24XX Machine Support
21snd-soc-jive-wm8750-objs := jive_wm8750.o 21snd-soc-jive-wm8750-objs := jive_wm8750.o
22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
23snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
24snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 23snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
25snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 24snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
26snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 25snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
@@ -38,7 +37,6 @@ snd-soc-smdk-spdif-objs := smdk_spdif.o
38 37
39obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
40obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
42obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
43obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
44obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o 42obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 4770a9550341..f97110e72e85 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -12,24 +12,24 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/io.h> 15#include <linux/io.h>
18#include <linux/delay.h> 16#include <linux/delay.h>
19#include <linux/clk.h> 17#include <linux/clk.h>
20 18
21#include <sound/soc.h> 19#include <sound/soc.h>
22 20
23#include <plat/regs-ac97.h>
24#include <mach/dma.h> 21#include <mach/dma.h>
22#include <plat/regs-ac97.h>
25#include <plat/audio.h> 23#include <plat/audio.h>
26 24
27#include "dma.h" 25#include "dma.h"
28#include "ac97.h"
29 26
30#define AC_CMD_ADDR(x) (x << 16) 27#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff) 28#define AC_CMD_DATA(x) (x & 0xffff)
32 29
30#define S3C_AC97_DAI_PCM 0
31#define S3C_AC97_DAI_MIC 1
32
33struct s3c_ac97_info { 33struct s3c_ac97_info {
34 struct clk *ac97_clk; 34 struct clk *ac97_clk;
35 void __iomem *regs; 35 void __iomem *regs;
diff --git a/sound/soc/samsung/ac97.h b/sound/soc/samsung/ac97.h
deleted file mode 100644
index 0d0e1b511457..000000000000
--- a/sound/soc/samsung/ac97.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* sound/soc/samsung/ac97.h
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.h
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __S3C_AC97_H_
16#define __S3C_AC97_H_
17
18#define S3C_AC97_DAI_PCM 0
19#define S3C_AC97_DAI_MIC 1
20
21#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 21240198c5d6..5cb3b880f0d5 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -14,17 +14,11 @@
14 * option) any later version. 14 * option) any later version.
15 */ 15 */
16 16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h> 17#include <linux/slab.h>
22#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
23 19
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/pcm_params.h>
28 22
29#include <asm/dma.h> 23#include <asm/dma.h>
30#include <mach/hardware.h> 24#include <mach/hardware.h>
@@ -32,6 +26,9 @@
32 26
33#include "dma.h" 27#include "dma.h"
34 28
29#define ST_RUNNING (1<<0)
30#define ST_OPENED (1<<1)
31
35static const struct snd_pcm_hardware dma_hardware = { 32static const struct snd_pcm_hardware dma_hardware = {
36 .info = SNDRV_PCM_INFO_INTERLEAVED | 33 .info = SNDRV_PCM_INFO_INTERLEAVED |
37 SNDRV_PCM_INFO_BLOCK_TRANSFER | 34 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -313,7 +310,7 @@ dma_pointer(struct snd_pcm_substream *substream)
313 /* we seem to be getting the odd error from the pcm library due 310 /* we seem to be getting the odd error from the pcm library due
314 * to out-of-bounds pointers. this is maybe due to the dma engine 311 * to out-of-bounds pointers. this is maybe due to the dma engine
315 * not having loaded the new values for the channel before being 312 * not having loaded the new values for the channel before being
316 * callled... (todo - fix ) 313 * called... (todo - fix )
317 */ 314 */
318 315
319 if (res >= snd_pcm_lib_buffer_bytes(substream)) { 316 if (res >= snd_pcm_lib_buffer_bytes(substream)) {
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index f8cd2b4223af..c50659269a40 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -12,9 +12,6 @@
12#ifndef _S3C_AUDIO_H 12#ifndef _S3C_AUDIO_H
13#define _S3C_AUDIO_H 13#define _S3C_AUDIO_H
14 14
15#define ST_RUNNING (1<<0)
16#define ST_OPENED (1<<1)
17
18struct s3c_dma_params { 15struct s3c_dma_params {
19 struct s3c2410_dma_client *client; /* stream identifier */ 16 struct s3c2410_dma_client *client; /* stream identifier */
20 int channel; /* Channel ID */ 17 int channel; /* Channel ID */
@@ -22,9 +19,4 @@ struct s3c_dma_params {
22 int dma_size; /* Size of the DMA transfer */ 19 int dma_size; /* Size of the DMA transfer */
23}; 20};
24 21
25#define S3C24XX_DAI_I2S 0
26
27/* platform data */
28extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
29
30#endif 22#endif
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 34dd9ef1b9c0..f6b3a3ce5919 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -11,21 +11,13 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <sound/soc.h> 14#include <sound/soc.h>
19#include <sound/jack.h> 15#include <sound/jack.h>
16
20#include <asm/mach-types.h> 17#include <asm/mach-types.h>
21#include <mach/gpio.h> 18#include <mach/gpio.h>
22#include <mach/regs-clock.h>
23 19
24#include <linux/mfd/wm8994/core.h>
25#include <linux/mfd/wm8994/registers.h>
26#include "../codecs/wm8994.h" 20#include "../codecs/wm8994.h"
27#include "dma.h"
28#include "i2s.h"
29 21
30#define MACHINE_NAME 0 22#define MACHINE_NAME 0
31#define CPU_VOICE_DAI 1 23#define CPU_VOICE_DAI 1
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c45f7ce14d61..241f55d00660 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -13,25 +13,16 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/i2c.h>
20#include <linux/gpio.h> 16#include <linux/gpio.h>
21 17
22#include <sound/soc.h> 18#include <sound/soc.h>
23#include <sound/uda1380.h>
24#include <sound/jack.h> 19#include <sound/jack.h>
25 20
26#include <plat/regs-iis.h> 21#include <plat/regs-iis.h>
27
28#include <mach/h1940-latch.h> 22#include <mach/h1940-latch.h>
29
30#include <asm/mach-types.h> 23#include <asm/mach-types.h>
31 24
32#include "dma.h"
33#include "s3c24xx-i2s.h" 25#include "s3c24xx-i2s.h"
34#include "../codecs/uda1380.h"
35 26
36static unsigned int rates[] = { 27static unsigned int rates[] = {
37 11025, 28 11025,
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d00ac3a7102c..ffa09b3b2caa 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -15,9 +15,8 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17 17
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/pcm_params.h>
21 20
22#include <plat/audio.h> 21#include <plat/audio.h>
23 22
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 08802520e014..3b53ad54bc33 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -11,22 +11,11 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12*/ 12*/
13 13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h> 14#include <sound/soc.h>
24 15
25#include <asm/mach-types.h> 16#include <asm/mach-types.h>
26 17
27#include "dma.h"
28#include "s3c2412-i2s.h" 18#include "s3c2412-i2s.h"
29
30#include "../codecs/wm8750.h" 19#include "../codecs/wm8750.h"
31 20
32static const struct snd_soc_dapm_route audio_map[] = { 21static const struct snd_soc_dapm_route audio_map[] = {
diff --git a/sound/soc/samsung/lm4857.h b/sound/soc/samsung/lm4857.h
deleted file mode 100644
index 0cf5b7011d6f..000000000000
--- a/sound/soc/samsung/lm4857.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * lm4857.h -- ALSA Soc Audio Layer
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 18th Jun 2007 Initial version.
15 */
16
17#ifndef LM4857_H_
18#define LM4857_H_
19
20/* The register offsets in the cache array */
21#define LM4857_MVOL 0
22#define LM4857_LVOL 1
23#define LM4857_RVOL 2
24#define LM4857_CTRL 3
25
26/* the shifts required to set these bits */
27#define LM4857_3D 5
28#define LM4857_WAKEUP 5
29#define LM4857_EPGAIN 4
30
31#endif /*LM4857_H_*/
32
diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index a2bb34def740..bd91c19a6c08 100644
--- a/sound/soc/samsung/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -16,15 +16,8 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h> 19#include <sound/soc.h>
24 20
25#include "dma.h"
26#include "ac97.h"
27
28static struct snd_soc_card ln2440sbc; 21static struct snd_soc_card ln2440sbc;
29 22
30static struct snd_soc_dai_link ln2440sbc_dai[] = { 23static struct snd_soc_dai_link ln2440sbc_dai[] = {
diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
deleted file mode 100644
index 0d0ae2b9eef6..000000000000
--- a/sound/soc/samsung/neo1973_gta02_wm8753.c
+++ /dev/null
@@ -1,504 +0,0 @@
1/*
2 * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02)
3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
6 * Copyright 2007 Wolfson Microelectronics PLC.
7 * Author: Graeme Gregory <linux@wolfsonmicro.com>
8 * Copyright 2009 Wolfson Microelectronics
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/timer.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25
26#include <asm/mach-types.h>
27
28#include <plat/regs-iis.h>
29
30#include <mach/regs-clock.h>
31#include <asm/io.h>
32#include <mach/gta02.h>
33#include "../codecs/wm8753.h"
34#include "dma.h"
35#include "s3c24xx-i2s.h"
36
37static struct snd_soc_card neo1973_gta02;
38
39static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 unsigned int pll_out = 0, bclk = 0;
46 int ret = 0;
47 unsigned long iis_clkrate;
48
49 iis_clkrate = s3c24xx_i2s_get_clockrate();
50
51 switch (params_rate(params)) {
52 case 8000:
53 case 16000:
54 pll_out = 12288000;
55 break;
56 case 48000:
57 bclk = WM8753_BCLK_DIV_4;
58 pll_out = 12288000;
59 break;
60 case 96000:
61 bclk = WM8753_BCLK_DIV_2;
62 pll_out = 12288000;
63 break;
64 case 11025:
65 bclk = WM8753_BCLK_DIV_16;
66 pll_out = 11289600;
67 break;
68 case 22050:
69 bclk = WM8753_BCLK_DIV_8;
70 pll_out = 11289600;
71 break;
72 case 44100:
73 bclk = WM8753_BCLK_DIV_4;
74 pll_out = 11289600;
75 break;
76 case 88200:
77 bclk = WM8753_BCLK_DIV_2;
78 pll_out = 11289600;
79 break;
80 }
81
82 /* set codec DAI configuration */
83 ret = snd_soc_dai_set_fmt(codec_dai,
84 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
85 SND_SOC_DAIFMT_CBM_CFM);
86 if (ret < 0)
87 return ret;
88
89 /* set cpu DAI configuration */
90 ret = snd_soc_dai_set_fmt(cpu_dai,
91 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
92 SND_SOC_DAIFMT_CBM_CFM);
93 if (ret < 0)
94 return ret;
95
96 /* set the codec system clock for DAC and ADC */
97 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
98 SND_SOC_CLOCK_IN);
99 if (ret < 0)
100 return ret;
101
102 /* set MCLK division for sample rate */
103 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
104 S3C2410_IISMOD_32FS);
105 if (ret < 0)
106 return ret;
107
108 /* set codec BCLK division for sample rate */
109 ret = snd_soc_dai_set_clkdiv(codec_dai,
110 WM8753_BCLKDIV, bclk);
111 if (ret < 0)
112 return ret;
113
114 /* set prescaler division for sample rate */
115 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
116 S3C24XX_PRESCALE(4, 4));
117 if (ret < 0)
118 return ret;
119
120 /* codec PLL input is PCLK/4 */
121 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
122 iis_clkrate / 4, pll_out);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
130{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct snd_soc_dai *codec_dai = rtd->codec_dai;
133
134 /* disable the PLL */
135 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
136}
137
138/*
139 * Neo1973 WM8753 HiFi DAI opserations.
140 */
141static struct snd_soc_ops neo1973_gta02_hifi_ops = {
142 .hw_params = neo1973_gta02_hifi_hw_params,
143 .hw_free = neo1973_gta02_hifi_hw_free,
144};
145
146static int neo1973_gta02_voice_hw_params(
147 struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *codec_dai = rtd->codec_dai;
152 unsigned int pcmdiv = 0;
153 int ret = 0;
154 unsigned long iis_clkrate;
155
156 iis_clkrate = s3c24xx_i2s_get_clockrate();
157
158 if (params_rate(params) != 8000)
159 return -EINVAL;
160 if (params_channels(params) != 1)
161 return -EINVAL;
162
163 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
164
165 /* todo: gg check mode (DSP_B) against CSR datasheet */
166 /* set codec DAI configuration */
167 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
168 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
169 if (ret < 0)
170 return ret;
171
172 /* set the codec system clock for DAC and ADC */
173 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK,
174 12288000, SND_SOC_CLOCK_IN);
175 if (ret < 0)
176 return ret;
177
178 /* set codec PCM division for sample rate */
179 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV,
180 pcmdiv);
181 if (ret < 0)
182 return ret;
183
184 /* configure and enable PLL for 12.288MHz output */
185 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
186 iis_clkrate / 4, 12288000);
187 if (ret < 0)
188 return ret;
189
190 return 0;
191}
192
193static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
194{
195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
196 struct snd_soc_dai *codec_dai = rtd->codec_dai;
197
198 /* disable the PLL */
199 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
200}
201
202static struct snd_soc_ops neo1973_gta02_voice_ops = {
203 .hw_params = neo1973_gta02_voice_hw_params,
204 .hw_free = neo1973_gta02_voice_hw_free,
205};
206
207#define LM4853_AMP 1
208#define LM4853_SPK 2
209
210static u8 lm4853_state;
211
212/* This has no effect, it exists only to maintain compatibility with
213 * existing ALSA state files.
214 */
215static int lm4853_set_state(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol)
217{
218 int val = ucontrol->value.integer.value[0];
219
220 if (val)
221 lm4853_state |= LM4853_AMP;
222 else
223 lm4853_state &= ~LM4853_AMP;
224
225 return 0;
226}
227
228static int lm4853_get_state(struct snd_kcontrol *kcontrol,
229 struct snd_ctl_elem_value *ucontrol)
230{
231 ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP;
232
233 return 0;
234}
235
236static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
237 struct snd_ctl_elem_value *ucontrol)
238{
239 int val = ucontrol->value.integer.value[0];
240
241 if (val) {
242 lm4853_state |= LM4853_SPK;
243 gpio_set_value(GTA02_GPIO_HP_IN, 0);
244 } else {
245 lm4853_state &= ~LM4853_SPK;
246 gpio_set_value(GTA02_GPIO_HP_IN, 1);
247 }
248
249 return 0;
250}
251
252static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
253 struct snd_ctl_elem_value *ucontrol)
254{
255 ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1;
256
257 return 0;
258}
259
260static int lm4853_event(struct snd_soc_dapm_widget *w,
261 struct snd_kcontrol *k,
262 int event)
263{
264 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
265
266 return 0;
267}
268
269static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
270 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
271 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
272 SND_SOC_DAPM_LINE("GSM Line In", NULL),
273 SND_SOC_DAPM_MIC("Headset Mic", NULL),
274 SND_SOC_DAPM_MIC("Handset Mic", NULL),
275 SND_SOC_DAPM_SPK("Handset Spk", NULL),
276};
277
278
279/* example machine audio_mapnections */
280static const struct snd_soc_dapm_route audio_map[] = {
281
282 /* Connections to the lm4853 amp */
283 {"Stereo Out", NULL, "LOUT1"},
284 {"Stereo Out", NULL, "ROUT1"},
285
286 /* Connections to the GSM Module */
287 {"GSM Line Out", NULL, "MONO1"},
288 {"GSM Line Out", NULL, "MONO2"},
289 {"RXP", NULL, "GSM Line In"},
290 {"RXN", NULL, "GSM Line In"},
291
292 /* Connections to Headset */
293 {"MIC1", NULL, "Mic Bias"},
294 {"Mic Bias", NULL, "Headset Mic"},
295
296 /* Call Mic */
297 {"MIC2", NULL, "Mic Bias"},
298 {"MIC2N", NULL, "Mic Bias"},
299 {"Mic Bias", NULL, "Handset Mic"},
300
301 /* Call Speaker */
302 {"Handset Spk", NULL, "LOUT2"},
303 {"Handset Spk", NULL, "ROUT2"},
304
305 /* Connect the ALC pins */
306 {"ACIN", NULL, "ACOP"},
307};
308
309static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
310 SOC_DAPM_PIN_SWITCH("Stereo Out"),
311 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
312 SOC_DAPM_PIN_SWITCH("GSM Line In"),
313 SOC_DAPM_PIN_SWITCH("Headset Mic"),
314 SOC_DAPM_PIN_SWITCH("Handset Mic"),
315 SOC_DAPM_PIN_SWITCH("Handset Spk"),
316
317 /* This has no effect, it exists only to maintain compatibility with
318 * existing ALSA state files.
319 */
320 SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0,
321 lm4853_get_state,
322 lm4853_set_state),
323 SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0,
324 lm4853_get_spk,
325 lm4853_set_spk),
326};
327
328/*
329 * This is an example machine initialisation for a wm8753 connected to a
330 * neo1973 GTA02.
331 */
332static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
333{
334 struct snd_soc_codec *codec = rtd->codec;
335 struct snd_soc_dapm_context *dapm = &codec->dapm;
336 int err;
337
338 /* set up NC codec pins */
339 snd_soc_dapm_nc_pin(dapm, "OUT3");
340 snd_soc_dapm_nc_pin(dapm, "OUT4");
341 snd_soc_dapm_nc_pin(dapm, "LINE1");
342 snd_soc_dapm_nc_pin(dapm, "LINE2");
343
344 /* Add neo1973 gta02 specific widgets */
345 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
346 ARRAY_SIZE(wm8753_dapm_widgets));
347
348 /* add neo1973 gta02 specific controls */
349 err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls,
350 ARRAY_SIZE(wm8753_neo1973_gta02_controls));
351
352 if (err < 0)
353 return err;
354
355 /* set up neo1973 gta02 specific audio path audio_map */
356 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
357
358 /* set endpoints to default off mode */
359 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
360 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
361 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
362 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
363 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
364 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
365
366 /* allow audio paths from the GSM modem to run during suspend */
367 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
368 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
369 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
370 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
371 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
372 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
373
374 snd_soc_dapm_sync(dapm);
375
376 return 0;
377}
378
379/*
380 * BT Codec DAI
381 */
382static struct snd_soc_dai_driver bt_dai = {
383 .name = "bluetooth-dai",
384 .playback = {
385 .channels_min = 1,
386 .channels_max = 1,
387 .rates = SNDRV_PCM_RATE_8000,
388 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
389 .capture = {
390 .channels_min = 1,
391 .channels_max = 1,
392 .rates = SNDRV_PCM_RATE_8000,
393 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
394};
395
396static struct snd_soc_dai_link neo1973_gta02_dai[] = {
397{ /* Hifi Playback - for similatious use with voice below */
398 .name = "WM8753",
399 .stream_name = "WM8753 HiFi",
400 .cpu_dai_name = "s3c24xx-iis",
401 .codec_dai_name = "wm8753-hifi",
402 .init = neo1973_gta02_wm8753_init,
403 .platform_name = "samsung-audio",
404 .codec_name = "wm8753-codec.0-001a",
405 .ops = &neo1973_gta02_hifi_ops,
406},
407{ /* Voice via BT */
408 .name = "Bluetooth",
409 .stream_name = "Voice",
410 .cpu_dai_name = "bluetooth-dai",
411 .codec_dai_name = "wm8753-voice",
412 .ops = &neo1973_gta02_voice_ops,
413 .codec_name = "wm8753-codec.0-001a",
414 .platform_name = "samsung-audio",
415},
416};
417
418static struct snd_soc_card neo1973_gta02 = {
419 .name = "neo1973-gta02",
420 .dai_link = neo1973_gta02_dai,
421 .num_links = ARRAY_SIZE(neo1973_gta02_dai),
422};
423
424static struct platform_device *neo1973_gta02_snd_device;
425
426static int __init neo1973_gta02_init(void)
427{
428 int ret;
429
430 if (!machine_is_neo1973_gta02()) {
431 printk(KERN_INFO
432 "Only GTA02 is supported by this ASoC driver\n");
433 return -ENODEV;
434 }
435
436 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
437 if (!neo1973_gta02_snd_device)
438 return -ENOMEM;
439
440 /* register bluetooth DAI here */
441 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
442 if (ret)
443 goto err_put_device;
444
445 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
446 ret = platform_device_add(neo1973_gta02_snd_device);
447
448 if (ret)
449 goto err_unregister_dai;
450
451 /* Initialise GPIOs used by amp */
452 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
453 if (ret) {
454 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
455 goto err_del_device;
456 }
457
458 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
459 if (ret) {
460 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN);
461 goto err_free_gpio_hp_in;
462 }
463
464 ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT");
465 if (ret) {
466 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT);
467 goto err_free_gpio_hp_in;
468 }
469
470 ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1);
471 if (ret) {
472 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT);
473 goto err_free_gpio_amp_shut;
474 }
475
476 return 0;
477
478err_free_gpio_amp_shut:
479 gpio_free(GTA02_GPIO_AMP_SHUT);
480err_free_gpio_hp_in:
481 gpio_free(GTA02_GPIO_HP_IN);
482err_del_device:
483 platform_device_del(neo1973_gta02_snd_device);
484err_unregister_dai:
485 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
486err_put_device:
487 platform_device_put(neo1973_gta02_snd_device);
488 return ret;
489}
490module_init(neo1973_gta02_init);
491
492static void __exit neo1973_gta02_exit(void)
493{
494 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
495 platform_device_unregister(neo1973_gta02_snd_device);
496 gpio_free(GTA02_GPIO_HP_IN);
497 gpio_free(GTA02_GPIO_AMP_SHUT);
498}
499module_exit(neo1973_gta02_exit);
500
501/* Module information */
502MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org");
503MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02");
504MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index d20815d5ab2e..78bfdb3f5d7e 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -1,57 +1,32 @@
1/* 1/*
2 * neo1973_wm8753.c -- SoC audio for Neo1973 2 * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices
3 * 3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
4 * Copyright 2007 Wolfson Microelectronics PLC. 6 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 7 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 8 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
9 * Copyright 2009 Wolfson Microelectronics
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 14 * option) any later version.
12 *
13 */ 15 */
14 16
15#include <linux/module.h> 17#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/i2c.h> 19#include <linux/gpio.h>
21#include <sound/core.h> 20
22#include <sound/pcm.h>
23#include <sound/soc.h> 21#include <sound/soc.h>
24#include <sound/tlv.h>
25 22
26#include <asm/mach-types.h> 23#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/regs-clock.h>
29#include <mach/regs-gpio.h>
30#include <mach/hardware.h>
31#include <linux/io.h>
32#include <mach/spi-gpio.h>
33
34#include <plat/regs-iis.h> 24#include <plat/regs-iis.h>
25#include <mach/gta02.h>
35 26
36#include "../codecs/wm8753.h" 27#include "../codecs/wm8753.h"
37#include "lm4857.h"
38#include "dma.h"
39#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
40 29
41/* define the scenarios */
42#define NEO_AUDIO_OFF 0
43#define NEO_GSM_CALL_AUDIO_HANDSET 1
44#define NEO_GSM_CALL_AUDIO_HEADSET 2
45#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3
46#define NEO_STEREO_TO_SPEAKERS 4
47#define NEO_STEREO_TO_HEADPHONES 5
48#define NEO_CAPTURE_HANDSET 6
49#define NEO_CAPTURE_HEADSET 7
50#define NEO_CAPTURE_BLUETOOTH 8
51
52static struct snd_soc_card neo1973;
53static struct i2c_client *i2c;
54
55static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 30static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params) 31 struct snd_pcm_hw_params *params)
57{ 32{
@@ -62,8 +37,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
62 int ret = 0; 37 int ret = 0;
63 unsigned long iis_clkrate; 38 unsigned long iis_clkrate;
64 39
65 pr_debug("Entered %s\n", __func__);
66
67 iis_clkrate = s3c24xx_i2s_get_clockrate(); 40 iis_clkrate = s3c24xx_i2s_get_clockrate();
68 41
69 switch (params_rate(params)) { 42 switch (params_rate(params)) {
@@ -148,8 +121,6 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_dai *codec_dai = rtd->codec_dai; 122 struct snd_soc_dai *codec_dai = rtd->codec_dai;
150 123
151 pr_debug("Entered %s\n", __func__);
152
153 /* disable the PLL */ 124 /* disable the PLL */
154 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); 125 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
155} 126}
@@ -171,8 +142,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
171 int ret = 0; 142 int ret = 0;
172 unsigned long iis_clkrate; 143 unsigned long iis_clkrate;
173 144
174 pr_debug("Entered %s\n", __func__);
175
176 iis_clkrate = s3c24xx_i2s_get_clockrate(); 145 iis_clkrate = s3c24xx_i2s_get_clockrate();
177 146
178 if (params_rate(params) != 8000) 147 if (params_rate(params) != 8000)
@@ -214,8 +183,6 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 183 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct snd_soc_dai *codec_dai = rtd->codec_dai; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
216 185
217 pr_debug("Entered %s\n", __func__);
218
219 /* disable the PLL */ 186 /* disable the PLL */
220 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); 187 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
221} 188}
@@ -225,335 +192,232 @@ static struct snd_soc_ops neo1973_voice_ops = {
225 .hw_free = neo1973_voice_hw_free, 192 .hw_free = neo1973_voice_hw_free,
226}; 193};
227 194
228static int neo1973_scenario; 195/* Shared routes and controls */
229
230static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_value *ucontrol)
232{
233 ucontrol->value.integer.value[0] = neo1973_scenario;
234 return 0;
235}
236
237static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
238{
239 struct snd_soc_dapm_context *dapm = &codec->dapm;
240
241 pr_debug("Entered %s\n", __func__);
242
243 switch (neo1973_scenario) {
244 case NEO_AUDIO_OFF:
245 snd_soc_dapm_disable_pin(dapm, "Audio Out");
246 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
247 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
248 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
249 snd_soc_dapm_disable_pin(dapm, "Call Mic");
250 break;
251 case NEO_GSM_CALL_AUDIO_HANDSET:
252 snd_soc_dapm_enable_pin(dapm, "Audio Out");
253 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
254 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
255 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
256 snd_soc_dapm_enable_pin(dapm, "Call Mic");
257 break;
258 case NEO_GSM_CALL_AUDIO_HEADSET:
259 snd_soc_dapm_enable_pin(dapm, "Audio Out");
260 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
261 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
262 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
263 snd_soc_dapm_disable_pin(dapm, "Call Mic");
264 break;
265 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
266 snd_soc_dapm_disable_pin(dapm, "Audio Out");
267 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
268 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
269 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
270 snd_soc_dapm_disable_pin(dapm, "Call Mic");
271 break;
272 case NEO_STEREO_TO_SPEAKERS:
273 snd_soc_dapm_enable_pin(dapm, "Audio Out");
274 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
275 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
276 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
277 snd_soc_dapm_disable_pin(dapm, "Call Mic");
278 break;
279 case NEO_STEREO_TO_HEADPHONES:
280 snd_soc_dapm_enable_pin(dapm, "Audio Out");
281 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
282 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
283 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
284 snd_soc_dapm_disable_pin(dapm, "Call Mic");
285 break;
286 case NEO_CAPTURE_HANDSET:
287 snd_soc_dapm_disable_pin(dapm, "Audio Out");
288 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
289 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
290 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
291 snd_soc_dapm_enable_pin(dapm, "Call Mic");
292 break;
293 case NEO_CAPTURE_HEADSET:
294 snd_soc_dapm_disable_pin(dapm, "Audio Out");
295 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
296 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
297 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
298 snd_soc_dapm_disable_pin(dapm, "Call Mic");
299 break;
300 case NEO_CAPTURE_BLUETOOTH:
301 snd_soc_dapm_disable_pin(dapm, "Audio Out");
302 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
303 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
304 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
305 snd_soc_dapm_disable_pin(dapm, "Call Mic");
306 break;
307 default:
308 snd_soc_dapm_disable_pin(dapm, "Audio Out");
309 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
310 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
311 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
312 snd_soc_dapm_disable_pin(dapm, "Call Mic");
313 }
314 196
315 snd_soc_dapm_sync(dapm); 197static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
198 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
199 SND_SOC_DAPM_LINE("GSM Line In", NULL),
200 SND_SOC_DAPM_MIC("Headset Mic", NULL),
201 SND_SOC_DAPM_MIC("Handset Mic", NULL),
202};
316 203
317 return 0; 204static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
318} 205 /* Connections to the GSM Module */
206 {"GSM Line Out", NULL, "MONO1"},
207 {"GSM Line Out", NULL, "MONO2"},
208 {"RXP", NULL, "GSM Line In"},
209 {"RXN", NULL, "GSM Line In"},
319 210
320static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, 211 /* Connections to Headset */
321 struct snd_ctl_elem_value *ucontrol) 212 {"MIC1", NULL, "Mic Bias"},
322{ 213 {"Mic Bias", NULL, "Headset Mic"},
323 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
324 214
325 pr_debug("Entered %s\n", __func__); 215 /* Call Mic */
216 {"MIC2", NULL, "Mic Bias"},
217 {"MIC2N", NULL, "Mic Bias"},
218 {"Mic Bias", NULL, "Handset Mic"},
326 219
327 if (neo1973_scenario == ucontrol->value.integer.value[0]) 220 /* Connect the ALC pins */
328 return 0; 221 {"ACIN", NULL, "ACOP"},
222};
329 223
330 neo1973_scenario = ucontrol->value.integer.value[0]; 224static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
331 set_scenario_endpoints(codec, neo1973_scenario); 225 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
332 return 1; 226 SOC_DAPM_PIN_SWITCH("GSM Line In"),
333} 227 SOC_DAPM_PIN_SWITCH("Headset Mic"),
228 SOC_DAPM_PIN_SWITCH("Handset Mic"),
229};
334 230
335static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; 231/* GTA02 specific routes and controlls */
336 232
337static void lm4857_write_regs(void) 233#ifdef CONFIG_MACH_NEO1973_GTA02
338{
339 pr_debug("Entered %s\n", __func__);
340 234
341 if (i2c_master_send(i2c, lm4857_regs, 4) != 4) 235static int gta02_speaker_enabled;
342 printk(KERN_ERR "lm4857: i2c write failed\n");
343}
344 236
345static int lm4857_get_reg(struct snd_kcontrol *kcontrol, 237static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol) 238 struct snd_ctl_elem_value *ucontrol)
347{ 239{
348 struct soc_mixer_control *mc = 240 gta02_speaker_enabled = ucontrol->value.integer.value[0];
349 (struct soc_mixer_control *)kcontrol->private_value;
350 int reg = mc->reg;
351 int shift = mc->shift;
352 int mask = mc->max;
353 241
354 pr_debug("Entered %s\n", __func__); 242 gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled);
355 243
356 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
357 return 0; 244 return 0;
358} 245}
359 246
360static int lm4857_set_reg(struct snd_kcontrol *kcontrol, 247static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_value *ucontrol) 248 struct snd_ctl_elem_value *ucontrol)
362{ 249{
363 struct soc_mixer_control *mc = 250 ucontrol->value.integer.value[0] = gta02_speaker_enabled;
364 (struct soc_mixer_control *)kcontrol->private_value; 251 return 0;
365 int reg = mc->reg;
366 int shift = mc->shift;
367 int mask = mc->max;
368
369 if (((lm4857_regs[reg] >> shift) & mask) ==
370 ucontrol->value.integer.value[0])
371 return 0;
372
373 lm4857_regs[reg] &= ~(mask << shift);
374 lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
375 lm4857_write_regs();
376 return 1;
377} 252}
378 253
379static int lm4857_get_mode(struct snd_kcontrol *kcontrol, 254static int lm4853_event(struct snd_soc_dapm_widget *w,
380 struct snd_ctl_elem_value *ucontrol) 255 struct snd_kcontrol *k, int event)
381{ 256{
382 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; 257 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
383
384 pr_debug("Entered %s\n", __func__);
385
386 if (value)
387 value -= 5;
388 258
389 ucontrol->value.integer.value[0] = value;
390 return 0; 259 return 0;
391} 260}
392 261
393static int lm4857_set_mode(struct snd_kcontrol *kcontrol, 262static const struct snd_soc_dapm_route neo1973_gta02_routes[] = {
394 struct snd_ctl_elem_value *ucontrol) 263 /* Connections to the amp */
395{ 264 {"Stereo Out", NULL, "LOUT1"},
396 u8 value = ucontrol->value.integer.value[0]; 265 {"Stereo Out", NULL, "ROUT1"},
397
398 pr_debug("Entered %s\n", __func__);
399
400 if (value)
401 value += 5;
402
403 if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
404 return 0;
405
406 lm4857_regs[LM4857_CTRL] &= 0xF0;
407 lm4857_regs[LM4857_CTRL] |= value;
408 lm4857_write_regs();
409 return 1;
410}
411 266
412static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { 267 /* Call Speaker */
413 SND_SOC_DAPM_LINE("Audio Out", NULL), 268 {"Handset Spk", NULL, "LOUT2"},
414 SND_SOC_DAPM_LINE("GSM Line Out", NULL), 269 {"Handset Spk", NULL, "ROUT2"},
415 SND_SOC_DAPM_LINE("GSM Line In", NULL),
416 SND_SOC_DAPM_MIC("Headset Mic", NULL),
417 SND_SOC_DAPM_MIC("Call Mic", NULL),
418}; 270};
419 271
272static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = {
273 SOC_DAPM_PIN_SWITCH("Handset Spk"),
274 SOC_DAPM_PIN_SWITCH("Stereo Out"),
420 275
421static const struct snd_soc_dapm_route dapm_routes[] = { 276 SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
422 277 lm4853_get_spk,
423 /* Connections to the lm4857 amp */ 278 lm4853_set_spk),
424 {"Audio Out", NULL, "LOUT1"}, 279};
425 {"Audio Out", NULL, "ROUT1"},
426
427 /* Connections to the GSM Module */
428 {"GSM Line Out", NULL, "MONO1"},
429 {"GSM Line Out", NULL, "MONO2"},
430 {"RXP", NULL, "GSM Line In"},
431 {"RXN", NULL, "GSM Line In"},
432 280
433 /* Connections to Headset */ 281static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = {
434 {"MIC1", NULL, "Mic Bias"}, 282 SND_SOC_DAPM_SPK("Handset Spk", NULL),
435 {"Mic Bias", NULL, "Headset Mic"}, 283 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
284};
436 285
437 /* Call Mic */ 286static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
438 {"MIC2", NULL, "Mic Bias"}, 287{
439 {"MIC2N", NULL, "Mic Bias"}, 288 struct snd_soc_dapm_context *dapm = &codec->dapm;
440 {"Mic Bias", NULL, "Call Mic"}, 289 int ret;
441 290
442 /* Connect the ALC pins */ 291 ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets,
443 {"ACIN", NULL, "ACOP"}, 292 ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets));
444}; 293 if (ret)
294 return ret;
445 295
446static const char *lm4857_mode[] = { 296 ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes,
447 "Off", 297 ARRAY_SIZE(neo1973_gta02_routes));
448 "Call Speaker", 298 if (ret)
449 "Stereo Speakers", 299 return ret;
450 "Stereo Speakers + Headphones",
451 "Headphones"
452};
453 300
454static const struct soc_enum lm4857_mode_enum[] = { 301 ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls,
455 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), 302 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
456}; 303 if (ret)
304 return ret;
457 305
458static const char *neo_scenarios[] = { 306 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
459 "Off", 307 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
460 "GSM Handset", 308 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
461 "GSM Headset", 309 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
462 "GSM Bluetooth",
463 "Speakers",
464 "Headphones",
465 "Capture Handset",
466 "Capture Headset",
467 "Capture Bluetooth"
468};
469 310
470static const struct soc_enum neo_scenario_enum[] = { 311 return 0;
471 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), 312}
472};
473 313
474static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); 314#else
475static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); 315static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; }
476 316#endif
477static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
478 SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
479 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
480 SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
481 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
482 SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
483 lm4857_get_reg, lm4857_set_reg, mono_tlv),
484 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
485 lm4857_get_mode, lm4857_set_mode),
486 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
487 neo1973_get_scenario, neo1973_set_scenario),
488 SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
489 lm4857_get_reg, lm4857_set_reg),
490 SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
491 lm4857_get_reg, lm4857_set_reg),
492 SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
493 lm4857_get_reg, lm4857_set_reg),
494 SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
495 lm4857_get_reg, lm4857_set_reg),
496};
497 317
498/*
499 * This is an example machine initialisation for a wm8753 connected to a
500 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
501 * to re-route the audio in such an event.
502 */
503static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 318static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
504{ 319{
505 struct snd_soc_codec *codec = rtd->codec; 320 struct snd_soc_codec *codec = rtd->codec;
506 struct snd_soc_dapm_context *dapm = &codec->dapm; 321 struct snd_soc_dapm_context *dapm = &codec->dapm;
507 int err; 322 int ret;
508
509 pr_debug("Entered %s\n", __func__);
510 323
511 /* set up NC codec pins */ 324 /* set up NC codec pins */
512 snd_soc_dapm_nc_pin(dapm, "LOUT2"); 325 if (machine_is_neo1973_gta01()) {
513 snd_soc_dapm_nc_pin(dapm, "ROUT2"); 326 snd_soc_dapm_nc_pin(dapm, "LOUT2");
327 snd_soc_dapm_nc_pin(dapm, "ROUT2");
328 }
514 snd_soc_dapm_nc_pin(dapm, "OUT3"); 329 snd_soc_dapm_nc_pin(dapm, "OUT3");
515 snd_soc_dapm_nc_pin(dapm, "OUT4"); 330 snd_soc_dapm_nc_pin(dapm, "OUT4");
516 snd_soc_dapm_nc_pin(dapm, "LINE1"); 331 snd_soc_dapm_nc_pin(dapm, "LINE1");
517 snd_soc_dapm_nc_pin(dapm, "LINE2"); 332 snd_soc_dapm_nc_pin(dapm, "LINE2");
518 333
519 /* Add neo1973 specific widgets */ 334 /* Add neo1973 specific widgets */
520 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, 335 ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets,
521 ARRAY_SIZE(wm8753_dapm_widgets)); 336 ARRAY_SIZE(neo1973_wm8753_dapm_widgets));
522 337 if (ret)
523 /* set endpoints to default mode */ 338 return ret;
524 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
525 339
526 /* add neo1973 specific controls */ 340 /* add neo1973 specific controls */
527 err = snd_soc_add_controls(codec, wm8753_neo1973_controls, 341 ret = snd_soc_add_controls(codec, neo1973_wm8753_controls,
528 ARRAY_SIZE(8753_neo1973_controls)); 342 ARRAY_SIZE(neo1973_wm8753_controls));
529 if (err < 0) 343 if (ret)
530 return err; 344 return ret;
531 345
532 /* set up neo1973 specific audio routes */ 346 /* set up neo1973 specific audio routes */
533 err = snd_soc_dapm_add_routes(dapm, dapm_routes, 347 ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes,
534 ARRAY_SIZE(dapm_routes)); 348 ARRAY_SIZE(neo1973_wm8753_routes));
349 if (ret)
350 return ret;
351
352 /* set endpoints to default off mode */
353 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
354 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
355 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
356 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
357
358 /* allow audio paths from the GSM modem to run during suspend */
359 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
360 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
361 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
362 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
363
364 if (machine_is_neo1973_gta02()) {
365 ret = neo1973_gta02_wm8753_init(codec);
366 if (ret)
367 return ret;
368 }
535 369
536 snd_soc_dapm_sync(dapm); 370 snd_soc_dapm_sync(dapm);
371
537 return 0; 372 return 0;
538} 373}
539 374
540/* 375/* GTA01 specific controlls */
541 * BT Codec DAI 376
542 */ 377#ifdef CONFIG_MACH_NEO1973_GTA01
543static struct snd_soc_dai bt_dai = { 378
544 .name = "bluetooth-dai", 379static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = {
545 .playback = { 380 {"Amp IN", NULL, "ROUT1"},
546 .channels_min = 1, 381 {"Amp IN", NULL, "LOUT1"},
547 .channels_max = 1, 382
548 .rates = SNDRV_PCM_RATE_8000, 383 {"Handset Spk", NULL, "Amp EP"},
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 384 {"Stereo Out", NULL, "Amp LS"},
550 .capture = { 385 {"Headphone", NULL, "Amp HP"},
551 .channels_min = 1, 386};
552 .channels_max = 1, 387
553 .rates = SNDRV_PCM_RATE_8000, 388static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = {
554 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 389 SND_SOC_DAPM_SPK("Handset Spk", NULL),
390 SND_SOC_DAPM_SPK("Stereo Out", NULL),
391 SND_SOC_DAPM_HP("Headphone", NULL),
555}; 392};
556 393
394static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
395{
396 int ret;
397
398 ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets,
399 ARRAY_SIZE(neo1973_lm4857_dapm_widgets));
400 if (ret)
401 return ret;
402
403 ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes,
404 ARRAY_SIZE(neo1973_lm4857_routes));
405 if (ret)
406 return ret;
407
408 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
409 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
410 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
411
412 snd_soc_dapm_sync(dapm);
413
414 return 0;
415}
416
417#else
418static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; };
419#endif
420
557static struct snd_soc_dai_link neo1973_dai[] = { 421static struct snd_soc_dai_link neo1973_dai[] = {
558{ /* Hifi Playback - for similatious use with voice below */ 422{ /* Hifi Playback - for similatious use with voice below */
559 .name = "WM8753", 423 .name = "WM8753",
@@ -569,90 +433,49 @@ static struct snd_soc_dai_link neo1973_dai[] = {
569 .name = "Bluetooth", 433 .name = "Bluetooth",
570 .stream_name = "Voice", 434 .stream_name = "Voice",
571 .platform_name = "samsung-audio", 435 .platform_name = "samsung-audio",
572 .cpu_dai_name = "bluetooth-dai", 436 .cpu_dai_name = "dfbmcs320-pcm",
573 .codec_dai_name = "wm8753-voice", 437 .codec_dai_name = "wm8753-voice",
574 .codec_name = "wm8753-codec.0-001a", 438 .codec_name = "wm8753-codec.0-001a",
575 .ops = &neo1973_voice_ops, 439 .ops = &neo1973_voice_ops,
576}, 440},
577}; 441};
578 442
579static struct snd_soc_card neo1973 = { 443static struct snd_soc_aux_dev neo1973_aux_devs[] = {
580 .name = "neo1973", 444 {
581 .dai_link = neo1973_dai, 445 .name = "dfbmcs320",
582 .num_links = ARRAY_SIZE(neo1973_dai), 446 .codec_name = "dfbmcs320.0",
447 },
448 {
449 .name = "lm4857",
450 .codec_name = "lm4857.0-007c",
451 .init = neo1973_lm4857_init,
452 },
583}; 453};
584 454
585static int lm4857_i2c_probe(struct i2c_client *client, 455static struct snd_soc_codec_conf neo1973_codec_conf[] = {
586 const struct i2c_device_id *id) 456 {
587{ 457 .dev_name = "lm4857.0-007c",
588 pr_debug("Entered %s\n", __func__); 458 .name_prefix = "Amp",
589 459 },
590 i2c = client; 460};
591
592 lm4857_write_regs();
593 return 0;
594}
595
596static int lm4857_i2c_remove(struct i2c_client *client)
597{
598 pr_debug("Entered %s\n", __func__);
599
600 i2c = NULL;
601
602 return 0;
603}
604
605static u8 lm4857_state;
606
607static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
608{
609 pr_debug("Entered %s\n", __func__);
610
611 dev_dbg(&dev->dev, "lm4857_suspend\n");
612 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
613 if (lm4857_state) {
614 lm4857_regs[LM4857_CTRL] &= 0xf0;
615 lm4857_write_regs();
616 }
617 return 0;
618}
619
620static int lm4857_resume(struct i2c_client *dev)
621{
622 pr_debug("Entered %s\n", __func__);
623
624 if (lm4857_state) {
625 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
626 lm4857_write_regs();
627 }
628 return 0;
629}
630
631static void lm4857_shutdown(struct i2c_client *dev)
632{
633 pr_debug("Entered %s\n", __func__);
634
635 dev_dbg(&dev->dev, "lm4857_shutdown\n");
636 lm4857_regs[LM4857_CTRL] &= 0xf0;
637 lm4857_write_regs();
638}
639 461
640static const struct i2c_device_id lm4857_i2c_id[] = { 462#ifdef CONFIG_MACH_NEO1973_GTA02
641 { "neo1973_lm4857", 0 }, 463static const struct gpio neo1973_gta02_gpios[] = {
642 { } 464 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
465 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
643}; 466};
467#else
468static const struct gpio neo1973_gta02_gpios[] = {};
469#endif
644 470
645static struct i2c_driver lm4857_i2c_driver = { 471static struct snd_soc_card neo1973 = {
646 .driver = { 472 .name = "neo1973",
647 .name = "LM4857 I2C Amp", 473 .dai_link = neo1973_dai,
648 .owner = THIS_MODULE, 474 .num_links = ARRAY_SIZE(neo1973_dai),
649 }, 475 .aux_dev = neo1973_aux_devs,
650 .suspend = lm4857_suspend, 476 .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
651 .resume = lm4857_resume, 477 .codec_conf = neo1973_codec_conf,
652 .shutdown = lm4857_shutdown, 478 .num_configs = ARRAY_SIZE(neo1973_codec_conf),
653 .probe = lm4857_i2c_probe,
654 .remove = lm4857_i2c_remove,
655 .id_table = lm4857_i2c_id,
656}; 479};
657 480
658static struct platform_device *neo1973_snd_device; 481static struct platform_device *neo1973_snd_device;
@@ -661,46 +484,56 @@ static int __init neo1973_init(void)
661{ 484{
662 int ret; 485 int ret;
663 486
664 pr_debug("Entered %s\n", __func__); 487 if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02())
665
666 if (!machine_is_neo1973_gta01()) {
667 printk(KERN_INFO
668 "Only GTA01 hardware supported by ASoC driver\n");
669 return -ENODEV; 488 return -ENODEV;
489
490 if (machine_is_neo1973_gta02()) {
491 neo1973.name = "neo1973gta02";
492 neo1973.num_aux_devs = 1;
493
494 ret = gpio_request_array(neo1973_gta02_gpios,
495 ARRAY_SIZE(neo1973_gta02_gpios));
496 if (ret)
497 return ret;
670 } 498 }
671 499
672 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 500 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
673 if (!neo1973_snd_device) 501 if (!neo1973_snd_device) {
674 return -ENOMEM; 502 ret = -ENOMEM;
503 goto err_gpio_free;
504 }
675 505
676 platform_set_drvdata(neo1973_snd_device, &neo1973); 506 platform_set_drvdata(neo1973_snd_device, &neo1973);
677 ret = platform_device_add(neo1973_snd_device); 507 ret = platform_device_add(neo1973_snd_device);
678 508
679 if (ret) { 509 if (ret)
680 platform_device_put(neo1973_snd_device); 510 goto err_put_device;
681 return ret;
682 }
683
684 ret = i2c_add_driver(&lm4857_i2c_driver);
685 511
686 if (ret != 0) 512 return 0;
687 platform_device_unregister(neo1973_snd_device);
688 513
514err_put_device:
515 platform_device_put(neo1973_snd_device);
516err_gpio_free:
517 if (machine_is_neo1973_gta02()) {
518 gpio_free_array(neo1973_gta02_gpios,
519 ARRAY_SIZE(neo1973_gta02_gpios));
520 }
689 return ret; 521 return ret;
690} 522}
523module_init(neo1973_init);
691 524
692static void __exit neo1973_exit(void) 525static void __exit neo1973_exit(void)
693{ 526{
694 pr_debug("Entered %s\n", __func__);
695
696 i2c_del_driver(&lm4857_i2c_driver);
697 platform_device_unregister(neo1973_snd_device); 527 platform_device_unregister(neo1973_snd_device);
698}
699 528
700module_init(neo1973_init); 529 if (machine_is_neo1973_gta02()) {
530 gpio_free_array(neo1973_gta02_gpios,
531 ARRAY_SIZE(neo1973_gta02_gpios));
532 }
533}
701module_exit(neo1973_exit); 534module_exit(neo1973_exit);
702 535
703/* Module information */ 536/* Module information */
704MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); 537MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
705MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); 538MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
706MODULE_LICENSE("GPL"); 539MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 48d0b750406b..38aac7d57a59 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -11,20 +11,11 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/delay.h>
18#include <linux/clk.h> 14#include <linux/clk.h>
19#include <linux/kernel.h>
20#include <linux/gpio.h>
21#include <linux/io.h> 15#include <linux/io.h>
22 16
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/initval.h>
27#include <sound/soc.h> 17#include <sound/soc.h>
18#include <sound/pcm_params.h>
28 19
29#include <plat/audio.h> 20#include <plat/audio.h>
30#include <plat/dma.h> 21#include <plat/dma.h>
@@ -32,6 +23,113 @@
32#include "dma.h" 23#include "dma.h"
33#include "pcm.h" 24#include "pcm.h"
34 25
26/*Register Offsets */
27#define S3C_PCM_CTL 0x00
28#define S3C_PCM_CLKCTL 0x04
29#define S3C_PCM_TXFIFO 0x08
30#define S3C_PCM_RXFIFO 0x0C
31#define S3C_PCM_IRQCTL 0x10
32#define S3C_PCM_IRQSTAT 0x14
33#define S3C_PCM_FIFOSTAT 0x18
34#define S3C_PCM_CLRINT 0x20
35
36/* PCM_CTL Bit-Fields */
37#define S3C_PCM_CTL_TXDIPSTICK_MASK 0x3f
38#define S3C_PCM_CTL_TXDIPSTICK_SHIFT 13
39#define S3C_PCM_CTL_RXDIPSTICK_MASK 0x3f
40#define S3C_PCM_CTL_RXDIPSTICK_SHIFT 7
41#define S3C_PCM_CTL_TXDMA_EN (0x1 << 6)
42#define S3C_PCM_CTL_RXDMA_EN (0x1 << 5)
43#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1 << 4)
44#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1 << 3)
45#define S3C_PCM_CTL_TXFIFO_EN (0x1 << 2)
46#define S3C_PCM_CTL_RXFIFO_EN (0x1 << 1)
47#define S3C_PCM_CTL_ENABLE (0x1 << 0)
48
49/* PCM_CLKCTL Bit-Fields */
50#define S3C_PCM_CLKCTL_SERCLK_EN (0x1 << 19)
51#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1 << 18)
52#define S3C_PCM_CLKCTL_SCLKDIV_MASK 0x1ff
53#define S3C_PCM_CLKCTL_SYNCDIV_MASK 0x1ff
54#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT 9
55#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT 0
56
57/* PCM_TXFIFO Bit-Fields */
58#define S3C_PCM_TXFIFO_DVALID (0x1 << 16)
59#define S3C_PCM_TXFIFO_DATA_MSK (0xffff << 0)
60
61/* PCM_RXFIFO Bit-Fields */
62#define S3C_PCM_RXFIFO_DVALID (0x1 << 16)
63#define S3C_PCM_RXFIFO_DATA_MSK (0xffff << 0)
64
65/* PCM_IRQCTL Bit-Fields */
66#define S3C_PCM_IRQCTL_IRQEN (0x1 << 14)
67#define S3C_PCM_IRQCTL_WRDEN (0x1 << 12)
68#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1 << 11)
69#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1 << 10)
70#define S3C_PCM_IRQCTL_TXFULLEN (0x1 << 9)
71#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1 << 8)
72#define S3C_PCM_IRQCTL_TXSTARVEN (0x1 << 7)
73#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1 << 6)
74#define S3C_PCM_IRQCTL_RXEMPTEN (0x1 << 5)
75#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1 << 4)
76#define S3C_PCM_IRQCTL_RXFULLEN (0x1 << 3)
77#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1 << 2)
78#define S3C_PCM_IRQCTL_RXSTARVEN (0x1 << 1)
79#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1 << 0)
80
81/* PCM_IRQSTAT Bit-Fields */
82#define S3C_PCM_IRQSTAT_IRQPND (0x1 << 13)
83#define S3C_PCM_IRQSTAT_WRD_XFER (0x1 << 12)
84#define S3C_PCM_IRQSTAT_TXEMPTY (0x1 << 11)
85#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1 << 10)
86#define S3C_PCM_IRQSTAT_TXFULL (0x1 << 9)
87#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1 << 8)
88#define S3C_PCM_IRQSTAT_TXSTARV (0x1 << 7)
89#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1 << 6)
90#define S3C_PCM_IRQSTAT_RXEMPT (0x1 << 5)
91#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1 << 4)
92#define S3C_PCM_IRQSTAT_RXFULL (0x1 << 3)
93#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1 << 2)
94#define S3C_PCM_IRQSTAT_RXSTARV (0x1 << 1)
95#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1 << 0)
96
97/* PCM_FIFOSTAT Bit-Fields */
98#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f << 14)
99#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1 << 13)
100#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1 << 12)
101#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1 << 11)
102#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1 << 10)
103#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f << 4)
104#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1 << 3)
105#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1 << 2)
106#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1 << 1)
107#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1 << 0)
108
109/**
110 * struct s3c_pcm_info - S3C PCM Controller information
111 * @dev: The parent device passed to use from the probe.
112 * @regs: The pointer to the device register block.
113 * @dma_playback: DMA information for playback channel.
114 * @dma_capture: DMA information for capture channel.
115 */
116struct s3c_pcm_info {
117 spinlock_t lock;
118 struct device *dev;
119 void __iomem *regs;
120
121 unsigned int sclk_per_fs;
122
123 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
124 unsigned int idleclk;
125
126 struct clk *pclk;
127 struct clk *cclk;
128
129 struct s3c_dma_params *dma_playback;
130 struct s3c_dma_params *dma_capture;
131};
132
35static struct s3c2410_dma_client s3c_pcm_dma_client_out = { 133static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
36 .name = "PCM Stereo out" 134 .name = "PCM Stereo out"
37}; 135};
diff --git a/sound/soc/samsung/pcm.h b/sound/soc/samsung/pcm.h
index 03393dcf852d..726baf814613 100644
--- a/sound/soc/samsung/pcm.h
+++ b/sound/soc/samsung/pcm.h
@@ -9,116 +9,9 @@
9#ifndef __S3C_PCM_H 9#ifndef __S3C_PCM_H
10#define __S3C_PCM_H __FILE__ 10#define __S3C_PCM_H __FILE__
11 11
12/*Register Offsets */
13#define S3C_PCM_CTL (0x00)
14#define S3C_PCM_CLKCTL (0x04)
15#define S3C_PCM_TXFIFO (0x08)
16#define S3C_PCM_RXFIFO (0x0C)
17#define S3C_PCM_IRQCTL (0x10)
18#define S3C_PCM_IRQSTAT (0x14)
19#define S3C_PCM_FIFOSTAT (0x18)
20#define S3C_PCM_CLRINT (0x20)
21
22/* PCM_CTL Bit-Fields */
23#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f)
24#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13)
25#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f)
26#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7)
27#define S3C_PCM_CTL_TXDMA_EN (0x1<<6)
28#define S3C_PCM_CTL_RXDMA_EN (0x1<<5)
29#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4)
30#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3)
31#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2)
32#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1)
33#define S3C_PCM_CTL_ENABLE (0x1<<0)
34
35/* PCM_CLKCTL Bit-Fields */
36#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19)
37#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18)
38#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff)
39#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff)
40#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9)
41#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0)
42
43/* PCM_TXFIFO Bit-Fields */
44#define S3C_PCM_TXFIFO_DVALID (0x1<<16)
45#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0)
46
47/* PCM_RXFIFO Bit-Fields */
48#define S3C_PCM_RXFIFO_DVALID (0x1<<16)
49#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0)
50
51/* PCM_IRQCTL Bit-Fields */
52#define S3C_PCM_IRQCTL_IRQEN (0x1<<14)
53#define S3C_PCM_IRQCTL_WRDEN (0x1<<12)
54#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11)
55#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10)
56#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9)
57#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8)
58#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7)
59#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6)
60#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5)
61#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4)
62#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3)
63#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2)
64#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1)
65#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0)
66
67/* PCM_IRQSTAT Bit-Fields */
68#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13)
69#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12)
70#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11)
71#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10)
72#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9)
73#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8)
74#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7)
75#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6)
76#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5)
77#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4)
78#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3)
79#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2)
80#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1)
81#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0)
82
83/* PCM_FIFOSTAT Bit-Fields */
84#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14)
85#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13)
86#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12)
87#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11)
88#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10)
89#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4)
90#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3)
91#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2)
92#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1)
93#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0)
94
95#define S3C_PCM_CLKSRC_PCLK 0 12#define S3C_PCM_CLKSRC_PCLK 0
96#define S3C_PCM_CLKSRC_MUX 1 13#define S3C_PCM_CLKSRC_MUX 1
97 14
98#define S3C_PCM_SCLK_PER_FS 0 15#define S3C_PCM_SCLK_PER_FS 0
99 16
100/**
101 * struct s3c_pcm_info - S3C PCM Controller information
102 * @dev: The parent device passed to use from the probe.
103 * @regs: The pointer to the device register block.
104 * @dma_playback: DMA information for playback channel.
105 * @dma_capture: DMA information for capture channel.
106 */
107struct s3c_pcm_info {
108 spinlock_t lock;
109 struct device *dev;
110 void __iomem *regs;
111
112 unsigned int sclk_per_fs;
113
114 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
115 unsigned int idleclk;
116
117 struct clk *pclk;
118 struct clk *cclk;
119
120 struct s3c_dma_params *dma_playback;
121 struct s3c_dma_params *dma_capture;
122};
123
124#endif /* __S3C_PCM_H */ 17#endif /* __S3C_PCM_H */
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index f40027445dda..1e574a5d440d 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -17,26 +17,15 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/platform_device.h>
23#include <linux/i2c.h>
24#include <linux/gpio.h> 20#include <linux/gpio.h>
25#include <linux/clk.h>
26 21
27#include <sound/soc.h> 22#include <sound/soc.h>
28#include <sound/uda1380.h>
29#include <sound/jack.h> 23#include <sound/jack.h>
30 24
31#include <plat/regs-iis.h> 25#include <plat/regs-iis.h>
32
33#include <mach/regs-clock.h>
34
35#include <asm/mach-types.h> 26#include <asm/mach-types.h>
36 27
37#include "dma.h"
38#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
39#include "../codecs/uda1380.h"
40 29
41static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); 30static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd);
42static int rx1950_startup(struct snd_pcm_substream *substream); 31static int rx1950_startup(struct snd_pcm_substream *substream);
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 094f36e41e83..52074a2b0696 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -20,9 +20,8 @@
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h>
26 25
27#include <mach/dma.h> 26#include <mach/dma.h>
28 27
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 7ea837867124..841ab14c1100 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -16,21 +16,13 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h> 19#include <linux/delay.h>
23#include <linux/gpio.h> 20#include <linux/gpio.h>
24#include <linux/clk.h> 21#include <linux/clk.h>
25#include <linux/kernel.h>
26#include <linux/io.h> 22#include <linux/io.h>
27 23
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/initval.h>
32#include <sound/soc.h> 24#include <sound/soc.h>
33#include <mach/hardware.h> 25#include <sound/pcm_params.h>
34 26
35#include <mach/regs-gpio.h> 27#include <mach/regs-gpio.h>
36#include <mach/dma.h> 28#include <mach/dma.h>
@@ -39,8 +31,6 @@
39#include "regs-i2s-v2.h" 31#include "regs-i2s-v2.h"
40#include "s3c2412-i2s.h" 32#include "s3c2412-i2s.h"
41 33
42#define S3C2412_I2S_DEBUG 0
43
44static struct s3c2410_dma_client s3c2412_dma_client_out = { 34static struct s3c2410_dma_client s3c2412_dma_client_out = {
45 .name = "I2S PCM Stereo out" 35 .name = "I2S PCM Stereo out"
46}; 36};
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 13e41ed8e22b..63d8849d80bd 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -14,28 +14,16 @@
14 * option) any later version. 14 * option) any later version.
15 */ 15 */
16 16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/device.h>
20#include <linux/delay.h> 17#include <linux/delay.h>
21#include <linux/clk.h> 18#include <linux/clk.h>
22#include <linux/jiffies.h>
23#include <linux/io.h> 19#include <linux/io.h>
24#include <linux/gpio.h> 20#include <linux/gpio.h>
25 21
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/initval.h>
30#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/pcm_params.h>
31 24
32#include <mach/hardware.h>
33#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h>
35
36#include <asm/dma.h>
37#include <mach/dma.h> 26#include <mach/dma.h>
38
39#include <plat/regs-iis.h> 27#include <plat/regs-iis.h>
40 28
41#include "dma.h" 29#include "dma.h"
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index a434032d1832..349566f0686b 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -7,20 +7,13 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/platform_device.h>
13#include <linux/gpio.h> 10#include <linux/gpio.h>
14#include <linux/clk.h> 11#include <linux/clk.h>
15#include <linux/i2c.h>
16 12
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h> 13#include <sound/soc.h>
20 14
21#include <plat/audio-simtec.h> 15#include <plat/audio-simtec.h>
22 16
23#include "dma.h"
24#include "s3c24xx-i2s.h" 17#include "s3c24xx-i2s.h"
25#include "s3c24xx_simtec.h" 18#include "s3c24xx_simtec.h"
26 19
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index 08fcaaa66907..ce6aef604179 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -7,18 +7,8 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h> 10#include <sound/soc.h>
17 11
18#include <plat/audio-simtec.h>
19
20#include "dma.h"
21#include "s3c24xx-i2s.h"
22#include "s3c24xx_simtec.h" 12#include "s3c24xx_simtec.h"
23 13
24static const struct snd_soc_dapm_widget dapm_widgets[] = { 14static const struct snd_soc_dapm_widget dapm_widgets[] = {
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index 116e3e670167..a7ef7db54687 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -7,22 +7,10 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h> 10#include <sound/soc.h>
17 11
18#include <plat/audio-simtec.h>
19
20#include "dma.h"
21#include "s3c24xx-i2s.h"
22#include "s3c24xx_simtec.h" 12#include "s3c24xx_simtec.h"
23 13
24#include "../codecs/tlv320aic23.h"
25
26/* supported machines: 14/* supported machines:
27 * 15 *
28 * Machine Connections AMP 16 * Machine Connections AMP
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 2c09e93dd566..3cb700751078 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -11,22 +11,15 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/clk.h> 14#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h> 15#include <linux/gpio.h>
18#include <sound/pcm.h> 16
19#include <sound/pcm_params.h>
20#include <sound/soc.h> 17#include <sound/soc.h>
21#include <sound/s3c24xx_uda134x.h> 18#include <sound/s3c24xx_uda134x.h>
22#include <sound/uda134x.h>
23 19
24#include <plat/regs-iis.h> 20#include <plat/regs-iis.h>
25 21
26#include "dma.h"
27#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
28#include "../codecs/uda134x.h"
29
30 23
31/* #define ENFORCE_RATES 1 */ 24/* #define ENFORCE_RATES 1 */
32/* 25/*
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 61e2b5219d42..0a2c4f223038 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -13,20 +13,14 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/gpio.h> 16#include <linux/gpio.h>
19 17
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h> 18#include <sound/soc.h>
23#include <sound/jack.h> 19#include <sound/jack.h>
24 20
25#include <asm/mach-types.h> 21#include <asm/mach-types.h>
26 22
27#include "dma.h"
28#include "i2s.h" 23#include "i2s.h"
29
30#include "../codecs/wm8750.h" 24#include "../codecs/wm8750.h"
31 25
32/* 26/*
diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 3be7e7e92d6e..3a0dbfc793f0 100644
--- a/sound/soc/samsung/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -12,15 +12,8 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/module.h>
16#include <linux/device.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h> 15#include <sound/soc.h>
20 16
21#include "dma.h"
22#include "ac97.h"
23
24static struct snd_soc_card smdk2443; 17static struct snd_soc_card smdk2443;
25 18
26static struct snd_soc_dai_link smdk2443_dai[] = { 19static struct snd_soc_dai_link smdk2443_dai[] = {
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index b5c3fad01bb8..e8ac961c6ba1 100644
--- a/sound/soc/samsung/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -10,15 +10,10 @@
10 * 10 *
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/device.h>
15#include <linux/clk.h> 13#include <linux/clk.h>
16 14
17#include <plat/devs.h>
18
19#include <sound/soc.h> 15#include <sound/soc.h>
20 16
21#include "dma.h"
22#include "spdif.h" 17#include "spdif.h"
23 18
24/* Audio clock settings are belonged to board specific part. Every 19/* Audio clock settings are belonged to board specific part. Every
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index b2cff1a44aed..8aacf23d6f3a 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -10,17 +10,12 @@
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12 12
13#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h> 13#include <sound/soc.h>
14#include <sound/pcm_params.h>
19 15
20#include <asm/mach-types.h> 16#include <asm/mach-types.h>
21 17
22#include "../codecs/wm8580.h" 18#include "../codecs/wm8580.h"
23#include "dma.h"
24#include "i2s.h" 19#include "i2s.h"
25 20
26/* 21/*
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index ae5fed6f772f..fffe3c1dd1bd 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -11,13 +11,8 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <sound/soc.h> 14#include <sound/soc.h>
17 15
18#include "dma.h"
19#include "ac97.h"
20
21static struct snd_soc_card smdk; 16static struct snd_soc_card smdk;
22 17
23/* 18/*
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index f0816404ea3e..28c491dacf7a 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -13,9 +13,8 @@
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/io.h> 14#include <linux/io.h>
15 15
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/pcm_params.h>
19 18
20#include <plat/audio.h> 19#include <plat/audio.h>
21#include <mach/dma.h> 20#include <mach/dma.h>
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index a14820ac9665..d6f4703b3c07 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -18,18 +18,26 @@ struct fsi_ak4642_data {
18 const char *cpu_dai; 18 const char *cpu_dai;
19 const char *codec; 19 const char *codec;
20 const char *platform; 20 const char *platform;
21 int id;
21}; 22};
22 23
23static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) 24static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
24{ 25{
25 struct snd_soc_dai *dai = rtd->codec_dai; 26 struct snd_soc_dai *codec = rtd->codec_dai;
27 struct snd_soc_dai *cpu = rtd->cpu_dai;
26 int ret; 28 int ret;
27 29
28 ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM); 30 ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
31 SND_SOC_DAIFMT_CBM_CFM);
29 if (ret < 0) 32 if (ret < 0)
30 return ret; 33 return ret;
31 34
32 ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0); 35 ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
36 if (ret < 0)
37 return ret;
38
39 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
40 SND_SOC_DAIFMT_CBS_CFS);
33 41
34 return ret; 42 return ret;
35} 43}
@@ -60,7 +68,7 @@ static int fsi_ak4642_probe(struct platform_device *pdev)
60 68
61 pdata = (struct fsi_ak4642_data *)id_entry->driver_data; 69 pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
62 70
63 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A); 71 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
64 if (!fsi_snd_device) 72 if (!fsi_snd_device)
65 goto out; 73 goto out;
66 74
@@ -93,6 +101,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = {
93 .cpu_dai = "fsia-dai", 101 .cpu_dai = "fsia-dai",
94 .codec = "ak4642-codec.0-0012", 102 .codec = "ak4642-codec.0-0012",
95 .platform = "sh_fsi.0", 103 .platform = "sh_fsi.0",
104 .id = FSI_PORT_A,
96}; 105};
97 106
98static struct fsi_ak4642_data fsi_b_ak4642 = { 107static struct fsi_ak4642_data fsi_b_ak4642 = {
@@ -101,6 +110,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = {
101 .cpu_dai = "fsib-dai", 110 .cpu_dai = "fsib-dai",
102 .codec = "ak4642-codec.0-0012", 111 .codec = "ak4642-codec.0-0012",
103 .platform = "sh_fsi.0", 112 .platform = "sh_fsi.0",
113 .id = FSI_PORT_B,
104}; 114};
105 115
106static struct fsi_ak4642_data fsi_a_ak4643 = { 116static struct fsi_ak4642_data fsi_a_ak4643 = {
@@ -109,6 +119,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = {
109 .cpu_dai = "fsia-dai", 119 .cpu_dai = "fsia-dai",
110 .codec = "ak4642-codec.0-0013", 120 .codec = "ak4642-codec.0-0013",
111 .platform = "sh_fsi.0", 121 .platform = "sh_fsi.0",
122 .id = FSI_PORT_A,
112}; 123};
113 124
114static struct fsi_ak4642_data fsi_b_ak4643 = { 125static struct fsi_ak4642_data fsi_b_ak4643 = {
@@ -117,6 +128,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = {
117 .cpu_dai = "fsib-dai", 128 .cpu_dai = "fsib-dai",
118 .codec = "ak4642-codec.0-0013", 129 .codec = "ak4642-codec.0-0013",
119 .platform = "sh_fsi.0", 130 .platform = "sh_fsi.0",
131 .id = FSI_PORT_B,
120}; 132};
121 133
122static struct fsi_ak4642_data fsi2_a_ak4642 = { 134static struct fsi_ak4642_data fsi2_a_ak4642 = {
@@ -125,6 +137,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = {
125 .cpu_dai = "fsia-dai", 137 .cpu_dai = "fsia-dai",
126 .codec = "ak4642-codec.0-0012", 138 .codec = "ak4642-codec.0-0012",
127 .platform = "sh_fsi2", 139 .platform = "sh_fsi2",
140 .id = FSI_PORT_A,
128}; 141};
129 142
130static struct fsi_ak4642_data fsi2_b_ak4642 = { 143static struct fsi_ak4642_data fsi2_b_ak4642 = {
@@ -133,6 +146,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = {
133 .cpu_dai = "fsib-dai", 146 .cpu_dai = "fsib-dai",
134 .codec = "ak4642-codec.0-0012", 147 .codec = "ak4642-codec.0-0012",
135 .platform = "sh_fsi2", 148 .platform = "sh_fsi2",
149 .id = FSI_PORT_B,
136}; 150};
137 151
138static struct fsi_ak4642_data fsi2_a_ak4643 = { 152static struct fsi_ak4642_data fsi2_a_ak4643 = {
@@ -141,6 +155,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = {
141 .cpu_dai = "fsia-dai", 155 .cpu_dai = "fsia-dai",
142 .codec = "ak4642-codec.0-0013", 156 .codec = "ak4642-codec.0-0013",
143 .platform = "sh_fsi2", 157 .platform = "sh_fsi2",
158 .id = FSI_PORT_A,
144}; 159};
145 160
146static struct fsi_ak4642_data fsi2_b_ak4643 = { 161static struct fsi_ak4642_data fsi2_b_ak4643 = {
@@ -149,6 +164,7 @@ static struct fsi_ak4642_data fsi2_b_ak4643 = {
149 .cpu_dai = "fsib-dai", 164 .cpu_dai = "fsib-dai",
150 .codec = "ak4642-codec.0-0013", 165 .codec = "ak4642-codec.0-0013",
151 .platform = "sh_fsi2", 166 .platform = "sh_fsi2",
167 .id = FSI_PORT_B,
152}; 168};
153 169
154static struct platform_device_id fsi_id_table[] = { 170static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index e8df9da92f71..dbafd7ac5590 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -15,11 +15,20 @@
15 15
16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) 16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
17{ 17{
18 struct snd_soc_dai *dai = rtd->codec_dai; 18 struct snd_soc_dai *codec = rtd->codec_dai;
19 struct snd_soc_dai *cpu = rtd->cpu_dai;
20 int ret;
19 21
20 return snd_soc_dai_set_fmt(dai, 22 ret = snd_soc_dai_set_fmt(codec,
21 SND_SOC_DAIFMT_I2S | 23 SND_SOC_DAIFMT_I2S |
22 SND_SOC_DAIFMT_CBM_CFM); 24 SND_SOC_DAIFMT_CBM_CFM);
25 if (ret < 0)
26 return ret;
27
28 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
29 SND_SOC_DAIFMT_CBS_CFS);
30
31 return ret;
23} 32}
24 33
25static struct snd_soc_dai_link fsi_da7210_dai = { 34static struct snd_soc_dai_link fsi_da7210_dai = {
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
index a52dd8ec71d3..9719985eb82d 100644
--- a/sound/soc/sh/fsi-hdmi.c
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -12,31 +12,59 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14 14
15struct fsi_hdmi_data {
16 const char *cpu_dai;
17 const char *card;
18 int id;
19};
20
21static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
22{
23 struct snd_soc_dai *cpu = rtd->cpu_dai;
24 int ret;
25
26 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
27
28 return ret;
29}
30
15static struct snd_soc_dai_link fsi_dai_link = { 31static struct snd_soc_dai_link fsi_dai_link = {
16 .name = "HDMI", 32 .name = "HDMI",
17 .stream_name = "HDMI", 33 .stream_name = "HDMI",
18 .cpu_dai_name = "fsib-dai", /* fsi B */
19 .codec_dai_name = "sh_mobile_hdmi-hifi", 34 .codec_dai_name = "sh_mobile_hdmi-hifi",
20 .platform_name = "sh_fsi2", 35 .platform_name = "sh_fsi2",
21 .codec_name = "sh-mobile-hdmi", 36 .codec_name = "sh-mobile-hdmi",
37 .init = fsi_hdmi_dai_init,
22}; 38};
23 39
24static struct snd_soc_card fsi_soc_card = { 40static struct snd_soc_card fsi_soc_card = {
25 .name = "FSI (SH MOBILE HDMI)",
26 .dai_link = &fsi_dai_link, 41 .dai_link = &fsi_dai_link,
27 .num_links = 1, 42 .num_links = 1,
28}; 43};
29 44
30static struct platform_device *fsi_snd_device; 45static struct platform_device *fsi_snd_device;
31 46
32static int __init fsi_hdmi_init(void) 47static int fsi_hdmi_probe(struct platform_device *pdev)
33{ 48{
34 int ret = -ENOMEM; 49 int ret = -ENOMEM;
50 const struct platform_device_id *id_entry;
51 struct fsi_hdmi_data *pdata;
52
53 id_entry = pdev->id_entry;
54 if (!id_entry) {
55 dev_err(&pdev->dev, "unknown fsi hdmi\n");
56 return -ENODEV;
57 }
35 58
36 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); 59 pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
60
61 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
37 if (!fsi_snd_device) 62 if (!fsi_snd_device)
38 goto out; 63 goto out;
39 64
65 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
66 fsi_soc_card.name = pdata->card;
67
40 platform_set_drvdata(fsi_snd_device, &fsi_soc_card); 68 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
41 ret = platform_device_add(fsi_snd_device); 69 ret = platform_device_add(fsi_snd_device);
42 70
@@ -47,9 +75,48 @@ out:
47 return ret; 75 return ret;
48} 76}
49 77
50static void __exit fsi_hdmi_exit(void) 78static int fsi_hdmi_remove(struct platform_device *pdev)
51{ 79{
52 platform_device_unregister(fsi_snd_device); 80 platform_device_unregister(fsi_snd_device);
81 return 0;
82}
83
84static struct fsi_hdmi_data fsi2_a_hdmi = {
85 .cpu_dai = "fsia-dai",
86 .card = "FSI2A (SH MOBILE HDMI)",
87 .id = FSI_PORT_A,
88};
89
90static struct fsi_hdmi_data fsi2_b_hdmi = {
91 .cpu_dai = "fsib-dai",
92 .card = "FSI2B (SH MOBILE HDMI)",
93 .id = FSI_PORT_B,
94};
95
96static struct platform_device_id fsi_id_table[] = {
97 /* FSI 2 */
98 { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
99 { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
100 {},
101};
102
103static struct platform_driver fsi_hdmi = {
104 .driver = {
105 .name = "fsi-hdmi-audio",
106 },
107 .probe = fsi_hdmi_probe,
108 .remove = fsi_hdmi_remove,
109 .id_table = fsi_id_table,
110};
111
112static int __init fsi_hdmi_init(void)
113{
114 return platform_driver_register(&fsi_hdmi);
115}
116
117static void __exit fsi_hdmi_exit(void)
118{
119 platform_driver_unregister(&fsi_hdmi);
53} 120}
54 121
55module_init(fsi_hdmi_init); 122module_init(fsi_hdmi_init);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2b06402801ef..0c9997e2d8c0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -78,6 +78,8 @@
78/* CKG1 */ 78/* CKG1 */
79#define ACKMD_MASK 0x00007000 79#define ACKMD_MASK 0x00007000
80#define BPFMD_MASK 0x00000700 80#define BPFMD_MASK 0x00000700
81#define DIMD (1 << 4)
82#define DOMD (1 << 0)
81 83
82/* A/B MST_CTLR */ 84/* A/B MST_CTLR */
83#define BP (1 << 4) /* Fix the signal of Biphase output */ 85#define BP (1 << 4) /* Fix the signal of Biphase output */
@@ -111,6 +113,8 @@
111 113
112#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 114#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
113 115
116typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
117
114/* 118/*
115 * FSI driver use below type name for variable 119 * FSI driver use below type name for variable
116 * 120 *
@@ -128,7 +132,6 @@ struct fsi_stream {
128 struct snd_pcm_substream *substream; 132 struct snd_pcm_substream *substream;
129 133
130 int fifo_max_num; 134 int fifo_max_num;
131 int chan_num;
132 135
133 int buff_offset; 136 int buff_offset;
134 int buff_len; 137 int buff_len;
@@ -143,6 +146,7 @@ struct fsi_priv {
143 void __iomem *base; 146 void __iomem *base;
144 struct fsi_master *master; 147 struct fsi_master *master;
145 148
149 int chan_num;
146 struct fsi_stream playback; 150 struct fsi_stream playback;
147 struct fsi_stream capture; 151 struct fsi_stream capture;
148 152
@@ -252,9 +256,8 @@ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
252 return rtd->cpu_dai; 256 return rtd->cpu_dai;
253} 257}
254 258
255static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) 259static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai)
256{ 260{
257 struct snd_soc_dai *dai = fsi_get_dai(substream);
258 struct fsi_master *master = snd_soc_dai_get_drvdata(dai); 261 struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
259 262
260 if (dai->id == 0) 263 if (dai->id == 0)
@@ -263,11 +266,27 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
263 return &master->fsib; 266 return &master->fsib;
264} 267}
265 268
269static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
270{
271 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
272}
273
274static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
275{
276 if (!master->info)
277 return NULL;
278
279 return master->info->set_rate;
280}
281
266static u32 fsi_get_info_flags(struct fsi_priv *fsi) 282static u32 fsi_get_info_flags(struct fsi_priv *fsi)
267{ 283{
268 int is_porta = fsi_is_port_a(fsi); 284 int is_porta = fsi_is_port_a(fsi);
269 struct fsi_master *master = fsi_get_master(fsi); 285 struct fsi_master *master = fsi_get_master(fsi);
270 286
287 if (!master->info)
288 return 0;
289
271 return is_porta ? master->info->porta_flags : 290 return is_porta ? master->info->porta_flags :
272 master->info->portb_flags; 291 master->info->portb_flags;
273} 292}
@@ -288,21 +307,6 @@ static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
288 return is_play ? &fsi->playback : &fsi->capture; 307 return is_play ? &fsi->playback : &fsi->capture;
289} 308}
290 309
291static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
292{
293 u32 mode;
294 u32 flags = fsi_get_info_flags(fsi);
295
296 mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
297
298 /* return
299 * 1 : master mode
300 * 0 : slave mode
301 */
302
303 return (mode & flags) != mode;
304}
305
306static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) 310static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
307{ 311{
308 int is_porta = fsi_is_port_a(fsi); 312 int is_porta = fsi_is_port_a(fsi);
@@ -357,7 +361,6 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 361static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
358{ 362{
359 u32 status; 363 u32 status;
360 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
361 int data_num; 364 int data_num;
362 365
363 status = is_play ? 366 status = is_play ?
@@ -365,7 +368,7 @@ static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
365 fsi_reg_read(fsi, DIFF_ST); 368 fsi_reg_read(fsi, DIFF_ST);
366 369
367 data_num = 0x1ff & (status >> 8); 370 data_num = 0x1ff & (status >> 8);
368 data_num *= io->chan_num; 371 data_num *= fsi->chan_num;
369 372
370 return data_num; 373 return data_num;
371} 374}
@@ -387,7 +390,7 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
387 struct snd_pcm_substream *substream = io->substream; 390 struct snd_pcm_substream *substream = io->substream;
388 struct snd_pcm_runtime *runtime = substream->runtime; 391 struct snd_pcm_runtime *runtime = substream->runtime;
389 392
390 return frames_to_bytes(runtime, 1) / io->chan_num; 393 return frames_to_bytes(runtime, 1) / fsi->chan_num;
391} 394}
392 395
393static void fsi_count_fifo_err(struct fsi_priv *fsi) 396static void fsi_count_fifo_err(struct fsi_priv *fsi)
@@ -580,10 +583,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
580 * 7 channels: 32 ( 32 x 7 = 224) 583 * 7 channels: 32 ( 32 x 7 = 224)
581 * 8 channels: 32 ( 32 x 8 = 256) 584 * 8 channels: 32 ( 32 x 8 = 256)
582 */ 585 */
583 for (i = 1; i < io->chan_num; i <<= 1) 586 for (i = 1; i < fsi->chan_num; i <<= 1)
584 io->fifo_max_num >>= 1; 587 io->fifo_max_num >>= 1;
585 dev_dbg(dai->dev, "%d channel %d store\n", 588 dev_dbg(dai->dev, "%d channel %d store\n",
586 io->chan_num, io->fifo_max_num); 589 fsi->chan_num, io->fifo_max_num);
587 590
588 /* 591 /*
589 * set interrupt generation factor 592 * set interrupt generation factor
@@ -659,7 +662,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
659 * data_num_max : number of FSI fifo free space 662 * data_num_max : number of FSI fifo free space
660 * data_num : number of ALSA residue data 663 * data_num : number of ALSA residue data
661 */ 664 */
662 data_num_max = io->fifo_max_num * io->chan_num; 665 data_num_max = io->fifo_max_num * fsi->chan_num;
663 data_num_max -= fsi_get_fifo_data_num(fsi, is_play); 666 data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
664 667
665 data_num = data_residue_num; 668 data_num = data_residue_num;
@@ -754,25 +757,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
754 struct snd_soc_dai *dai) 757 struct snd_soc_dai *dai)
755{ 758{
756 struct fsi_priv *fsi = fsi_get_priv(substream); 759 struct fsi_priv *fsi = fsi_get_priv(substream);
757 struct fsi_master *master = fsi_get_master(fsi);
758 struct fsi_stream *io;
759 u32 flags = fsi_get_info_flags(fsi); 760 u32 flags = fsi_get_info_flags(fsi);
760 u32 fmt;
761 u32 data; 761 u32 data;
762 int is_play = fsi_is_play(substream); 762 int is_play = fsi_is_play(substream);
763 int is_master;
764
765 io = fsi_get_stream(fsi, is_play);
766 763
767 pm_runtime_get_sync(dai->dev); 764 pm_runtime_get_sync(dai->dev);
768 765
769 /* CKG1 */
770 data = is_play ? (1 << 0) : (1 << 4);
771 is_master = fsi_is_master_mode(fsi, is_play);
772 if (is_master)
773 fsi_reg_mask_set(fsi, CKG1, data, data);
774 else
775 fsi_reg_mask_set(fsi, CKG1, data, 0);
776 766
777 /* clock inversion (CKG2) */ 767 /* clock inversion (CKG2) */
778 data = 0; 768 data = 0;
@@ -787,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
787 777
788 fsi_reg_write(fsi, CKG2, data); 778 fsi_reg_write(fsi, CKG2, data);
789 779
790 /* do fmt, di fmt */
791 data = 0;
792 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
793 switch (fmt) {
794 case SH_FSI_FMT_MONO:
795 data = CR_MONO;
796 io->chan_num = 1;
797 break;
798 case SH_FSI_FMT_MONO_DELAY:
799 data = CR_MONO_D;
800 io->chan_num = 1;
801 break;
802 case SH_FSI_FMT_PCM:
803 data = CR_PCM;
804 io->chan_num = 2;
805 break;
806 case SH_FSI_FMT_I2S:
807 data = CR_I2S;
808 io->chan_num = 2;
809 break;
810 case SH_FSI_FMT_TDM:
811 io->chan_num = is_play ?
812 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
813 data = CR_TDM | (io->chan_num - 1);
814 break;
815 case SH_FSI_FMT_TDM_DELAY:
816 io->chan_num = is_play ?
817 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
818 data = CR_TDM_D | (io->chan_num - 1);
819 break;
820 case SH_FSI_FMT_SPDIF:
821 if (master->core->ver < 2) {
822 dev_err(dai->dev, "This FSI can not use SPDIF\n");
823 return -EINVAL;
824 }
825 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
826 io->chan_num = 2;
827 fsi_spdif_clk_ctrl(fsi, 1);
828 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
829 break;
830 default:
831 dev_err(dai->dev, "unknown format.\n");
832 return -EINVAL;
833 }
834 is_play ?
835 fsi_reg_write(fsi, DO_FMT, data) :
836 fsi_reg_write(fsi, DI_FMT, data);
837
838 /* irq clear */ 780 /* irq clear */
839 fsi_irq_disable(fsi, is_play); 781 fsi_irq_disable(fsi, is_play);
840 fsi_irq_clear_status(fsi); 782 fsi_irq_clear_status(fsi);
@@ -851,12 +793,12 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
851 struct fsi_priv *fsi = fsi_get_priv(substream); 793 struct fsi_priv *fsi = fsi_get_priv(substream);
852 int is_play = fsi_is_play(substream); 794 int is_play = fsi_is_play(substream);
853 struct fsi_master *master = fsi_get_master(fsi); 795 struct fsi_master *master = fsi_get_master(fsi);
854 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 796 set_rate_func set_rate;
855 797
856 fsi_irq_disable(fsi, is_play); 798 fsi_irq_disable(fsi, is_play);
857 fsi_clk_ctrl(fsi, 0); 799 fsi_clk_ctrl(fsi, 0);
858 800
859 set_rate = master->info->set_rate; 801 set_rate = fsi_get_info_set_rate(master);
860 if (set_rate && fsi->rate) 802 if (set_rate && fsi->rate)
861 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
862 fsi->rate = 0; 804 fsi->rate = 0;
@@ -889,18 +831,100 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
889 return ret; 831 return ret;
890} 832}
891 833
834static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
835{
836 u32 data = 0;
837
838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
839 case SND_SOC_DAIFMT_I2S:
840 data = CR_I2S;
841 fsi->chan_num = 2;
842 break;
843 case SND_SOC_DAIFMT_LEFT_J:
844 data = CR_PCM;
845 fsi->chan_num = 2;
846 break;
847 default:
848 return -EINVAL;
849 }
850
851 fsi_reg_write(fsi, DO_FMT, data);
852 fsi_reg_write(fsi, DI_FMT, data);
853
854 return 0;
855}
856
857static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
858{
859 struct fsi_master *master = fsi_get_master(fsi);
860 u32 data = 0;
861
862 if (master->core->ver < 2)
863 return -EINVAL;
864
865 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
866 fsi->chan_num = 2;
867 fsi_spdif_clk_ctrl(fsi, 1);
868 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
869
870 fsi_reg_write(fsi, DO_FMT, data);
871 fsi_reg_write(fsi, DI_FMT, data);
872
873 return 0;
874}
875
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
879 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0;
881 int ret;
882
883 pm_runtime_get_sync(dai->dev);
884
885 /* set master/slave audio interface */
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD;
889 break;
890 case SND_SOC_DAIFMT_CBS_CFS:
891 break;
892 default:
893 ret = -EINVAL;
894 goto set_fmt_exit;
895 }
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897
898 /* set format */
899 switch (flags & SH_FSI_FMT_MASK) {
900 case SH_FSI_FMT_DAI:
901 ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
902 break;
903 case SH_FSI_FMT_SPDIF:
904 ret = fsi_set_fmt_spdif(fsi);
905 break;
906 default:
907 ret = -EINVAL;
908 }
909
910set_fmt_exit:
911 pm_runtime_put_sync(dai->dev);
912
913 return ret;
914}
915
892static int fsi_dai_hw_params(struct snd_pcm_substream *substream, 916static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
893 struct snd_pcm_hw_params *params, 917 struct snd_pcm_hw_params *params,
894 struct snd_soc_dai *dai) 918 struct snd_soc_dai *dai)
895{ 919{
896 struct fsi_priv *fsi = fsi_get_priv(substream); 920 struct fsi_priv *fsi = fsi_get_priv(substream);
897 struct fsi_master *master = fsi_get_master(fsi); 921 struct fsi_master *master = fsi_get_master(fsi);
898 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 922 set_rate_func set_rate;
899 int fsi_ver = master->core->ver; 923 int fsi_ver = master->core->ver;
900 long rate = params_rate(params); 924 long rate = params_rate(params);
901 int ret; 925 int ret;
902 926
903 set_rate = master->info->set_rate; 927 set_rate = fsi_get_info_set_rate(master);
904 if (!set_rate) 928 if (!set_rate)
905 return 0; 929 return 0;
906 930
@@ -975,6 +999,7 @@ static struct snd_soc_dai_ops fsi_dai_ops = {
975 .startup = fsi_dai_startup, 999 .startup = fsi_dai_startup,
976 .shutdown = fsi_dai_shutdown, 1000 .shutdown = fsi_dai_shutdown,
977 .trigger = fsi_dai_trigger, 1001 .trigger = fsi_dai_trigger,
1002 .set_fmt = fsi_dai_set_fmt,
978 .hw_params = fsi_dai_hw_params, 1003 .hw_params = fsi_dai_hw_params,
979}; 1004};
980 1005
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 8c2a21a978ac..5d76da43b14c 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -18,6 +18,8 @@
18#include <linux/bitmap.h> 18#include <linux/bitmap.h>
19#include <linux/rbtree.h> 19#include <linux/rbtree.h>
20 20
21#include <trace/events/asoc.h>
22
21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
22 unsigned int reg) 24 unsigned int reg)
23{ 25{
@@ -25,7 +27,8 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
25 unsigned int val; 27 unsigned int val;
26 28
27 if (reg >= codec->driver->reg_cache_size || 29 if (reg >= codec->driver->reg_cache_size ||
28 snd_soc_codec_volatile_register(codec, reg)) { 30 snd_soc_codec_volatile_register(codec, reg) ||
31 codec->cache_bypass) {
29 if (codec->cache_only) 32 if (codec->cache_only)
30 return -1; 33 return -1;
31 34
@@ -49,7 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
49 data[1] = value & 0x00ff; 52 data[1] = value & 0x00ff;
50 53
51 if (!snd_soc_codec_volatile_register(codec, reg) && 54 if (!snd_soc_codec_volatile_register(codec, reg) &&
52 reg < codec->driver->reg_cache_size) { 55 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) {
53 ret = snd_soc_cache_write(codec, reg, value); 57 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0) 58 if (ret < 0)
55 return -1; 59 return -1;
@@ -106,7 +110,8 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
106 unsigned int val; 110 unsigned int val;
107 111
108 if (reg >= codec->driver->reg_cache_size || 112 if (reg >= codec->driver->reg_cache_size ||
109 snd_soc_codec_volatile_register(codec, reg)) { 113 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) {
110 if (codec->cache_only) 115 if (codec->cache_only)
111 return -1; 116 return -1;
112 117
@@ -130,7 +135,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
130 data[1] = value & 0x00ff; 135 data[1] = value & 0x00ff;
131 136
132 if (!snd_soc_codec_volatile_register(codec, reg) && 137 if (!snd_soc_codec_volatile_register(codec, reg) &&
133 reg < codec->driver->reg_cache_size) { 138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
134 ret = snd_soc_cache_write(codec, reg, value); 140 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0) 141 if (ret < 0)
136 return -1; 142 return -1;
@@ -191,7 +197,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
191 data[1] = value & 0xff; 197 data[1] = value & 0xff;
192 198
193 if (!snd_soc_codec_volatile_register(codec, reg) && 199 if (!snd_soc_codec_volatile_register(codec, reg) &&
194 reg < codec->driver->reg_cache_size) { 200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
195 ret = snd_soc_cache_write(codec, reg, value); 202 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0) 203 if (ret < 0)
197 return -1; 204 return -1;
@@ -216,7 +223,8 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
216 223
217 reg &= 0xff; 224 reg &= 0xff;
218 if (reg >= codec->driver->reg_cache_size || 225 if (reg >= codec->driver->reg_cache_size ||
219 snd_soc_codec_volatile_register(codec, reg)) { 226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
220 if (codec->cache_only) 228 if (codec->cache_only)
221 return -1; 229 return -1;
222 230
@@ -271,7 +279,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
271 data[2] = value & 0xff; 279 data[2] = value & 0xff;
272 280
273 if (!snd_soc_codec_volatile_register(codec, reg) && 281 if (!snd_soc_codec_volatile_register(codec, reg) &&
274 reg < codec->driver->reg_cache_size) { 282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
275 ret = snd_soc_cache_write(codec, reg, value); 284 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0) 285 if (ret < 0)
277 return -1; 286 return -1;
@@ -295,7 +304,8 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
295 unsigned int val; 304 unsigned int val;
296 305
297 if (reg >= codec->driver->reg_cache_size || 306 if (reg >= codec->driver->reg_cache_size ||
298 snd_soc_codec_volatile_register(codec, reg)) { 307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
299 if (codec->cache_only) 309 if (codec->cache_only)
300 return -1; 310 return -1;
301 311
@@ -450,7 +460,8 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
450 460
451 reg &= 0xff; 461 reg &= 0xff;
452 if (reg >= codec->driver->reg_cache_size || 462 if (reg >= codec->driver->reg_cache_size ||
453 snd_soc_codec_volatile_register(codec, reg)) { 463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
454 if (codec->cache_only) 465 if (codec->cache_only)
455 return -1; 466 return -1;
456 467
@@ -476,7 +487,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
476 487
477 reg &= 0xff; 488 reg &= 0xff;
478 if (!snd_soc_codec_volatile_register(codec, reg) && 489 if (!snd_soc_codec_volatile_register(codec, reg) &&
479 reg < codec->driver->reg_cache_size) { 490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
480 ret = snd_soc_cache_write(codec, reg, value); 492 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0) 493 if (ret < 0)
482 return -1; 494 return -1;
@@ -568,7 +580,8 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
568 unsigned int val; 580 unsigned int val;
569 581
570 if (reg >= codec->driver->reg_cache_size || 582 if (reg >= codec->driver->reg_cache_size ||
571 snd_soc_codec_volatile_register(codec, reg)) { 583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
572 if (codec->cache_only) 585 if (codec->cache_only)
573 return -1; 586 return -1;
574 587
@@ -595,7 +608,8 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
595 data[3] = value & 0xff; 608 data[3] = value & 0xff;
596 609
597 if (!snd_soc_codec_volatile_register(codec, reg) && 610 if (!snd_soc_codec_volatile_register(codec, reg) &&
598 reg < codec->driver->reg_cache_size) { 611 reg < codec->driver->reg_cache_size &&
612 !codec->cache_bypass) {
599 ret = snd_soc_cache_write(codec, reg, value); 613 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0) 614 if (ret < 0)
601 return -1; 615 return -1;
@@ -761,6 +775,49 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
761} 775}
762EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 776EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
763 777
778static bool snd_soc_set_cache_val(void *base, unsigned int idx,
779 unsigned int val, unsigned int word_size)
780{
781 switch (word_size) {
782 case 1: {
783 u8 *cache = base;
784 if (cache[idx] == val)
785 return true;
786 cache[idx] = val;
787 break;
788 }
789 case 2: {
790 u16 *cache = base;
791 if (cache[idx] == val)
792 return true;
793 cache[idx] = val;
794 break;
795 }
796 default:
797 BUG();
798 }
799 return false;
800}
801
802static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
803 unsigned int word_size)
804{
805 switch (word_size) {
806 case 1: {
807 const u8 *cache = base;
808 return cache[idx];
809 }
810 case 2: {
811 const u16 *cache = base;
812 return cache[idx];
813 }
814 default:
815 BUG();
816 }
817 /* unreachable */
818 return -1;
819}
820
764struct snd_soc_rbtree_node { 821struct snd_soc_rbtree_node {
765 struct rb_node node; 822 struct rb_node node;
766 unsigned int reg; 823 unsigned int reg;
@@ -835,7 +892,9 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
835 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 892 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
836 if (ret) 893 if (ret)
837 return ret; 894 return ret;
895 codec->cache_bypass = 1;
838 ret = snd_soc_write(codec, rbnode->reg, val); 896 ret = snd_soc_write(codec, rbnode->reg, val);
897 codec->cache_bypass = 0;
839 if (ret) 898 if (ret)
840 return ret; 899 return ret;
841 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 900 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -924,7 +983,12 @@ static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
924 983
925static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) 984static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
926{ 985{
986 struct snd_soc_rbtree_node *rbtree_node;
927 struct snd_soc_rbtree_ctx *rbtree_ctx; 987 struct snd_soc_rbtree_ctx *rbtree_ctx;
988 unsigned int val;
989 unsigned int word_size;
990 int i;
991 int ret;
928 992
929 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); 993 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
930 if (!codec->reg_cache) 994 if (!codec->reg_cache)
@@ -936,53 +1000,25 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
936 if (!codec->reg_def_copy) 1000 if (!codec->reg_def_copy)
937 return 0; 1001 return 0;
938 1002
939/* 1003 /*
940 * populate the rbtree with the initialized registers. All other 1004 * populate the rbtree with the initialized registers. All other
941 * registers will be inserted into the tree when they are first written. 1005 * registers will be inserted when they are first modified.
942 * 1006 */
943 * The reasoning behind this, is that we need to step through and 1007 word_size = codec->driver->reg_word_size;
944 * dereference the cache in u8/u16 increments without sacrificing 1008 for (i = 0; i < codec->driver->reg_cache_size; ++i) {
945 * portability. This could also be done using memcpy() but that would 1009 val = snd_soc_get_cache_val(codec->reg_def_copy, i, word_size);
946 * be slightly more cryptic. 1010 if (!val)
947 */ 1011 continue;
948#define snd_soc_rbtree_populate(cache) \ 1012 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL);
949({ \ 1013 if (!rbtree_node) {
950 int ret, i; \ 1014 ret = -ENOMEM;
951 struct snd_soc_rbtree_node *rbtree_node; \ 1015 snd_soc_cache_exit(codec);
952 \ 1016 break;
953 ret = 0; \ 1017 }
954 cache = codec->reg_def_copy; \ 1018 rbtree_node->reg = i;
955 for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ 1019 rbtree_node->value = val;
956 if (!cache[i]) \ 1020 rbtree_node->defval = val;
957 continue; \ 1021 snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node);
958 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
959 if (!rbtree_node) { \
960 ret = -ENOMEM; \
961 snd_soc_cache_exit(codec); \
962 break; \
963 } \
964 rbtree_node->reg = i; \
965 rbtree_node->value = cache[i]; \
966 rbtree_node->defval = cache[i]; \
967 snd_soc_rbtree_insert(&rbtree_ctx->root, \
968 rbtree_node); \
969 } \
970 ret; \
971})
972
973 switch (codec->driver->reg_word_size) {
974 case 1: {
975 const u8 *cache;
976
977 return snd_soc_rbtree_populate(cache);
978 }
979 case 2: {
980 const u16 *cache;
981
982 return snd_soc_rbtree_populate(cache);
983 }
984 default:
985 BUG();
986 } 1022 }
987 1023
988 return 0; 1024 return 0;
@@ -1080,34 +1116,28 @@ static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1080 unsigned int reg) 1116 unsigned int reg)
1081{ 1117{
1082 const struct snd_soc_codec_driver *codec_drv; 1118 const struct snd_soc_codec_driver *codec_drv;
1083 size_t reg_size;
1084 1119
1085 codec_drv = codec->driver; 1120 codec_drv = codec->driver;
1086 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1087 return (reg * codec_drv->reg_word_size) / 1121 return (reg * codec_drv->reg_word_size) /
1088 DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); 1122 DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1089} 1123}
1090 1124
1091static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, 1125static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1092 unsigned int reg) 1126 unsigned int reg)
1093{ 1127{
1094 const struct snd_soc_codec_driver *codec_drv; 1128 const struct snd_soc_codec_driver *codec_drv;
1095 size_t reg_size;
1096 1129
1097 codec_drv = codec->driver; 1130 codec_drv = codec->driver;
1098 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1131 return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
1099 return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
1100 codec_drv->reg_word_size); 1132 codec_drv->reg_word_size);
1101} 1133}
1102 1134
1103static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 1135static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1104{ 1136{
1105 const struct snd_soc_codec_driver *codec_drv; 1137 const struct snd_soc_codec_driver *codec_drv;
1106 size_t reg_size;
1107 1138
1108 codec_drv = codec->driver; 1139 codec_drv = codec->driver;
1109 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1140 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1110 return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1111} 1141}
1112 1142
1113static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) 1143static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
@@ -1122,7 +1152,9 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1122 ret = snd_soc_cache_read(codec, i, &val); 1152 ret = snd_soc_cache_read(codec, i, &val);
1123 if (ret) 1153 if (ret)
1124 return ret; 1154 return ret;
1155 codec->cache_bypass = 1;
1125 ret = snd_soc_write(codec, i, val); 1156 ret = snd_soc_write(codec, i, val);
1157 codec->cache_bypass = 0;
1126 if (ret) 1158 if (ret)
1127 return ret; 1159 return ret;
1128 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 1160 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -1165,29 +1197,10 @@ static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1165 } 1197 }
1166 1198
1167 /* write the new value to the cache */ 1199 /* write the new value to the cache */
1168 switch (codec->driver->reg_word_size) { 1200 if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
1169 case 1: { 1201 codec->driver->reg_word_size)) {
1170 u8 *cache; 1202 kfree(lzo_block->dst);
1171 cache = lzo_block->dst; 1203 goto out;
1172 if (cache[blkpos] == value) {
1173 kfree(lzo_block->dst);
1174 goto out;
1175 }
1176 cache[blkpos] = value;
1177 }
1178 break;
1179 case 2: {
1180 u16 *cache;
1181 cache = lzo_block->dst;
1182 if (cache[blkpos] == value) {
1183 kfree(lzo_block->dst);
1184 goto out;
1185 }
1186 cache[blkpos] = value;
1187 }
1188 break;
1189 default:
1190 BUG();
1191 } 1204 }
1192 1205
1193 /* prepare the source to be the decompressed block */ 1206 /* prepare the source to be the decompressed block */
@@ -1241,25 +1254,10 @@ static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1241 1254
1242 /* decompress the block */ 1255 /* decompress the block */
1243 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); 1256 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1244 if (ret >= 0) { 1257 if (ret >= 0)
1245 /* fetch the value from the cache */ 1258 /* fetch the value from the cache */
1246 switch (codec->driver->reg_word_size) { 1259 *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
1247 case 1: { 1260 codec->driver->reg_word_size);
1248 u8 *cache;
1249 cache = lzo_block->dst;
1250 *value = cache[blkpos];
1251 }
1252 break;
1253 case 2: {
1254 u16 *cache;
1255 cache = lzo_block->dst;
1256 *value = cache[blkpos];
1257 }
1258 break;
1259 default:
1260 BUG();
1261 }
1262 }
1263 1261
1264 kfree(lzo_block->dst); 1262 kfree(lzo_block->dst);
1265 /* restore the pointer and length of the compressed block */ 1263 /* restore the pointer and length of the compressed block */
@@ -1301,7 +1299,7 @@ static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1301static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) 1299static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1302{ 1300{
1303 struct snd_soc_lzo_ctx **lzo_blocks; 1301 struct snd_soc_lzo_ctx **lzo_blocks;
1304 size_t reg_size, bmp_size; 1302 size_t bmp_size;
1305 const struct snd_soc_codec_driver *codec_drv; 1303 const struct snd_soc_codec_driver *codec_drv;
1306 int ret, tofree, i, blksize, blkcount; 1304 int ret, tofree, i, blksize, blkcount;
1307 const char *p, *end; 1305 const char *p, *end;
@@ -1309,7 +1307,6 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1309 1307
1310 ret = 0; 1308 ret = 0;
1311 codec_drv = codec->driver; 1309 codec_drv = codec->driver;
1312 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1313 1310
1314 /* 1311 /*
1315 * If we have not been given a default register cache 1312 * If we have not been given a default register cache
@@ -1321,8 +1318,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1321 tofree = 1; 1318 tofree = 1;
1322 1319
1323 if (!codec->reg_def_copy) { 1320 if (!codec->reg_def_copy) {
1324 codec->reg_def_copy = kzalloc(reg_size, 1321 codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
1325 GFP_KERNEL);
1326 if (!codec->reg_def_copy) 1322 if (!codec->reg_def_copy)
1327 return -ENOMEM; 1323 return -ENOMEM;
1328 } 1324 }
@@ -1370,7 +1366,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1370 1366
1371 blksize = snd_soc_lzo_get_blksize(codec); 1367 blksize = snd_soc_lzo_get_blksize(codec);
1372 p = codec->reg_def_copy; 1368 p = codec->reg_def_copy;
1373 end = codec->reg_def_copy + reg_size; 1369 end = codec->reg_def_copy + codec->reg_size;
1374 /* compress the register map and fill the lzo blocks */ 1370 /* compress the register map and fill the lzo blocks */
1375 for (i = 0; i < blkcount; ++i, p += blksize) { 1371 for (i = 0; i < blkcount; ++i, p += blksize) {
1376 lzo_blocks[i]->src = p; 1372 lzo_blocks[i]->src = p;
@@ -1414,28 +1410,10 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1414 ret = snd_soc_cache_read(codec, i, &val); 1410 ret = snd_soc_cache_read(codec, i, &val);
1415 if (ret) 1411 if (ret)
1416 return ret; 1412 return ret;
1417 if (codec_drv->reg_cache_default) { 1413 if (codec->reg_def_copy)
1418 switch (codec_drv->reg_word_size) { 1414 if (snd_soc_get_cache_val(codec->reg_def_copy,
1419 case 1: { 1415 i, codec_drv->reg_word_size) == val)
1420 const u8 *cache; 1416 continue;
1421
1422 cache = codec_drv->reg_cache_default;
1423 if (cache[i] == val)
1424 continue;
1425 }
1426 break;
1427 case 2: {
1428 const u16 *cache;
1429
1430 cache = codec_drv->reg_cache_default;
1431 if (cache[i] == val)
1432 continue;
1433 }
1434 break;
1435 default:
1436 BUG();
1437 }
1438 }
1439 ret = snd_soc_write(codec, i, val); 1417 ret = snd_soc_write(codec, i, val);
1440 if (ret) 1418 if (ret)
1441 return ret; 1419 return ret;
@@ -1448,50 +1426,16 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1448static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, 1426static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1449 unsigned int reg, unsigned int value) 1427 unsigned int reg, unsigned int value)
1450{ 1428{
1451 switch (codec->driver->reg_word_size) { 1429 snd_soc_set_cache_val(codec->reg_cache, reg, value,
1452 case 1: { 1430 codec->driver->reg_word_size);
1453 u8 *cache;
1454
1455 cache = codec->reg_cache;
1456 cache[reg] = value;
1457 }
1458 break;
1459 case 2: {
1460 u16 *cache;
1461
1462 cache = codec->reg_cache;
1463 cache[reg] = value;
1464 }
1465 break;
1466 default:
1467 BUG();
1468 }
1469
1470 return 0; 1431 return 0;
1471} 1432}
1472 1433
1473static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, 1434static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1474 unsigned int reg, unsigned int *value) 1435 unsigned int reg, unsigned int *value)
1475{ 1436{
1476 switch (codec->driver->reg_word_size) { 1437 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
1477 case 1: { 1438 codec->driver->reg_word_size);
1478 u8 *cache;
1479
1480 cache = codec->reg_cache;
1481 *value = cache[reg];
1482 }
1483 break;
1484 case 2: {
1485 u16 *cache;
1486
1487 cache = codec->reg_cache;
1488 *value = cache[reg];
1489 }
1490 break;
1491 default:
1492 BUG();
1493 }
1494
1495 return 0; 1439 return 0;
1496} 1440}
1497 1441
@@ -1507,24 +1451,14 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1507static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 1451static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1508{ 1452{
1509 const struct snd_soc_codec_driver *codec_drv; 1453 const struct snd_soc_codec_driver *codec_drv;
1510 size_t reg_size;
1511 1454
1512 codec_drv = codec->driver; 1455 codec_drv = codec->driver;
1513 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1514 1456
1515 /* 1457 if (codec->reg_def_copy)
1516 * for flat compression, we don't need to keep a copy of the 1458 codec->reg_cache = kmemdup(codec->reg_def_copy,
1517 * original defaults register cache as it will definitely not 1459 codec->reg_size, GFP_KERNEL);
1518 * be marked as __devinitconst
1519 */
1520 kfree(codec->reg_def_copy);
1521 codec->reg_def_copy = NULL;
1522
1523 if (codec_drv->reg_cache_default)
1524 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
1525 reg_size, GFP_KERNEL);
1526 else 1460 else
1527 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL); 1461 codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
1528 if (!codec->reg_cache) 1462 if (!codec->reg_cache)
1529 return -ENOMEM; 1463 return -ENOMEM;
1530 1464
@@ -1669,21 +1603,77 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1669int snd_soc_cache_sync(struct snd_soc_codec *codec) 1603int snd_soc_cache_sync(struct snd_soc_codec *codec)
1670{ 1604{
1671 int ret; 1605 int ret;
1606 const char *name;
1672 1607
1673 if (!codec->cache_sync) { 1608 if (!codec->cache_sync) {
1674 return 0; 1609 return 0;
1675 } 1610 }
1676 1611
1677 if (codec->cache_ops && codec->cache_ops->sync) { 1612 if (!codec->cache_ops || !codec->cache_ops->sync)
1678 if (codec->cache_ops->name) 1613 return -EINVAL;
1679 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1680 codec->cache_ops->name, codec->name);
1681 ret = codec->cache_ops->sync(codec);
1682 if (!ret)
1683 codec->cache_sync = 0;
1684 return ret;
1685 }
1686 1614
1687 return -EINVAL; 1615 if (codec->cache_ops->name)
1616 name = codec->cache_ops->name;
1617 else
1618 name = "unknown";
1619
1620 if (codec->cache_ops->name)
1621 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1622 codec->cache_ops->name, codec->name);
1623 trace_snd_soc_cache_sync(codec, name, "start");
1624 ret = codec->cache_ops->sync(codec);
1625 if (!ret)
1626 codec->cache_sync = 0;
1627 trace_snd_soc_cache_sync(codec, name, "end");
1628 return ret;
1688} 1629}
1689EXPORT_SYMBOL_GPL(snd_soc_cache_sync); 1630EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
1631
1632static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
1633 unsigned int reg)
1634{
1635 const struct snd_soc_codec_driver *codec_drv;
1636 unsigned int min, max, index;
1637
1638 codec_drv = codec->driver;
1639 min = 0;
1640 max = codec_drv->reg_access_size - 1;
1641 do {
1642 index = (min + max) / 2;
1643 if (codec_drv->reg_access_default[index].reg == reg)
1644 return index;
1645 if (codec_drv->reg_access_default[index].reg < reg)
1646 min = index + 1;
1647 else
1648 max = index;
1649 } while (min <= max);
1650 return -1;
1651}
1652
1653int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
1654 unsigned int reg)
1655{
1656 int index;
1657
1658 if (reg >= codec->driver->reg_cache_size)
1659 return 1;
1660 index = snd_soc_get_reg_access_index(codec, reg);
1661 if (index < 0)
1662 return 0;
1663 return codec->driver->reg_access_default[index].vol;
1664}
1665EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
1666
1667int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1668 unsigned int reg)
1669{
1670 int index;
1671
1672 if (reg >= codec->driver->reg_cache_size)
1673 return 1;
1674 index = snd_soc_get_reg_access_index(codec, reg);
1675 if (index < 0)
1676 return 0;
1677 return codec->driver->reg_access_default[index].read;
1678}
1679EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c3f6f1e72790..17efacdb248a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -48,7 +48,8 @@ static DEFINE_MUTEX(pcm_mutex);
48static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 48static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
49 49
50#ifdef CONFIG_DEBUG_FS 50#ifdef CONFIG_DEBUG_FS
51static struct dentry *debugfs_root; 51struct dentry *snd_soc_debugfs_root;
52EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
52#endif 53#endif
53 54
54static DEFINE_MUTEX(client_mutex); 55static DEFINE_MUTEX(client_mutex);
@@ -57,8 +58,6 @@ static LIST_HEAD(dai_list);
57static LIST_HEAD(platform_list); 58static LIST_HEAD(platform_list);
58static LIST_HEAD(codec_list); 59static LIST_HEAD(codec_list);
59 60
60static int snd_soc_register_card(struct snd_soc_card *card);
61static int snd_soc_unregister_card(struct snd_soc_card *card);
62static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); 61static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
63 62
64/* 63/*
@@ -70,10 +69,73 @@ static int pmdown_time = 5000;
70module_param(pmdown_time, int, 0); 69module_param(pmdown_time, int, 0);
71MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 70MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
72 71
72/* returns the minimum number of bytes needed to represent
73 * a particular given value */
74static int min_bytes_needed(unsigned long val)
75{
76 int c = 0;
77 int i;
78
79 for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
80 if (val & (1UL << i))
81 break;
82 c = (sizeof val * 8) - c;
83 if (!c || (c % 8))
84 c = (c + 8) / 8;
85 else
86 c /= 8;
87 return c;
88}
89
90/* fill buf which is 'len' bytes with a formatted
91 * string of the form 'reg: value\n' */
92static int format_register_str(struct snd_soc_codec *codec,
93 unsigned int reg, char *buf, size_t len)
94{
95 int wordsize = codec->driver->reg_word_size * 2;
96 int regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
97 int ret;
98 char tmpbuf[len + 1];
99 char regbuf[regsize + 1];
100
101 /* since tmpbuf is allocated on the stack, warn the callers if they
102 * try to abuse this function */
103 WARN_ON(len > 63);
104
105 /* +2 for ': ' and + 1 for '\n' */
106 if (wordsize + regsize + 2 + 1 != len)
107 return -EINVAL;
108
109 ret = snd_soc_read(codec , reg);
110 if (ret < 0) {
111 memset(regbuf, 'X', regsize);
112 regbuf[regsize] = '\0';
113 } else {
114 snprintf(regbuf, regsize + 1, "%.*x", regsize, ret);
115 }
116
117 /* prepare the buffer */
118 snprintf(tmpbuf, len + 1, "%.*x: %s\n", wordsize, reg, regbuf);
119 /* copy it back to the caller without the '\0' */
120 memcpy(buf, tmpbuf, len);
121
122 return 0;
123}
124
73/* codec register dump */ 125/* codec register dump */
74static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 126static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
127 size_t count, loff_t pos)
75{ 128{
76 int ret, i, step = 1, count = 0; 129 int i, step = 1;
130 int wordsize, regsize;
131 int len;
132 size_t total = 0;
133 loff_t p = 0;
134
135 wordsize = codec->driver->reg_word_size * 2;
136 regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
137
138 len = wordsize + regsize + 2 + 1;
77 139
78 if (!codec->driver->reg_cache_size) 140 if (!codec->driver->reg_cache_size)
79 return 0; 141 return 0;
@@ -81,55 +143,37 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
81 if (codec->driver->reg_cache_step) 143 if (codec->driver->reg_cache_step)
82 step = codec->driver->reg_cache_step; 144 step = codec->driver->reg_cache_step;
83 145
84 count += sprintf(buf, "%s registers\n", codec->name);
85 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 146 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
86 if (codec->driver->readable_register && !codec->driver->readable_register(i)) 147 if (codec->readable_register && !codec->readable_register(codec, i))
87 continue; 148 continue;
88
89 count += sprintf(buf + count, "%2x: ", i);
90 if (count >= PAGE_SIZE - 1)
91 break;
92
93 if (codec->driver->display_register) { 149 if (codec->driver->display_register) {
94 count += codec->driver->display_register(codec, buf + count, 150 count += codec->driver->display_register(codec, buf + count,
95 PAGE_SIZE - count, i); 151 PAGE_SIZE - count, i);
96 } else { 152 } else {
97 /* If the read fails it's almost certainly due to 153 /* only support larger than PAGE_SIZE bytes debugfs
98 * the register being volatile and the device being 154 * entries for the default case */
99 * powered off. 155 if (p >= pos) {
100 */ 156 if (total + len >= count - 1)
101 ret = snd_soc_read(codec, i); 157 break;
102 if (ret >= 0) 158 format_register_str(codec, i, buf + total, len);
103 count += snprintf(buf + count, 159 total += len;
104 PAGE_SIZE - count, 160 }
105 "%4x", ret); 161 p += len;
106 else
107 count += snprintf(buf + count,
108 PAGE_SIZE - count,
109 "<no data: %d>", ret);
110 } 162 }
111
112 if (count >= PAGE_SIZE - 1)
113 break;
114
115 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
116 if (count >= PAGE_SIZE - 1)
117 break;
118 } 163 }
119 164
120 /* Truncate count; min() would cause a warning */ 165 total = min(total, count - 1);
121 if (count >= PAGE_SIZE)
122 count = PAGE_SIZE - 1;
123 166
124 return count; 167 return total;
125} 168}
169
126static ssize_t codec_reg_show(struct device *dev, 170static ssize_t codec_reg_show(struct device *dev,
127 struct device_attribute *attr, char *buf) 171 struct device_attribute *attr, char *buf)
128{ 172{
129 struct snd_soc_pcm_runtime *rtd = 173 struct snd_soc_pcm_runtime *rtd =
130 container_of(dev, struct snd_soc_pcm_runtime, dev); 174 container_of(dev, struct snd_soc_pcm_runtime, dev);
131 175
132 return soc_codec_reg_show(rtd->codec, buf); 176 return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
133} 177}
134 178
135static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 179static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
@@ -168,16 +212,28 @@ static int codec_reg_open_file(struct inode *inode, struct file *file)
168} 212}
169 213
170static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, 214static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
171 size_t count, loff_t *ppos) 215 size_t count, loff_t *ppos)
172{ 216{
173 ssize_t ret; 217 ssize_t ret;
174 struct snd_soc_codec *codec = file->private_data; 218 struct snd_soc_codec *codec = file->private_data;
175 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 219 char *buf;
220
221 if (*ppos < 0 || !count)
222 return -EINVAL;
223
224 buf = kmalloc(count, GFP_KERNEL);
176 if (!buf) 225 if (!buf)
177 return -ENOMEM; 226 return -ENOMEM;
178 ret = soc_codec_reg_show(codec, buf); 227
179 if (ret >= 0) 228 ret = soc_codec_reg_show(codec, buf, count, *ppos);
180 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 229 if (ret >= 0) {
230 if (copy_to_user(user_buf, buf, ret)) {
231 kfree(buf);
232 return -EFAULT;
233 }
234 *ppos += ret;
235 }
236
181 kfree(buf); 237 kfree(buf);
182 return ret; 238 return ret;
183} 239}
@@ -209,6 +265,10 @@ static ssize_t codec_reg_write_file(struct file *file,
209 start++; 265 start++;
210 if (strict_strtoul(start, 16, &value)) 266 if (strict_strtoul(start, 16, &value))
211 return -EINVAL; 267 return -EINVAL;
268
269 /* Userspace has been fiddling around behind the kernel's back */
270 add_taint(TAINT_USER);
271
212 snd_soc_write(codec, reg, value); 272 snd_soc_write(codec, reg, value);
213 return buf_size; 273 return buf_size;
214} 274}
@@ -232,6 +292,11 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
232 return; 292 return;
233 } 293 }
234 294
295 debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root,
296 &codec->cache_sync);
297 debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
298 &codec->cache_only);
299
235 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 300 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
236 codec->debugfs_codec_root, 301 codec->debugfs_codec_root,
237 codec, &codec_reg_fops); 302 codec, &codec_reg_fops);
@@ -356,7 +421,7 @@ static const struct file_operations platform_list_fops = {
356static void soc_init_card_debugfs(struct snd_soc_card *card) 421static void soc_init_card_debugfs(struct snd_soc_card *card)
357{ 422{
358 card->debugfs_card_root = debugfs_create_dir(card->name, 423 card->debugfs_card_root = debugfs_create_dir(card->name,
359 debugfs_root); 424 snd_soc_debugfs_root);
360 if (!card->debugfs_card_root) { 425 if (!card->debugfs_card_root) {
361 dev_warn(card->dev, 426 dev_warn(card->dev,
362 "ASoC: Failed to create codec debugfs directory\n"); 427 "ASoC: Failed to create codec debugfs directory\n");
@@ -435,20 +500,30 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
435 struct snd_soc_dai *codec_dai = rtd->codec_dai; 500 struct snd_soc_dai *codec_dai = rtd->codec_dai;
436 int ret; 501 int ret;
437 502
438 if (codec_dai->driver->symmetric_rates || cpu_dai->driver->symmetric_rates || 503 if (!codec_dai->driver->symmetric_rates &&
439 rtd->dai_link->symmetric_rates) { 504 !cpu_dai->driver->symmetric_rates &&
440 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", 505 !rtd->dai_link->symmetric_rates)
441 rtd->rate); 506 return 0;
442 507
443 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 508 /* This can happen if multiple streams are starting simultaneously -
444 SNDRV_PCM_HW_PARAM_RATE, 509 * the second can need to get its constraints before the first has
445 rtd->rate, 510 * picked a rate. Complain and allow the application to carry on.
446 rtd->rate); 511 */
447 if (ret < 0) { 512 if (!rtd->rate) {
448 dev_err(&rtd->dev, 513 dev_warn(&rtd->dev,
449 "Unable to apply rate symmetry constraint: %d\n", ret); 514 "Not enforcing symmetric_rates due to race\n");
450 return ret; 515 return 0;
451 } 516 }
517
518 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate);
519
520 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
521 SNDRV_PCM_HW_PARAM_RATE,
522 rtd->rate, rtd->rate);
523 if (ret < 0) {
524 dev_err(&rtd->dev,
525 "Unable to apply rate symmetry constraint: %d\n", ret);
526 return ret;
452 } 527 }
453 528
454 return 0; 529 return 0;
@@ -962,12 +1037,11 @@ static struct snd_pcm_ops soc_pcm_ops = {
962 .pointer = soc_pcm_pointer, 1037 .pointer = soc_pcm_pointer,
963}; 1038};
964 1039
965#ifdef CONFIG_PM 1040#ifdef CONFIG_PM_SLEEP
966/* powers down audio subsystem for suspend */ 1041/* powers down audio subsystem for suspend */
967static int soc_suspend(struct device *dev) 1042int snd_soc_suspend(struct device *dev)
968{ 1043{
969 struct platform_device *pdev = to_platform_device(dev); 1044 struct snd_soc_card *card = dev_get_drvdata(dev);
970 struct snd_soc_card *card = platform_get_drvdata(pdev);
971 struct snd_soc_codec *codec; 1045 struct snd_soc_codec *codec;
972 int i; 1046 int i;
973 1047
@@ -1008,7 +1082,7 @@ static int soc_suspend(struct device *dev)
1008 } 1082 }
1009 1083
1010 if (card->suspend_pre) 1084 if (card->suspend_pre)
1011 card->suspend_pre(pdev, PMSG_SUSPEND); 1085 card->suspend_pre(card);
1012 1086
1013 for (i = 0; i < card->num_rtd; i++) { 1087 for (i = 0; i < card->num_rtd; i++) {
1014 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 1088 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
@@ -1075,10 +1149,11 @@ static int soc_suspend(struct device *dev)
1075 } 1149 }
1076 1150
1077 if (card->suspend_post) 1151 if (card->suspend_post)
1078 card->suspend_post(pdev, PMSG_SUSPEND); 1152 card->suspend_post(card);
1079 1153
1080 return 0; 1154 return 0;
1081} 1155}
1156EXPORT_SYMBOL_GPL(snd_soc_suspend);
1082 1157
1083/* deferred resume work, so resume can complete before we finished 1158/* deferred resume work, so resume can complete before we finished
1084 * setting our codec back up, which can be very slow on I2C 1159 * setting our codec back up, which can be very slow on I2C
@@ -1087,7 +1162,6 @@ static void soc_resume_deferred(struct work_struct *work)
1087{ 1162{
1088 struct snd_soc_card *card = 1163 struct snd_soc_card *card =
1089 container_of(work, struct snd_soc_card, deferred_resume_work); 1164 container_of(work, struct snd_soc_card, deferred_resume_work);
1090 struct platform_device *pdev = to_platform_device(card->dev);
1091 struct snd_soc_codec *codec; 1165 struct snd_soc_codec *codec;
1092 int i; 1166 int i;
1093 1167
@@ -1101,7 +1175,7 @@ static void soc_resume_deferred(struct work_struct *work)
1101 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); 1175 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
1102 1176
1103 if (card->resume_pre) 1177 if (card->resume_pre)
1104 card->resume_pre(pdev); 1178 card->resume_pre(card);
1105 1179
1106 /* resume AC97 DAIs */ 1180 /* resume AC97 DAIs */
1107 for (i = 0; i < card->num_rtd; i++) { 1181 for (i = 0; i < card->num_rtd; i++) {
@@ -1176,7 +1250,7 @@ static void soc_resume_deferred(struct work_struct *work)
1176 } 1250 }
1177 1251
1178 if (card->resume_post) 1252 if (card->resume_post)
1179 card->resume_post(pdev); 1253 card->resume_post(card);
1180 1254
1181 dev_dbg(card->dev, "resume work completed\n"); 1255 dev_dbg(card->dev, "resume work completed\n");
1182 1256
@@ -1185,10 +1259,9 @@ static void soc_resume_deferred(struct work_struct *work)
1185} 1259}
1186 1260
1187/* powers up audio subsystem after a suspend */ 1261/* powers up audio subsystem after a suspend */
1188static int soc_resume(struct device *dev) 1262int snd_soc_resume(struct device *dev)
1189{ 1263{
1190 struct platform_device *pdev = to_platform_device(dev); 1264 struct snd_soc_card *card = dev_get_drvdata(dev);
1191 struct snd_soc_card *card = platform_get_drvdata(pdev);
1192 int i; 1265 int i;
1193 1266
1194 /* AC97 devices might have other drivers hanging off them so 1267 /* AC97 devices might have other drivers hanging off them so
@@ -1210,9 +1283,10 @@ static int soc_resume(struct device *dev)
1210 1283
1211 return 0; 1284 return 0;
1212} 1285}
1286EXPORT_SYMBOL_GPL(snd_soc_resume);
1213#else 1287#else
1214#define soc_suspend NULL 1288#define snd_soc_suspend NULL
1215#define soc_resume NULL 1289#define snd_soc_resume NULL
1216#endif 1290#endif
1217 1291
1218static struct snd_soc_dai_ops null_dai_ops = { 1292static struct snd_soc_dai_ops null_dai_ops = {
@@ -1400,31 +1474,44 @@ static int soc_probe_codec(struct snd_soc_card *card,
1400 struct snd_soc_codec *codec) 1474 struct snd_soc_codec *codec)
1401{ 1475{
1402 int ret = 0; 1476 int ret = 0;
1477 const struct snd_soc_codec_driver *driver = codec->driver;
1403 1478
1404 codec->card = card; 1479 codec->card = card;
1405 codec->dapm.card = card; 1480 codec->dapm.card = card;
1406 soc_set_name_prefix(card, codec); 1481 soc_set_name_prefix(card, codec);
1407 1482
1408 if (codec->driver->probe) { 1483 if (!try_module_get(codec->dev->driver->owner))
1409 ret = codec->driver->probe(codec); 1484 return -ENODEV;
1485
1486 if (driver->probe) {
1487 ret = driver->probe(codec);
1410 if (ret < 0) { 1488 if (ret < 0) {
1411 dev_err(codec->dev, 1489 dev_err(codec->dev,
1412 "asoc: failed to probe CODEC %s: %d\n", 1490 "asoc: failed to probe CODEC %s: %d\n",
1413 codec->name, ret); 1491 codec->name, ret);
1414 return ret; 1492 goto err_probe;
1415 } 1493 }
1416 } 1494 }
1417 1495
1496 if (driver->dapm_widgets)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1498 driver->num_dapm_widgets);
1499 if (driver->dapm_routes)
1500 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1501 driver->num_dapm_routes);
1502
1418 soc_init_codec_debugfs(codec); 1503 soc_init_codec_debugfs(codec);
1419 1504
1420 /* mark codec as probed and add to card codec list */ 1505 /* mark codec as probed and add to card codec list */
1421 if (!try_module_get(codec->dev->driver->owner))
1422 return -ENODEV;
1423
1424 codec->probed = 1; 1506 codec->probed = 1;
1425 list_add(&codec->card_list, &card->codec_dev_list); 1507 list_add(&codec->card_list, &card->codec_dev_list);
1426 list_add(&codec->dapm.list, &card->dapm_list); 1508 list_add(&codec->dapm.list, &card->dapm_list);
1427 1509
1510 return 0;
1511
1512err_probe:
1513 module_put(codec->dev->driver->owner);
1514
1428 return ret; 1515 return ret;
1429} 1516}
1430 1517
@@ -1468,7 +1555,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1468 1555
1469 /* Make sure all DAPM widgets are instantiated */ 1556 /* Make sure all DAPM widgets are instantiated */
1470 snd_soc_dapm_new_widgets(&codec->dapm); 1557 snd_soc_dapm_new_widgets(&codec->dapm);
1471 snd_soc_dapm_sync(&codec->dapm);
1472 1558
1473 /* register the rtd device */ 1559 /* register the rtd device */
1474 rtd->codec = codec; 1560 rtd->codec = codec;
@@ -1543,19 +1629,19 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1543 1629
1544 /* probe the platform */ 1630 /* probe the platform */
1545 if (!platform->probed) { 1631 if (!platform->probed) {
1632 if (!try_module_get(platform->dev->driver->owner))
1633 return -ENODEV;
1634
1546 if (platform->driver->probe) { 1635 if (platform->driver->probe) {
1547 ret = platform->driver->probe(platform); 1636 ret = platform->driver->probe(platform);
1548 if (ret < 0) { 1637 if (ret < 0) {
1549 printk(KERN_ERR "asoc: failed to probe platform %s\n", 1638 printk(KERN_ERR "asoc: failed to probe platform %s\n",
1550 platform->name); 1639 platform->name);
1640 module_put(platform->dev->driver->owner);
1551 return ret; 1641 return ret;
1552 } 1642 }
1553 } 1643 }
1554 /* mark platform as probed and add to card platform list */ 1644 /* mark platform as probed and add to card platform list */
1555
1556 if (!try_module_get(platform->dev->driver->owner))
1557 return -ENODEV;
1558
1559 platform->probed = 1; 1645 platform->probed = 1;
1560 list_add(&platform->card_list, &card->platform_dev_list); 1646 list_add(&platform->card_list, &card->platform_dev_list);
1561 } 1647 }
@@ -1713,7 +1799,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1713 1799
1714static void snd_soc_instantiate_card(struct snd_soc_card *card) 1800static void snd_soc_instantiate_card(struct snd_soc_card *card)
1715{ 1801{
1716 struct platform_device *pdev = to_platform_device(card->dev);
1717 struct snd_soc_codec *codec; 1802 struct snd_soc_codec *codec;
1718 struct snd_soc_codec_conf *codec_conf; 1803 struct snd_soc_codec_conf *codec_conf;
1719 enum snd_soc_compress_type compress_type; 1804 enum snd_soc_compress_type compress_type;
@@ -1740,6 +1825,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1740 list_for_each_entry(codec, &codec_list, list) { 1825 list_for_each_entry(codec, &codec_list, list) {
1741 if (codec->cache_init) 1826 if (codec->cache_init)
1742 continue; 1827 continue;
1828 /* by default we don't override the compress_type */
1829 compress_type = 0;
1743 /* check to see if we need to override the compress_type */ 1830 /* check to see if we need to override the compress_type */
1744 for (i = 0; i < card->num_configs; ++i) { 1831 for (i = 0; i < card->num_configs; ++i) {
1745 codec_conf = &card->codec_conf[i]; 1832 codec_conf = &card->codec_conf[i];
@@ -1750,18 +1837,6 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1750 break; 1837 break;
1751 } 1838 }
1752 } 1839 }
1753 if (i == card->num_configs) {
1754 /* no need to override the compress_type so
1755 * go ahead and do the standard thing */
1756 ret = snd_soc_init_codec_cache(codec, 0);
1757 if (ret < 0) {
1758 mutex_unlock(&card->mutex);
1759 return;
1760 }
1761 continue;
1762 }
1763 /* override the compress_type with the one supplied in
1764 * the machine driver */
1765 ret = snd_soc_init_codec_cache(codec, compress_type); 1840 ret = snd_soc_init_codec_cache(codec, compress_type);
1766 if (ret < 0) { 1841 if (ret < 0) {
1767 mutex_unlock(&card->mutex); 1842 mutex_unlock(&card->mutex);
@@ -1780,14 +1855,19 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1780 } 1855 }
1781 card->snd_card->dev = card->dev; 1856 card->snd_card->dev = card->dev;
1782 1857
1783#ifdef CONFIG_PM 1858 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1859 card->dapm.dev = card->dev;
1860 card->dapm.card = card;
1861 list_add(&card->dapm.list, &card->dapm_list);
1862
1863#ifdef CONFIG_PM_SLEEP
1784 /* deferred resume work */ 1864 /* deferred resume work */
1785 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1786#endif 1866#endif
1787 1867
1788 /* initialise the sound card only once */ 1868 /* initialise the sound card only once */
1789 if (card->probe) { 1869 if (card->probe) {
1790 ret = card->probe(pdev); 1870 ret = card->probe(card);
1791 if (ret < 0) 1871 if (ret < 0)
1792 goto card_probe_error; 1872 goto card_probe_error;
1793 } 1873 }
@@ -1810,11 +1890,37 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1810 } 1890 }
1811 } 1891 }
1812 1892
1893 if (card->dapm_widgets)
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1895 card->num_dapm_widgets);
1896 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes);
1899
1900#ifdef CONFIG_DEBUG_FS
1901 card->dapm.debugfs_dapm = debugfs_create_dir("dapm",
1902 card->debugfs_card_root);
1903 if (!card->dapm.debugfs_dapm)
1904 printk(KERN_WARNING
1905 "Failed to create card DAPM debugfs directory\n");
1906
1907 snd_soc_dapm_debugfs_init(&card->dapm);
1908#endif
1909
1813 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1910 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1814 "%s", card->name); 1911 "%s", card->name);
1815 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1912 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1816 "%s", card->name); 1913 "%s", card->name);
1817 1914
1915 if (card->late_probe) {
1916 ret = card->late_probe(card);
1917 if (ret < 0) {
1918 dev_err(card->dev, "%s late_probe() failed: %d\n",
1919 card->name, ret);
1920 goto probe_aux_dev_err;
1921 }
1922 }
1923
1818 ret = snd_card_register(card->snd_card); 1924 ret = snd_card_register(card->snd_card);
1819 if (ret < 0) { 1925 if (ret < 0) {
1820 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1926 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -1848,7 +1954,7 @@ probe_dai_err:
1848 1954
1849card_probe_error: 1955card_probe_error:
1850 if (card->remove) 1956 if (card->remove)
1851 card->remove(pdev); 1957 card->remove(card);
1852 1958
1853 snd_card_free(card->snd_card); 1959 snd_card_free(card->snd_card);
1854 1960
@@ -1872,16 +1978,15 @@ static int soc_probe(struct platform_device *pdev)
1872 struct snd_soc_card *card = platform_get_drvdata(pdev); 1978 struct snd_soc_card *card = platform_get_drvdata(pdev);
1873 int ret = 0; 1979 int ret = 0;
1874 1980
1981 /*
1982 * no card, so machine driver should be registering card
1983 * we should not be here in that case so ret error
1984 */
1985 if (!card)
1986 return -EINVAL;
1987
1875 /* Bodge while we unpick instantiation */ 1988 /* Bodge while we unpick instantiation */
1876 card->dev = &pdev->dev; 1989 card->dev = &pdev->dev;
1877 INIT_LIST_HEAD(&card->dai_dev_list);
1878 INIT_LIST_HEAD(&card->codec_dev_list);
1879 INIT_LIST_HEAD(&card->platform_dev_list);
1880 INIT_LIST_HEAD(&card->widgets);
1881 INIT_LIST_HEAD(&card->paths);
1882 INIT_LIST_HEAD(&card->dapm_list);
1883
1884 soc_init_card_debugfs(card);
1885 1990
1886 ret = snd_soc_register_card(card); 1991 ret = snd_soc_register_card(card);
1887 if (ret != 0) { 1992 if (ret != 0) {
@@ -1892,45 +1997,48 @@ static int soc_probe(struct platform_device *pdev)
1892 return 0; 1997 return 0;
1893} 1998}
1894 1999
1895/* removes a socdev */ 2000static int soc_cleanup_card_resources(struct snd_soc_card *card)
1896static int soc_remove(struct platform_device *pdev)
1897{ 2001{
1898 struct snd_soc_card *card = platform_get_drvdata(pdev);
1899 int i; 2002 int i;
1900 2003
1901 if (card->instantiated) { 2004 /* make sure any delayed work runs */
2005 for (i = 0; i < card->num_rtd; i++) {
2006 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
2007 flush_delayed_work_sync(&rtd->delayed_work);
2008 }
1902 2009
1903 /* make sure any delayed work runs */ 2010 /* remove auxiliary devices */
1904 for (i = 0; i < card->num_rtd; i++) { 2011 for (i = 0; i < card->num_aux_devs; i++)
1905 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 2012 soc_remove_aux_dev(card, i);
1906 flush_delayed_work_sync(&rtd->delayed_work);
1907 }
1908 2013
1909 /* remove auxiliary devices */ 2014 /* remove and free each DAI */
1910 for (i = 0; i < card->num_aux_devs; i++) 2015 for (i = 0; i < card->num_rtd; i++)
1911 soc_remove_aux_dev(card, i); 2016 soc_remove_dai_link(card, i);
1912 2017
1913 /* remove and free each DAI */ 2018 soc_cleanup_card_debugfs(card);
1914 for (i = 0; i < card->num_rtd; i++)
1915 soc_remove_dai_link(card, i);
1916 2019
1917 soc_cleanup_card_debugfs(card); 2020 /* remove the card */
2021 if (card->remove)
2022 card->remove(card);
2023
2024 kfree(card->rtd);
2025 snd_card_free(card->snd_card);
2026 return 0;
1918 2027
1919 /* remove the card */ 2028}
1920 if (card->remove) 2029
1921 card->remove(pdev); 2030/* removes a socdev */
2031static int soc_remove(struct platform_device *pdev)
2032{
2033 struct snd_soc_card *card = platform_get_drvdata(pdev);
1922 2034
1923 kfree(card->rtd);
1924 snd_card_free(card->snd_card);
1925 }
1926 snd_soc_unregister_card(card); 2035 snd_soc_unregister_card(card);
1927 return 0; 2036 return 0;
1928} 2037}
1929 2038
1930static int soc_poweroff(struct device *dev) 2039int snd_soc_poweroff(struct device *dev)
1931{ 2040{
1932 struct platform_device *pdev = to_platform_device(dev); 2041 struct snd_soc_card *card = dev_get_drvdata(dev);
1933 struct snd_soc_card *card = platform_get_drvdata(pdev);
1934 int i; 2042 int i;
1935 2043
1936 if (!card->instantiated) 2044 if (!card->instantiated)
@@ -1947,11 +2055,12 @@ static int soc_poweroff(struct device *dev)
1947 2055
1948 return 0; 2056 return 0;
1949} 2057}
2058EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1950 2059
1951static const struct dev_pm_ops soc_pm_ops = { 2060const struct dev_pm_ops snd_soc_pm_ops = {
1952 .suspend = soc_suspend, 2061 .suspend = snd_soc_suspend,
1953 .resume = soc_resume, 2062 .resume = snd_soc_resume,
1954 .poweroff = soc_poweroff, 2063 .poweroff = snd_soc_poweroff,
1955}; 2064};
1956 2065
1957/* ASoC platform driver */ 2066/* ASoC platform driver */
@@ -1959,7 +2068,7 @@ static struct platform_driver soc_driver = {
1959 .driver = { 2068 .driver = {
1960 .name = "soc-audio", 2069 .name = "soc-audio",
1961 .owner = THIS_MODULE, 2070 .owner = THIS_MODULE,
1962 .pm = &soc_pm_ops, 2071 .pm = &snd_soc_pm_ops,
1963 }, 2072 },
1964 .probe = soc_probe, 2073 .probe = soc_probe,
1965 .remove = soc_remove, 2074 .remove = soc_remove,
@@ -2029,10 +2138,11 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2029 * 2138 *
2030 * Boolean function indiciating if a CODEC register is volatile. 2139 * Boolean function indiciating if a CODEC register is volatile.
2031 */ 2140 */
2032int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg) 2141int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2142 unsigned int reg)
2033{ 2143{
2034 if (codec->driver->volatile_register) 2144 if (codec->volatile_register)
2035 return codec->driver->volatile_register(reg); 2145 return codec->volatile_register(codec, reg);
2036 else 2146 else
2037 return 0; 2147 return 0;
2038} 2148}
@@ -2129,19 +2239,27 @@ EXPORT_SYMBOL_GPL(snd_soc_write);
2129 * 2239 *
2130 * Writes new register value. 2240 * Writes new register value.
2131 * 2241 *
2132 * Returns 1 for change else 0. 2242 * Returns 1 for change, 0 for no change, or negative error code.
2133 */ 2243 */
2134int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 2244int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
2135 unsigned int mask, unsigned int value) 2245 unsigned int mask, unsigned int value)
2136{ 2246{
2137 int change; 2247 int change;
2138 unsigned int old, new; 2248 unsigned int old, new;
2249 int ret;
2139 2250
2140 old = snd_soc_read(codec, reg); 2251 ret = snd_soc_read(codec, reg);
2252 if (ret < 0)
2253 return ret;
2254
2255 old = ret;
2141 new = (old & ~mask) | value; 2256 new = (old & ~mask) | value;
2142 change = old != new; 2257 change = old != new;
2143 if (change) 2258 if (change) {
2144 snd_soc_write(codec, reg, new); 2259 ret = snd_soc_write(codec, reg, new);
2260 if (ret < 0)
2261 return ret;
2262 }
2145 2263
2146 return change; 2264 return change;
2147} 2265}
@@ -2226,22 +2344,45 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
2226 * @_template: control template 2344 * @_template: control template
2227 * @data: control private data 2345 * @data: control private data
2228 * @long_name: control long name 2346 * @long_name: control long name
2347 * @prefix: control name prefix
2229 * 2348 *
2230 * Create a new mixer control from a template control. 2349 * Create a new mixer control from a template control.
2231 * 2350 *
2232 * Returns 0 for success, else error. 2351 * Returns 0 for success, else error.
2233 */ 2352 */
2234struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2353struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2235 void *data, char *long_name) 2354 void *data, char *long_name,
2355 const char *prefix)
2236{ 2356{
2237 struct snd_kcontrol_new template; 2357 struct snd_kcontrol_new template;
2358 struct snd_kcontrol *kcontrol;
2359 char *name = NULL;
2360 int name_len;
2238 2361
2239 memcpy(&template, _template, sizeof(template)); 2362 memcpy(&template, _template, sizeof(template));
2240 if (long_name)
2241 template.name = long_name;
2242 template.index = 0; 2363 template.index = 0;
2243 2364
2244 return snd_ctl_new1(&template, data); 2365 if (!long_name)
2366 long_name = template.name;
2367
2368 if (prefix) {
2369 name_len = strlen(long_name) + strlen(prefix) + 2;
2370 name = kmalloc(name_len, GFP_ATOMIC);
2371 if (!name)
2372 return NULL;
2373
2374 snprintf(name, name_len, "%s %s", prefix, long_name);
2375
2376 template.name = name;
2377 } else {
2378 template.name = long_name;
2379 }
2380
2381 kcontrol = snd_ctl_new1(&template, data);
2382
2383 kfree(name);
2384
2385 return kcontrol;
2245} 2386}
2246EXPORT_SYMBOL_GPL(snd_soc_cnew); 2387EXPORT_SYMBOL_GPL(snd_soc_cnew);
2247 2388
@@ -2260,22 +2401,16 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
2260 const struct snd_kcontrol_new *controls, int num_controls) 2401 const struct snd_kcontrol_new *controls, int num_controls)
2261{ 2402{
2262 struct snd_card *card = codec->card->snd_card; 2403 struct snd_card *card = codec->card->snd_card;
2263 char prefixed_name[44], *name;
2264 int err, i; 2404 int err, i;
2265 2405
2266 for (i = 0; i < num_controls; i++) { 2406 for (i = 0; i < num_controls; i++) {
2267 const struct snd_kcontrol_new *control = &controls[i]; 2407 const struct snd_kcontrol_new *control = &controls[i];
2268 if (codec->name_prefix) { 2408 err = snd_ctl_add(card, snd_soc_cnew(control, codec,
2269 snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", 2409 control->name,
2270 codec->name_prefix, control->name); 2410 codec->name_prefix));
2271 name = prefixed_name;
2272 } else {
2273 name = control->name;
2274 }
2275 err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
2276 if (err < 0) { 2411 if (err < 0) {
2277 dev_err(codec->dev, "%s: Failed to add %s: %d\n", 2412 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2278 codec->name, name, err); 2413 codec->name, control->name, err);
2279 return err; 2414 return err;
2280 } 2415 }
2281 } 2416 }
@@ -2956,12 +3091,34 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2956{ 3091{
2957 if (dai->driver && dai->driver->ops->set_sysclk) 3092 if (dai->driver && dai->driver->ops->set_sysclk)
2958 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 3093 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
3094 else if (dai->codec && dai->codec->driver->set_sysclk)
3095 return dai->codec->driver->set_sysclk(dai->codec, clk_id,
3096 freq, dir);
2959 else 3097 else
2960 return -EINVAL; 3098 return -EINVAL;
2961} 3099}
2962EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); 3100EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2963 3101
2964/** 3102/**
3103 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
3104 * @codec: CODEC
3105 * @clk_id: DAI specific clock ID
3106 * @freq: new clock frequency in Hz
3107 * @dir: new clock direction - input/output.
3108 *
3109 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
3110 */
3111int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
3112 unsigned int freq, int dir)
3113{
3114 if (codec->driver->set_sysclk)
3115 return codec->driver->set_sysclk(codec, clk_id, freq, dir);
3116 else
3117 return -EINVAL;
3118}
3119EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
3120
3121/**
2965 * snd_soc_dai_set_clkdiv - configure DAI clock dividers. 3122 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
2966 * @dai: DAI 3123 * @dai: DAI
2967 * @div_id: DAI specific clock divider ID 3124 * @div_id: DAI specific clock divider ID
@@ -2997,11 +3154,35 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2997 if (dai->driver && dai->driver->ops->set_pll) 3154 if (dai->driver && dai->driver->ops->set_pll)
2998 return dai->driver->ops->set_pll(dai, pll_id, source, 3155 return dai->driver->ops->set_pll(dai, pll_id, source,
2999 freq_in, freq_out); 3156 freq_in, freq_out);
3157 else if (dai->codec && dai->codec->driver->set_pll)
3158 return dai->codec->driver->set_pll(dai->codec, pll_id, source,
3159 freq_in, freq_out);
3000 else 3160 else
3001 return -EINVAL; 3161 return -EINVAL;
3002} 3162}
3003EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); 3163EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
3004 3164
3165/*
3166 * snd_soc_codec_set_pll - configure codec PLL.
3167 * @codec: CODEC
3168 * @pll_id: DAI specific PLL ID
3169 * @source: DAI specific source for the PLL
3170 * @freq_in: PLL input clock frequency in Hz
3171 * @freq_out: requested PLL output clock frequency in Hz
3172 *
3173 * Configures and enables PLL to generate output clock based on input clock.
3174 */
3175int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
3176 unsigned int freq_in, unsigned int freq_out)
3177{
3178 if (codec->driver->set_pll)
3179 return codec->driver->set_pll(codec, pll_id, source,
3180 freq_in, freq_out);
3181 else
3182 return -EINVAL;
3183}
3184EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
3185
3005/** 3186/**
3006 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 3187 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
3007 * @dai: DAI 3188 * @dai: DAI
@@ -3101,17 +3282,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3101 * 3282 *
3102 * @card: Card to register 3283 * @card: Card to register
3103 * 3284 *
3104 * Note that currently this is an internal only function: it will be
3105 * exposed to machine drivers after further backporting of ASoC v2
3106 * registration APIs.
3107 */ 3285 */
3108static int snd_soc_register_card(struct snd_soc_card *card) 3286int snd_soc_register_card(struct snd_soc_card *card)
3109{ 3287{
3110 int i; 3288 int i;
3111 3289
3112 if (!card->name || !card->dev) 3290 if (!card->name || !card->dev)
3113 return -EINVAL; 3291 return -EINVAL;
3114 3292
3293 snd_soc_initialize_card_lists(card);
3294
3295 soc_init_card_debugfs(card);
3296
3115 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * 3297 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
3116 (card->num_links + card->num_aux_devs), 3298 (card->num_links + card->num_aux_devs),
3117 GFP_KERNEL); 3299 GFP_KERNEL);
@@ -3135,18 +3317,18 @@ static int snd_soc_register_card(struct snd_soc_card *card)
3135 3317
3136 return 0; 3318 return 0;
3137} 3319}
3320EXPORT_SYMBOL_GPL(snd_soc_register_card);
3138 3321
3139/** 3322/**
3140 * snd_soc_unregister_card - Unregister a card with the ASoC core 3323 * snd_soc_unregister_card - Unregister a card with the ASoC core
3141 * 3324 *
3142 * @card: Card to unregister 3325 * @card: Card to unregister
3143 * 3326 *
3144 * Note that currently this is an internal only function: it will be
3145 * exposed to machine drivers after further backporting of ASoC v2
3146 * registration APIs.
3147 */ 3327 */
3148static int snd_soc_unregister_card(struct snd_soc_card *card) 3328int snd_soc_unregister_card(struct snd_soc_card *card)
3149{ 3329{
3330 if (card->instantiated)
3331 soc_cleanup_card_resources(card);
3150 mutex_lock(&client_mutex); 3332 mutex_lock(&client_mutex);
3151 list_del(&card->list); 3333 list_del(&card->list);
3152 mutex_unlock(&client_mutex); 3334 mutex_unlock(&client_mutex);
@@ -3154,6 +3336,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
3154 3336
3155 return 0; 3337 return 0;
3156} 3338}
3339EXPORT_SYMBOL_GPL(snd_soc_unregister_card);
3157 3340
3158/* 3341/*
3159 * Simplify DAI link configuration by removing ".-1" from device names 3342 * Simplify DAI link configuration by removing ".-1" from device names
@@ -3483,9 +3666,12 @@ int snd_soc_register_codec(struct device *dev,
3483 3666
3484 codec->write = codec_drv->write; 3667 codec->write = codec_drv->write;
3485 codec->read = codec_drv->read; 3668 codec->read = codec_drv->read;
3669 codec->volatile_register = codec_drv->volatile_register;
3670 codec->readable_register = codec_drv->readable_register;
3486 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3671 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3487 codec->dapm.dev = dev; 3672 codec->dapm.dev = dev;
3488 codec->dapm.codec = codec; 3673 codec->dapm.codec = codec;
3674 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3489 codec->dev = dev; 3675 codec->dev = dev;
3490 codec->driver = codec_drv; 3676 codec->driver = codec_drv;
3491 codec->num_dai = num_dai; 3677 codec->num_dai = num_dai;
@@ -3494,20 +3680,30 @@ int snd_soc_register_codec(struct device *dev,
3494 /* allocate CODEC register cache */ 3680 /* allocate CODEC register cache */
3495 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { 3681 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
3496 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 3682 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
3683 codec->reg_size = reg_size;
3497 /* it is necessary to make a copy of the default register cache 3684 /* it is necessary to make a copy of the default register cache
3498 * because in the case of using a compression type that requires 3685 * because in the case of using a compression type that requires
3499 * the default register cache to be marked as __devinitconst the 3686 * the default register cache to be marked as __devinitconst the
3500 * kernel might have freed the array by the time we initialize 3687 * kernel might have freed the array by the time we initialize
3501 * the cache. 3688 * the cache.
3502 */ 3689 */
3503 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default, 3690 if (codec_drv->reg_cache_default) {
3504 reg_size, GFP_KERNEL); 3691 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
3505 if (!codec->reg_def_copy) { 3692 reg_size, GFP_KERNEL);
3506 ret = -ENOMEM; 3693 if (!codec->reg_def_copy) {
3507 goto fail; 3694 ret = -ENOMEM;
3695 goto fail;
3696 }
3508 } 3697 }
3509 } 3698 }
3510 3699
3700 if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
3701 if (!codec->volatile_register)
3702 codec->volatile_register = snd_soc_default_volatile_register;
3703 if (!codec->readable_register)
3704 codec->readable_register = snd_soc_default_readable_register;
3705 }
3706
3511 for (i = 0; i < num_dai; i++) { 3707 for (i = 0; i < num_dai; i++) {
3512 fixup_codec_formats(&dai_drv[i].playback); 3708 fixup_codec_formats(&dai_drv[i].playback);
3513 fixup_codec_formats(&dai_drv[i].capture); 3709 fixup_codec_formats(&dai_drv[i].capture);
@@ -3574,22 +3770,22 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
3574static int __init snd_soc_init(void) 3770static int __init snd_soc_init(void)
3575{ 3771{
3576#ifdef CONFIG_DEBUG_FS 3772#ifdef CONFIG_DEBUG_FS
3577 debugfs_root = debugfs_create_dir("asoc", NULL); 3773 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3578 if (IS_ERR(debugfs_root) || !debugfs_root) { 3774 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3579 printk(KERN_WARNING 3775 printk(KERN_WARNING
3580 "ASoC: Failed to create debugfs directory\n"); 3776 "ASoC: Failed to create debugfs directory\n");
3581 debugfs_root = NULL; 3777 snd_soc_debugfs_root = NULL;
3582 } 3778 }
3583 3779
3584 if (!debugfs_create_file("codecs", 0444, debugfs_root, NULL, 3780 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
3585 &codec_list_fops)) 3781 &codec_list_fops))
3586 pr_warn("ASoC: Failed to create CODEC list debugfs file\n"); 3782 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
3587 3783
3588 if (!debugfs_create_file("dais", 0444, debugfs_root, NULL, 3784 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
3589 &dai_list_fops)) 3785 &dai_list_fops))
3590 pr_warn("ASoC: Failed to create DAI list debugfs file\n"); 3786 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
3591 3787
3592 if (!debugfs_create_file("platforms", 0444, debugfs_root, NULL, 3788 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
3593 &platform_list_fops)) 3789 &platform_list_fops))
3594 pr_warn("ASoC: Failed to create platform list debugfs file\n"); 3790 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3595#endif 3791#endif
@@ -3601,7 +3797,7 @@ module_init(snd_soc_init);
3601static void __exit snd_soc_exit(void) 3797static void __exit snd_soc_exit(void)
3602{ 3798{
3603#ifdef CONFIG_DEBUG_FS 3799#ifdef CONFIG_DEBUG_FS
3604 debugfs_remove_recursive(debugfs_root); 3800 debugfs_remove_recursive(snd_soc_debugfs_root);
3605#endif 3801#endif
3606 platform_driver_unregister(&soc_driver); 3802 platform_driver_unregister(&soc_driver);
3607} 3803}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1790f83ee665..81c4052c127c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/async.h>
35#include <linux/delay.h> 36#include <linux/delay.h>
36#include <linux/pm.h> 37#include <linux/pm.h>
37#include <linux/bitops.h> 38#include <linux/bitops.h>
@@ -125,17 +126,17 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
125 126
126/** 127/**
127 * snd_soc_dapm_set_bias_level - set the bias level for the system 128 * snd_soc_dapm_set_bias_level - set the bias level for the system
128 * @card: audio device 129 * @dapm: DAPM context
129 * @level: level to configure 130 * @level: level to configure
130 * 131 *
131 * Configure the bias (power) levels for the SoC audio device. 132 * Configure the bias (power) levels for the SoC audio device.
132 * 133 *
133 * Returns 0 for success else error. 134 * Returns 0 for success else error.
134 */ 135 */
135static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, 136static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
136 struct snd_soc_dapm_context *dapm,
137 enum snd_soc_bias_level level) 137 enum snd_soc_bias_level level)
138{ 138{
139 struct snd_soc_card *card = dapm->card;
139 int ret = 0; 140 int ret = 0;
140 141
141 switch (level) { 142 switch (level) {
@@ -365,9 +366,20 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
365 struct snd_soc_dapm_widget *w) 366 struct snd_soc_dapm_widget *w)
366{ 367{
367 int i, ret = 0; 368 int i, ret = 0;
368 size_t name_len; 369 size_t name_len, prefix_len;
369 struct snd_soc_dapm_path *path; 370 struct snd_soc_dapm_path *path;
370 struct snd_card *card = dapm->codec->card->snd_card; 371 struct snd_card *card = dapm->card->snd_card;
372 const char *prefix;
373
374 if (dapm->codec)
375 prefix = dapm->codec->name_prefix;
376 else
377 prefix = NULL;
378
379 if (prefix)
380 prefix_len = strlen(prefix) + 1;
381 else
382 prefix_len = 0;
371 383
372 /* add kcontrol */ 384 /* add kcontrol */
373 for (i = 0; i < w->num_kcontrols; i++) { 385 for (i = 0; i < w->num_kcontrols; i++) {
@@ -396,8 +408,15 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
396 408
397 switch (w->id) { 409 switch (w->id) {
398 default: 410 default:
411 /* The control will get a prefix from
412 * the control creation process but
413 * we're also using the same prefix
414 * for widgets so cut the prefix off
415 * the front of the widget name.
416 */
399 snprintf(path->long_name, name_len, "%s %s", 417 snprintf(path->long_name, name_len, "%s %s",
400 w->name, w->kcontrols[i].name); 418 w->name + prefix_len,
419 w->kcontrols[i].name);
401 break; 420 break;
402 case snd_soc_dapm_mixer_named_ctl: 421 case snd_soc_dapm_mixer_named_ctl:
403 snprintf(path->long_name, name_len, "%s", 422 snprintf(path->long_name, name_len, "%s",
@@ -408,7 +427,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
408 path->long_name[name_len - 1] = '\0'; 427 path->long_name[name_len - 1] = '\0';
409 428
410 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 429 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
411 path->long_name); 430 path->long_name, prefix);
412 ret = snd_ctl_add(card, path->kcontrol); 431 ret = snd_ctl_add(card, path->kcontrol);
413 if (ret < 0) { 432 if (ret < 0) {
414 dev_err(dapm->dev, 433 dev_err(dapm->dev,
@@ -429,7 +448,9 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
429{ 448{
430 struct snd_soc_dapm_path *path = NULL; 449 struct snd_soc_dapm_path *path = NULL;
431 struct snd_kcontrol *kcontrol; 450 struct snd_kcontrol *kcontrol;
432 struct snd_card *card = dapm->codec->card->snd_card; 451 struct snd_card *card = dapm->card->snd_card;
452 const char *prefix;
453 size_t prefix_len;
433 int ret = 0; 454 int ret = 0;
434 455
435 if (!w->num_kcontrols) { 456 if (!w->num_kcontrols) {
@@ -437,7 +458,22 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
437 return -EINVAL; 458 return -EINVAL;
438 } 459 }
439 460
440 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 461 if (dapm->codec)
462 prefix = dapm->codec->name_prefix;
463 else
464 prefix = NULL;
465
466 if (prefix)
467 prefix_len = strlen(prefix) + 1;
468 else
469 prefix_len = 0;
470
471 /* The control will get a prefix from the control creation
472 * process but we're also using the same prefix for widgets so
473 * cut the prefix off the front of the widget name.
474 */
475 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name + prefix_len,
476 prefix);
441 ret = snd_ctl_add(card, kcontrol); 477 ret = snd_ctl_add(card, kcontrol);
442 478
443 if (ret < 0) 479 if (ret < 0)
@@ -479,7 +515,7 @@ static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
479 */ 515 */
480static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 516static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
481{ 517{
482 int level = snd_power_get_state(widget->dapm->codec->card->snd_card); 518 int level = snd_power_get_state(widget->dapm->card->snd_card);
483 519
484 switch (level) { 520 switch (level) {
485 case SNDRV_CTL_POWER_D3hot: 521 case SNDRV_CTL_POWER_D3hot:
@@ -734,10 +770,23 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
734 770
735static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 771static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
736 struct snd_soc_dapm_widget *b, 772 struct snd_soc_dapm_widget *b,
737 int sort[]) 773 bool power_up)
738{ 774{
775 int *sort;
776
777 if (power_up)
778 sort = dapm_up_seq;
779 else
780 sort = dapm_down_seq;
781
739 if (sort[a->id] != sort[b->id]) 782 if (sort[a->id] != sort[b->id])
740 return sort[a->id] - sort[b->id]; 783 return sort[a->id] - sort[b->id];
784 if (a->subseq != b->subseq) {
785 if (power_up)
786 return a->subseq - b->subseq;
787 else
788 return b->subseq - a->subseq;
789 }
741 if (a->reg != b->reg) 790 if (a->reg != b->reg)
742 return a->reg - b->reg; 791 return a->reg - b->reg;
743 if (a->dapm != b->dapm) 792 if (a->dapm != b->dapm)
@@ -749,12 +798,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
749/* Insert a widget in order into a DAPM power sequence. */ 798/* Insert a widget in order into a DAPM power sequence. */
750static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 799static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
751 struct list_head *list, 800 struct list_head *list,
752 int sort[]) 801 bool power_up)
753{ 802{
754 struct snd_soc_dapm_widget *w; 803 struct snd_soc_dapm_widget *w;
755 804
756 list_for_each_entry(w, list, power_list) 805 list_for_each_entry(w, list, power_list)
757 if (dapm_seq_compare(new_widget, w, sort) < 0) { 806 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
758 list_add_tail(&new_widget->power_list, &w->power_list); 807 list_add_tail(&new_widget->power_list, &w->power_list);
759 return; 808 return;
760 } 809 }
@@ -865,26 +914,42 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
865 * handled. 914 * handled.
866 */ 915 */
867static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 916static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
868 struct list_head *list, int event, int sort[]) 917 struct list_head *list, int event, bool power_up)
869{ 918{
870 struct snd_soc_dapm_widget *w, *n; 919 struct snd_soc_dapm_widget *w, *n;
871 LIST_HEAD(pending); 920 LIST_HEAD(pending);
872 int cur_sort = -1; 921 int cur_sort = -1;
922 int cur_subseq = -1;
873 int cur_reg = SND_SOC_NOPM; 923 int cur_reg = SND_SOC_NOPM;
874 struct snd_soc_dapm_context *cur_dapm = NULL; 924 struct snd_soc_dapm_context *cur_dapm = NULL;
875 int ret; 925 int ret, i;
926 int *sort;
927
928 if (power_up)
929 sort = dapm_up_seq;
930 else
931 sort = dapm_down_seq;
876 932
877 list_for_each_entry_safe(w, n, list, power_list) { 933 list_for_each_entry_safe(w, n, list, power_list) {
878 ret = 0; 934 ret = 0;
879 935
880 /* Do we need to apply any queued changes? */ 936 /* Do we need to apply any queued changes? */
881 if (sort[w->id] != cur_sort || w->reg != cur_reg || 937 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
882 w->dapm != cur_dapm) { 938 w->dapm != cur_dapm || w->subseq != cur_subseq) {
883 if (!list_empty(&pending)) 939 if (!list_empty(&pending))
884 dapm_seq_run_coalesced(cur_dapm, &pending); 940 dapm_seq_run_coalesced(cur_dapm, &pending);
885 941
942 if (cur_dapm && cur_dapm->seq_notifier) {
943 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
944 if (sort[i] == cur_sort)
945 cur_dapm->seq_notifier(cur_dapm,
946 i,
947 cur_subseq);
948 }
949
886 INIT_LIST_HEAD(&pending); 950 INIT_LIST_HEAD(&pending);
887 cur_sort = -1; 951 cur_sort = -1;
952 cur_subseq = -1;
888 cur_reg = SND_SOC_NOPM; 953 cur_reg = SND_SOC_NOPM;
889 cur_dapm = NULL; 954 cur_dapm = NULL;
890 } 955 }
@@ -929,6 +994,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
929 default: 994 default:
930 /* Queue it up for application */ 995 /* Queue it up for application */
931 cur_sort = sort[w->id]; 996 cur_sort = sort[w->id];
997 cur_subseq = w->subseq;
932 cur_reg = w->reg; 998 cur_reg = w->reg;
933 cur_dapm = w->dapm; 999 cur_dapm = w->dapm;
934 list_move(&w->power_list, &pending); 1000 list_move(&w->power_list, &pending);
@@ -942,6 +1008,13 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
942 1008
943 if (!list_empty(&pending)) 1009 if (!list_empty(&pending))
944 dapm_seq_run_coalesced(cur_dapm, &pending); 1010 dapm_seq_run_coalesced(cur_dapm, &pending);
1011
1012 if (cur_dapm && cur_dapm->seq_notifier) {
1013 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1014 if (sort[i] == cur_sort)
1015 cur_dapm->seq_notifier(cur_dapm,
1016 i, cur_subseq);
1017 }
945} 1018}
946 1019
947static void dapm_widget_update(struct snd_soc_dapm_context *dapm) 1020static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
@@ -977,7 +1050,62 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
977 } 1050 }
978} 1051}
979 1052
1053/* Async callback run prior to DAPM sequences - brings to _PREPARE if
1054 * they're changing state.
1055 */
1056static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1057{
1058 struct snd_soc_dapm_context *d = data;
1059 int ret;
980 1060
1061 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
1062 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1063 if (ret != 0)
1064 dev_err(d->dev,
1065 "Failed to turn on bias: %d\n", ret);
1066 }
1067
1068 /* If we're changing to all on or all off then prepare */
1069 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1070 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1071 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1072 if (ret != 0)
1073 dev_err(d->dev,
1074 "Failed to prepare bias: %d\n", ret);
1075 }
1076}
1077
1078/* Async callback run prior to DAPM sequences - brings to their final
1079 * state.
1080 */
1081static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1082{
1083 struct snd_soc_dapm_context *d = data;
1084 int ret;
1085
1086 /* If we just powered the last thing off drop to standby bias */
1087 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1088 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1089 if (ret != 0)
1090 dev_err(d->dev, "Failed to apply standby bias: %d\n",
1091 ret);
1092 }
1093
1094 /* If we're in standby and can support bias off then do that */
1095 if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
1096 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1097 if (ret != 0)
1098 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1099 }
1100
1101 /* If we just powered up then move to active bias */
1102 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1103 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1104 if (ret != 0)
1105 dev_err(d->dev, "Failed to apply active bias: %d\n",
1106 ret);
1107 }
1108}
981 1109
982/* 1110/*
983 * Scan each dapm widget for complete audio path. 1111 * Scan each dapm widget for complete audio path.
@@ -990,12 +1118,12 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
990 */ 1118 */
991static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) 1119static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
992{ 1120{
993 struct snd_soc_card *card = dapm->codec->card; 1121 struct snd_soc_card *card = dapm->card;
994 struct snd_soc_dapm_widget *w; 1122 struct snd_soc_dapm_widget *w;
995 struct snd_soc_dapm_context *d; 1123 struct snd_soc_dapm_context *d;
996 LIST_HEAD(up_list); 1124 LIST_HEAD(up_list);
997 LIST_HEAD(down_list); 1125 LIST_HEAD(down_list);
998 int ret = 0; 1126 LIST_HEAD(async_domain);
999 int power; 1127 int power;
1000 1128
1001 trace_snd_soc_dapm_start(card); 1129 trace_snd_soc_dapm_start(card);
@@ -1010,10 +1138,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1010 list_for_each_entry(w, &card->widgets, list) { 1138 list_for_each_entry(w, &card->widgets, list) {
1011 switch (w->id) { 1139 switch (w->id) {
1012 case snd_soc_dapm_pre: 1140 case snd_soc_dapm_pre:
1013 dapm_seq_insert(w, &down_list, dapm_down_seq); 1141 dapm_seq_insert(w, &down_list, false);
1014 break; 1142 break;
1015 case snd_soc_dapm_post: 1143 case snd_soc_dapm_post:
1016 dapm_seq_insert(w, &up_list, dapm_up_seq); 1144 dapm_seq_insert(w, &up_list, true);
1017 break; 1145 break;
1018 1146
1019 default: 1147 default:
@@ -1033,9 +1161,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1033 trace_snd_soc_dapm_widget_power(w, power); 1161 trace_snd_soc_dapm_widget_power(w, power);
1034 1162
1035 if (power) 1163 if (power)
1036 dapm_seq_insert(w, &up_list, dapm_up_seq); 1164 dapm_seq_insert(w, &up_list, true);
1037 else 1165 else
1038 dapm_seq_insert(w, &down_list, dapm_down_seq); 1166 dapm_seq_insert(w, &down_list, false);
1039 1167
1040 w->power = power; 1168 w->power = power;
1041 break; 1169 break;
@@ -1073,65 +1201,25 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1073 } 1201 }
1074 } 1202 }
1075 1203
1076 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1204 /* Run all the bias changes in parallel */
1077 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) { 1205 list_for_each_entry(d, &dapm->card->dapm_list, list)
1078 ret = snd_soc_dapm_set_bias_level(card, d, 1206 async_schedule_domain(dapm_pre_sequence_async, d,
1079 SND_SOC_BIAS_STANDBY); 1207 &async_domain);
1080 if (ret != 0) 1208 async_synchronize_full_domain(&async_domain);
1081 dev_err(d->dev,
1082 "Failed to turn on bias: %d\n", ret);
1083 }
1084
1085 /* If we're changing to all on or all off then prepare */
1086 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1087 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1088 ret = snd_soc_dapm_set_bias_level(card, d,
1089 SND_SOC_BIAS_PREPARE);
1090 if (ret != 0)
1091 dev_err(d->dev,
1092 "Failed to prepare bias: %d\n", ret);
1093 }
1094 }
1095 1209
1096 /* Power down widgets first; try to avoid amplifying pops. */ 1210 /* Power down widgets first; try to avoid amplifying pops. */
1097 dapm_seq_run(dapm, &down_list, event, dapm_down_seq); 1211 dapm_seq_run(dapm, &down_list, event, false);
1098 1212
1099 dapm_widget_update(dapm); 1213 dapm_widget_update(dapm);
1100 1214
1101 /* Now power up. */ 1215 /* Now power up. */
1102 dapm_seq_run(dapm, &up_list, event, dapm_up_seq); 1216 dapm_seq_run(dapm, &up_list, event, true);
1103
1104 list_for_each_entry(d, &dapm->card->dapm_list, list) {
1105 /* If we just powered the last thing off drop to standby bias */
1106 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1107 ret = snd_soc_dapm_set_bias_level(card, d,
1108 SND_SOC_BIAS_STANDBY);
1109 if (ret != 0)
1110 dev_err(d->dev,
1111 "Failed to apply standby bias: %d\n",
1112 ret);
1113 }
1114 1217
1115 /* If we're in standby and can support bias off then do that */ 1218 /* Run all the bias changes in parallel */
1116 if (d->bias_level == SND_SOC_BIAS_STANDBY && 1219 list_for_each_entry(d, &dapm->card->dapm_list, list)
1117 d->idle_bias_off) { 1220 async_schedule_domain(dapm_post_sequence_async, d,
1118 ret = snd_soc_dapm_set_bias_level(card, d, 1221 &async_domain);
1119 SND_SOC_BIAS_OFF); 1222 async_synchronize_full_domain(&async_domain);
1120 if (ret != 0)
1121 dev_err(d->dev,
1122 "Failed to turn off bias: %d\n", ret);
1123 }
1124
1125 /* If we just powered up then move to active bias */
1126 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1127 ret = snd_soc_dapm_set_bias_level(card, d,
1128 SND_SOC_BIAS_ON);
1129 if (ret != 0)
1130 dev_err(d->dev,
1131 "Failed to apply active bias: %d\n",
1132 ret);
1133 }
1134 }
1135 1223
1136 pop_dbg(dapm->dev, card->pop_time, 1224 pop_dbg(dapm->dev, card->pop_time,
1137 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1225 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
@@ -1189,7 +1277,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1189 1277
1190 if (p->connect) 1278 if (p->connect)
1191 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1279 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1192 " in %s %s\n", 1280 " in \"%s\" \"%s\"\n",
1193 p->name ? p->name : "static", 1281 p->name ? p->name : "static",
1194 p->source->name); 1282 p->source->name);
1195 } 1283 }
@@ -1199,7 +1287,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1199 1287
1200 if (p->connect) 1288 if (p->connect)
1201 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1289 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1202 " out %s %s\n", 1290 " out \"%s\" \"%s\"\n",
1203 p->name ? p->name : "static", 1291 p->name ? p->name : "static",
1204 p->sink->name); 1292 p->sink->name);
1205 } 1293 }
@@ -1464,7 +1552,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1464 char prefixed_source[80]; 1552 char prefixed_source[80];
1465 int ret = 0; 1553 int ret = 0;
1466 1554
1467 if (dapm->codec->name_prefix) { 1555 if (dapm->codec && dapm->codec->name_prefix) {
1468 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 1556 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1469 dapm->codec->name_prefix, route->sink); 1557 dapm->codec->name_prefix, route->sink);
1470 sink = prefixed_sink; 1558 sink = prefixed_sink;
@@ -2114,14 +2202,14 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2114 return -ENOMEM; 2202 return -ENOMEM;
2115 2203
2116 name_len = strlen(widget->name) + 1; 2204 name_len = strlen(widget->name) + 1;
2117 if (dapm->codec->name_prefix) 2205 if (dapm->codec && dapm->codec->name_prefix)
2118 name_len += 1 + strlen(dapm->codec->name_prefix); 2206 name_len += 1 + strlen(dapm->codec->name_prefix);
2119 w->name = kmalloc(name_len, GFP_KERNEL); 2207 w->name = kmalloc(name_len, GFP_KERNEL);
2120 if (w->name == NULL) { 2208 if (w->name == NULL) {
2121 kfree(w); 2209 kfree(w);
2122 return -ENOMEM; 2210 return -ENOMEM;
2123 } 2211 }
2124 if (dapm->codec->name_prefix) 2212 if (dapm->codec && dapm->codec->name_prefix)
2125 snprintf(w->name, name_len, "%s %s", 2213 snprintf(w->name, name_len, "%s %s",
2126 dapm->codec->name_prefix, widget->name); 2214 dapm->codec->name_prefix, widget->name);
2127 else 2215 else
@@ -2226,7 +2314,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2226 mutex_unlock(&codec->mutex); 2314 mutex_unlock(&codec->mutex);
2227 return 0; 2315 return 0;
2228} 2316}
2229EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2230 2317
2231/** 2318/**
2232 * snd_soc_dapm_enable_pin - enable pin. 2319 * snd_soc_dapm_enable_pin - enable pin.
@@ -2393,7 +2480,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2393 if (w->dapm != dapm) 2480 if (w->dapm != dapm)
2394 continue; 2481 continue;
2395 if (w->power) { 2482 if (w->power) {
2396 dapm_seq_insert(w, &down_list, dapm_down_seq); 2483 dapm_seq_insert(w, &down_list, false);
2397 w->power = 0; 2484 w->power = 0;
2398 powerdown = 1; 2485 powerdown = 1;
2399 } 2486 }
@@ -2403,9 +2490,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2403 * standby. 2490 * standby.
2404 */ 2491 */
2405 if (powerdown) { 2492 if (powerdown) {
2406 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2493 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
2407 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); 2494 dapm_seq_run(dapm, &down_list, 0, false);
2408 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); 2495 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
2409 } 2496 }
2410} 2497}
2411 2498
@@ -2418,7 +2505,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2418 2505
2419 list_for_each_entry(codec, &card->codec_dev_list, list) { 2506 list_for_each_entry(codec, &card->codec_dev_list, list) {
2420 soc_dapm_shutdown_codec(&codec->dapm); 2507 soc_dapm_shutdown_codec(&codec->dapm);
2421 snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); 2508 snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
2422 } 2509 }
2423} 2510}
2424 2511
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index ac5a5bc7375a..fcab80b36a37 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
37{ 37{
38 jack->codec = codec; 38 jack->codec = codec;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 INIT_LIST_HEAD(&jack->jack_zones);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 41 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
41 42
42 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack); 43 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
@@ -100,7 +101,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
100 } 101 }
101 102
102 /* Report before the DAPM sync to help users updating micbias status */ 103 /* Report before the DAPM sync to help users updating micbias status */
103 blocking_notifier_call_chain(&jack->notifier, status, NULL); 104 blocking_notifier_call_chain(&jack->notifier, status, jack);
104 105
105 snd_soc_dapm_sync(dapm); 106 snd_soc_dapm_sync(dapm);
106 107
@@ -112,6 +113,51 @@ out:
112EXPORT_SYMBOL_GPL(snd_soc_jack_report); 113EXPORT_SYMBOL_GPL(snd_soc_jack_report);
113 114
114/** 115/**
116 * snd_soc_jack_add_zones - Associate voltage zones with jack
117 *
118 * @jack: ASoC jack
119 * @count: Number of zones
120 * @zone: Array of zones
121 *
122 * After this function has been called the zones specified in the
123 * array will be associated with the jack.
124 */
125int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
126 struct snd_soc_jack_zone *zones)
127{
128 int i;
129
130 for (i = 0; i < count; i++) {
131 INIT_LIST_HEAD(&zones[i].list);
132 list_add(&(zones[i].list), &jack->jack_zones);
133 }
134 return 0;
135}
136EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones);
137
138/**
139 * snd_soc_jack_get_type - Based on the mic bias value, this function returns
140 * the type of jack from the zones delcared in the jack type
141 *
142 * @micbias_voltage: mic bias voltage at adc channel when jack is plugged in
143 *
144 * Based on the mic bias value passed, this function helps identify
145 * the type of jack from the already delcared jack zones
146 */
147int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage)
148{
149 struct snd_soc_jack_zone *zone;
150
151 list_for_each_entry(zone, &jack->jack_zones, list) {
152 if (micbias_voltage >= zone->min_mv &&
153 micbias_voltage < zone->max_mv)
154 return zone->jack_type;
155 }
156 return 0;
157}
158EXPORT_SYMBOL_GPL(snd_soc_jack_get_type);
159
160/**
115 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack 161 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
116 * 162 *
117 * @jack: ASoC jack 163 * @jack: ASoC jack
@@ -194,7 +240,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
194 int enable; 240 int enable;
195 int report; 241 int report;
196 242
197 enable = gpio_get_value(gpio->gpio); 243 enable = gpio_get_value_cansleep(gpio->gpio);
198 if (gpio->invert) 244 if (gpio->invert)
199 enable = !enable; 245 enable = !enable;
200 246
@@ -284,6 +330,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
284 if (ret) 330 if (ret)
285 goto err; 331 goto err;
286 332
333 if (gpios[i].wake) {
334 ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
335 if (ret != 0)
336 printk(KERN_ERR
337 "Failed to mark GPIO %d as wake source: %d\n",
338 gpios[i].gpio, ret);
339 }
340
287#ifdef CONFIG_GPIO_SYSFS 341#ifdef CONFIG_GPIO_SYSFS
288 /* Expose GPIO value over sysfs for diagnostic purposes */ 342 /* Expose GPIO value over sysfs for diagnostic purposes */
289 gpio_export(gpios[i].gpio, false); 343 gpio_export(gpios[i].gpio, false);
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 1d07b931f3d8..3f45e6a439bf 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -28,26 +28,9 @@ int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
28{ 28{
29 int sample_size; 29 int sample_size;
30 30
31 switch (params_format(params)) { 31 sample_size = snd_pcm_format_width(params_format(params));
32 case SNDRV_PCM_FORMAT_S16_LE: 32 if (sample_size < 0)
33 case SNDRV_PCM_FORMAT_S16_BE: 33 return sample_size;
34 sample_size = 16;
35 break;
36 case SNDRV_PCM_FORMAT_S20_3LE:
37 case SNDRV_PCM_FORMAT_S20_3BE:
38 sample_size = 20;
39 break;
40 case SNDRV_PCM_FORMAT_S24_LE:
41 case SNDRV_PCM_FORMAT_S24_BE:
42 sample_size = 24;
43 break;
44 case SNDRV_PCM_FORMAT_S32_LE:
45 case SNDRV_PCM_FORMAT_S32_BE:
46 sample_size = 32;
47 break;
48 default:
49 return -ENOTSUPP;
50 }
51 34
52 return snd_soc_calc_frame_size(sample_size, params_channels(params), 35 return snd_soc_calc_frame_size(sample_size, params_channels(params),
53 1); 36 1);
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
new file mode 100644
index 000000000000..66b504f06c23
--- /dev/null
+++ b/sound/soc/tegra/Kconfig
@@ -0,0 +1,26 @@
1config SND_TEGRA_SOC
2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
4 default m
5 help
6 Say Y or M here if you want support for SoC audio on Tegra.
7
8config SND_TEGRA_SOC_I2S
9 tristate
10 depends on SND_TEGRA_SOC
11 default m
12 help
13 Say Y or M if you want to add support for codecs attached to the
14 Tegra I2S interface. You will also need to select the individual
15 machine drivers to support below.
16
17config SND_TEGRA_SOC_HARMONY
18 tristate "SoC Audio support for Tegra Harmony reference board"
19 depends on SND_TEGRA_SOC && MACH_HARMONY && I2C
20 default m
21 select SND_TEGRA_SOC_I2S
22 select SND_SOC_WM8903
23 help
24 Say Y or M here if you want to add support for SoC audio on the
25 Tegra Harmony reference board.
26
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
new file mode 100644
index 000000000000..fd183d3ab4f1
--- /dev/null
+++ b/sound/soc/tegra/Makefile
@@ -0,0 +1,15 @@
1# Tegra platform Support
2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o
6
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o
8obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o
9obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o
10obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o
11
12# Tegra machine Support
13snd-soc-tegra-harmony-objs := harmony.o
14
15obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
new file mode 100644
index 000000000000..8585957477eb
--- /dev/null
+++ b/sound/soc/tegra/harmony.c
@@ -0,0 +1,393 @@
1/*
2 * harmony.c - Harmony machine ASoC driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/harmony_audio.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/wm8903.h"
47
48#include "tegra_das.h"
49#include "tegra_i2s.h"
50#include "tegra_pcm.h"
51#include "tegra_asoc_utils.h"
52
53#define DRV_NAME "tegra-snd-harmony"
54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_INT_MIC_EN BIT(1)
57#define GPIO_EXT_MIC_EN BIT(2)
58
59struct tegra_harmony {
60 struct tegra_asoc_utils_data util_data;
61 struct harmony_audio_platform_data *pdata;
62 int gpio_requested;
63};
64
65static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card;
73 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
74 int srate, mclk, mclk_change;
75 int err;
76
77 srate = params_rate(params);
78 switch (srate) {
79 case 64000:
80 case 88200:
81 case 96000:
82 mclk = 128 * srate;
83 break;
84 default:
85 mclk = 256 * srate;
86 break;
87 }
88 /* FIXME: Codec only requires >= 3MHz if OSR==0 */
89 while (mclk < 6000000)
90 mclk *= 2;
91
92 err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk,
93 &mclk_change);
94 if (err < 0) {
95 dev_err(card->dev, "Can't configure clocks\n");
96 return err;
97 }
98
99 err = snd_soc_dai_set_fmt(codec_dai,
100 SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBS_CFS);
103 if (err < 0) {
104 dev_err(card->dev, "codec_dai fmt not set\n");
105 return err;
106 }
107
108 err = snd_soc_dai_set_fmt(cpu_dai,
109 SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 if (mclk_change) {
118 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
119 SND_SOC_CLOCK_IN);
120 if (err < 0) {
121 dev_err(card->dev, "codec_dai clock not set\n");
122 return err;
123 }
124 }
125
126 return 0;
127}
128
129static struct snd_soc_ops harmony_asoc_ops = {
130 .hw_params = harmony_asoc_hw_params,
131};
132
133static struct snd_soc_jack harmony_hp_jack;
134
135static struct snd_soc_jack_pin harmony_hp_jack_pins[] = {
136 {
137 .pin = "Headphone Jack",
138 .mask = SND_JACK_HEADPHONE,
139 },
140};
141
142static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = {
143 {
144 .name = "headphone detect",
145 .report = SND_JACK_HEADPHONE,
146 .debounce_time = 150,
147 .invert = 1,
148 }
149};
150
151static struct snd_soc_jack harmony_mic_jack;
152
153static struct snd_soc_jack_pin harmony_mic_jack_pins[] = {
154 {
155 .pin = "Mic Jack",
156 .mask = SND_JACK_MICROPHONE,
157 },
158};
159
160static int harmony_event_int_spk(struct snd_soc_dapm_widget *w,
161 struct snd_kcontrol *k, int event)
162{
163 struct snd_soc_codec *codec = w->codec;
164 struct snd_soc_card *card = codec->card;
165 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
166 struct harmony_audio_platform_data *pdata = harmony->pdata;
167
168 gpio_set_value_cansleep(pdata->gpio_spkr_en,
169 SND_SOC_DAPM_EVENT_ON(event));
170
171 return 0;
172}
173
174static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
175 SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk),
176 SND_SOC_DAPM_HP("Headphone Jack", NULL),
177 SND_SOC_DAPM_MIC("Mic Jack", NULL),
178};
179
180static const struct snd_soc_dapm_route harmony_audio_map[] = {
181 {"Headphone Jack", NULL, "HPOUTR"},
182 {"Headphone Jack", NULL, "HPOUTL"},
183 {"Int Spk", NULL, "ROP"},
184 {"Int Spk", NULL, "RON"},
185 {"Int Spk", NULL, "LOP"},
186 {"Int Spk", NULL, "LON"},
187 {"Mic Bias", NULL, "Mic Jack"},
188 {"IN1L", NULL, "Mic Bias"},
189};
190
191static const struct snd_kcontrol_new harmony_controls[] = {
192 SOC_DAPM_PIN_SWITCH("Int Spk"),
193};
194
195static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
196{
197 struct snd_soc_codec *codec = rtd->codec;
198 struct snd_soc_dapm_context *dapm = &codec->dapm;
199 struct snd_soc_card *card = codec->card;
200 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
201 struct harmony_audio_platform_data *pdata = harmony->pdata;
202 int ret;
203
204 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
205 if (ret) {
206 dev_err(card->dev, "cannot get spkr_en gpio\n");
207 return ret;
208 }
209 harmony->gpio_requested |= GPIO_SPKR_EN;
210
211 gpio_direction_output(pdata->gpio_spkr_en, 0);
212
213 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
214 if (ret) {
215 dev_err(card->dev, "cannot get int_mic_en gpio\n");
216 return ret;
217 }
218 harmony->gpio_requested |= GPIO_INT_MIC_EN;
219
220 /* Disable int mic; enable signal is active-high */
221 gpio_direction_output(pdata->gpio_int_mic_en, 0);
222
223 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
224 if (ret) {
225 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
226 return ret;
227 }
228 harmony->gpio_requested |= GPIO_EXT_MIC_EN;
229
230 /* Enable ext mic; enable signal is active-low */
231 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
232
233 ret = snd_soc_add_controls(codec, harmony_controls,
234 ARRAY_SIZE(harmony_controls));
235 if (ret < 0)
236 return ret;
237
238 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
239 ARRAY_SIZE(harmony_dapm_widgets));
240
241 snd_soc_dapm_add_routes(dapm, harmony_audio_map,
242 ARRAY_SIZE(harmony_audio_map));
243
244 harmony_hp_jack_gpios[0].gpio = pdata->gpio_hp_det;
245 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
246 &harmony_hp_jack);
247 snd_soc_jack_add_pins(&harmony_hp_jack,
248 ARRAY_SIZE(harmony_hp_jack_pins),
249 harmony_hp_jack_pins);
250 snd_soc_jack_add_gpios(&harmony_hp_jack,
251 ARRAY_SIZE(harmony_hp_jack_gpios),
252 harmony_hp_jack_gpios);
253
254 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
255 &harmony_mic_jack);
256 snd_soc_jack_add_pins(&harmony_mic_jack,
257 ARRAY_SIZE(harmony_mic_jack_pins),
258 harmony_mic_jack_pins);
259 wm8903_mic_detect(codec, &harmony_mic_jack, SND_JACK_MICROPHONE, 0);
260
261 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
262
263 snd_soc_dapm_nc_pin(dapm, "IN3L");
264 snd_soc_dapm_nc_pin(dapm, "IN3R");
265 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
266 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
267
268 snd_soc_dapm_sync(dapm);
269
270 return 0;
271}
272
273static struct snd_soc_dai_link harmony_wm8903_dai = {
274 .name = "WM8903",
275 .stream_name = "WM8903 PCM",
276 .codec_name = "wm8903.0-001a",
277 .platform_name = "tegra-pcm-audio",
278 .cpu_dai_name = "tegra-i2s.0",
279 .codec_dai_name = "wm8903-hifi",
280 .init = harmony_asoc_init,
281 .ops = &harmony_asoc_ops,
282};
283
284static struct snd_soc_card snd_soc_harmony = {
285 .name = "tegra-harmony",
286 .dai_link = &harmony_wm8903_dai,
287 .num_links = 1,
288};
289
290static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev)
291{
292 struct snd_soc_card *card = &snd_soc_harmony;
293 struct tegra_harmony *harmony;
294 struct harmony_audio_platform_data *pdata;
295 int ret;
296
297 if (!machine_is_harmony()) {
298 dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
299 return -ENODEV;
300 }
301
302 pdata = pdev->dev.platform_data;
303 if (!pdata) {
304 dev_err(&pdev->dev, "no platform data supplied\n");
305 return -EINVAL;
306 }
307
308 harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL);
309 if (!harmony) {
310 dev_err(&pdev->dev, "Can't allocate tegra_harmony\n");
311 return -ENOMEM;
312 }
313
314 harmony->pdata = pdata;
315
316 ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev);
317 if (ret)
318 goto err_free_harmony;
319
320 card->dev = &pdev->dev;
321 platform_set_drvdata(pdev, card);
322 snd_soc_card_set_drvdata(card, harmony);
323
324 ret = snd_soc_register_card(card);
325 if (ret) {
326 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
327 ret);
328 goto err_clear_drvdata;
329 }
330
331 return 0;
332
333err_clear_drvdata:
334 snd_soc_card_set_drvdata(card, NULL);
335 platform_set_drvdata(pdev, NULL);
336 card->dev = NULL;
337 tegra_asoc_utils_fini(&harmony->util_data);
338err_free_harmony:
339 kfree(harmony);
340 return ret;
341}
342
343static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev)
344{
345 struct snd_soc_card *card = platform_get_drvdata(pdev);
346 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
347 struct harmony_audio_platform_data *pdata = harmony->pdata;
348
349 snd_soc_unregister_card(card);
350
351 snd_soc_card_set_drvdata(card, NULL);
352 platform_set_drvdata(pdev, NULL);
353 card->dev = NULL;
354
355 tegra_asoc_utils_fini(&harmony->util_data);
356
357 if (harmony->gpio_requested & GPIO_EXT_MIC_EN)
358 gpio_free(pdata->gpio_ext_mic_en);
359 if (harmony->gpio_requested & GPIO_INT_MIC_EN)
360 gpio_free(pdata->gpio_int_mic_en);
361 if (harmony->gpio_requested & GPIO_SPKR_EN)
362 gpio_free(pdata->gpio_spkr_en);
363
364 kfree(harmony);
365
366 return 0;
367}
368
369static struct platform_driver tegra_snd_harmony_driver = {
370 .driver = {
371 .name = DRV_NAME,
372 .owner = THIS_MODULE,
373 },
374 .probe = tegra_snd_harmony_probe,
375 .remove = __devexit_p(tegra_snd_harmony_remove),
376};
377
378static int __init snd_tegra_harmony_init(void)
379{
380 return platform_driver_register(&tegra_snd_harmony_driver);
381}
382module_init(snd_tegra_harmony_init);
383
384static void __exit snd_tegra_harmony_exit(void)
385{
386 platform_driver_unregister(&tegra_snd_harmony_driver);
387}
388module_exit(snd_tegra_harmony_exit);
389
390MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
391MODULE_DESCRIPTION("Harmony machine ASoC driver");
392MODULE_LICENSE("GPL");
393MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
new file mode 100644
index 000000000000..52f0a3f9ce40
--- /dev/null
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -0,0 +1,155 @@
1/*
2 * tegra_asoc_utils.c - Harmony machine ASoC driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/device.h>
25#include <linux/err.h>
26#include <linux/kernel.h>
27
28#include "tegra_asoc_utils.h"
29
30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
31 int mclk, int *mclk_change)
32{
33 int new_baseclock;
34 int err;
35
36 switch (srate) {
37 case 11025:
38 case 22050:
39 case 44100:
40 case 88200:
41 new_baseclock = 56448000;
42 break;
43 case 8000:
44 case 16000:
45 case 32000:
46 case 48000:
47 case 64000:
48 case 96000:
49 new_baseclock = 73728000;
50 break;
51 default:
52 return -EINVAL;
53 }
54
55 *mclk_change = ((new_baseclock != data->set_baseclock) ||
56 (mclk != data->set_mclk));
57 if (!*mclk_change)
58 return 0;
59
60 data->set_baseclock = 0;
61 data->set_mclk = 0;
62
63 clk_disable(data->clk_cdev1);
64 clk_disable(data->clk_pll_a_out0);
65 clk_disable(data->clk_pll_a);
66
67 err = clk_set_rate(data->clk_pll_a, new_baseclock);
68 if (err) {
69 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
70 return err;
71 }
72
73 err = clk_set_rate(data->clk_pll_a_out0, mclk);
74 if (err) {
75 dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
76 return err;
77 }
78
79 /* Don't set cdev1 rate; its locked to pll_a_out0 */
80
81 err = clk_enable(data->clk_pll_a);
82 if (err) {
83 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
84 return err;
85 }
86
87 err = clk_enable(data->clk_pll_a_out0);
88 if (err) {
89 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
90 return err;
91 }
92
93 err = clk_enable(data->clk_cdev1);
94 if (err) {
95 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
96 return err;
97 }
98
99 data->set_baseclock = new_baseclock;
100 data->set_mclk = mclk;
101
102 return 0;
103}
104EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
105
106int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
107 struct device *dev)
108{
109 int ret;
110
111 data->dev = dev;
112
113 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
114 if (IS_ERR(data->clk_pll_a)) {
115 dev_err(data->dev, "Can't retrieve clk pll_a\n");
116 ret = PTR_ERR(data->clk_pll_a);
117 goto err;
118 }
119
120 data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
121 if (IS_ERR(data->clk_pll_a_out0)) {
122 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
123 ret = PTR_ERR(data->clk_pll_a_out0);
124 goto err_put_pll_a;
125 }
126
127 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
128 if (IS_ERR(data->clk_cdev1)) {
129 dev_err(data->dev, "Can't retrieve clk cdev1\n");
130 ret = PTR_ERR(data->clk_cdev1);
131 goto err_put_pll_a_out0;
132 }
133
134 return 0;
135
136err_put_pll_a_out0:
137 clk_put(data->clk_pll_a_out0);
138err_put_pll_a:
139 clk_put(data->clk_pll_a);
140err:
141 return ret;
142}
143EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
144
145void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
146{
147 clk_put(data->clk_cdev1);
148 clk_put(data->clk_pll_a_out0);
149 clk_put(data->clk_pll_a);
150}
151EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
152
153MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
154MODULE_DESCRIPTION("Tegra ASoC utility code");
155MODULE_LICENSE("GPL");
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
new file mode 100644
index 000000000000..bbba7afdfc2c
--- /dev/null
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -0,0 +1,45 @@
1/*
2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA_ASOC_UTILS_H__
24#define __TEGRA_ASOC_UTILS_H_
25
26struct clk;
27struct device;
28
29struct tegra_asoc_utils_data {
30 struct device *dev;
31 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1;
34 int set_baseclock;
35 int set_mclk;
36};
37
38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
39 int mclk, int *mclk_change);
40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
41 struct device *dev);
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
43
44#endif
45
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
new file mode 100644
index 000000000000..9f24ef73f2cb
--- /dev/null
+++ b/sound/soc/tegra/tegra_das.c
@@ -0,0 +1,265 @@
1/*
2 * tegra_das.c - Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/debugfs.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/seq_file.h>
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <mach/iomap.h>
31#include <sound/soc.h>
32#include "tegra_das.h"
33
34#define DRV_NAME "tegra-das"
35
36static struct tegra_das *das;
37
38static inline void tegra_das_write(u32 reg, u32 val)
39{
40 __raw_writel(val, das->regs + reg);
41}
42
43static inline u32 tegra_das_read(u32 reg)
44{
45 return __raw_readl(das->regs + reg);
46}
47
48int tegra_das_connect_dap_to_dac(int dap, int dac)
49{
50 u32 addr;
51 u32 reg;
52
53 if (!das)
54 return -ENODEV;
55
56 addr = TEGRA_DAS_DAP_CTRL_SEL +
57 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
58 reg = dac << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
59
60 tegra_das_write(addr, reg);
61
62 return 0;
63}
64EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
65
66int tegra_das_connect_dap_to_dap(int dap, int otherdap, int master,
67 int sdata1rx, int sdata2rx)
68{
69 u32 addr;
70 u32 reg;
71
72 if (!das)
73 return -ENODEV;
74
75 addr = TEGRA_DAS_DAP_CTRL_SEL +
76 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
77 reg = otherdap << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
78 !!sdata2rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
79 !!sdata1rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
80 !!master << TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
81
82 tegra_das_write(addr, reg);
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
87
88int tegra_das_connect_dac_to_dap(int dac, int dap)
89{
90 u32 addr;
91 u32 reg;
92
93 if (!das)
94 return -ENODEV;
95
96 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
97 (dac * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
98 reg = dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
99 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
100 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
101
102 tegra_das_write(addr, reg);
103
104 return 0;
105}
106EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
107
108#ifdef CONFIG_DEBUG_FS
109static int tegra_das_show(struct seq_file *s, void *unused)
110{
111 int i;
112 u32 addr;
113 u32 reg;
114
115 for (i = 0; i < TEGRA_DAS_DAP_CTRL_SEL_COUNT; i++) {
116 addr = TEGRA_DAS_DAP_CTRL_SEL +
117 (i * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
118 reg = tegra_das_read(addr);
119 seq_printf(s, "TEGRA_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
120 }
121
122 for (i = 0; i < TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
123 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
124 (i * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
125 reg = tegra_das_read(addr);
126 seq_printf(s, "TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
127 i, reg);
128 }
129
130 return 0;
131}
132
133static int tegra_das_debug_open(struct inode *inode, struct file *file)
134{
135 return single_open(file, tegra_das_show, inode->i_private);
136}
137
138static const struct file_operations tegra_das_debug_fops = {
139 .open = tegra_das_debug_open,
140 .read = seq_read,
141 .llseek = seq_lseek,
142 .release = single_release,
143};
144
145static void tegra_das_debug_add(struct tegra_das *das)
146{
147 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
148 snd_soc_debugfs_root, das,
149 &tegra_das_debug_fops);
150}
151
152static void tegra_das_debug_remove(struct tegra_das *das)
153{
154 if (das->debug)
155 debugfs_remove(das->debug);
156}
157#else
158static inline void tegra_das_debug_add(struct tegra_das *das)
159{
160}
161
162static inline void tegra_das_debug_remove(struct tegra_das *das)
163{
164}
165#endif
166
167static int __devinit tegra_das_probe(struct platform_device *pdev)
168{
169 struct resource *res, *region;
170 int ret = 0;
171
172 if (das)
173 return -ENODEV;
174
175 das = kzalloc(sizeof(struct tegra_das), GFP_KERNEL);
176 if (!das) {
177 dev_err(&pdev->dev, "Can't allocate tegra_das\n");
178 ret = -ENOMEM;
179 goto exit;
180 }
181 das->dev = &pdev->dev;
182
183 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 if (!res) {
185 dev_err(&pdev->dev, "No memory resource\n");
186 ret = -ENODEV;
187 goto err_free;
188 }
189
190 region = request_mem_region(res->start, resource_size(res),
191 pdev->name);
192 if (!region) {
193 dev_err(&pdev->dev, "Memory region already claimed\n");
194 ret = -EBUSY;
195 goto err_free;
196 }
197
198 das->regs = ioremap(res->start, resource_size(res));
199 if (!das->regs) {
200 dev_err(&pdev->dev, "ioremap failed\n");
201 ret = -ENOMEM;
202 goto err_release;
203 }
204
205 tegra_das_debug_add(das);
206
207 platform_set_drvdata(pdev, das);
208
209 return 0;
210
211err_release:
212 release_mem_region(res->start, resource_size(res));
213err_free:
214 kfree(das);
215 das = 0;
216exit:
217 return ret;
218}
219
220static int __devexit tegra_das_remove(struct platform_device *pdev)
221{
222 struct resource *res;
223
224 if (!das)
225 return -ENODEV;
226
227 platform_set_drvdata(pdev, NULL);
228
229 tegra_das_debug_remove(das);
230
231 iounmap(das->regs);
232
233 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
234 release_mem_region(res->start, resource_size(res));
235
236 kfree(das);
237 das = 0;
238
239 return 0;
240}
241
242static struct platform_driver tegra_das_driver = {
243 .probe = tegra_das_probe,
244 .remove = __devexit_p(tegra_das_remove),
245 .driver = {
246 .name = DRV_NAME,
247 },
248};
249
250static int __init tegra_das_modinit(void)
251{
252 return platform_driver_register(&tegra_das_driver);
253}
254module_init(tegra_das_modinit);
255
256static void __exit tegra_das_modexit(void)
257{
258 platform_driver_unregister(&tegra_das_driver);
259}
260module_exit(tegra_das_modexit);
261
262MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
263MODULE_DESCRIPTION("Tegra DAS driver");
264MODULE_LICENSE("GPL");
265MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_das.h b/sound/soc/tegra/tegra_das.h
new file mode 100644
index 000000000000..2c96c7b3c459
--- /dev/null
+++ b/sound/soc/tegra/tegra_das.h
@@ -0,0 +1,135 @@
1/*
2 * tegra_das.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA_DAS_H__
24#define __TEGRA_DAS_H__
25
26/* Register TEGRA_DAS_DAP_CTRL_SEL */
27#define TEGRA_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA_DAS_DAP_SEL_DAC1 0
41#define TEGRA_DAS_DAP_SEL_DAC2 1
42#define TEGRA_DAS_DAP_SEL_DAC3 2
43#define TEGRA_DAS_DAP_SEL_DAP1 16
44#define TEGRA_DAS_DAP_SEL_DAP2 17
45#define TEGRA_DAS_DAP_SEL_DAP3 18
46#define TEGRA_DAS_DAP_SEL_DAP4 19
47#define TEGRA_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA_DAS_DAC_SEL_DAP1 0
67#define TEGRA_DAS_DAC_SEL_DAP2 1
68#define TEGRA_DAS_DAC_SEL_DAP3 2
69#define TEGRA_DAS_DAC_SEL_DAP4 3
70#define TEGRA_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA_DAS_DAP_ID_1 0
77#define TEGRA_DAS_DAP_ID_2 1
78#define TEGRA_DAS_DAP_ID_3 2
79#define TEGRA_DAS_DAP_ID_4 3
80#define TEGRA_DAS_DAP_ID_5 4
81
82#define TEGRA_DAS_DAC_ID_1 0
83#define TEGRA_DAS_DAC_ID_2 1
84#define TEGRA_DAS_DAC_ID_3 2
85
86struct tegra_das {
87 struct device *dev;
88 void __iomem *regs;
89 struct dentry *debug;
90};
91
92/*
93 * Terminology:
94 * DAS: Digital audio switch (HW module controlled by this driver)
95 * DAP: Digital audio port (port/pins on Tegra device)
96 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
97 *
98 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
99 * DAC, or another DAP. When DAPs are connected, one must be the master and
100 * one the slave. Each DAC allows selection of a specific DAP for input, to
101 * cater for the case where N DAPs are connected to 1 DAC for broadcast
102 * output.
103 *
104 * This driver is dumb; no attempt is made to ensure that a valid routing
105 * configuration is programmed.
106 */
107
108/*
109 * Connect a DAP to to a DAC
110 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA_DAS_DAP_SEL_DAC*
112 */
113extern int tegra_das_connect_dap_to_dac(int dap_id, int dac_sel);
114
115/*
116 * Connect a DAP to to another DAP
117 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA_DAS_DAP_SEL_DAP*
119 * master: Is this DAP the master (1) or slave (0)
120 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
121 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
122 */
123extern int tegra_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
124 int master, int sdata1rx,
125 int sdata2rx);
126
127/*
128 * Connect a DAC's input to a DAP
129 * (DAC outputs are selected by the DAP)
130 * dac_id: DAC ID to connect: TEGRA_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA_DAS_DAC_SEL_DAP*
132 */
133extern int tegra_das_connect_dac_to_dap(int dac_id, int dap_sel);
134
135#endif
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
new file mode 100644
index 000000000000..4f5e2c90b020
--- /dev/null
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -0,0 +1,503 @@
1/*
2 * tegra_i2s.c - Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h>
34#include <linux/device.h>
35#include <linux/platform_device.h>
36#include <linux/seq_file.h>
37#include <linux/slab.h>
38#include <linux/io.h>
39#include <mach/iomap.h>
40#include <sound/core.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
43#include <sound/soc.h>
44
45#include "tegra_das.h"
46#include "tegra_i2s.h"
47
48#define DRV_NAME "tegra-i2s"
49
50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val)
51{
52 __raw_writel(val, i2s->regs + reg);
53}
54
55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg)
56{
57 return __raw_readl(i2s->regs + reg);
58}
59
60#ifdef CONFIG_DEBUG_FS
61static int tegra_i2s_show(struct seq_file *s, void *unused)
62{
63#define REG(r) { r, #r }
64 static const struct {
65 int offset;
66 const char *name;
67 } regs[] = {
68 REG(TEGRA_I2S_CTRL),
69 REG(TEGRA_I2S_STATUS),
70 REG(TEGRA_I2S_TIMING),
71 REG(TEGRA_I2S_FIFO_SCR),
72 REG(TEGRA_I2S_PCM_CTRL),
73 REG(TEGRA_I2S_NW_CTRL),
74 REG(TEGRA_I2S_TDM_CTRL),
75 REG(TEGRA_I2S_TDM_TX_RX_CTRL),
76 };
77#undef REG
78
79 struct tegra_i2s *i2s = s->private;
80 int i;
81
82 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_i2s_read(i2s, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 }
86
87 return 0;
88}
89
90static int tegra_i2s_debug_open(struct inode *inode, struct file *file)
91{
92 return single_open(file, tegra_i2s_show, inode->i_private);
93}
94
95static const struct file_operations tegra_i2s_debug_fops = {
96 .open = tegra_i2s_debug_open,
97 .read = seq_read,
98 .llseek = seq_lseek,
99 .release = single_release,
100};
101
102static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
103{
104 char name[] = DRV_NAME ".0";
105
106 snprintf(name, sizeof(name), DRV_NAME".%1d", id);
107 i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
108 i2s, &tegra_i2s_debug_fops);
109}
110
111static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
112{
113 if (i2s->debug)
114 debugfs_remove(i2s->debug);
115}
116#else
117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
118{
119}
120
121static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
122{
123}
124#endif
125
126static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
127 unsigned int fmt)
128{
129 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
130
131 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
132 case SND_SOC_DAIFMT_NB_NF:
133 break;
134 default:
135 return -EINVAL;
136 }
137
138 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE;
139 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
140 case SND_SOC_DAIFMT_CBS_CFS:
141 i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE;
142 break;
143 case SND_SOC_DAIFMT_CBM_CFM:
144 break;
145 default:
146 return -EINVAL;
147 }
148
149 i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK |
150 TEGRA_I2S_CTRL_LRCK_MASK);
151 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
152 case SND_SOC_DAIFMT_DSP_A:
153 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
154 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
155 break;
156 case SND_SOC_DAIFMT_DSP_B:
157 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
158 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW;
159 break;
160 case SND_SOC_DAIFMT_I2S:
161 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S;
162 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
163 break;
164 case SND_SOC_DAIFMT_RIGHT_J:
165 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM;
166 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
167 break;
168 case SND_SOC_DAIFMT_LEFT_J:
169 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM;
170 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
171 break;
172 default:
173 return -EINVAL;
174 }
175
176 return 0;
177}
178
179static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
180 struct snd_pcm_hw_params *params,
181 struct snd_soc_dai *dai)
182{
183 struct device *dev = substream->pcm->card->dev;
184 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
185 u32 reg;
186 int ret, sample_size, srate, i2sclock, bitcnt;
187
188 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK;
189 switch (params_format(params)) {
190 case SNDRV_PCM_FORMAT_S16_LE:
191 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16;
192 sample_size = 16;
193 break;
194 case SNDRV_PCM_FORMAT_S24_LE:
195 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24;
196 sample_size = 24;
197 break;
198 case SNDRV_PCM_FORMAT_S32_LE:
199 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32;
200 sample_size = 32;
201 break;
202 default:
203 return -EINVAL;
204 }
205
206 srate = params_rate(params);
207
208 /* Final "* 2" required by Tegra hardware */
209 i2sclock = srate * params_channels(params) * sample_size * 2;
210
211 ret = clk_set_rate(i2s->clk_i2s, i2sclock);
212 if (ret) {
213 dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
214 return ret;
215 }
216
217 bitcnt = (i2sclock / (2 * srate)) - 1;
218 if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
219 return -EINVAL;
220 reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
221
222 if (i2sclock % (2 * srate))
223 reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
224
225 tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
226
227 tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
228 TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
229 TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
230
231 return 0;
232}
233
234static void tegra_i2s_start_playback(struct tegra_i2s *i2s)
235{
236 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE;
237 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
238}
239
240static void tegra_i2s_stop_playback(struct tegra_i2s *i2s)
241{
242 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE;
243 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
244}
245
246static void tegra_i2s_start_capture(struct tegra_i2s *i2s)
247{
248 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE;
249 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
250}
251
252static void tegra_i2s_stop_capture(struct tegra_i2s *i2s)
253{
254 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE;
255 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
256}
257
258static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
259 struct snd_soc_dai *dai)
260{
261 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
262
263 switch (cmd) {
264 case SNDRV_PCM_TRIGGER_START:
265 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
266 case SNDRV_PCM_TRIGGER_RESUME:
267 if (!i2s->clk_refs)
268 clk_enable(i2s->clk_i2s);
269 i2s->clk_refs++;
270 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
271 tegra_i2s_start_playback(i2s);
272 else
273 tegra_i2s_start_capture(i2s);
274 break;
275 case SNDRV_PCM_TRIGGER_STOP:
276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
277 case SNDRV_PCM_TRIGGER_SUSPEND:
278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
279 tegra_i2s_stop_playback(i2s);
280 else
281 tegra_i2s_stop_capture(i2s);
282 i2s->clk_refs--;
283 if (!i2s->clk_refs)
284 clk_disable(i2s->clk_i2s);
285 break;
286 default:
287 return -EINVAL;
288 }
289
290 return 0;
291}
292
293static int tegra_i2s_probe(struct snd_soc_dai *dai)
294{
295 struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai);
296
297 dai->capture_dma_data = &i2s->capture_dma_data;
298 dai->playback_dma_data = &i2s->playback_dma_data;
299
300 return 0;
301}
302
303static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
304 .set_fmt = tegra_i2s_set_fmt,
305 .hw_params = tegra_i2s_hw_params,
306 .trigger = tegra_i2s_trigger,
307};
308
309struct snd_soc_dai_driver tegra_i2s_dai[] = {
310 {
311 .name = DRV_NAME ".0",
312 .probe = tegra_i2s_probe,
313 .playback = {
314 .channels_min = 2,
315 .channels_max = 2,
316 .rates = SNDRV_PCM_RATE_8000_96000,
317 .formats = SNDRV_PCM_FMTBIT_S16_LE,
318 },
319 .capture = {
320 .channels_min = 2,
321 .channels_max = 2,
322 .rates = SNDRV_PCM_RATE_8000_96000,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 },
325 .ops = &tegra_i2s_dai_ops,
326 .symmetric_rates = 1,
327 },
328 {
329 .name = DRV_NAME ".1",
330 .probe = tegra_i2s_probe,
331 .playback = {
332 .channels_min = 2,
333 .channels_max = 2,
334 .rates = SNDRV_PCM_RATE_8000_96000,
335 .formats = SNDRV_PCM_FMTBIT_S16_LE,
336 },
337 .capture = {
338 .channels_min = 2,
339 .channels_max = 2,
340 .rates = SNDRV_PCM_RATE_8000_96000,
341 .formats = SNDRV_PCM_FMTBIT_S16_LE,
342 },
343 .ops = &tegra_i2s_dai_ops,
344 .symmetric_rates = 1,
345 },
346};
347
348static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
349{
350 struct tegra_i2s * i2s;
351 char clk_name[12]; /* tegra-i2s.0 */
352 struct resource *mem, *memregion, *dmareq;
353 int ret;
354
355 if ((pdev->id < 0) ||
356 (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
357 dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
358 return -EINVAL;
359 }
360
361 /*
362 * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
363 * 1:1 mapping between audio controllers and audio ports.
364 */
365 ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
366 TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
367 if (ret) {
368 dev_err(&pdev->dev, "Can't set up DAP connection\n");
369 return ret;
370 }
371 ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
372 TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
373 if (ret) {
374 dev_err(&pdev->dev, "Can't set up DAC connection\n");
375 return ret;
376 }
377
378 i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
379 if (!i2s) {
380 dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
381 ret = -ENOMEM;
382 goto exit;
383 }
384 dev_set_drvdata(&pdev->dev, i2s);
385
386 snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
387 i2s->clk_i2s = clk_get_sys(clk_name, NULL);
388 if (IS_ERR(i2s->clk_i2s)) {
389 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
390 ret = PTR_ERR(i2s->clk_i2s);
391 goto err_free;
392 }
393
394 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
395 if (!mem) {
396 dev_err(&pdev->dev, "No memory resource\n");
397 ret = -ENODEV;
398 goto err_clk_put;
399 }
400
401 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
402 if (!dmareq) {
403 dev_err(&pdev->dev, "No DMA resource\n");
404 ret = -ENODEV;
405 goto err_clk_put;
406 }
407
408 memregion = request_mem_region(mem->start, resource_size(mem),
409 DRV_NAME);
410 if (!memregion) {
411 dev_err(&pdev->dev, "Memory region already claimed\n");
412 ret = -EBUSY;
413 goto err_clk_put;
414 }
415
416 i2s->regs = ioremap(mem->start, resource_size(mem));
417 if (!i2s->regs) {
418 dev_err(&pdev->dev, "ioremap failed\n");
419 ret = -ENOMEM;
420 goto err_release;
421 }
422
423 i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
424 i2s->capture_dma_data.wrap = 4;
425 i2s->capture_dma_data.width = 32;
426 i2s->capture_dma_data.req_sel = dmareq->start;
427
428 i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
429 i2s->playback_dma_data.wrap = 4;
430 i2s->playback_dma_data.width = 32;
431 i2s->playback_dma_data.req_sel = dmareq->start;
432
433 i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
434
435 ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
436 if (ret) {
437 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
438 ret = -ENOMEM;
439 goto err_unmap;
440 }
441
442 tegra_i2s_debug_add(i2s, pdev->id);
443
444 return 0;
445
446err_unmap:
447 iounmap(i2s->regs);
448err_release:
449 release_mem_region(mem->start, resource_size(mem));
450err_clk_put:
451 clk_put(i2s->clk_i2s);
452err_free:
453 kfree(i2s);
454exit:
455 return ret;
456}
457
458static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
459{
460 struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
461 struct resource *res;
462
463 snd_soc_unregister_dai(&pdev->dev);
464
465 tegra_i2s_debug_remove(i2s);
466
467 iounmap(i2s->regs);
468
469 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
470 release_mem_region(res->start, resource_size(res));
471
472 clk_put(i2s->clk_i2s);
473
474 kfree(i2s);
475
476 return 0;
477}
478
479static struct platform_driver tegra_i2s_driver = {
480 .driver = {
481 .name = DRV_NAME,
482 .owner = THIS_MODULE,
483 },
484 .probe = tegra_i2s_platform_probe,
485 .remove = __devexit_p(tegra_i2s_platform_remove),
486};
487
488static int __init snd_tegra_i2s_init(void)
489{
490 return platform_driver_register(&tegra_i2s_driver);
491}
492module_init(snd_tegra_i2s_init);
493
494static void __exit snd_tegra_i2s_exit(void)
495{
496 platform_driver_unregister(&tegra_i2s_driver);
497}
498module_exit(snd_tegra_i2s_exit);
499
500MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
501MODULE_DESCRIPTION("Tegra I2S ASoC driver");
502MODULE_LICENSE("GPL");
503MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h
new file mode 100644
index 000000000000..2b38a096f46c
--- /dev/null
+++ b/sound/soc/tegra/tegra_i2s.h
@@ -0,0 +1,165 @@
1/*
2 * tegra_i2s.h - Definitions for Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA_I2S_H__
32#define __TEGRA_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
37
38#define TEGRA_I2S_CTRL 0x00
39#define TEGRA_I2S_STATUS 0x04
40#define TEGRA_I2S_TIMING 0x08
41#define TEGRA_I2S_FIFO_SCR 0x0c
42#define TEGRA_I2S_PCM_CTRL 0x10
43#define TEGRA_I2S_NW_CTRL 0x14
44#define TEGRA_I2S_TDM_CTRL 0x20
45#define TEGRA_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA_I2S_FIFO1 0x40
47#define TEGRA_I2S_FIFO2 0x80
48
49/* Fields in TEGRA_I2S_CTRL */
50
51#define TEGRA_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA_I2S_LRCK_LEFT_LOW 0
59#define TEGRA_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA_I2S_CTRL_LRCK_MASK (1 << TEGRA_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA_I2S_CTRL_LRCK_L_LOW (TEGRA_I2S_LRCK_LEFT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA_I2S_CTRL_LRCK_R_LOW (TEGRA_I2S_LRCK_RIGHT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA_I2S_BIT_FORMAT_I2S 0
67#define TEGRA_I2S_BIT_FORMAT_RJM 1
68#define TEGRA_I2S_BIT_FORMAT_LJM 2
69#define TEGRA_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA_I2S_CTRL_BIT_FORMAT_I2S (TEGRA_I2S_BIT_FORMAT_I2S << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA_I2S_CTRL_BIT_FORMAT_RJM (TEGRA_I2S_BIT_FORMAT_RJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA_I2S_CTRL_BIT_FORMAT_LJM (TEGRA_I2S_BIT_FORMAT_LJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA_I2S_CTRL_BIT_FORMAT_DSP (TEGRA_I2S_BIT_FORMAT_DSP << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA_I2S_BIT_SIZE_16 0
79#define TEGRA_I2S_BIT_SIZE_20 1
80#define TEGRA_I2S_BIT_SIZE_24 2
81#define TEGRA_I2S_BIT_SIZE_32 3
82
83#define TEGRA_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA_I2S_CTRL_BIT_SIZE_16 (TEGRA_I2S_BIT_SIZE_16 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA_I2S_CTRL_BIT_SIZE_20 (TEGRA_I2S_BIT_SIZE_20 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA_I2S_CTRL_BIT_SIZE_24 (TEGRA_I2S_BIT_SIZE_24 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA_I2S_CTRL_BIT_SIZE_32 (TEGRA_I2S_BIT_SIZE_32 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA_I2S_FIFO_16_LSB 0
91#define TEGRA_I2S_FIFO_20_LSB 1
92#define TEGRA_I2S_FIFO_24_LSB 2
93#define TEGRA_I2S_FIFO_32 3
94#define TEGRA_I2S_FIFO_PACKED 7
95
96#define TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA_I2S_FIFO_16_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA_I2S_FIFO_20_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA_I2S_FIFO_24_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA_I2S_CTRL_FIFO_FORMAT_32 (TEGRA_I2S_FIFO_32 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA_I2S_FIFO_PACKED << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA_I2S_STATUS */
110
111#define TEGRA_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA_I2S_TIMING */
121
122#define TEGRA_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA_I2S_FIFO_SCR */
128
129#define TEGRA_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra_i2s {
156 struct clk *clk_i2s;
157 int clk_refs;
158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data;
160 void __iomem *regs;
161 struct dentry *debug;
162 u32 reg_ctrl;
163};
164
165#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
new file mode 100644
index 000000000000..3c271f953582
--- /dev/null
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -0,0 +1,404 @@
1/*
2 * tegra_pcm.c - Tegra PCM driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 * Vijay Mali <vmali@nvidia.com>
12 *
13 * Copyright (C) 2010 Google, Inc.
14 * Iliyan Malchev <malchev@google.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31
32#include <linux/module.h>
33#include <linux/dma-mapping.h>
34#include <linux/slab.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include "tegra_pcm.h"
41
42#define DRV_NAME "tegra-pcm-audio"
43
44static const struct snd_pcm_hardware tegra_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID |
47 SNDRV_PCM_INFO_PAUSE |
48 SNDRV_PCM_INFO_RESUME |
49 SNDRV_PCM_INFO_INTERLEAVED,
50 .formats = SNDRV_PCM_FMTBIT_S16_LE,
51 .channels_min = 2,
52 .channels_max = 2,
53 .period_bytes_min = 1024,
54 .period_bytes_max = PAGE_SIZE,
55 .periods_min = 2,
56 .periods_max = 8,
57 .buffer_bytes_max = PAGE_SIZE * 8,
58 .fifo_size = 4,
59};
60
61static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
62{
63 struct snd_pcm_substream *substream = prtd->substream;
64 struct snd_dma_buffer *buf = &substream->dma_buffer;
65 struct tegra_dma_req *dma_req;
66 unsigned long addr;
67
68 dma_req = &prtd->dma_req[prtd->dma_req_idx];
69 prtd->dma_req_idx = 1 - prtd->dma_req_idx;
70
71 addr = buf->addr + prtd->dma_pos;
72 prtd->dma_pos += dma_req->size;
73 if (prtd->dma_pos >= prtd->dma_pos_end)
74 prtd->dma_pos = 0;
75
76 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
77 dma_req->source_addr = addr;
78 else
79 dma_req->dest_addr = addr;
80
81 tegra_dma_enqueue_req(prtd->dma_chan, dma_req);
82}
83
84static void dma_complete_callback(struct tegra_dma_req *req)
85{
86 struct tegra_runtime_data *prtd = (struct tegra_runtime_data *)req->dev;
87 struct snd_pcm_substream *substream = prtd->substream;
88 struct snd_pcm_runtime *runtime = substream->runtime;
89
90 spin_lock(&prtd->lock);
91
92 if (!prtd->running) {
93 spin_unlock(&prtd->lock);
94 return;
95 }
96
97 if (++prtd->period_index >= runtime->periods)
98 prtd->period_index = 0;
99
100 tegra_pcm_queue_dma(prtd);
101
102 spin_unlock(&prtd->lock);
103
104 snd_pcm_period_elapsed(substream);
105}
106
107static void setup_dma_tx_request(struct tegra_dma_req *req,
108 struct tegra_pcm_dma_params * dmap)
109{
110 req->complete = dma_complete_callback;
111 req->to_memory = false;
112 req->dest_addr = dmap->addr;
113 req->dest_wrap = dmap->wrap;
114 req->source_bus_width = 32;
115 req->source_wrap = 0;
116 req->dest_bus_width = dmap->width;
117 req->req_sel = dmap->req_sel;
118}
119
120static void setup_dma_rx_request(struct tegra_dma_req *req,
121 struct tegra_pcm_dma_params * dmap)
122{
123 req->complete = dma_complete_callback;
124 req->to_memory = true;
125 req->source_addr = dmap->addr;
126 req->dest_wrap = 0;
127 req->source_bus_width = dmap->width;
128 req->source_wrap = dmap->wrap;
129 req->dest_bus_width = 32;
130 req->req_sel = dmap->req_sel;
131}
132
133static int tegra_pcm_open(struct snd_pcm_substream *substream)
134{
135 struct snd_pcm_runtime *runtime = substream->runtime;
136 struct tegra_runtime_data *prtd;
137 struct snd_soc_pcm_runtime *rtd = substream->private_data;
138 struct tegra_pcm_dma_params * dmap;
139 int ret = 0;
140
141 prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
142 if (prtd == NULL)
143 return -ENOMEM;
144
145 runtime->private_data = prtd;
146 prtd->substream = substream;
147
148 spin_lock_init(&prtd->lock);
149
150 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
151 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
152 setup_dma_tx_request(&prtd->dma_req[0], dmap);
153 setup_dma_tx_request(&prtd->dma_req[1], dmap);
154 } else {
155 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
156 setup_dma_rx_request(&prtd->dma_req[0], dmap);
157 setup_dma_rx_request(&prtd->dma_req[1], dmap);
158 }
159
160 prtd->dma_req[0].dev = prtd;
161 prtd->dma_req[1].dev = prtd;
162
163 prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
164 if (prtd->dma_chan == NULL) {
165 ret = -ENOMEM;
166 goto err;
167 }
168
169 /* Set HW params now that initialization is complete */
170 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
171
172 /* Ensure that buffer size is a multiple of period size */
173 ret = snd_pcm_hw_constraint_integer(runtime,
174 SNDRV_PCM_HW_PARAM_PERIODS);
175 if (ret < 0)
176 goto err;
177
178 return 0;
179
180err:
181 if (prtd->dma_chan) {
182 tegra_dma_free_channel(prtd->dma_chan);
183 }
184
185 kfree(prtd);
186
187 return ret;
188}
189
190static int tegra_pcm_close(struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct tegra_runtime_data *prtd = runtime->private_data;
194
195 tegra_dma_free_channel(prtd->dma_chan);
196
197 kfree(prtd);
198
199 return 0;
200}
201
202static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params)
204{
205 struct snd_pcm_runtime *runtime = substream->runtime;
206 struct tegra_runtime_data *prtd = runtime->private_data;
207
208 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
209
210 prtd->dma_req[0].size = params_period_bytes(params);
211 prtd->dma_req[1].size = prtd->dma_req[0].size;
212
213 return 0;
214}
215
216static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
217{
218 snd_pcm_set_runtime_buffer(substream, NULL);
219
220 return 0;
221}
222
223static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
224{
225 struct snd_pcm_runtime *runtime = substream->runtime;
226 struct tegra_runtime_data *prtd = runtime->private_data;
227 unsigned long flags;
228
229 switch (cmd) {
230 case SNDRV_PCM_TRIGGER_START:
231 prtd->dma_pos = 0;
232 prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size);
233 prtd->period_index = 0;
234 prtd->dma_req_idx = 0;
235 /* Fall-through */
236 case SNDRV_PCM_TRIGGER_RESUME:
237 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
238 spin_lock_irqsave(&prtd->lock, flags);
239 prtd->running = 1;
240 spin_unlock_irqrestore(&prtd->lock, flags);
241 tegra_pcm_queue_dma(prtd);
242 tegra_pcm_queue_dma(prtd);
243 break;
244 case SNDRV_PCM_TRIGGER_STOP:
245 case SNDRV_PCM_TRIGGER_SUSPEND:
246 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
247 spin_lock_irqsave(&prtd->lock, flags);
248 prtd->running = 0;
249 spin_unlock_irqrestore(&prtd->lock, flags);
250 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
251 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
252 break;
253 default:
254 return -EINVAL;
255 }
256
257 return 0;
258}
259
260static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
261{
262 struct snd_pcm_runtime *runtime = substream->runtime;
263 struct tegra_runtime_data *prtd = runtime->private_data;
264
265 return prtd->period_index * runtime->period_size;
266}
267
268
269static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
270 struct vm_area_struct *vma)
271{
272 struct snd_pcm_runtime *runtime = substream->runtime;
273
274 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
275 runtime->dma_area,
276 runtime->dma_addr,
277 runtime->dma_bytes);
278}
279
280static struct snd_pcm_ops tegra_pcm_ops = {
281 .open = tegra_pcm_open,
282 .close = tegra_pcm_close,
283 .ioctl = snd_pcm_lib_ioctl,
284 .hw_params = tegra_pcm_hw_params,
285 .hw_free = tegra_pcm_hw_free,
286 .trigger = tegra_pcm_trigger,
287 .pointer = tegra_pcm_pointer,
288 .mmap = tegra_pcm_mmap,
289};
290
291static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
292{
293 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
294 struct snd_dma_buffer *buf = &substream->dma_buffer;
295 size_t size = tegra_pcm_hardware.buffer_bytes_max;
296
297 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
298 &buf->addr, GFP_KERNEL);
299 if (!buf->area)
300 return -ENOMEM;
301
302 buf->dev.type = SNDRV_DMA_TYPE_DEV;
303 buf->dev.dev = pcm->card->dev;
304 buf->private_data = NULL;
305 buf->bytes = size;
306
307 return 0;
308}
309
310static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
311{
312 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
313 struct snd_dma_buffer *buf = &substream->dma_buffer;
314
315 if (!buf->area)
316 return;
317
318 dma_free_writecombine(pcm->card->dev, buf->bytes,
319 buf->area, buf->addr);
320 buf->area = NULL;
321}
322
323static u64 tegra_dma_mask = DMA_BIT_MASK(32);
324
325static int tegra_pcm_new(struct snd_card *card,
326 struct snd_soc_dai *dai, struct snd_pcm *pcm)
327{
328 int ret = 0;
329
330 if (!card->dev->dma_mask)
331 card->dev->dma_mask = &tegra_dma_mask;
332 if (!card->dev->coherent_dma_mask)
333 card->dev->coherent_dma_mask = 0xffffffff;
334
335 if (dai->driver->playback.channels_min) {
336 ret = tegra_pcm_preallocate_dma_buffer(pcm,
337 SNDRV_PCM_STREAM_PLAYBACK);
338 if (ret)
339 goto err;
340 }
341
342 if (dai->driver->capture.channels_min) {
343 ret = tegra_pcm_preallocate_dma_buffer(pcm,
344 SNDRV_PCM_STREAM_CAPTURE);
345 if (ret)
346 goto err_free_play;
347 }
348
349 return 0;
350
351err_free_play:
352 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
353err:
354 return ret;
355}
356
357static void tegra_pcm_free(struct snd_pcm *pcm)
358{
359 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE);
360 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
361}
362
363struct snd_soc_platform_driver tegra_pcm_platform = {
364 .ops = &tegra_pcm_ops,
365 .pcm_new = tegra_pcm_new,
366 .pcm_free = tegra_pcm_free,
367};
368
369static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev)
370{
371 return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform);
372}
373
374static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev)
375{
376 snd_soc_unregister_platform(&pdev->dev);
377 return 0;
378}
379
380static struct platform_driver tegra_pcm_driver = {
381 .driver = {
382 .name = DRV_NAME,
383 .owner = THIS_MODULE,
384 },
385 .probe = tegra_pcm_platform_probe,
386 .remove = __devexit_p(tegra_pcm_platform_remove),
387};
388
389static int __init snd_tegra_pcm_init(void)
390{
391 return platform_driver_register(&tegra_pcm_driver);
392}
393module_init(snd_tegra_pcm_init);
394
395static void __exit snd_tegra_pcm_exit(void)
396{
397 platform_driver_unregister(&tegra_pcm_driver);
398}
399module_exit(snd_tegra_pcm_exit);
400
401MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
402MODULE_DESCRIPTION("Tegra PCM ASoC driver");
403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
new file mode 100644
index 000000000000..dbb90339fe0d
--- /dev/null
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -0,0 +1,55 @@
1/*
2 * tegra_pcm.h - Definitions for Tegra PCM driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA_PCM_H__
32#define __TEGRA_PCM_H__
33
34#include <mach/dma.h>
35
36struct tegra_pcm_dma_params {
37 unsigned long addr;
38 unsigned long wrap;
39 unsigned long width;
40 unsigned long req_sel;
41};
42
43struct tegra_runtime_data {
44 struct snd_pcm_substream *substream;
45 spinlock_t lock;
46 int running;
47 int dma_pos;
48 int dma_pos_end;
49 int period_index;
50 int dma_req_idx;
51 struct tegra_dma_req dma_req[2];
52 struct tegra_dma_channel *dma_chan;
53};
54
55#endif