aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/codecs/Kconfig8
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ac97.c4
-rw-r--r--sound/soc/codecs/ad1836.c4
-rw-r--r--sound/soc/codecs/ad193x.c4
-rw-r--r--sound/soc/codecs/adau1701.c3
-rw-r--r--sound/soc/codecs/ak4104.c3
-rw-r--r--sound/soc/codecs/ak4535.c3
-rw-r--r--sound/soc/codecs/ak4641.c113
-rw-r--r--sound/soc/codecs/alc5623.c3
-rw-r--r--sound/soc/codecs/alc5632.c3
-rw-r--r--sound/soc/codecs/cs4270.c11
-rw-r--r--sound/soc/codecs/cs4271.c3
-rw-r--r--sound/soc/codecs/cs42l51.c9
-rw-r--r--sound/soc/codecs/cs42l73.c29
-rw-r--r--sound/soc/codecs/da7210.c157
-rw-r--r--sound/soc/codecs/jz4740.c3
-rw-r--r--sound/soc/codecs/lm49453.c1550
-rw-r--r--sound/soc/codecs/lm49453.h380
-rw-r--r--sound/soc/codecs/max98095.c158
-rw-r--r--sound/soc/codecs/max98095.h22
-rw-r--r--sound/soc/codecs/ml26124.c681
-rw-r--r--sound/soc/codecs/ml26124.h184
-rw-r--r--sound/soc/codecs/rt5631.c3
-rw-r--r--sound/soc/codecs/sgtl5000.c25
-rw-r--r--sound/soc/codecs/ssm2602.c9
-rw-r--r--sound/soc/codecs/sta32x.c3
-rw-r--r--sound/soc/codecs/tlv320aic23.c13
-rw-r--r--sound/soc/codecs/tlv320aic26.c3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c3
-rw-r--r--sound/soc/codecs/tlv320dac33.c35
-rw-r--r--sound/soc/codecs/twl4030.c18
-rw-r--r--sound/soc/codecs/twl6040.c9
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/uda1380.c6
-rw-r--r--sound/soc/codecs/wl1273.c6
-rw-r--r--sound/soc/codecs/wm5100.c9
-rw-r--r--sound/soc/codecs/wm8400.c135
-rw-r--r--sound/soc/codecs/wm8510.c3
-rw-r--r--sound/soc/codecs/wm8523.c3
-rw-r--r--sound/soc/codecs/wm8728.c3
-rw-r--r--sound/soc/codecs/wm8737.c3
-rw-r--r--sound/soc/codecs/wm8741.c3
-rw-r--r--sound/soc/codecs/wm8750.c3
-rw-r--r--sound/soc/codecs/wm8753.c6
-rw-r--r--sound/soc/codecs/wm8900.c3
-rw-r--r--sound/soc/codecs/wm8903.c3
-rw-r--r--sound/soc/codecs/wm8940.c3
-rw-r--r--sound/soc/codecs/wm8960.c3
-rw-r--r--sound/soc/codecs/wm8962.c18
-rw-r--r--sound/soc/codecs/wm8971.c3
-rw-r--r--sound/soc/codecs/wm8978.c3
-rw-r--r--sound/soc/codecs/wm8988.c3
-rw-r--r--sound/soc/codecs/wm8990.c3
-rw-r--r--sound/soc/codecs/wm8994.c84
-rw-r--r--sound/soc/codecs/wm9705.c4
-rw-r--r--sound/soc/codecs/wm9712.c8
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c74
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c49
-rw-r--r--sound/soc/fsl/Kconfig121
-rw-r--r--sound/soc/fsl/Makefile29
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c (renamed from sound/soc/imx/eukrea-tlv320.c)2
-rw-r--r--sound/soc/fsl/fsl_ssi.c167
-rw-r--r--sound/soc/fsl/fsl_utils.c91
-rw-r--r--sound/soc/fsl/fsl_utils.h26
-rw-r--r--sound/soc/fsl/imx-audmux.c (renamed from sound/soc/imx/imx-audmux.c)0
-rw-r--r--sound/soc/fsl/imx-audmux.h (renamed from sound/soc/imx/imx-audmux.h)0
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c (renamed from sound/soc/imx/imx-pcm-dma-mx2.c)3
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c (renamed from sound/soc/imx/imx-pcm-fiq.c)0
-rw-r--r--sound/soc/fsl/imx-pcm.c (renamed from sound/soc/imx/imx-pcm.c)0
-rw-r--r--sound/soc/fsl/imx-pcm.h (renamed from sound/soc/imx/imx-pcm.h)1
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c190
-rw-r--r--sound/soc/fsl/imx-ssi.c (renamed from sound/soc/imx/imx-ssi.c)2
-rw-r--r--sound/soc/fsl/imx-ssi.h (renamed from sound/soc/imx/imx-ssi.h)0
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c166
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c (renamed from sound/soc/imx/mx27vis-aic32x4.c)0
-rw-r--r--sound/soc/fsl/p1022_ds.c158
-rw-r--r--sound/soc/fsl/phycore-ac97.c (renamed from sound/soc/imx/phycore-ac97.c)0
-rw-r--r--sound/soc/fsl/wm1133-ev1.c (renamed from sound/soc/imx/wm1133-ev1.c)0
-rw-r--r--sound/soc/imx/Kconfig79
-rw-r--r--sound/soc/imx/Makefile22
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c4
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c4
-rw-r--r--sound/soc/soc-core.c346
-rw-r--r--sound/soc/soc-dapm.c252
-rw-r--r--sound/soc/soc-jack.c5
-rw-r--r--sound/soc/soc-pcm.c9
-rw-r--r--sound/soc/tegra/Kconfig39
-rw-r--r--sound/soc/tegra/Makefile14
-rw-r--r--sound/soc/tegra/tegra20_das.c260
-rw-r--r--sound/soc/tegra/tegra20_das.h135
-rw-r--r--sound/soc/tegra/tegra20_i2s.c (renamed from sound/soc/tegra/tegra_i2s.c)242
-rw-r--r--sound/soc/tegra/tegra20_i2s.h165
-rw-r--r--sound/soc/tegra/tegra20_spdif.c (renamed from sound/soc/tegra/tegra_spdif.c)199
-rw-r--r--sound/soc/tegra/tegra20_spdif.h472
-rw-r--r--sound/soc/tegra/tegra_alc5632.c48
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c35
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h9
-rw-r--r--sound/soc/tegra/tegra_das.c261
-rw-r--r--sound/soc/tegra/tegra_das.h135
-rw-r--r--sound/soc/tegra/tegra_i2s.h166
-rw-r--r--sound/soc/tegra/tegra_pcm.c28
-rw-r--r--sound/soc/tegra/tegra_pcm.h5
-rw-r--r--sound/soc/tegra/tegra_spdif.h473
-rw-r--r--sound/soc/tegra/tegra_wm8903.c29
-rw-r--r--sound/soc/tegra/trimslice.c7
108 files changed, 5713 insertions, 2597 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 91c985599d32..0f85f6d526e0 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -35,7 +35,6 @@ source "sound/soc/blackfin/Kconfig"
35source "sound/soc/davinci/Kconfig" 35source "sound/soc/davinci/Kconfig"
36source "sound/soc/ep93xx/Kconfig" 36source "sound/soc/ep93xx/Kconfig"
37source "sound/soc/fsl/Kconfig" 37source "sound/soc/fsl/Kconfig"
38source "sound/soc/imx/Kconfig"
39source "sound/soc/jz4740/Kconfig" 38source "sound/soc/jz4740/Kconfig"
40source "sound/soc/nuc900/Kconfig" 39source "sound/soc/nuc900/Kconfig"
41source "sound/soc/omap/Kconfig" 40source "sound/soc/omap/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 2feaf376e94b..363dfd6cffe7 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_SND_SOC) += blackfin/
12obj-$(CONFIG_SND_SOC) += davinci/ 12obj-$(CONFIG_SND_SOC) += davinci/
13obj-$(CONFIG_SND_SOC) += ep93xx/ 13obj-$(CONFIG_SND_SOC) += ep93xx/
14obj-$(CONFIG_SND_SOC) += fsl/ 14obj-$(CONFIG_SND_SOC) += fsl/
15obj-$(CONFIG_SND_SOC) += imx/
16obj-$(CONFIG_SND_SOC) += jz4740/ 15obj-$(CONFIG_SND_SOC) += jz4740/
17obj-$(CONFIG_SND_SOC) += mid-x86/ 16obj-$(CONFIG_SND_SOC) += mid-x86/
18obj-$(CONFIG_SND_SOC) += mxs/ 17obj-$(CONFIG_SND_SOC) += mxs/
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6508e8b790bb..2e51eb08b303 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -37,11 +37,13 @@ config SND_SOC_ALL_CODECS
37 select SND_SOC_DFBMCS320 37 select SND_SOC_DFBMCS320
38 select SND_SOC_JZ4740_CODEC 38 select SND_SOC_JZ4740_CODEC
39 select SND_SOC_LM4857 if I2C 39 select SND_SOC_LM4857 if I2C
40 select SND_SOC_LM49453 if I2C
40 select SND_SOC_MAX98088 if I2C 41 select SND_SOC_MAX98088 if I2C
41 select SND_SOC_MAX98095 if I2C 42 select SND_SOC_MAX98095 if I2C
42 select SND_SOC_MAX9850 if I2C 43 select SND_SOC_MAX9850 if I2C
43 select SND_SOC_MAX9768 if I2C 44 select SND_SOC_MAX9768 if I2C
44 select SND_SOC_MAX9877 if I2C 45 select SND_SOC_MAX9877 if I2C
46 select SND_SOC_ML26124 if I2C
45 select SND_SOC_PCM3008 47 select SND_SOC_PCM3008
46 select SND_SOC_RT5631 if I2C 48 select SND_SOC_RT5631 if I2C
47 select SND_SOC_SGTL5000 if I2C 49 select SND_SOC_SGTL5000 if I2C
@@ -217,6 +219,9 @@ config SND_SOC_DFBMCS320
217config SND_SOC_DMIC 219config SND_SOC_DMIC
218 tristate 220 tristate
219 221
222config SND_SOC_LM49453
223 tristate
224
220config SND_SOC_MAX98088 225config SND_SOC_MAX98088
221 tristate 226 tristate
222 227
@@ -436,5 +441,8 @@ config SND_SOC_MAX9768
436config SND_SOC_MAX9877 441config SND_SOC_MAX9877
437 tristate 442 tristate
438 443
444config SND_SOC_ML26124
445 tristate
446
439config SND_SOC_TPA6130A2 447config SND_SOC_TPA6130A2
440 tristate 448 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6662eb0cdcc0..db61c4499715 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -25,10 +25,12 @@ snd-soc-dmic-objs := dmic.o
25snd-soc-jz4740-codec-objs := jz4740.o 25snd-soc-jz4740-codec-objs := jz4740.o
26snd-soc-l3-objs := l3.o 26snd-soc-l3-objs := l3.o
27snd-soc-lm4857-objs := lm4857.o 27snd-soc-lm4857-objs := lm4857.o
28snd-soc-lm49453-objs := lm49453.o
28snd-soc-max9768-objs := max9768.o 29snd-soc-max9768-objs := max9768.o
29snd-soc-max98088-objs := max98088.o 30snd-soc-max98088-objs := max98088.o
30snd-soc-max98095-objs := max98095.o 31snd-soc-max98095-objs := max98095.o
31snd-soc-max9850-objs := max9850.o 32snd-soc-max9850-objs := max9850.o
33snd-soc-ml26124-objs := ml26124.o
32snd-soc-pcm3008-objs := pcm3008.o 34snd-soc-pcm3008-objs := pcm3008.o
33snd-soc-rt5631-objs := rt5631.o 35snd-soc-rt5631-objs := rt5631.o
34snd-soc-sgtl5000-objs := sgtl5000.o 36snd-soc-sgtl5000-objs := sgtl5000.o
@@ -128,13 +130,15 @@ obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
128obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 130obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
129obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 131obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
130obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 132obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
133obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
131obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 134obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
132obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 135obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
133obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 136obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
134obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o 137obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
135obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 138obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
136obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 139obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
137obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 140obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
141obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
138obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 142obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
139obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 143obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
140obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 144obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 1bbad4c16d28..a99a1b304e1c 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -26,9 +26,7 @@
26static int ac97_prepare(struct snd_pcm_substream *substream, 26static int ac97_prepare(struct snd_pcm_substream *substream,
27 struct snd_soc_dai *dai) 27 struct snd_soc_dai *dai)
28{ 28{
29 struct snd_pcm_runtime *runtime = substream->runtime; 29 struct snd_soc_codec *codec = dai->codec;
30 struct snd_soc_pcm_runtime *rtd = substream->private_data;
31 struct snd_soc_codec *codec = rtd->codec;
32 30
33 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 31 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
34 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 32 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 12e3b4118557..c67b50d8b317 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -162,9 +162,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
162 struct snd_soc_dai *dai) 162 struct snd_soc_dai *dai)
163{ 163{
164 int word_len = 0; 164 int word_len = 0;
165 165 struct snd_soc_codec *codec = dai->codec;
166 struct snd_soc_pcm_runtime *rtd = substream->private_data;
167 struct snd_soc_codec *codec = rtd->codec;
168 166
169 /* bit size */ 167 /* bit size */
170 switch (params_format(params)) { 168 switch (params_format(params)) {
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index a4a6bef2c0bb..13e62be4f990 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -245,9 +245,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
245 struct snd_soc_dai *dai) 245 struct snd_soc_dai *dai)
246{ 246{
247 int word_len = 0, master_rate = 0; 247 int word_len = 0, master_rate = 0;
248 248 struct snd_soc_codec *codec = dai->codec;
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250 struct snd_soc_codec *codec = rtd->codec;
251 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 249 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
252 250
253 /* bit size */ 251 /* bit size */
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 78e9ce48bb99..3d50fc8646b6 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -258,8 +258,7 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
258static int adau1701_hw_params(struct snd_pcm_substream *substream, 258static int adau1701_hw_params(struct snd_pcm_substream *substream,
259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
260{ 260{
261 struct snd_soc_pcm_runtime *rtd = substream->private_data; 261 struct snd_soc_codec *codec = dai->codec;
262 struct snd_soc_codec *codec = rtd->codec;
263 snd_pcm_format_t format; 262 snd_pcm_format_t format;
264 unsigned int val; 263 unsigned int val;
265 264
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index ceb96ecf5588..31d4483245d0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -88,8 +88,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params, 88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
90{ 90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 struct snd_soc_codec *codec = dai->codec;
92 struct snd_soc_codec *codec = rtd->codec;
93 int val = 0; 92 int val = 0;
94 93
95 /* set the IEC958 bits: consumer mode, no copyright bit */ 94 /* set the IEC958 bits: consumer mode, no copyright bit */
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 838ae8b22b50..618fdc30f73e 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -262,8 +262,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params, 262 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai) 263 struct snd_soc_dai *dai)
264{ 264{
265 struct snd_soc_pcm_runtime *rtd = substream->private_data; 265 struct snd_soc_codec *codec = dai->codec;
266 struct snd_soc_codec *codec = rtd->codec;
267 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 266 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
268 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5); 267 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
269 int rate = params_rate(params), fs = 256; 268 int rate = params_rate(params), fs = 256;
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index c4d165a4bddf..543a12f471be 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -296,8 +296,7 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
296 struct snd_pcm_hw_params *params, 296 struct snd_pcm_hw_params *params,
297 struct snd_soc_dai *dai) 297 struct snd_soc_dai *dai)
298{ 298{
299 struct snd_soc_pcm_runtime *rtd = substream->private_data; 299 struct snd_soc_codec *codec = dai->codec;
300 struct snd_soc_codec *codec = rtd->codec;
301 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); 300 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
302 int rate = params_rate(params), fs = 256; 301 int rate = params_rate(params), fs = 256;
303 u8 mode2; 302 u8 mode2;
@@ -517,67 +516,24 @@ static int ak4641_resume(struct snd_soc_codec *codec)
517 516
518static int ak4641_probe(struct snd_soc_codec *codec) 517static int ak4641_probe(struct snd_soc_codec *codec)
519{ 518{
520 struct ak4641_platform_data *pdata = codec->dev->platform_data;
521 int ret; 519 int ret;
522 520
523
524 if (pdata) {
525 if (gpio_is_valid(pdata->gpio_power)) {
526 ret = gpio_request_one(pdata->gpio_power,
527 GPIOF_OUT_INIT_LOW, "ak4641 power");
528 if (ret)
529 goto err_out;
530 }
531 if (gpio_is_valid(pdata->gpio_npdn)) {
532 ret = gpio_request_one(pdata->gpio_npdn,
533 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
534 if (ret)
535 goto err_gpio;
536
537 udelay(1); /* > 150 ns */
538 gpio_set_value(pdata->gpio_npdn, 1);
539 }
540 }
541
542 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 521 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
543 if (ret != 0) { 522 if (ret != 0) {
544 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 523 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
545 goto err_register; 524 return ret;
546 } 525 }
547 526
548 /* power on device */ 527 /* power on device */
549 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 528 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
550 529
551 return 0; 530 return 0;
552
553err_register:
554 if (pdata) {
555 if (gpio_is_valid(pdata->gpio_power))
556 gpio_set_value(pdata->gpio_power, 0);
557 if (gpio_is_valid(pdata->gpio_npdn))
558 gpio_free(pdata->gpio_npdn);
559 }
560err_gpio:
561 if (pdata && gpio_is_valid(pdata->gpio_power))
562 gpio_free(pdata->gpio_power);
563err_out:
564 return ret;
565} 531}
566 532
567static int ak4641_remove(struct snd_soc_codec *codec) 533static int ak4641_remove(struct snd_soc_codec *codec)
568{ 534{
569 struct ak4641_platform_data *pdata = codec->dev->platform_data;
570
571 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); 535 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
572 536
573 if (pdata) {
574 if (gpio_is_valid(pdata->gpio_power)) {
575 gpio_set_value(pdata->gpio_power, 0);
576 gpio_free(pdata->gpio_power);
577 }
578 if (gpio_is_valid(pdata->gpio_npdn))
579 gpio_free(pdata->gpio_npdn);
580 }
581 return 0; 537 return 0;
582} 538}
583 539
@@ -604,6 +560,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
604static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, 560static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
605 const struct i2c_device_id *id) 561 const struct i2c_device_id *id)
606{ 562{
563 struct ak4641_platform_data *pdata = i2c->dev.platform_data;
607 struct ak4641_priv *ak4641; 564 struct ak4641_priv *ak4641;
608 int ret; 565 int ret;
609 566
@@ -612,16 +569,62 @@ static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
612 if (!ak4641) 569 if (!ak4641)
613 return -ENOMEM; 570 return -ENOMEM;
614 571
572 if (pdata) {
573 if (gpio_is_valid(pdata->gpio_power)) {
574 ret = gpio_request_one(pdata->gpio_power,
575 GPIOF_OUT_INIT_LOW, "ak4641 power");
576 if (ret)
577 goto err_out;
578 }
579 if (gpio_is_valid(pdata->gpio_npdn)) {
580 ret = gpio_request_one(pdata->gpio_npdn,
581 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
582 if (ret)
583 goto err_gpio;
584
585 udelay(1); /* > 150 ns */
586 gpio_set_value(pdata->gpio_npdn, 1);
587 }
588 }
589
615 i2c_set_clientdata(i2c, ak4641); 590 i2c_set_clientdata(i2c, ak4641);
616 591
617 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641, 592 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
618 ak4641_dai, ARRAY_SIZE(ak4641_dai)); 593 ak4641_dai, ARRAY_SIZE(ak4641_dai));
594 if (ret != 0)
595 goto err_gpio2;
596
597 return 0;
598
599err_gpio2:
600 if (pdata) {
601 if (gpio_is_valid(pdata->gpio_power))
602 gpio_set_value(pdata->gpio_power, 0);
603 if (gpio_is_valid(pdata->gpio_npdn))
604 gpio_free(pdata->gpio_npdn);
605 }
606err_gpio:
607 if (pdata && gpio_is_valid(pdata->gpio_power))
608 gpio_free(pdata->gpio_power);
609err_out:
619 return ret; 610 return ret;
620} 611}
621 612
622static int __devexit ak4641_i2c_remove(struct i2c_client *i2c) 613static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
623{ 614{
615 struct ak4641_platform_data *pdata = i2c->dev.platform_data;
616
624 snd_soc_unregister_codec(&i2c->dev); 617 snd_soc_unregister_codec(&i2c->dev);
618
619 if (pdata) {
620 if (gpio_is_valid(pdata->gpio_power)) {
621 gpio_set_value(pdata->gpio_power, 0);
622 gpio_free(pdata->gpio_power);
623 }
624 if (gpio_is_valid(pdata->gpio_npdn))
625 gpio_free(pdata->gpio_npdn);
626 }
627
625 return 0; 628 return 0;
626} 629}
627 630
@@ -641,23 +644,7 @@ static struct i2c_driver ak4641_i2c_driver = {
641 .id_table = ak4641_i2c_id, 644 .id_table = ak4641_i2c_id,
642}; 645};
643 646
644static int __init ak4641_modinit(void) 647module_i2c_driver(ak4641_i2c_driver);
645{
646 int ret;
647
648 ret = i2c_add_driver(&ak4641_i2c_driver);
649 if (ret != 0)
650 pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
651
652 return ret;
653}
654module_init(ak4641_modinit);
655
656static void __exit ak4641_exit(void)
657{
658 i2c_del_driver(&ak4641_i2c_driver);
659}
660module_exit(ak4641_exit);
661 648
662MODULE_DESCRIPTION("SoC AK4641 driver"); 649MODULE_DESCRIPTION("SoC AK4641 driver");
663MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>"); 650MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index d47b62ddb210..3061d35e9f5c 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -705,8 +705,7 @@ static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
705static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, 705static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
706 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 706 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
707{ 707{
708 struct snd_soc_pcm_runtime *rtd = substream->private_data; 708 struct snd_soc_codec *codec = dai->codec;
709 struct snd_soc_codec *codec = rtd->codec;
710 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 709 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
711 int coeff, rate; 710 int coeff, rate;
712 u16 iface; 711 u16 iface;
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index e2111e0ccad7..93a5909fcc49 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -861,8 +861,7 @@ static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
861static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, 861static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
862 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 862 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
863{ 863{
864 struct snd_soc_pcm_runtime *rtd = substream->private_data; 864 struct snd_soc_codec *codec = dai->codec;
865 struct snd_soc_codec *codec = rtd->codec;
866 int coeff, rate; 865 int coeff, rate;
867 u16 iface; 866 u16 iface;
868 867
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 1d672f528662..047917f0b8ae 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -307,8 +307,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
307 struct snd_pcm_hw_params *params, 307 struct snd_pcm_hw_params *params,
308 struct snd_soc_dai *dai) 308 struct snd_soc_dai *dai)
309{ 309{
310 struct snd_soc_pcm_runtime *rtd = substream->private_data; 310 struct snd_soc_codec *codec = dai->codec;
311 struct snd_soc_codec *codec = rtd->codec;
312 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 311 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
313 int ret; 312 int ret;
314 unsigned int i; 313 unsigned int i;
@@ -600,10 +599,12 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec)
600static int cs4270_soc_resume(struct snd_soc_codec *codec) 599static int cs4270_soc_resume(struct snd_soc_codec *codec)
601{ 600{
602 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 601 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
603 int reg; 602 int reg, ret;
604 603
605 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), 604 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
606 cs4270->supplies); 605 cs4270->supplies);
606 if (ret != 0)
607 return ret;
607 608
608 /* In case the device was put to hard reset during sleep, we need to 609 /* In case the device was put to hard reset during sleep, we need to
609 * wait 500ns here before any I2C communication. */ 610 * wait 500ns here before any I2C communication. */
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index bf7141280a74..9eb01d7d58a3 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -318,8 +318,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
318 struct snd_pcm_hw_params *params, 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai) 319 struct snd_soc_dai *dai)
320{ 320{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_codec *codec = dai->codec;
322 struct snd_soc_codec *codec = rtd->codec;
323 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 322 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
324 int i, ret; 323 int i, ret;
325 unsigned int ratio, val; 324 unsigned int ratio, val;
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index a8bf588e8740..091d0193f507 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -141,15 +141,15 @@ static const struct soc_enum cs42l51_chan_mix =
141static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 141static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
142 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", 142 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
143 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 143 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
144 7, 0xffffff99, 0x18, adc_pcm_tlv), 144 6, 0x19, 0x7F, adc_pcm_tlv),
145 SOC_DOUBLE_R("PCM Playback Switch", 145 SOC_DOUBLE_R("PCM Playback Switch",
146 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), 146 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
147 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", 147 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
148 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL, 148 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
149 8, 0xffffff19, 0x18, aout_tlv), 149 0, 0x34, 0xE4, aout_tlv),
150 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", 150 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
151 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 151 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
152 7, 0xffffff99, 0x18, adc_pcm_tlv), 152 6, 0x19, 0x7F, adc_pcm_tlv),
153 SOC_DOUBLE_R("ADC Mixer Switch", 153 SOC_DOUBLE_R("ADC Mixer Switch",
154 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), 154 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
155 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), 155 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
@@ -356,8 +356,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params, 356 struct snd_pcm_hw_params *params,
357 struct snd_soc_dai *dai) 357 struct snd_soc_dai *dai)
358{ 358{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data; 359 struct snd_soc_codec *codec = dai->codec;
360 struct snd_soc_codec *codec = rtd->codec;
361 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 360 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
362 int ret; 361 int ret;
363 unsigned int i; 362 unsigned int i;
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 78979b3e0e95..2cc50b379a0e 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -402,37 +402,37 @@ static const struct snd_kcontrol_new ear_amp_ctl =
402 402
403static const struct snd_kcontrol_new cs42l73_snd_controls[] = { 403static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
404 SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume", 404 SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume",
405 CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7, 405 CS42L73_HPAAVOL, CS42L73_HPBAVOL, 0,
406 0xffffffC1, 0x0C, hpaloa_tlv), 406 0x41, 0x4B, hpaloa_tlv),
407 407
408 SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL, 408 SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL,
409 CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv), 409 CS42L73_LOBAVOL, 0, 0x41, 0x4B, hpaloa_tlv),
410 410
411 SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL, 411 SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL,
412 CS42L73_MICBPREPGABVOL, 5, 0xffffff35, 412 CS42L73_MICBPREPGABVOL, 5, 0x34,
413 0x34, micpga_tlv), 413 0x24, micpga_tlv),
414 414
415 SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL, 415 SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL,
416 CS42L73_MICBPREPGABVOL, 6, 1, 1), 416 CS42L73_MICBPREPGABVOL, 6, 1, 1),
417 417
418 SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL, 418 SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL,
419 CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv), 419 CS42L73_IPBDVOL, 0, 0xA0, 0x6C, ipd_tlv),
420 420
421 SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume", 421 SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume",
422 CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5, 422 CS42L73_HLADVOL, CS42L73_HLBDVOL,
423 0xE4, hl_tlv), 423 0, 0x34, 0xE4, hl_tlv),
424 424
425 SOC_SINGLE_TLV("ADC A Boost Volume", 425 SOC_SINGLE_TLV("ADC A Boost Volume",
426 CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv), 426 CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv),
427 427
428 SOC_SINGLE_TLV("ADC B Boost Volume", 428 SOC_SINGLE_TLV("ADC B Boost Volume",
429 CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv), 429 CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv),
430 430
431 SOC_SINGLE_TLV("Speakerphone Digital Playback Volume", 431 SOC_SINGLE_SX_TLV("Speakerphone Digital Volume",
432 CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv), 432 CS42L73_SPKDVOL, 0, 0x34, 0xE4, hl_tlv),
433 433
434 SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume", 434 SOC_SINGLE_SX_TLV("Ear Speaker Digital Volume",
435 CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv), 435 CS42L73_ESLDVOL, 0, 0x34, 0xE4, hl_tlv),
436 436
437 SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL, 437 SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL,
438 CS42L73_HPBAVOL, 7, 1, 1), 438 CS42L73_HPBAVOL, 7, 1, 1),
@@ -1089,8 +1089,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
1089 struct snd_pcm_hw_params *params, 1089 struct snd_pcm_hw_params *params,
1090 struct snd_soc_dai *dai) 1090 struct snd_soc_dai *dai)
1091{ 1091{
1092 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1092 struct snd_soc_codec *codec = dai->codec;
1093 struct snd_soc_codec *codec = rtd->codec;
1094 struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); 1093 struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
1095 int id = dai->id; 1094 int id = dai->id;
1096 int mclk_coeff; 1095 int mclk_coeff;
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 7843711729bc..5dfdf6e7a39a 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h>
20#include <linux/regmap.h> 21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/module.h> 23#include <linux/module.h>
@@ -27,6 +28,7 @@
27#include <sound/tlv.h> 28#include <sound/tlv.h>
28 29
29/* DA7210 register space */ 30/* DA7210 register space */
31#define DA7210_PAGE_CONTROL 0x00
30#define DA7210_CONTROL 0x01 32#define DA7210_CONTROL 0x01
31#define DA7210_STATUS 0x02 33#define DA7210_STATUS 0x02
32#define DA7210_STARTUP1 0x03 34#define DA7210_STARTUP1 0x03
@@ -631,6 +633,7 @@ struct da7210_priv {
631}; 633};
632 634
633static struct reg_default da7210_reg_defaults[] = { 635static struct reg_default da7210_reg_defaults[] = {
636 { 0x00, 0x00 },
634 { 0x01, 0x11 }, 637 { 0x01, 0x11 },
635 { 0x03, 0x00 }, 638 { 0x03, 0x00 },
636 { 0x04, 0x00 }, 639 { 0x04, 0x00 },
@@ -713,8 +716,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
713 struct snd_pcm_hw_params *params, 716 struct snd_pcm_hw_params *params,
714 struct snd_soc_dai *dai) 717 struct snd_soc_dai *dai)
715{ 718{
716 struct snd_soc_pcm_runtime *rtd = substream->private_data; 719 struct snd_soc_codec *codec = dai->codec;
717 struct snd_soc_codec *codec = rtd->codec;
718 u32 dai_cfg1; 720 u32 dai_cfg1;
719 u32 fs, bypass; 721 u32 fs, bypass;
720 722
@@ -928,13 +930,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
928 */ 930 */
929 931
930 /* 932 /*
931 * make sure that DA7210 use bypass mode before start up
932 */
933 snd_soc_write(codec, DA7210_STARTUP1, 0);
934 snd_soc_write(codec, DA7210_PLL_DIV3,
935 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
936
937 /*
938 * ADC settings 933 * ADC settings
939 */ 934 */
940 935
@@ -1025,16 +1020,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
1025 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 1020 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
1026 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); 1021 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
1027 1022
1028 /* As suggested by Dialog */
1029 /* unlock */
1030 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
1031 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
1032 regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
1033 regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
1034 /* re-lock */
1035 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
1036 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
1037
1038 /* Activate all enabled subsystem */ 1023 /* Activate all enabled subsystem */
1039 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 1024 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
1040 1025
@@ -1055,7 +1040,26 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1055 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), 1040 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
1056}; 1041};
1057 1042
1058static struct regmap_config da7210_regmap = { 1043#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1044
1045static struct reg_default da7210_regmap_i2c_patch[] = {
1046
1047 /* System controller master disable */
1048 { DA7210_STARTUP1, 0x00 },
1049 /* make sure that DA7210 use bypass mode before start up */
1050 { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP },
1051
1052 /* to unlock */
1053 { DA7210_A_HID_UNLOCK, 0x8B},
1054 { DA7210_A_TEST_UNLOCK, 0xB4},
1055 { DA7210_A_PLL1, 0x01},
1056 { DA7210_A_CP_MODE, 0x7C},
1057 /* to re-lock */
1058 { DA7210_A_HID_UNLOCK, 0x00},
1059 { DA7210_A_TEST_UNLOCK, 0x00},
1060};
1061
1062static const struct regmap_config da7210_regmap_config_i2c = {
1059 .reg_bits = 8, 1063 .reg_bits = 8,
1060 .val_bits = 8, 1064 .val_bits = 8,
1061 1065
@@ -1066,7 +1070,6 @@ static struct regmap_config da7210_regmap = {
1066 .cache_type = REGCACHE_RBTREE, 1070 .cache_type = REGCACHE_RBTREE,
1067}; 1071};
1068 1072
1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1070static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 1073static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1071 const struct i2c_device_id *id) 1074 const struct i2c_device_id *id)
1072{ 1075{
@@ -1080,13 +1083,18 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1080 1083
1081 i2c_set_clientdata(i2c, da7210); 1084 i2c_set_clientdata(i2c, da7210);
1082 1085
1083 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); 1086 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c);
1084 if (IS_ERR(da7210->regmap)) { 1087 if (IS_ERR(da7210->regmap)) {
1085 ret = PTR_ERR(da7210->regmap); 1088 ret = PTR_ERR(da7210->regmap);
1086 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 1089 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1087 return ret; 1090 return ret;
1088 } 1091 }
1089 1092
1093 ret = regmap_register_patch(da7210->regmap, da7210_regmap_i2c_patch,
1094 ARRAY_SIZE(da7210_regmap_i2c_patch));
1095 if (ret != 0)
1096 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1097
1090 ret = snd_soc_register_codec(&i2c->dev, 1098 ret = snd_soc_register_codec(&i2c->dev,
1091 &soc_codec_dev_da7210, &da7210_dai, 1); 1099 &soc_codec_dev_da7210, &da7210_dai, 1);
1092 if (ret < 0) { 1100 if (ret < 0) {
@@ -1119,7 +1127,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
1119/* I2C codec control layer */ 1127/* I2C codec control layer */
1120static struct i2c_driver da7210_i2c_driver = { 1128static struct i2c_driver da7210_i2c_driver = {
1121 .driver = { 1129 .driver = {
1122 .name = "da7210-codec", 1130 .name = "da7210",
1123 .owner = THIS_MODULE, 1131 .owner = THIS_MODULE,
1124 }, 1132 },
1125 .probe = da7210_i2c_probe, 1133 .probe = da7210_i2c_probe,
@@ -1128,12 +1136,112 @@ static struct i2c_driver da7210_i2c_driver = {
1128}; 1136};
1129#endif 1137#endif
1130 1138
1139#if defined(CONFIG_SPI_MASTER)
1140
1141static struct reg_default da7210_regmap_spi_patch[] = {
1142 /* Dummy read to give two pulses over nCS for SPI */
1143 { DA7210_AUX2, 0x00 },
1144 { DA7210_AUX2, 0x00 },
1145
1146 /* System controller master disable */
1147 { DA7210_STARTUP1, 0x00 },
1148 /* make sure that DA7210 use bypass mode before start up */
1149 { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP },
1150
1151 /* to set PAGE1 of SPI register space */
1152 { DA7210_PAGE_CONTROL, 0x80 },
1153 /* to unlock */
1154 { DA7210_A_HID_UNLOCK, 0x8B},
1155 { DA7210_A_TEST_UNLOCK, 0xB4},
1156 { DA7210_A_PLL1, 0x01},
1157 { DA7210_A_CP_MODE, 0x7C},
1158 /* to re-lock */
1159 { DA7210_A_HID_UNLOCK, 0x00},
1160 { DA7210_A_TEST_UNLOCK, 0x00},
1161 /* to set back PAGE0 of SPI register space */
1162 { DA7210_PAGE_CONTROL, 0x00 },
1163};
1164
1165static const struct regmap_config da7210_regmap_config_spi = {
1166 .reg_bits = 8,
1167 .val_bits = 8,
1168 .read_flag_mask = 0x01,
1169 .write_flag_mask = 0x00,
1170
1171 .reg_defaults = da7210_reg_defaults,
1172 .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
1173 .volatile_reg = da7210_volatile_register,
1174 .readable_reg = da7210_readable_register,
1175 .cache_type = REGCACHE_RBTREE,
1176};
1177
1178static int __devinit da7210_spi_probe(struct spi_device *spi)
1179{
1180 struct da7210_priv *da7210;
1181 int ret;
1182
1183 da7210 = devm_kzalloc(&spi->dev, sizeof(struct da7210_priv),
1184 GFP_KERNEL);
1185 if (!da7210)
1186 return -ENOMEM;
1187
1188 spi_set_drvdata(spi, da7210);
1189 da7210->regmap = devm_regmap_init_spi(spi, &da7210_regmap_config_spi);
1190 if (IS_ERR(da7210->regmap)) {
1191 ret = PTR_ERR(da7210->regmap);
1192 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
1193 return ret;
1194 }
1195
1196 ret = regmap_register_patch(da7210->regmap, da7210_regmap_spi_patch,
1197 ARRAY_SIZE(da7210_regmap_spi_patch));
1198 if (ret != 0)
1199 dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
1200
1201 ret = snd_soc_register_codec(&spi->dev,
1202 &soc_codec_dev_da7210, &da7210_dai, 1);
1203 if (ret < 0)
1204 goto err_regmap;
1205
1206 return ret;
1207
1208err_regmap:
1209 regmap_exit(da7210->regmap);
1210
1211 return ret;
1212}
1213
1214static int __devexit da7210_spi_remove(struct spi_device *spi)
1215{
1216 struct da7210_priv *da7210 = spi_get_drvdata(spi);
1217 snd_soc_unregister_codec(&spi->dev);
1218 regmap_exit(da7210->regmap);
1219 return 0;
1220}
1221
1222static struct spi_driver da7210_spi_driver = {
1223 .driver = {
1224 .name = "da7210",
1225 .owner = THIS_MODULE,
1226 },
1227 .probe = da7210_spi_probe,
1228 .remove = __devexit_p(da7210_spi_remove)
1229};
1230#endif
1231
1131static int __init da7210_modinit(void) 1232static int __init da7210_modinit(void)
1132{ 1233{
1133 int ret = 0; 1234 int ret = 0;
1134#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1235#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1135 ret = i2c_add_driver(&da7210_i2c_driver); 1236 ret = i2c_add_driver(&da7210_i2c_driver);
1136#endif 1237#endif
1238#if defined(CONFIG_SPI_MASTER)
1239 ret = spi_register_driver(&da7210_spi_driver);
1240 if (ret) {
1241 printk(KERN_ERR "Failed to register da7210 SPI driver: %d\n",
1242 ret);
1243 }
1244#endif
1137 return ret; 1245 return ret;
1138} 1246}
1139module_init(da7210_modinit); 1247module_init(da7210_modinit);
@@ -1143,6 +1251,9 @@ static void __exit da7210_exit(void)
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1251#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1144 i2c_del_driver(&da7210_i2c_driver); 1252 i2c_del_driver(&da7210_i2c_driver);
1145#endif 1253#endif
1254#if defined(CONFIG_SPI_MASTER)
1255 spi_unregister_driver(&da7210_spi_driver);
1256#endif
1146} 1257}
1147module_exit(da7210_exit); 1258module_exit(da7210_exit);
1148 1259
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 4624e752a188..85d9cabe6d55 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -164,8 +164,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
164 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 164 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
165{ 165{
166 uint32_t val; 166 uint32_t val;
167 struct snd_soc_pcm_runtime *rtd = substream->private_data; 167 struct snd_soc_codec *codec = dai->codec;
168 struct snd_soc_codec *codec =rtd->codec;
169 168
170 switch (params_rate(params)) { 169 switch (params_rate(params)) {
171 case 8000: 170 case 8000:
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
new file mode 100644
index 000000000000..5eb726b3ff1b
--- /dev/null
+++ b/sound/soc/codecs/lm49453.c
@@ -0,0 +1,1550 @@
1/*
2 * lm49453.c - LM49453 ALSA Soc Audio driver
3 *
4 * Copyright (c) 2012 Texas Instruments, 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 as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * Initially based on sound/soc/codecs/wm8350.c
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/version.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
29#include <sound/jack.h>
30#include <sound/initval.h>
31#include <asm/div64.h>
32#include "lm49453.h"
33
34static struct reg_default lm49453_reg_defs[] = {
35 { 0, 0x00 },
36 { 1, 0x00 },
37 { 2, 0x00 },
38 { 3, 0x00 },
39 { 4, 0x00 },
40 { 5, 0x00 },
41 { 6, 0x00 },
42 { 7, 0x00 },
43 { 8, 0x00 },
44 { 9, 0x00 },
45 { 10, 0x00 },
46 { 11, 0x00 },
47 { 12, 0x00 },
48 { 13, 0x00 },
49 { 14, 0x00 },
50 { 15, 0x00 },
51 { 16, 0x00 },
52 { 17, 0x00 },
53 { 18, 0x00 },
54 { 19, 0x00 },
55 { 20, 0x00 },
56 { 21, 0x00 },
57 { 22, 0x00 },
58 { 23, 0x00 },
59 { 32, 0x00 },
60 { 33, 0x00 },
61 { 35, 0x00 },
62 { 36, 0x00 },
63 { 37, 0x00 },
64 { 46, 0x00 },
65 { 48, 0x00 },
66 { 49, 0x00 },
67 { 51, 0x00 },
68 { 56, 0x00 },
69 { 58, 0x00 },
70 { 59, 0x00 },
71 { 60, 0x00 },
72 { 61, 0x00 },
73 { 62, 0x00 },
74 { 63, 0x00 },
75 { 64, 0x00 },
76 { 65, 0x00 },
77 { 66, 0x00 },
78 { 67, 0x00 },
79 { 68, 0x00 },
80 { 69, 0x00 },
81 { 70, 0x00 },
82 { 71, 0x00 },
83 { 72, 0x00 },
84 { 73, 0x00 },
85 { 74, 0x00 },
86 { 75, 0x00 },
87 { 76, 0x00 },
88 { 77, 0x00 },
89 { 78, 0x00 },
90 { 79, 0x00 },
91 { 80, 0x00 },
92 { 81, 0x00 },
93 { 82, 0x00 },
94 { 83, 0x00 },
95 { 85, 0x00 },
96 { 85, 0x00 },
97 { 86, 0x00 },
98 { 87, 0x00 },
99 { 88, 0x00 },
100 { 89, 0x00 },
101 { 90, 0x00 },
102 { 91, 0x00 },
103 { 92, 0x00 },
104 { 93, 0x00 },
105 { 94, 0x00 },
106 { 95, 0x00 },
107 { 96, 0x01 },
108 { 97, 0x00 },
109 { 98, 0x00 },
110 { 99, 0x00 },
111 { 100, 0x00 },
112 { 101, 0x00 },
113 { 102, 0x00 },
114 { 103, 0x01 },
115 { 105, 0x01 },
116 { 106, 0x00 },
117 { 107, 0x01 },
118 { 107, 0x00 },
119 { 108, 0x00 },
120 { 109, 0x00 },
121 { 110, 0x00 },
122 { 111, 0x02 },
123 { 112, 0x02 },
124 { 113, 0x00 },
125 { 121, 0x80 },
126 { 122, 0xBB },
127 { 123, 0x80 },
128 { 124, 0xBB },
129 { 128, 0x00 },
130 { 130, 0x00 },
131 { 131, 0x00 },
132 { 132, 0x00 },
133 { 133, 0x0A },
134 { 134, 0x0A },
135 { 135, 0x0A },
136 { 136, 0x0F },
137 { 137, 0x00 },
138 { 138, 0x73 },
139 { 139, 0x33 },
140 { 140, 0x73 },
141 { 141, 0x33 },
142 { 142, 0x73 },
143 { 143, 0x33 },
144 { 144, 0x73 },
145 { 145, 0x33 },
146 { 146, 0x73 },
147 { 147, 0x33 },
148 { 148, 0x73 },
149 { 149, 0x33 },
150 { 150, 0x73 },
151 { 151, 0x33 },
152 { 152, 0x00 },
153 { 153, 0x00 },
154 { 154, 0x00 },
155 { 155, 0x00 },
156 { 176, 0x00 },
157 { 177, 0x00 },
158 { 178, 0x00 },
159 { 179, 0x00 },
160 { 180, 0x00 },
161 { 181, 0x00 },
162 { 182, 0x00 },
163 { 183, 0x00 },
164 { 184, 0x00 },
165 { 185, 0x00 },
166 { 186, 0x00 },
167 { 189, 0x00 },
168 { 188, 0x00 },
169 { 194, 0x00 },
170 { 195, 0x00 },
171 { 196, 0x00 },
172 { 197, 0x00 },
173 { 200, 0x00 },
174 { 201, 0x00 },
175 { 202, 0x00 },
176 { 203, 0x00 },
177 { 204, 0x00 },
178 { 205, 0x00 },
179 { 208, 0x00 },
180 { 209, 0x00 },
181 { 210, 0x00 },
182 { 211, 0x00 },
183 { 213, 0x00 },
184 { 214, 0x00 },
185 { 215, 0x00 },
186 { 216, 0x00 },
187 { 217, 0x00 },
188 { 218, 0x00 },
189 { 219, 0x00 },
190 { 221, 0x00 },
191 { 222, 0x00 },
192 { 224, 0x00 },
193 { 225, 0x00 },
194 { 226, 0x00 },
195 { 227, 0x00 },
196 { 228, 0x00 },
197 { 229, 0x00 },
198 { 230, 0x13 },
199 { 231, 0x00 },
200 { 232, 0x80 },
201 { 233, 0x0C },
202 { 234, 0xDD },
203 { 235, 0x00 },
204 { 236, 0x04 },
205 { 237, 0x00 },
206 { 238, 0x00 },
207 { 239, 0x00 },
208 { 240, 0x00 },
209 { 241, 0x00 },
210 { 242, 0x00 },
211 { 243, 0x00 },
212 { 244, 0x00 },
213 { 245, 0x00 },
214 { 248, 0x00 },
215 { 249, 0x00 },
216 { 254, 0x00 },
217 { 255, 0x00 },
218};
219
220/* codec private data */
221struct lm49453_priv {
222 struct regmap *regmap;
223 int fs_rate;
224};
225
226/* capture path controls */
227
228static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"};
229
230static const SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5,
231 lm49453_mic2mode_text);
232
233static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"};
234
235static const SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum,
236 LM49453_P0_DIGITAL_MIC1_CONFIG_REG,
237 7, lm49453_dmic_cfg_text);
238
239static const SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum,
240 LM49453_P0_DIGITAL_MIC2_CONFIG_REG,
241 7, lm49453_dmic_cfg_text);
242
243/* MUX Controls */
244static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" };
245
246static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" };
247
248static const struct soc_enum lm49453_adcl_enum =
249 SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
250 ARRAY_SIZE(lm49453_adcl_mux_text),
251 lm49453_adcl_mux_text);
252
253static const struct soc_enum lm49453_adcr_enum =
254 SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
255 ARRAY_SIZE(lm49453_adcr_mux_text),
256 lm49453_adcr_mux_text);
257
258static const struct snd_kcontrol_new lm49453_adcl_mux_control =
259 SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum);
260
261static const struct snd_kcontrol_new lm49453_adcr_mux_control =
262 SOC_DAPM_ENUM("ADC Right Mux", lm49453_adcr_enum);
263
264static const struct snd_kcontrol_new lm49453_headset_left_mixer[] = {
265SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHPL1_REG, 0, 1, 0),
266SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHPL1_REG, 1, 1, 0),
267SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHPL1_REG, 2, 1, 0),
268SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHPL1_REG, 3, 1, 0),
269SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHPL1_REG, 4, 1, 0),
270SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHPL1_REG, 5, 1, 0),
271SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHPL1_REG, 6, 1, 0),
272SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHPL1_REG, 7, 1, 0),
273SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHPL2_REG, 0, 1, 0),
274SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHPL2_REG, 1, 1, 0),
275SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHPL2_REG, 2, 1, 0),
276SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHPL2_REG, 3, 1, 0),
277SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHPL2_REG, 4, 1, 0),
278SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHPL2_REG, 5, 1, 0),
279SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHPL2_REG, 6, 1, 0),
280SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHPL2_REG, 7, 1, 0),
281SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 0, 0, 0),
282};
283
284static const struct snd_kcontrol_new lm49453_headset_right_mixer[] = {
285SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHPR1_REG, 0, 1, 0),
286SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHPR1_REG, 1, 1, 0),
287SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHPR1_REG, 2, 1, 0),
288SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHPR1_REG, 3, 1, 0),
289SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHPR1_REG, 4, 1, 0),
290SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHPR1_REG, 5, 1, 0),
291SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHPR1_REG, 6, 1, 0),
292SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHPR1_REG, 7, 1, 0),
293SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHPR2_REG, 0, 1, 0),
294SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHPR2_REG, 1, 1, 0),
295SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHPR2_REG, 2, 1, 0),
296SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHPR2_REG, 3, 1, 0),
297SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHPR2_REG, 4, 1, 0),
298SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHPR2_REG, 5, 1, 0),
299SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHPR2_REG, 6, 1, 0),
300SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHPR2_REG, 7, 1, 0),
301SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 1, 0, 0),
302};
303
304static const struct snd_kcontrol_new lm49453_speaker_left_mixer[] = {
305SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLSL1_REG, 0, 1, 0),
306SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLSL1_REG, 1, 1, 0),
307SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLSL1_REG, 2, 1, 0),
308SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLSL1_REG, 3, 1, 0),
309SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLSL1_REG, 4, 1, 0),
310SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLSL1_REG, 5, 1, 0),
311SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLSL1_REG, 6, 1, 0),
312SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLSL1_REG, 7, 1, 0),
313SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLSL2_REG, 0, 1, 0),
314SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLSL2_REG, 1, 1, 0),
315SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLSL2_REG, 2, 1, 0),
316SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLSL2_REG, 3, 1, 0),
317SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLSL2_REG, 4, 1, 0),
318SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLSL2_REG, 5, 1, 0),
319SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLSL2_REG, 6, 1, 0),
320SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLSL2_REG, 7, 1, 0),
321SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 2, 0, 0),
322};
323
324static const struct snd_kcontrol_new lm49453_speaker_right_mixer[] = {
325SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLSR1_REG, 0, 1, 0),
326SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLSR1_REG, 1, 1, 0),
327SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLSR1_REG, 2, 1, 0),
328SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLSR1_REG, 3, 1, 0),
329SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLSR1_REG, 4, 1, 0),
330SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLSR1_REG, 5, 1, 0),
331SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLSR1_REG, 6, 1, 0),
332SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLSR1_REG, 7, 1, 0),
333SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLSR2_REG, 0, 1, 0),
334SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLSR2_REG, 1, 1, 0),
335SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLSR2_REG, 2, 1, 0),
336SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLSR2_REG, 3, 1, 0),
337SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLSR2_REG, 4, 1, 0),
338SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLSR2_REG, 5, 1, 0),
339SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLSR2_REG, 6, 1, 0),
340SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLSR2_REG, 7, 1, 0),
341SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 3, 0, 0),
342};
343
344static const struct snd_kcontrol_new lm49453_haptic_left_mixer[] = {
345SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHAL1_REG, 0, 1, 0),
346SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHAL1_REG, 1, 1, 0),
347SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHAL1_REG, 2, 1, 0),
348SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHAL1_REG, 3, 1, 0),
349SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHAL1_REG, 4, 1, 0),
350SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHAL1_REG, 5, 1, 0),
351SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHAL1_REG, 6, 1, 0),
352SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHAL1_REG, 7, 1, 0),
353SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHAL2_REG, 0, 1, 0),
354SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHAL2_REG, 1, 1, 0),
355SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHAL2_REG, 2, 1, 0),
356SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHAL2_REG, 3, 1, 0),
357SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHAL2_REG, 4, 1, 0),
358SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHAL2_REG, 5, 1, 0),
359SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHAL2_REG, 6, 1, 0),
360SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHAL2_REG, 7, 1, 0),
361SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 4, 0, 0),
362};
363
364static const struct snd_kcontrol_new lm49453_haptic_right_mixer[] = {
365SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHAR1_REG, 0, 1, 0),
366SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHAR1_REG, 1, 1, 0),
367SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHAR1_REG, 2, 1, 0),
368SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHAR1_REG, 3, 1, 0),
369SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHAR1_REG, 4, 1, 0),
370SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHAR1_REG, 5, 1, 0),
371SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHAR1_REG, 6, 1, 0),
372SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHAR1_REG, 7, 1, 0),
373SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHAR2_REG, 0, 1, 0),
374SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHAR2_REG, 1, 1, 0),
375SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHAR2_REG, 2, 1, 0),
376SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHAR2_REG, 3, 1, 0),
377SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHAR2_REG, 4, 1, 0),
378SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHAR2_REG, 5, 1, 0),
379SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHAR2_REG, 6, 1, 0),
380SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHAR2_REG, 7, 1, 0),
381SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 5, 0, 0),
382};
383
384static const struct snd_kcontrol_new lm49453_lineout_left_mixer[] = {
385SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLOL1_REG, 0, 1, 0),
386SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLOL1_REG, 1, 1, 0),
387SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLOL1_REG, 2, 1, 0),
388SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLOL1_REG, 3, 1, 0),
389SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLOL1_REG, 4, 1, 0),
390SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLOL1_REG, 5, 1, 0),
391SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLOL1_REG, 6, 1, 0),
392SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLOL1_REG, 7, 1, 0),
393SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLOL2_REG, 0, 1, 0),
394SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLOL2_REG, 1, 1, 0),
395SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLOL2_REG, 2, 1, 0),
396SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLOL2_REG, 3, 1, 0),
397SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLOL2_REG, 4, 1, 0),
398SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLOL2_REG, 5, 1, 0),
399SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLOL2_REG, 6, 1, 0),
400SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLOL2_REG, 7, 1, 0),
401SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 6, 0, 0),
402};
403
404static const struct snd_kcontrol_new lm49453_lineout_right_mixer[] = {
405SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLOR1_REG, 0, 1, 0),
406SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLOR1_REG, 1, 1, 0),
407SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLOR1_REG, 2, 1, 0),
408SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLOR1_REG, 3, 1, 0),
409SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLOR1_REG, 4, 1, 0),
410SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLOR1_REG, 5, 1, 0),
411SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLOR1_REG, 6, 1, 0),
412SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLOR1_REG, 7, 1, 0),
413SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLOR2_REG, 0, 1, 0),
414SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLOR2_REG, 1, 1, 0),
415SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLOR2_REG, 2, 1, 0),
416SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLOR2_REG, 3, 1, 0),
417SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLOR2_REG, 4, 1, 0),
418SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLOR2_REG, 5, 1, 0),
419SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLOR2_REG, 6, 1, 0),
420SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLOR2_REG, 7, 1, 0),
421SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 7, 0, 0),
422};
423
424static const struct snd_kcontrol_new lm49453_port1_tx1_mixer[] = {
425SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX1_REG, 0, 1, 0),
426SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX1_REG, 1, 1, 0),
427SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX1_REG, 2, 1, 0),
428SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX1_REG, 3, 1, 0),
429SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX1_REG, 4, 1, 0),
430SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX1_REG, 5, 1, 0),
431SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_PORT1_TX1_REG, 6, 1, 0),
432SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_PORT1_TX1_REG, 7, 1, 0),
433};
434
435static const struct snd_kcontrol_new lm49453_port1_tx2_mixer[] = {
436SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX2_REG, 0, 1, 0),
437SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX2_REG, 1, 1, 0),
438SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX2_REG, 2, 1, 0),
439SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX2_REG, 3, 1, 0),
440SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX2_REG, 4, 1, 0),
441SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX2_REG, 5, 1, 0),
442SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_PORT1_TX2_REG, 6, 1, 0),
443SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT1_TX2_REG, 7, 1, 0),
444};
445
446static const struct snd_kcontrol_new lm49453_port1_tx3_mixer[] = {
447SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX3_REG, 0, 1, 0),
448SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX3_REG, 1, 1, 0),
449SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX3_REG, 2, 1, 0),
450SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX3_REG, 3, 1, 0),
451SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX3_REG, 4, 1, 0),
452SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX3_REG, 5, 1, 0),
453SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_PORT1_TX3_REG, 6, 1, 0),
454};
455
456static const struct snd_kcontrol_new lm49453_port1_tx4_mixer[] = {
457SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX4_REG, 0, 1, 0),
458SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX4_REG, 1, 1, 0),
459SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX4_REG, 2, 1, 0),
460SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX4_REG, 3, 1, 0),
461SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX4_REG, 4, 1, 0),
462SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX4_REG, 5, 1, 0),
463SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_PORT1_TX4_REG, 6, 1, 0),
464};
465
466static const struct snd_kcontrol_new lm49453_port1_tx5_mixer[] = {
467SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX5_REG, 0, 1, 0),
468SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX5_REG, 1, 1, 0),
469SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX5_REG, 2, 1, 0),
470SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX5_REG, 3, 1, 0),
471SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX5_REG, 4, 1, 0),
472SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX5_REG, 5, 1, 0),
473SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_PORT1_TX5_REG, 6, 1, 0),
474};
475
476static const struct snd_kcontrol_new lm49453_port1_tx6_mixer[] = {
477SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX6_REG, 0, 1, 0),
478SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX6_REG, 1, 1, 0),
479SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX6_REG, 2, 1, 0),
480SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX6_REG, 3, 1, 0),
481SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX6_REG, 4, 1, 0),
482SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX6_REG, 5, 1, 0),
483SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_PORT1_TX6_REG, 6, 1, 0),
484};
485
486static const struct snd_kcontrol_new lm49453_port1_tx7_mixer[] = {
487SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX7_REG, 0, 1, 0),
488SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX7_REG, 1, 1, 0),
489SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX7_REG, 2, 1, 0),
490SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX7_REG, 3, 1, 0),
491SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX7_REG, 4, 1, 0),
492SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX7_REG, 5, 1, 0),
493SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_PORT1_TX7_REG, 6, 1, 0),
494};
495
496static const struct snd_kcontrol_new lm49453_port1_tx8_mixer[] = {
497SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX8_REG, 0, 1, 0),
498SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX8_REG, 1, 1, 0),
499SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX8_REG, 2, 1, 0),
500SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX8_REG, 3, 1, 0),
501SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX8_REG, 4, 1, 0),
502SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX8_REG, 5, 1, 0),
503SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_PORT1_TX8_REG, 6, 1, 0),
504};
505
506static const struct snd_kcontrol_new lm49453_port2_tx1_mixer[] = {
507SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT2_TX1_REG, 0, 1, 0),
508SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT2_TX1_REG, 1, 1, 0),
509SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT2_TX1_REG, 2, 1, 0),
510SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT2_TX1_REG, 3, 1, 0),
511SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT2_TX1_REG, 4, 1, 0),
512SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT2_TX1_REG, 5, 1, 0),
513SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_PORT2_TX1_REG, 6, 1, 0),
514SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_PORT2_TX1_REG, 7, 1, 0),
515};
516
517static const struct snd_kcontrol_new lm49453_port2_tx2_mixer[] = {
518SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT2_TX2_REG, 0, 1, 0),
519SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT2_TX2_REG, 1, 1, 0),
520SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT2_TX2_REG, 2, 1, 0),
521SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT2_TX2_REG, 3, 1, 0),
522SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT2_TX2_REG, 4, 1, 0),
523SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT2_TX2_REG, 5, 1, 0),
524SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_PORT2_TX2_REG, 6, 1, 0),
525SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT2_TX2_REG, 7, 1, 0),
526};
527
528/* TLV Declarations */
529static const DECLARE_TLV_DB_SCALE(digital_tlv, -7650, 150, 1);
530static const DECLARE_TLV_DB_SCALE(port_tlv, 0, 600, 0);
531
532static const struct snd_kcontrol_new lm49453_sidetone_mixer_controls[] = {
533/* Sidetone supports mono only */
534SOC_DAPM_SINGLE_TLV("Sidetone ADCL Volume", LM49453_P0_STN_VOL_ADCL_REG,
535 0, 0x3F, 0, digital_tlv),
536SOC_DAPM_SINGLE_TLV("Sidetone ADCR Volume", LM49453_P0_STN_VOL_ADCR_REG,
537 0, 0x3F, 0, digital_tlv),
538SOC_DAPM_SINGLE_TLV("Sidetone DMIC1L Volume", LM49453_P0_STN_VOL_DMIC1L_REG,
539 0, 0x3F, 0, digital_tlv),
540SOC_DAPM_SINGLE_TLV("Sidetone DMIC1R Volume", LM49453_P0_STN_VOL_DMIC1R_REG,
541 0, 0x3F, 0, digital_tlv),
542SOC_DAPM_SINGLE_TLV("Sidetone DMIC2L Volume", LM49453_P0_STN_VOL_DMIC2L_REG,
543 0, 0x3F, 0, digital_tlv),
544SOC_DAPM_SINGLE_TLV("Sidetone DMIC2R Volume", LM49453_P0_STN_VOL_DMIC2R_REG,
545 0, 0x3F, 0, digital_tlv),
546};
547
548static const struct snd_kcontrol_new lm49453_snd_controls[] = {
549 /* mic1 and mic2 supports mono only */
550 SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_ADC_LEVELL_REG, 0, 6,
551 0, digital_tlv),
552 SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_ADC_LEVELR_REG, 0, 6,
553 0, digital_tlv),
554
555 SOC_DOUBLE_R_TLV("DMIC1 Volume", LM49453_P0_DMIC1_LEVELL_REG,
556 LM49453_P0_DMIC1_LEVELR_REG, 0, 6, 0, digital_tlv),
557 SOC_DOUBLE_R_TLV("DMIC2 Volume", LM49453_P0_DMIC2_LEVELL_REG,
558 LM49453_P0_DMIC2_LEVELR_REG, 0, 6, 0, digital_tlv),
559
560 SOC_DAPM_ENUM("Mic2Mode", lm49453_mic2mode_enum),
561 SOC_DAPM_ENUM("DMIC12 SRC", lm49453_dmic12_cfg_enum),
562 SOC_DAPM_ENUM("DMIC34 SRC", lm49453_dmic34_cfg_enum),
563
564 /* Capture path filter enable */
565 SOC_SINGLE("DMIC1 HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
566 0, 1, 0),
567 SOC_SINGLE("DMIC2 HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
568 1, 1, 0),
569 SOC_SINGLE("ADC HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
570 2, 1, 0),
571
572 SOC_DOUBLE_R_TLV("DAC HP Volume", LM49453_P0_DAC_HP_LEVELL_REG,
573 LM49453_P0_DAC_HP_LEVELR_REG, 0, 6, 0, digital_tlv),
574 SOC_DOUBLE_R_TLV("DAC LO Volume", LM49453_P0_DAC_LO_LEVELL_REG,
575 LM49453_P0_DAC_LO_LEVELR_REG, 0, 6, 0, digital_tlv),
576 SOC_DOUBLE_R_TLV("DAC LS Volume", LM49453_P0_DAC_LS_LEVELL_REG,
577 LM49453_P0_DAC_LS_LEVELR_REG, 0, 6, 0, digital_tlv),
578 SOC_DOUBLE_R_TLV("DAC HA Volume", LM49453_P0_DAC_HA_LEVELL_REG,
579 LM49453_P0_DAC_HA_LEVELR_REG, 0, 6, 0, digital_tlv),
580
581 SOC_SINGLE_TLV("EP Volume", LM49453_P0_DAC_LS_LEVELL_REG,
582 0, 6, 0, digital_tlv),
583
584 SOC_SINGLE_TLV("PORT1_1_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
585 0, 3, 0, port_tlv),
586 SOC_SINGLE_TLV("PORT1_2_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
587 2, 3, 0, port_tlv),
588 SOC_SINGLE_TLV("PORT1_3_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
589 4, 3, 0, port_tlv),
590 SOC_SINGLE_TLV("PORT1_4_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
591 6, 3, 0, port_tlv),
592 SOC_SINGLE_TLV("PORT1_5_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
593 0, 3, 0, port_tlv),
594 SOC_SINGLE_TLV("PORT1_6_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
595 2, 3, 0, port_tlv),
596 SOC_SINGLE_TLV("PORT1_7_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
597 4, 3, 0, port_tlv),
598 SOC_SINGLE_TLV("PORT1_8_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
599 6, 3, 0, port_tlv),
600
601 SOC_SINGLE_TLV("PORT2_1_RX_LVL Volume", LM49453_P0_PORT2_RX_LVL_REG,
602 0, 3, 0, port_tlv),
603 SOC_SINGLE_TLV("PORT2_2_RX_LVL Volume", LM49453_P0_PORT2_RX_LVL_REG,
604 2, 3, 0, port_tlv),
605
606 SOC_SINGLE("Port1 Playback Switch", LM49453_P0_AUDIO_PORT1_BASIC_REG,
607 1, 1, 0),
608 SOC_SINGLE("Port2 Playback Switch", LM49453_P0_AUDIO_PORT2_BASIC_REG,
609 1, 1, 0),
610 SOC_SINGLE("Port1 Capture Switch", LM49453_P0_AUDIO_PORT1_BASIC_REG,
611 2, 1, 0),
612 SOC_SINGLE("Port2 Capture Switch", LM49453_P0_AUDIO_PORT2_BASIC_REG,
613 2, 1, 0)
614
615};
616
617/* DAPM widgets */
618static const struct snd_soc_dapm_widget lm49453_dapm_widgets[] = {
619
620 /* All end points HP,EP, LS, Lineout and Haptic */
621 SND_SOC_DAPM_OUTPUT("HPOUTL"),
622 SND_SOC_DAPM_OUTPUT("HPOUTR"),
623 SND_SOC_DAPM_OUTPUT("EPOUT"),
624 SND_SOC_DAPM_OUTPUT("LSOUTL"),
625 SND_SOC_DAPM_OUTPUT("LSOUTR"),
626 SND_SOC_DAPM_OUTPUT("LOOUTR"),
627 SND_SOC_DAPM_OUTPUT("LOOUTL"),
628 SND_SOC_DAPM_OUTPUT("HAOUTL"),
629 SND_SOC_DAPM_OUTPUT("HAOUTR"),
630
631 SND_SOC_DAPM_INPUT("AMIC1"),
632 SND_SOC_DAPM_INPUT("AMIC2"),
633 SND_SOC_DAPM_INPUT("DMIC1DAT"),
634 SND_SOC_DAPM_INPUT("DMIC2DAT"),
635 SND_SOC_DAPM_INPUT("AUXL"),
636 SND_SOC_DAPM_INPUT("AUXR"),
637
638 SND_SOC_DAPM_PGA("PORT1_1_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
639 SND_SOC_DAPM_PGA("PORT1_2_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
640 SND_SOC_DAPM_PGA("PORT1_3_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
641 SND_SOC_DAPM_PGA("PORT1_4_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
642 SND_SOC_DAPM_PGA("PORT1_5_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
643 SND_SOC_DAPM_PGA("PORT1_6_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
644 SND_SOC_DAPM_PGA("PORT1_7_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
645 SND_SOC_DAPM_PGA("PORT1_8_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
646 SND_SOC_DAPM_PGA("PORT2_1_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
647 SND_SOC_DAPM_PGA("PORT2_2_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
648
649 SND_SOC_DAPM_SUPPLY("AMIC1Bias", LM49453_P0_MICL_REG, 6, 0, NULL, 0),
650 SND_SOC_DAPM_SUPPLY("AMIC2Bias", LM49453_P0_MICR_REG, 6, 0, NULL, 0),
651
652 /* playback path driver enables */
653 SND_SOC_DAPM_OUT_DRV("Headset Switch",
654 LM49453_P0_PMC_SETUP_REG, 0, 0, NULL, 0),
655 SND_SOC_DAPM_OUT_DRV("Earpiece Switch",
656 LM49453_P0_EP_REG, 0, 0, NULL, 0),
657 SND_SOC_DAPM_OUT_DRV("Speaker Left Switch",
658 LM49453_P0_DIS_PKVL_FB_REG, 0, 1, NULL, 0),
659 SND_SOC_DAPM_OUT_DRV("Speaker Right Switch",
660 LM49453_P0_DIS_PKVL_FB_REG, 1, 1, NULL, 0),
661 SND_SOC_DAPM_OUT_DRV("Haptic Left Switch",
662 LM49453_P0_DIS_PKVL_FB_REG, 2, 1, NULL, 0),
663 SND_SOC_DAPM_OUT_DRV("Haptic Right Switch",
664 LM49453_P0_DIS_PKVL_FB_REG, 3, 1, NULL, 0),
665
666 /* DAC */
667 SND_SOC_DAPM_DAC("HPL DAC", "Headset", SND_SOC_NOPM, 0, 0),
668 SND_SOC_DAPM_DAC("HPR DAC", "Headset", SND_SOC_NOPM, 0, 0),
669 SND_SOC_DAPM_DAC("LSL DAC", "Speaker", SND_SOC_NOPM, 0, 0),
670 SND_SOC_DAPM_DAC("LSR DAC", "Speaker", SND_SOC_NOPM, 0, 0),
671 SND_SOC_DAPM_DAC("HAL DAC", "Haptic", SND_SOC_NOPM, 0, 0),
672 SND_SOC_DAPM_DAC("HAR DAC", "Haptic", SND_SOC_NOPM, 0, 0),
673 SND_SOC_DAPM_DAC("LOL DAC", "Lineout", SND_SOC_NOPM, 0, 0),
674 SND_SOC_DAPM_DAC("LOR DAC", "Lineout", SND_SOC_NOPM, 0, 0),
675
676
677 SND_SOC_DAPM_PGA("AUXL Input",
678 LM49453_P0_ANALOG_MIXER_ADC_REG, 2, 0, NULL, 0),
679 SND_SOC_DAPM_PGA("AUXR Input",
680 LM49453_P0_ANALOG_MIXER_ADC_REG, 3, 0, NULL, 0),
681
682 SND_SOC_DAPM_PGA("Sidetone", SND_SOC_NOPM, 0, 0, NULL, 0),
683
684 /* ADC */
685 SND_SOC_DAPM_ADC("DMIC1 Left", "Capture", SND_SOC_NOPM, 1, 0),
686 SND_SOC_DAPM_ADC("DMIC1 Right", "Capture", SND_SOC_NOPM, 1, 0),
687 SND_SOC_DAPM_ADC("DMIC2 Left", "Capture", SND_SOC_NOPM, 1, 0),
688 SND_SOC_DAPM_ADC("DMIC2 Right", "Capture", SND_SOC_NOPM, 1, 0),
689
690 SND_SOC_DAPM_ADC("ADC Left", "Capture", SND_SOC_NOPM, 1, 0),
691 SND_SOC_DAPM_ADC("ADC Right", "Capture", SND_SOC_NOPM, 0, 0),
692
693 SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 0, 0,
694 &lm49453_adcl_mux_control),
695 SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
696 &lm49453_adcr_mux_control),
697
698 SND_SOC_DAPM_MUX("Mic1 Input",
699 SND_SOC_NOPM, 0, 0, &lm49453_adcl_mux_control),
700
701 SND_SOC_DAPM_MUX("Mic2 Input",
702 SND_SOC_NOPM, 0, 0, &lm49453_adcr_mux_control),
703
704 /* AIF */
705 SND_SOC_DAPM_AIF_IN("PORT1_SDI", NULL, 0,
706 LM49453_P0_PULL_CONFIG1_REG, 2, 0),
707 SND_SOC_DAPM_AIF_IN("PORT2_SDI", NULL, 0,
708 LM49453_P0_PULL_CONFIG1_REG, 6, 0),
709
710 SND_SOC_DAPM_AIF_OUT("PORT1_SDO", NULL, 0,
711 LM49453_P0_PULL_CONFIG1_REG, 3, 0),
712 SND_SOC_DAPM_AIF_OUT("PORT2_SDO", NULL, 0,
713 LM49453_P0_PULL_CONFIG1_REG, 7, 0),
714
715 /* Port1 TX controls */
716 SND_SOC_DAPM_OUT_DRV("P1_1_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
717 SND_SOC_DAPM_OUT_DRV("P1_2_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
718 SND_SOC_DAPM_OUT_DRV("P1_3_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
719 SND_SOC_DAPM_OUT_DRV("P1_4_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
720 SND_SOC_DAPM_OUT_DRV("P1_5_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
721 SND_SOC_DAPM_OUT_DRV("P1_6_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
722 SND_SOC_DAPM_OUT_DRV("P1_7_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
723 SND_SOC_DAPM_OUT_DRV("P1_8_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
724
725 /* Port2 TX controls */
726 SND_SOC_DAPM_OUT_DRV("P2_1_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
727 SND_SOC_DAPM_OUT_DRV("P2_2_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
728
729 /* Sidetone Mixer */
730 SND_SOC_DAPM_MIXER("Sidetone Mixer", SND_SOC_NOPM, 0, 0,
731 lm49453_sidetone_mixer_controls,
732 ARRAY_SIZE(lm49453_sidetone_mixer_controls)),
733
734 /* DAC MIXERS */
735 SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0,
736 lm49453_headset_left_mixer,
737 ARRAY_SIZE(lm49453_headset_left_mixer)),
738 SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0,
739 lm49453_headset_right_mixer,
740 ARRAY_SIZE(lm49453_headset_right_mixer)),
741 SND_SOC_DAPM_MIXER("LOL Mixer", SND_SOC_NOPM, 0, 0,
742 lm49453_lineout_left_mixer,
743 ARRAY_SIZE(lm49453_lineout_left_mixer)),
744 SND_SOC_DAPM_MIXER("LOR Mixer", SND_SOC_NOPM, 0, 0,
745 lm49453_lineout_right_mixer,
746 ARRAY_SIZE(lm49453_lineout_right_mixer)),
747 SND_SOC_DAPM_MIXER("LSL Mixer", SND_SOC_NOPM, 0, 0,
748 lm49453_speaker_left_mixer,
749 ARRAY_SIZE(lm49453_speaker_left_mixer)),
750 SND_SOC_DAPM_MIXER("LSR Mixer", SND_SOC_NOPM, 0, 0,
751 lm49453_speaker_right_mixer,
752 ARRAY_SIZE(lm49453_speaker_right_mixer)),
753 SND_SOC_DAPM_MIXER("HAL Mixer", SND_SOC_NOPM, 0, 0,
754 lm49453_haptic_left_mixer,
755 ARRAY_SIZE(lm49453_haptic_left_mixer)),
756 SND_SOC_DAPM_MIXER("HAR Mixer", SND_SOC_NOPM, 0, 0,
757 lm49453_haptic_right_mixer,
758 ARRAY_SIZE(lm49453_haptic_right_mixer)),
759
760 /* Capture Mixer */
761 SND_SOC_DAPM_MIXER("Port1_1 Mixer", SND_SOC_NOPM, 0, 0,
762 lm49453_port1_tx1_mixer,
763 ARRAY_SIZE(lm49453_port1_tx1_mixer)),
764 SND_SOC_DAPM_MIXER("Port1_2 Mixer", SND_SOC_NOPM, 0, 0,
765 lm49453_port1_tx2_mixer,
766 ARRAY_SIZE(lm49453_port1_tx2_mixer)),
767 SND_SOC_DAPM_MIXER("Port1_3 Mixer", SND_SOC_NOPM, 0, 0,
768 lm49453_port1_tx3_mixer,
769 ARRAY_SIZE(lm49453_port1_tx3_mixer)),
770 SND_SOC_DAPM_MIXER("Port1_4 Mixer", SND_SOC_NOPM, 0, 0,
771 lm49453_port1_tx4_mixer,
772 ARRAY_SIZE(lm49453_port1_tx4_mixer)),
773 SND_SOC_DAPM_MIXER("Port1_5 Mixer", SND_SOC_NOPM, 0, 0,
774 lm49453_port1_tx5_mixer,
775 ARRAY_SIZE(lm49453_port1_tx5_mixer)),
776 SND_SOC_DAPM_MIXER("Port1_6 Mixer", SND_SOC_NOPM, 0, 0,
777 lm49453_port1_tx6_mixer,
778 ARRAY_SIZE(lm49453_port1_tx6_mixer)),
779 SND_SOC_DAPM_MIXER("Port1_7 Mixer", SND_SOC_NOPM, 0, 0,
780 lm49453_port1_tx7_mixer,
781 ARRAY_SIZE(lm49453_port1_tx7_mixer)),
782 SND_SOC_DAPM_MIXER("Port1_8 Mixer", SND_SOC_NOPM, 0, 0,
783 lm49453_port1_tx8_mixer,
784 ARRAY_SIZE(lm49453_port1_tx8_mixer)),
785
786 SND_SOC_DAPM_MIXER("Port2_1 Mixer", SND_SOC_NOPM, 0, 0,
787 lm49453_port2_tx1_mixer,
788 ARRAY_SIZE(lm49453_port2_tx1_mixer)),
789 SND_SOC_DAPM_MIXER("Port2_2 Mixer", SND_SOC_NOPM, 0, 0,
790 lm49453_port2_tx2_mixer,
791 ARRAY_SIZE(lm49453_port2_tx2_mixer)),
792};
793
794static const struct snd_soc_dapm_route lm49453_audio_map[] = {
795 /* Port SDI mapping */
796 { "PORT1_1_RX", "Port1 Playback Switch", "PORT1_SDI" },
797 { "PORT1_2_RX", "Port1 Playback Switch", "PORT1_SDI" },
798 { "PORT1_3_RX", "Port1 Playback Switch", "PORT1_SDI" },
799 { "PORT1_4_RX", "Port1 Playback Switch", "PORT1_SDI" },
800 { "PORT1_5_RX", "Port1 Playback Switch", "PORT1_SDI" },
801 { "PORT1_6_RX", "Port1 Playback Switch", "PORT1_SDI" },
802 { "PORT1_7_RX", "Port1 Playback Switch", "PORT1_SDI" },
803 { "PORT1_8_RX", "Port1 Playback Switch", "PORT1_SDI" },
804
805 { "PORT2_1_RX", "Port2 Playback Switch", "PORT2_SDI" },
806 { "PORT2_2_RX", "Port2 Playback Switch", "PORT2_SDI" },
807
808 /* HP mapping */
809 { "HPL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
810 { "HPL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
811 { "HPL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
812 { "HPL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
813 { "HPL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
814 { "HPL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
815 { "HPL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
816 { "HPL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
817
818 { "HPL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
819 { "HPL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
820
821 { "HPL Mixer", "ADCL Switch", "ADC Left" },
822 { "HPL Mixer", "ADCR Switch", "ADC Right" },
823 { "HPL Mixer", "DMIC1L Switch", "DMIC1 Left" },
824 { "HPL Mixer", "DMIC1R Switch", "DMIC1 Right" },
825 { "HPL Mixer", "DMIC2L Switch", "DMIC2 Left" },
826 { "HPL Mixer", "DMIC2R Switch", "DMIC2 Right" },
827 { "HPL Mixer", "Sidetone Switch", "Sidetone" },
828
829 { "HPL DAC", NULL, "HPL Mixer" },
830
831 { "HPR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
832 { "HPR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
833 { "HPR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
834 { "HPR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
835 { "HPR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
836 { "HPR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
837 { "HPR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
838 { "HPR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
839
840 /* Port 2 */
841 { "HPR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
842 { "HPR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
843
844 { "HPR Mixer", "ADCL Switch", "ADC Left" },
845 { "HPR Mixer", "ADCR Switch", "ADC Right" },
846 { "HPR Mixer", "DMIC1L Switch", "DMIC1 Left" },
847 { "HPR Mixer", "DMIC1R Switch", "DMIC1 Right" },
848 { "HPR Mixer", "DMIC2L Switch", "DMIC2 Left" },
849 { "HPR Mixer", "DMIC2L Switch", "DMIC2 Right" },
850 { "HPR Mixer", "Sidetone Switch", "Sidetone" },
851
852 { "HPR DAC", NULL, "HPR Mixer" },
853
854 { "HPOUTL", "Headset Switch", "HPL DAC"},
855 { "HPOUTR", "Headset Switch", "HPR DAC"},
856
857 /* EP map */
858 { "EPOUT", "Earpiece Switch", "HPL DAC" },
859
860 /* Speaker map */
861 { "LSL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
862 { "LSL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
863 { "LSL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
864 { "LSL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
865 { "LSL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
866 { "LSL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
867 { "LSL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
868 { "LSL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
869
870 /* Port 2 */
871 { "LSL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
872 { "LSL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
873
874 { "LSL Mixer", "ADCL Switch", "ADC Left" },
875 { "LSL Mixer", "ADCR Switch", "ADC Right" },
876 { "LSL Mixer", "DMIC1L Switch", "DMIC1 Left" },
877 { "LSL Mixer", "DMIC1R Switch", "DMIC1 Right" },
878 { "LSL Mixer", "DMIC2L Switch", "DMIC2 Left" },
879 { "LSL Mixer", "DMIC2R Switch", "DMIC2 Right" },
880 { "LSL Mixer", "Sidetone Switch", "Sidetone" },
881
882 { "LSL DAC", NULL, "LSL Mixer" },
883
884 { "LSR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
885 { "LSR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
886 { "LSR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
887 { "LSR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
888 { "LSR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
889 { "LSR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
890 { "LSR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
891 { "LSR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
892
893 /* Port 2 */
894 { "LSR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
895 { "LSR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
896
897 { "LSR Mixer", "ADCL Switch", "ADC Left" },
898 { "LSR Mixer", "ADCR Switch", "ADC Right" },
899 { "LSR Mixer", "DMIC1L Switch", "DMIC1 Left" },
900 { "LSR Mixer", "DMIC1R Switch", "DMIC1 Right" },
901 { "LSR Mixer", "DMIC2L Switch", "DMIC2 Left" },
902 { "LSR Mixer", "DMIC2R Switch", "DMIC2 Right" },
903 { "LSR Mixer", "Sidetone Switch", "Sidetone" },
904
905 { "LSR DAC", NULL, "LSR Mixer" },
906
907 { "LSOUTL", "Speaker Left Switch", "LSL DAC"},
908 { "LSOUTR", "Speaker Left Switch", "LSR DAC"},
909
910 /* Haptic map */
911 { "HAL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
912 { "HAL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
913 { "HAL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
914 { "HAL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
915 { "HAL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
916 { "HAL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
917 { "HAL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
918 { "HAL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
919
920 /* Port 2 */
921 { "HAL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
922 { "HAL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
923
924 { "HAL Mixer", "ADCL Switch", "ADC Left" },
925 { "HAL Mixer", "ADCR Switch", "ADC Right" },
926 { "HAL Mixer", "DMIC1L Switch", "DMIC1 Left" },
927 { "HAL Mixer", "DMIC1R Switch", "DMIC1 Right" },
928 { "HAL Mixer", "DMIC2L Switch", "DMIC2 Left" },
929 { "HAL Mixer", "DMIC2R Switch", "DMIC2 Right" },
930 { "HAL Mixer", "Sidetone Switch", "Sidetone" },
931
932 { "HAL DAC", NULL, "HAL Mixer" },
933
934 { "HAR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
935 { "HAR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
936 { "HAR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
937 { "HAR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
938 { "HAR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
939 { "HAR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
940 { "HAR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
941 { "HAR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
942
943 /* Port 2 */
944 { "HAR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
945 { "HAR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
946
947 { "HAR Mixer", "ADCL Switch", "ADC Left" },
948 { "HAR Mixer", "ADCR Switch", "ADC Right" },
949 { "HAR Mixer", "DMIC1L Switch", "DMIC1 Left" },
950 { "HAR Mixer", "DMIC1R Switch", "DMIC1 Right" },
951 { "HAR Mixer", "DMIC2L Switch", "DMIC2 Left" },
952 { "HAR Mixer", "DMIC2R Switch", "DMIC2 Right" },
953 { "HAR Mixer", "Sideton Switch", "Sidetone" },
954
955 { "HAR DAC", NULL, "HAR Mixer" },
956
957 { "HAOUTL", "Haptic Left Switch", "HAL DAC" },
958 { "HAOUTR", "Haptic Right Switch", "HAR DAC" },
959
960 /* Lineout map */
961 { "LOL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
962 { "LOL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
963 { "LOL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
964 { "LOL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
965 { "LOL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
966 { "LOL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
967 { "LOL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
968 { "LOL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
969
970 /* Port 2 */
971 { "LOL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
972 { "LOL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
973
974 { "LOL Mixer", "ADCL Switch", "ADC Left" },
975 { "LOL Mixer", "ADCR Switch", "ADC Right" },
976 { "LOL Mixer", "DMIC1L Switch", "DMIC1 Left" },
977 { "LOL Mixer", "DMIC1R Switch", "DMIC1 Right" },
978 { "LOL Mixer", "DMIC2L Switch", "DMIC2 Left" },
979 { "LOL Mixer", "DMIC2R Switch", "DMIC2 Right" },
980 { "LOL Mixer", "Sidetone Switch", "Sidetone" },
981
982 { "LOL DAC", NULL, "LOL Mixer" },
983
984 { "LOR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
985 { "LOR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
986 { "LOR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
987 { "LOR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
988 { "LOR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
989 { "LOR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
990 { "LOR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
991 { "LOR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
992
993 /* Port 2 */
994 { "LOR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
995 { "LOR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
996
997 { "LOR Mixer", "ADCL Switch", "ADC Left" },
998 { "LOR Mixer", "ADCR Switch", "ADC Right" },
999 { "LOR Mixer", "DMIC1L Switch", "DMIC1 Left" },
1000 { "LOR Mixer", "DMIC1R Switch", "DMIC1 Right" },
1001 { "LOR Mixer", "DMIC2L Switch", "DMIC2 Left" },
1002 { "LOR Mixer", "DMIC2R Switch", "DMIC2 Right" },
1003 { "LOR Mixer", "Sidetone Switch", "Sidetone" },
1004
1005 { "LOR DAC", NULL, "LOR Mixer" },
1006
1007 { "LOOUTL", NULL, "LOL DAC" },
1008 { "LOOUTR", NULL, "LOR DAC" },
1009
1010 /* TX map */
1011 /* Port1 mappings */
1012 { "Port1_1 Mixer", "ADCL Switch", "ADC Left" },
1013 { "Port1_1 Mixer", "ADCR Switch", "ADC Right" },
1014 { "Port1_1 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1015 { "Port1_1 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1016 { "Port1_1 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1017 { "Port1_1 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1018
1019 { "Port1_2 Mixer", "ADCL Switch", "ADC Left" },
1020 { "Port1_2 Mixer", "ADCR Switch", "ADC Right" },
1021 { "Port1_2 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1022 { "Port1_2 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1023 { "Port1_2 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1024 { "Port1_2 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1025
1026 { "Port1_3 Mixer", "ADCL Switch", "ADC Left" },
1027 { "Port1_3 Mixer", "ADCR Switch", "ADC Right" },
1028 { "Port1_3 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1029 { "Port1_3 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1030 { "Port1_3 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1031 { "Port1_3 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1032
1033 { "Port1_4 Mixer", "ADCL Switch", "ADC Left" },
1034 { "Port1_4 Mixer", "ADCR Switch", "ADC Right" },
1035 { "Port1_4 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1036 { "Port1_4 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1037 { "Port1_4 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1038 { "Port1_4 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1039
1040 { "Port1_5 Mixer", "ADCL Switch", "ADC Left" },
1041 { "Port1_5 Mixer", "ADCR Switch", "ADC Right" },
1042 { "Port1_5 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1043 { "Port1_5 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1044 { "Port1_5 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1045 { "Port1_5 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1046
1047 { "Port1_6 Mixer", "ADCL Switch", "ADC Left" },
1048 { "Port1_6 Mixer", "ADCR Switch", "ADC Right" },
1049 { "Port1_6 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1050 { "Port1_6 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1051 { "Port1_6 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1052 { "Port1_6 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1053
1054 { "Port1_7 Mixer", "ADCL Switch", "ADC Left" },
1055 { "Port1_7 Mixer", "ADCR Switch", "ADC Right" },
1056 { "Port1_7 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1057 { "Port1_7 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1058 { "Port1_7 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1059 { "Port1_7 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1060
1061 { "Port1_8 Mixer", "ADCL Switch", "ADC Left" },
1062 { "Port1_8 Mixer", "ADCR Switch", "ADC Right" },
1063 { "Port1_8 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1064 { "Port1_8 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1065 { "Port1_8 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1066 { "Port1_8 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1067
1068 { "Port2_1 Mixer", "ADCL Switch", "ADC Left" },
1069 { "Port2_1 Mixer", "ADCR Switch", "ADC Right" },
1070 { "Port2_1 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1071 { "Port2_1 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1072 { "Port2_1 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1073 { "Port2_1 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1074
1075 { "Port2_2 Mixer", "ADCL Switch", "ADC Left" },
1076 { "Port2_2 Mixer", "ADCR Switch", "ADC Right" },
1077 { "Port2_2 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1078 { "Port2_2 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1079 { "Port2_2 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1080 { "Port2_2 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1081
1082 { "P1_1_TX", NULL, "Port1_1 Mixer" },
1083 { "P1_2_TX", NULL, "Port1_2 Mixer" },
1084 { "P1_3_TX", NULL, "Port1_3 Mixer" },
1085 { "P1_4_TX", NULL, "Port1_4 Mixer" },
1086 { "P1_5_TX", NULL, "Port1_5 Mixer" },
1087 { "P1_6_TX", NULL, "Port1_6 Mixer" },
1088 { "P1_7_TX", NULL, "Port1_7 Mixer" },
1089 { "P1_8_TX", NULL, "Port1_8 Mixer" },
1090
1091 { "P2_1_TX", NULL, "Port2_1 Mixer" },
1092 { "P2_2_TX", NULL, "Port2_2 Mixer" },
1093
1094 { "PORT1_SDO", "Port1 Capture Switch", "P1_1_TX"},
1095 { "PORT1_SDO", "Port1 Capture Switch", "P1_2_TX"},
1096 { "PORT1_SDO", "Port1 Capture Switch", "P1_3_TX"},
1097 { "PORT1_SDO", "Port1 Capture Switch", "P1_4_TX"},
1098 { "PORT1_SDO", "Port1 Capture Switch", "P1_5_TX"},
1099 { "PORT1_SDO", "Port1 Capture Switch", "P1_6_TX"},
1100 { "PORT1_SDO", "Port1 Capture Switch", "P1_7_TX"},
1101 { "PORT1_SDO", "Port1 Capture Switch", "P1_8_TX"},
1102
1103 { "PORT2_SDO", "Port2 Capture Switch", "P2_1_TX"},
1104 { "PORT2_SDO", "Port2 Capture Switch", "P2_2_TX"},
1105
1106 { "Mic1 Input", NULL, "AMIC1" },
1107 { "Mic2 Input", NULL, "AMIC2" },
1108
1109 { "AUXL Input", NULL, "AUXL" },
1110 { "AUXR Input", NULL, "AUXR" },
1111
1112 /* AUX connections */
1113 { "ADCL Mux", "Aux_L", "AUXL Input" },
1114 { "ADCL Mux", "MIC1", "Mic1 Input" },
1115
1116 { "ADCR Mux", "Aux_R", "AUXR Input" },
1117 { "ADCR Mux", "MIC2", "Mic2 Input" },
1118
1119 /* ADC connection */
1120 { "ADC Left", NULL, "ADCL Mux"},
1121 { "ADC Right", NULL, "ADCR Mux"},
1122
1123 { "DMIC1 Left", NULL, "DMIC1DAT"},
1124 { "DMIC1 Right", NULL, "DMIC1DAT"},
1125 { "DMIC2 Left", NULL, "DMIC2DAT"},
1126 { "DMIC2 Right", NULL, "DMIC2DAT"},
1127
1128 /* Sidetone map */
1129 { "Sidetone Mixer", NULL, "ADC Left" },
1130 { "Sidetone Mixer", NULL, "ADC Right" },
1131 { "Sidetone Mixer", NULL, "DMIC1 Left" },
1132 { "Sidetone Mixer", NULL, "DMIC1 Right" },
1133 { "Sidetone Mixer", NULL, "DMIC2 Left" },
1134 { "Sidetone Mixer", NULL, "DMIC2 Right" },
1135
1136 { "Sidetone", "Sidetone Switch", "Sidetone Mixer" },
1137};
1138
1139static int lm49453_hw_params(struct snd_pcm_substream *substream,
1140 struct snd_pcm_hw_params *params,
1141 struct snd_soc_dai *dai)
1142{
1143 struct snd_soc_codec *codec = dai->codec;
1144 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1145 u16 clk_div = 0;
1146
1147 lm49453->fs_rate = params_rate(params);
1148
1149 /* Setting DAC clock dividers based on substream sample rate. */
1150 switch (lm49453->fs_rate) {
1151 case 8000:
1152 case 16000:
1153 case 32000:
1154 case 24000:
1155 case 48000:
1156 clk_div = 256;
1157 break;
1158 case 11025:
1159 case 22050:
1160 case 44100:
1161 clk_div = 216;
1162 break;
1163 case 96000:
1164 clk_div = 127;
1165 break;
1166 default:
1167 return -EINVAL;
1168 }
1169
1170 snd_soc_write(codec, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
1171 snd_soc_write(codec, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
1172
1173 return 0;
1174}
1175
1176static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1177{
1178 struct snd_soc_codec *codec = codec_dai->codec;
1179
1180 u16 aif_val;
1181 int mode = 0;
1182 int clk_phase = 0;
1183 int clk_shift = 0;
1184
1185 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1186 case SND_SOC_DAIFMT_CBS_CFS:
1187 aif_val = 0;
1188 break;
1189 case SND_SOC_DAIFMT_CBS_CFM:
1190 aif_val = LM49453_AUDIO_PORT1_BASIC_SYNC_MS;
1191 break;
1192 case SND_SOC_DAIFMT_CBM_CFS:
1193 aif_val = LM49453_AUDIO_PORT1_BASIC_CLK_MS;
1194 break;
1195 case SND_SOC_DAIFMT_CBM_CFM:
1196 aif_val = LM49453_AUDIO_PORT1_BASIC_CLK_MS |
1197 LM49453_AUDIO_PORT1_BASIC_SYNC_MS;
1198 break;
1199 default:
1200 return -EINVAL;
1201 }
1202
1203
1204 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1205 case SND_SOC_DAIFMT_I2S:
1206 break;
1207 case SND_SOC_DAIFMT_DSP_A:
1208 mode = 1;
1209 clk_phase = (1 << 5);
1210 clk_shift = 1;
1211 break;
1212 case SND_SOC_DAIFMT_DSP_B:
1213 mode = 1;
1214 clk_phase = (1 << 5);
1215 clk_shift = 0;
1216 break;
1217 default:
1218 return -EINVAL;
1219 }
1220
1221 snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG,
1222 LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(1)|BIT(5),
1223 (aif_val | mode | clk_phase));
1224
1225 snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
1226
1227 return 0;
1228}
1229
1230static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1231 unsigned int freq, int dir)
1232{
1233 struct snd_soc_codec *codec = dai->codec;
1234 u16 pll_clk = 0;
1235
1236 switch (freq) {
1237 case 12288000:
1238 case 26000000:
1239 case 19200000:
1240 /* pll clk slection */
1241 pll_clk = 0;
1242 break;
1243 case 48000:
1244 case 32576:
1245 /* fll clk slection */
1246 pll_clk = BIT(4);
1247 return 0;
1248 default:
1249 return -EINVAL;
1250 }
1251
1252 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
1253
1254 return 0;
1255}
1256
1257static int lm49453_hp_mute(struct snd_soc_dai *dai, int mute)
1258{
1259 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
1260 (mute ? (BIT(1)|BIT(0)) : 0));
1261 return 0;
1262}
1263
1264static int lm49453_lo_mute(struct snd_soc_dai *dai, int mute)
1265{
1266 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
1267 (mute ? (BIT(3)|BIT(2)) : 0));
1268 return 0;
1269}
1270
1271static int lm49453_ls_mute(struct snd_soc_dai *dai, int mute)
1272{
1273 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
1274 (mute ? (BIT(5)|BIT(4)) : 0));
1275 return 0;
1276}
1277
1278static int lm49453_ep_mute(struct snd_soc_dai *dai, int mute)
1279{
1280 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(4),
1281 (mute ? BIT(4) : 0));
1282 return 0;
1283}
1284
1285static int lm49453_ha_mute(struct snd_soc_dai *dai, int mute)
1286{
1287 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
1288 (mute ? (BIT(7)|BIT(6)) : 0));
1289 return 0;
1290}
1291
1292static int lm49453_set_bias_level(struct snd_soc_codec *codec,
1293 enum snd_soc_bias_level level)
1294{
1295 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1296
1297 switch (level) {
1298 case SND_SOC_BIAS_ON:
1299 case SND_SOC_BIAS_PREPARE:
1300 break;
1301
1302 case SND_SOC_BIAS_STANDBY:
1303 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1304 regcache_sync(lm49453->regmap);
1305
1306 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
1307 LM49453_PMC_SETUP_CHIP_EN, LM49453_CHIP_EN);
1308 break;
1309
1310 case SND_SOC_BIAS_OFF:
1311 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
1312 LM49453_PMC_SETUP_CHIP_EN, 0);
1313 break;
1314 }
1315
1316 codec->dapm.bias_level = level;
1317
1318 return 0;
1319}
1320
1321/* Formates supported by LM49453 driver. */
1322#define LM49453_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1323 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1324
1325static struct snd_soc_dai_ops lm49453_headset_dai_ops = {
1326 .hw_params = lm49453_hw_params,
1327 .set_sysclk = lm49453_set_dai_sysclk,
1328 .set_fmt = lm49453_set_dai_fmt,
1329 .digital_mute = lm49453_hp_mute,
1330};
1331
1332static struct snd_soc_dai_ops lm49453_speaker_dai_ops = {
1333 .hw_params = lm49453_hw_params,
1334 .set_sysclk = lm49453_set_dai_sysclk,
1335 .set_fmt = lm49453_set_dai_fmt,
1336 .digital_mute = lm49453_ls_mute,
1337};
1338
1339static struct snd_soc_dai_ops lm49453_haptic_dai_ops = {
1340 .hw_params = lm49453_hw_params,
1341 .set_sysclk = lm49453_set_dai_sysclk,
1342 .set_fmt = lm49453_set_dai_fmt,
1343 .digital_mute = lm49453_ha_mute,
1344};
1345
1346static struct snd_soc_dai_ops lm49453_ep_dai_ops = {
1347 .hw_params = lm49453_hw_params,
1348 .set_sysclk = lm49453_set_dai_sysclk,
1349 .set_fmt = lm49453_set_dai_fmt,
1350 .digital_mute = lm49453_ep_mute,
1351};
1352
1353static struct snd_soc_dai_ops lm49453_lineout_dai_ops = {
1354 .hw_params = lm49453_hw_params,
1355 .set_sysclk = lm49453_set_dai_sysclk,
1356 .set_fmt = lm49453_set_dai_fmt,
1357 .digital_mute = lm49453_lo_mute,
1358};
1359
1360/* LM49453 dai structure. */
1361struct snd_soc_dai_driver lm49453_dai[] = {
1362 {
1363 .name = "LM49453 Headset",
1364 .playback = {
1365 .stream_name = "Headset",
1366 .channels_min = 2,
1367 .channels_max = 2,
1368 .rates = SNDRV_PCM_RATE_8000_192000,
1369 .formats = LM49453_FORMATS,
1370 },
1371 .capture = {
1372 .stream_name = "Capture",
1373 .channels_min = 1,
1374 .channels_max = 5,
1375 .rates = SNDRV_PCM_RATE_8000_192000,
1376 .formats = LM49453_FORMATS,
1377 },
1378 .ops = &lm49453_headset_dai_ops,
1379 .symmetric_rates = 1,
1380 },
1381 {
1382 .name = "LM49453 Speaker",
1383 .playback = {
1384 .stream_name = "Speaker",
1385 .channels_min = 2,
1386 .channels_max = 2,
1387 .rates = SNDRV_PCM_RATE_8000_192000,
1388 .formats = LM49453_FORMATS,
1389 },
1390 .ops = &lm49453_speaker_dai_ops,
1391 },
1392 {
1393 .name = "LM49453 Haptic",
1394 .playback = {
1395 .stream_name = "Haptic",
1396 .channels_min = 2,
1397 .channels_max = 2,
1398 .rates = SNDRV_PCM_RATE_8000_192000,
1399 .formats = LM49453_FORMATS,
1400 },
1401 .ops = &lm49453_haptic_dai_ops,
1402 },
1403 {
1404 .name = "LM49453 Earpiece",
1405 .playback = {
1406 .stream_name = "Earpiece",
1407 .channels_min = 1,
1408 .channels_max = 1,
1409 .rates = SNDRV_PCM_RATE_8000_192000,
1410 .formats = LM49453_FORMATS,
1411 },
1412 .ops = &lm49453_ep_dai_ops,
1413 },
1414 {
1415 .name = "LM49453 line out",
1416 .playback = {
1417 .stream_name = "Lineout",
1418 .channels_min = 2,
1419 .channels_max = 2,
1420 .rates = SNDRV_PCM_RATE_8000_192000,
1421 .formats = LM49453_FORMATS,
1422 },
1423 .ops = &lm49453_lineout_dai_ops,
1424 },
1425};
1426
1427static int lm49453_suspend(struct snd_soc_codec *codec)
1428{
1429 lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
1430 return 0;
1431}
1432
1433static int lm49453_resume(struct snd_soc_codec *codec)
1434{
1435 lm49453_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1436 return 0;
1437}
1438
1439static int lm49453_probe(struct snd_soc_codec *codec)
1440{
1441 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1442 int ret = 0;
1443
1444 codec->control_data = lm49453->regmap;
1445
1446 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1447 if (ret < 0) {
1448 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1449 return ret;
1450 }
1451
1452 return 0;
1453}
1454
1455/* power down chip */
1456static int lm49453_remove(struct snd_soc_codec *codec)
1457{
1458 lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
1459 return 0;
1460}
1461
1462static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
1463 .probe = lm49453_probe,
1464 .remove = lm49453_remove,
1465 .suspend = lm49453_suspend,
1466 .resume = lm49453_resume,
1467 .set_bias_level = lm49453_set_bias_level,
1468 .controls = lm49453_snd_controls,
1469 .num_controls = ARRAY_SIZE(lm49453_snd_controls),
1470 .dapm_widgets = lm49453_dapm_widgets,
1471 .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets),
1472 .dapm_routes = lm49453_audio_map,
1473 .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map),
1474 .idle_bias_off = true,
1475};
1476
1477static const struct regmap_config lm49453_regmap_config = {
1478 .reg_bits = 8,
1479 .val_bits = 8,
1480
1481 .max_register = LM49453_MAX_REGISTER,
1482 .reg_defaults = lm49453_reg_defs,
1483 .num_reg_defaults = ARRAY_SIZE(lm49453_reg_defs),
1484 .cache_type = REGCACHE_RBTREE,
1485};
1486
1487static __devinit int lm49453_i2c_probe(struct i2c_client *i2c,
1488 const struct i2c_device_id *id)
1489{
1490 struct lm49453_priv *lm49453;
1491 int ret = 0;
1492
1493 lm49453 = devm_kzalloc(&i2c->dev, sizeof(struct lm49453_priv),
1494 GFP_KERNEL);
1495
1496 if (lm49453 == NULL)
1497 return -ENOMEM;
1498
1499 i2c_set_clientdata(i2c, lm49453);
1500
1501 lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config);
1502 if (IS_ERR(lm49453->regmap)) {
1503 ret = PTR_ERR(lm49453->regmap);
1504 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1505 ret);
1506 return ret;
1507 }
1508
1509 ret = snd_soc_register_codec(&i2c->dev,
1510 &soc_codec_dev_lm49453,
1511 lm49453_dai, ARRAY_SIZE(lm49453_dai));
1512 if (ret < 0) {
1513 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1514 regmap_exit(lm49453->regmap);
1515 return ret;
1516 }
1517
1518 return ret;
1519}
1520
1521static int __devexit lm49453_i2c_remove(struct i2c_client *client)
1522{
1523 struct lm49453_priv *lm49453 = i2c_get_clientdata(client);
1524
1525 snd_soc_unregister_codec(&client->dev);
1526 regmap_exit(lm49453->regmap);
1527 return 0;
1528}
1529
1530static const struct i2c_device_id lm49453_i2c_id[] = {
1531 { "lm49453", 0 },
1532 { }
1533};
1534MODULE_DEVICE_TABLE(i2c, lm49453_i2c_id);
1535
1536static struct i2c_driver lm49453_i2c_driver = {
1537 .driver = {
1538 .name = "lm49453",
1539 .owner = THIS_MODULE,
1540 },
1541 .probe = lm49453_i2c_probe,
1542 .remove = __devexit_p(lm49453_i2c_remove),
1543 .id_table = lm49453_i2c_id,
1544};
1545
1546module_i2c_driver(lm49453_i2c_driver);
1547
1548MODULE_DESCRIPTION("ASoC LM49453 driver");
1549MODULE_AUTHOR("M R Swami Reddy <MR.Swami.Reddy@ti.com");
1550MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/lm49453.h b/sound/soc/codecs/lm49453.h
new file mode 100644
index 000000000000..a63cfa5c0883
--- /dev/null
+++ b/sound/soc/codecs/lm49453.h
@@ -0,0 +1,380 @@
1/*
2 * lm49453.h - LM49453 ALSA Soc Audio drive
3 *
4 * Copyright (c) 2012 Texas Instruments, 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 as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 */
11
12#ifndef _LM49453_H
13#define _LM49453_H
14
15#include <linux/bitops.h>
16
17/* LM49453_P0 register space for page0 */
18#define LM49453_P0_PMC_SETUP_REG 0x00
19#define LM49453_P0_PLL_CLK_SEL1_REG 0x01
20#define LM49453_P0_PLL_CLK_SEL2_REG 0x02
21#define LM49453_P0_PMC_CLK_DIV_REG 0x03
22#define LM49453_P0_HSDET_CLK_DIV_REG 0x04
23#define LM49453_P0_DMIC_CLK_DIV_REG 0x05
24#define LM49453_P0_ADC_CLK_DIV_REG 0x06
25#define LM49453_P0_DAC_OT_CLK_DIV_REG 0x07
26#define LM49453_P0_PLL_HF_M_REG 0x08
27#define LM49453_P0_PLL_LF_M_REG 0x09
28#define LM49453_P0_PLL_NL_REG 0x0A
29#define LM49453_P0_PLL_N_MODL_REG 0x0B
30#define LM49453_P0_PLL_N_MODH_REG 0x0C
31#define LM49453_P0_PLL_P1_REG 0x0D
32#define LM49453_P0_PLL_P2_REG 0x0E
33#define LM49453_P0_FLL_REF_FREQL_REG 0x0F
34#define LM49453_P0_FLL_REF_FREQH_REG 0x10
35#define LM49453_P0_VCO_TARGETLL_REG 0x11
36#define LM49453_P0_VCO_TARGETLH_REG 0x12
37#define LM49453_P0_VCO_TARGETHL_REG 0x13
38#define LM49453_P0_VCO_TARGETHH_REG 0x14
39#define LM49453_P0_PLL_CONFIG_REG 0x15
40#define LM49453_P0_DAC_CLK_SEL_REG 0x16
41#define LM49453_P0_DAC_HP_CLK_DIV_REG 0x17
42
43/* Analog Mixer Input Stages */
44#define LM49453_P0_MICL_REG 0x20
45#define LM49453_P0_MICR_REG 0x21
46#define LM49453_P0_EP_REG 0x24
47#define LM49453_P0_DIS_PKVL_FB_REG 0x25
48
49/* Analog Mixer Output Stages */
50#define LM49453_P0_ANALOG_MIXER_ADC_REG 0x2E
51
52/*ADC or DAC */
53#define LM49453_P0_ADC_DSP_REG 0x30
54#define LM49453_P0_DAC_DSP_REG 0x31
55
56/* EFFECTS ENABLES */
57#define LM49453_P0_ADC_FX_ENABLES_REG 0x33
58
59/* GPIO */
60#define LM49453_P0_GPIO1_REG 0x38
61#define LM49453_P0_GPIO2_REG 0x39
62#define LM49453_P0_GPIO3_REG 0x3A
63#define LM49453_P0_HAP_CTL_REG 0x3B
64#define LM49453_P0_HAP_FREQ_PROG_LEFTL_REG 0x3C
65#define LM49453_P0_HAP_FREQ_PROG_LEFTH_REG 0x3D
66#define LM49453_P0_HAP_FREQ_PROG_RIGHTL_REG 0x3E
67#define LM49453_P0_HAP_FREQ_PROG_RIGHTH_REG 0x3F
68
69/* DIGITAL MIXER */
70#define LM49453_P0_DMIX_CLK_SEL_REG 0x40
71#define LM49453_P0_PORT1_RX_LVL1_REG 0x41
72#define LM49453_P0_PORT1_RX_LVL2_REG 0x42
73#define LM49453_P0_PORT2_RX_LVL_REG 0x43
74#define LM49453_P0_PORT1_TX1_REG 0x44
75#define LM49453_P0_PORT1_TX2_REG 0x45
76#define LM49453_P0_PORT1_TX3_REG 0x46
77#define LM49453_P0_PORT1_TX4_REG 0x47
78#define LM49453_P0_PORT1_TX5_REG 0x48
79#define LM49453_P0_PORT1_TX6_REG 0x49
80#define LM49453_P0_PORT1_TX7_REG 0x4A
81#define LM49453_P0_PORT1_TX8_REG 0x4B
82#define LM49453_P0_PORT2_TX1_REG 0x4C
83#define LM49453_P0_PORT2_TX2_REG 0x4D
84#define LM49453_P0_STN_SEL_REG 0x4F
85#define LM49453_P0_DACHPL1_REG 0x50
86#define LM49453_P0_DACHPL2_REG 0x51
87#define LM49453_P0_DACHPR1_REG 0x52
88#define LM49453_P0_DACHPR2_REG 0x53
89#define LM49453_P0_DACLOL1_REG 0x54
90#define LM49453_P0_DACLOL2_REG 0x55
91#define LM49453_P0_DACLOR1_REG 0x56
92#define LM49453_P0_DACLOR2_REG 0x57
93#define LM49453_P0_DACLSL1_REG 0x58
94#define LM49453_P0_DACLSL2_REG 0x59
95#define LM49453_P0_DACLSR1_REG 0x5A
96#define LM49453_P0_DACLSR2_REG 0x5B
97#define LM49453_P0_DACHAL1_REG 0x5C
98#define LM49453_P0_DACHAL2_REG 0x5D
99#define LM49453_P0_DACHAR1_REG 0x5E
100#define LM49453_P0_DACHAR2_REG 0x5F
101
102/* AUDIO PORT 1 (TDM) */
103#define LM49453_P0_AUDIO_PORT1_BASIC_REG 0x60
104#define LM49453_P0_AUDIO_PORT1_CLK_GEN1_REG 0x61
105#define LM49453_P0_AUDIO_PORT1_CLK_GEN2_REG 0x62
106#define LM49453_P0_AUDIO_PORT1_CLK_GEN3_REG 0x63
107#define LM49453_P0_AUDIO_PORT1_SYNC_RATE_REG 0x64
108#define LM49453_P0_AUDIO_PORT1_SYNC_SDO_SETUP_REG 0x65
109#define LM49453_P0_AUDIO_PORT1_DATA_WIDTH_REG 0x66
110#define LM49453_P0_AUDIO_PORT1_RX_MSB_REG 0x67
111#define LM49453_P0_AUDIO_PORT1_TX_MSB_REG 0x68
112#define LM49453_P0_AUDIO_PORT1_TDM_CHANNELS_REG 0x69
113
114/* AUDIO PORT 2 */
115#define LM49453_P0_AUDIO_PORT2_BASIC_REG 0x6A
116#define LM49453_P0_AUDIO_PORT2_CLK_GEN1_REG 0x6B
117#define LM49453_P0_AUDIO_PORT2_CLK_GEN2_REG 0x6C
118#define LM49453_P0_AUDIO_PORT2_SYNC_GEN_REG 0x6D
119#define LM49453_P0_AUDIO_PORT2_DATA_WIDTH_REG 0x6E
120#define LM49453_P0_AUDIO_PORT2_RX_MODE_REG 0x6F
121#define LM49453_P0_AUDIO_PORT2_TX_MODE_REG 0x70
122
123/* SAMPLE RATE */
124#define LM49453_P0_PORT1_SR_LSB_REG 0x79
125#define LM49453_P0_PORT1_SR_MSB_REG 0x7A
126#define LM49453_P0_PORT2_SR_LSB_REG 0x7B
127#define LM49453_P0_PORT2_SR_MSB_REG 0x7C
128
129/* EFFECTS - HPFs */
130#define LM49453_P0_HPF_REG 0x80
131
132/* EFFECTS ADC ALC */
133#define LM49453_P0_ADC_ALC1_REG 0x82
134#define LM49453_P0_ADC_ALC2_REG 0x83
135#define LM49453_P0_ADC_ALC3_REG 0x84
136#define LM49453_P0_ADC_ALC4_REG 0x85
137#define LM49453_P0_ADC_ALC5_REG 0x86
138#define LM49453_P0_ADC_ALC6_REG 0x87
139#define LM49453_P0_ADC_ALC7_REG 0x88
140#define LM49453_P0_ADC_ALC8_REG 0x89
141#define LM49453_P0_DMIC1_LEVELL_REG 0x8A
142#define LM49453_P0_DMIC1_LEVELR_REG 0x8B
143#define LM49453_P0_DMIC2_LEVELL_REG 0x8C
144#define LM49453_P0_DMIC2_LEVELR_REG 0x8D
145#define LM49453_P0_ADC_LEVELL_REG 0x8E
146#define LM49453_P0_ADC_LEVELR_REG 0x8F
147#define LM49453_P0_DAC_HP_LEVELL_REG 0x90
148#define LM49453_P0_DAC_HP_LEVELR_REG 0x91
149#define LM49453_P0_DAC_LO_LEVELL_REG 0x92
150#define LM49453_P0_DAC_LO_LEVELR_REG 0x93
151#define LM49453_P0_DAC_LS_LEVELL_REG 0x94
152#define LM49453_P0_DAC_LS_LEVELR_REG 0x95
153#define LM49453_P0_DAC_HA_LEVELL_REG 0x96
154#define LM49453_P0_DAC_HA_LEVELR_REG 0x97
155#define LM49453_P0_SOFT_MUTE_REG 0x98
156#define LM49453_P0_DMIC_MUTE_CFG_REG 0x99
157#define LM49453_P0_ADC_MUTE_CFG_REG 0x9A
158#define LM49453_P0_DAC_MUTE_CFG_REG 0x9B
159
160/*DIGITAL MIC1 */
161#define LM49453_P0_DIGITAL_MIC1_CONFIG_REG 0xB0
162#define LM49453_P0_DIGITAL_MIC1_DATA_DELAYL_REG 0xB1
163#define LM49453_P0_DIGITAL_MIC1_DATA_DELAYR_REG 0xB2
164
165/*DIGITAL MIC2 */
166#define LM49453_P0_DIGITAL_MIC2_CONFIG_REG 0xB3
167#define LM49453_P0_DIGITAL_MIC2_DATA_DELAYL_REG 0xB4
168#define LM49453_P0_DIGITAL_MIC2_DATA_DELAYR_REG 0xB5
169
170/* ADC DECIMATOR */
171#define LM49453_P0_ADC_DECIMATOR_REG 0xB6
172
173/* DAC CONFIGURE */
174#define LM49453_P0_DAC_CONFIG_REG 0xB7
175
176/* SIDETONE */
177#define LM49453_P0_STN_VOL_ADCL_REG 0xB8
178#define LM49453_P0_STN_VOL_ADCR_REG 0xB9
179#define LM49453_P0_STN_VOL_DMIC1L_REG 0xBA
180#define LM49453_P0_STN_VOL_DMIC1R_REG 0xBB
181#define LM49453_P0_STN_VOL_DMIC2L_REG 0xBC
182#define LM49453_P0_STN_VOL_DMIC2R_REG 0xBD
183
184/* ADC/DAC CLIPPING MONITORS (Read Only/Write to Clear) */
185#define LM49453_P0_ADC_DEC_CLIP_REG 0xC2
186#define LM49453_P0_ADC_HPF_CLIP_REG 0xC3
187#define LM49453_P0_ADC_LVL_CLIP_REG 0xC4
188#define LM49453_P0_DAC_LVL_CLIP_REG 0xC5
189
190/* ADC ALC EFFECT MONITORS (Read Only) */
191#define LM49453_P0_ADC_LVLMONL_REG 0xC8
192#define LM49453_P0_ADC_LVLMONR_REG 0xC9
193#define LM49453_P0_ADC_ALCMONL_REG 0xCA
194#define LM49453_P0_ADC_ALCMONR_REG 0xCB
195#define LM49453_P0_ADC_MUTED_REG 0xCC
196#define LM49453_P0_DAC_MUTED_REG 0xCD
197
198/* HEADSET DETECT */
199#define LM49453_P0_HSD_PPB_LONG_CNT_LIMITL_REG 0xD0
200#define LM49453_P0_HSD_PPB_LONG_CNT_LIMITR_REG 0xD1
201#define LM49453_P0_HSD_PIN3_4_EX_LOOP_CNT_LIMITL_REG 0xD2
202#define LM49453_P0_HSD_PIN3_4_EX_LOOP_CNT_LIMITH_REG 0xD3
203#define LM49453_P0_HSD_TIMEOUT1_REG 0xD4
204#define LM49453_P0_HSD_TIMEOUT2_REG 0xD5
205#define LM49453_P0_HSD_TIMEOUT3_REG 0xD6
206#define LM49453_P0_HSD_PIN3_4_CFG_REG 0xD7
207#define LM49453_P0_HSD_IRQ1_REG 0xD8
208#define LM49453_P0_HSD_IRQ2_REG 0xD9
209#define LM49453_P0_HSD_IRQ3_REG 0xDA
210#define LM49453_P0_HSD_IRQ4_REG 0xDB
211#define LM49453_P0_HSD_IRQ_MASK1_REG 0xDC
212#define LM49453_P0_HSD_IRQ_MASK2_REG 0xDD
213#define LM49453_P0_HSD_IRQ_MASK3_REG 0xDE
214#define LM49453_P0_HSD_R_HPLL_REG 0xE0
215#define LM49453_P0_HSD_R_HPLH_REG 0xE1
216#define LM49453_P0_HSD_R_HPLU_REG 0xE2
217#define LM49453_P0_HSD_R_HPRL_REG 0xE3
218#define LM49453_P0_HSD_R_HPRH_REG 0xE4
219#define LM49453_P0_HSD_R_HPRU_REG 0xE5
220#define LM49453_P0_HSD_VEL_L_FINALL_REG 0xE6
221#define LM49453_P0_HSD_VEL_L_FINALH_REG 0xE7
222#define LM49453_P0_HSD_VEL_L_FINALU_REG 0xE8
223#define LM49453_P0_HSD_RO_FINALL_REG 0xE9
224#define LM49453_P0_HSD_RO_FINALH_REG 0xEA
225#define LM49453_P0_HSD_RO_FINALU_REG 0xEB
226#define LM49453_P0_HSD_VMIC_BIAS_FINALL_REG 0xEC
227#define LM49453_P0_HSD_VMIC_BIAS_FINALH_REG 0xED
228#define LM49453_P0_HSD_VMIC_BIAS_FINALU_REG 0xEE
229#define LM49453_P0_HSD_PIN_CONFIG_REG 0xEF
230#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS1_REG 0xF1
231#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS2_REG 0xF2
232#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS3_REG 0xF3
233#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATEL_REG 0xF4
234#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATEH_REG 0xF5
235
236/* I/O PULLDOWN CONFIG */
237#define LM49453_P0_PULL_CONFIG1_REG 0xF8
238#define LM49453_P0_PULL_CONFIG2_REG 0xF9
239#define LM49453_P0_PULL_CONFIG3_REG 0xFA
240
241/* RESET */
242#define LM49453_P0_RESET_REG 0xFE
243
244/* PAGE */
245#define LM49453_PAGE_REG 0xFF
246
247#define LM49453_MAX_REGISTER (0xFF+1)
248
249/* LM49453_P0_PMC_SETUP_REG (0x00h) */
250#define LM49453_PMC_SETUP_CHIP_EN (BIT(1)|BIT(0))
251#define LM49453_PMC_SETUP_PLL_EN BIT(2)
252#define LM49453_PMC_SETUP_PLL_P2_EN BIT(3)
253#define LM49453_PMC_SETUP_PLL_FLL BIT(4)
254#define LM49453_PMC_SETUP_MCLK_OVER BIT(5)
255#define LM49453_PMC_SETUP_RTC_CLK_OVER BIT(6)
256#define LM49453_PMC_SETUP_CHIP_ACTIVE BIT(7)
257
258/* Chip Enable bits */
259#define LM49453_CHIP_EN_SHUTDOWN 0x00
260#define LM49453_CHIP_EN 0x01
261#define LM49453_CHIP_EN_HSD_DETECT 0x02
262#define LM49453_CHIP_EN_INVALID_HSD 0x03
263
264/* LM49453_P0_PLL_CLK_SEL1_REG (0x01h) */
265#define LM49453_CLK_SEL1_MCLK_SEL 0x11
266#define LM49453_CLK_SEL1_RTC_SEL 0x11
267#define LM49453_CLK_SEL1_PORT1_SEL 0x10
268#define LM49453_CLK_SEL1_PORT2_SEL 0x11
269
270/* LM49453_P0_PLL_CLK_SEL2_REG (0x02h) */
271#define LM49453_CLK_SEL2_ADC_CLK_SEL 0x38
272
273/* LM49453_P0_FLL_REF_FREQL_REG (0x0F) */
274#define LM49453_FLL_REF_FREQ_VAL 0x8ca0001
275
276/* LM49453_P0_VCO_TARGETLL_REG (0x11) */
277#define LM49453_VCO_TARGET_VAL 0x8ca0001
278
279/* LM49453_P0_ADC_DSP_REG (0x30h) */
280#define LM49453_ADC_DSP_ADC_MUTEL BIT(0)
281#define LM49453_ADC_DSP_ADC_MUTER BIT(1)
282#define LM49453_ADC_DSP_DMIC1_MUTEL BIT(2)
283#define LM49453_ADC_DSP_DMIC1_MUTER BIT(3)
284#define LM49453_ADC_DSP_DMIC2_MUTEL BIT(4)
285#define LM49453_ADC_DSP_DMIC2_MUTER BIT(5)
286#define LM49453_ADC_DSP_MUTE_ALL 0x3F
287
288/* LM49453_P0_DAC_DSP_REG (0x31h) */
289#define LM49453_DAC_DSP_MUTE_ALL 0xFF
290
291/* LM49453_P0_AUDIO_PORT1_BASIC_REG (0x60h) */
292#define LM49453_AUDIO_PORT1_BASIC_FMT_MASK (BIT(4)|BIT(3))
293#define LM49453_AUDIO_PORT1_BASIC_CLK_MS BIT(3)
294#define LM49453_AUDIO_PORT1_BASIC_SYNC_MS BIT(4)
295
296/* LM49453_P0_RESET_REG (0xFEh) */
297#define LM49453_RESET_REG_RST BIT(0)
298
299/* Page select register bits (0xFF) */
300#define LM49453_PAGE0_SELECT 0x0
301#define LM49453_PAGE1_SELECT 0x1
302
303/* LM49453_P0_HSD_PIN3_4_CFG_REG (Jack Pin config - 0xD7) */
304#define LM49453_JACK_DISABLE 0x00
305#define LM49453_JACK_CONFIG1 0x01
306#define LM49453_JACK_CONFIG2 0x02
307#define LM49453_JACK_CONFIG3 0x03
308#define LM49453_JACK_CONFIG4 0x04
309#define LM49453_JACK_CONFIG5 0x05
310
311/* Page 1 REGISTERS */
312
313/* SIDETONE */
314#define LM49453_P1_SIDETONE_SA0L_REG 0x80
315#define LM49453_P1_SIDETONE_SA0H_REG 0x81
316#define LM49453_P1_SIDETONE_SAB0U_REG 0x82
317#define LM49453_P1_SIDETONE_SB0L_REG 0x83
318#define LM49453_P1_SIDETONE_SB0H_REG 0x84
319#define LM49453_P1_SIDETONE_SH0L_REG 0x85
320#define LM49453_P1_SIDETONE_SH0H_REG 0x86
321#define LM49453_P1_SIDETONE_SH0U_REG 0x87
322#define LM49453_P1_SIDETONE_SA1L_REG 0x88
323#define LM49453_P1_SIDETONE_SA1H_REG 0x89
324#define LM49453_P1_SIDETONE_SAB1U_REG 0x8A
325#define LM49453_P1_SIDETONE_SB1L_REG 0x8B
326#define LM49453_P1_SIDETONE_SB1H_REG 0x8C
327#define LM49453_P1_SIDETONE_SH1L_REG 0x8D
328#define LM49453_P1_SIDETONE_SH1H_REG 0x8E
329#define LM49453_P1_SIDETONE_SH1U_REG 0x8F
330#define LM49453_P1_SIDETONE_SA2L_REG 0x90
331#define LM49453_P1_SIDETONE_SA2H_REG 0x91
332#define LM49453_P1_SIDETONE_SAB2U_REG 0x92
333#define LM49453_P1_SIDETONE_SB2L_REG 0x93
334#define LM49453_P1_SIDETONE_SB2H_REG 0x94
335#define LM49453_P1_SIDETONE_SH2L_REG 0x95
336#define LM49453_P1_SIDETONE_SH2H_REG 0x96
337#define LM49453_P1_SIDETONE_SH2U_REG 0x97
338#define LM49453_P1_SIDETONE_SA3L_REG 0x98
339#define LM49453_P1_SIDETONE_SA3H_REG 0x99
340#define LM49453_P1_SIDETONE_SAB3U_REG 0x9A
341#define LM49453_P1_SIDETONE_SB3L_REG 0x9B
342#define LM49453_P1_SIDETONE_SB3H_REG 0x9C
343#define LM49453_P1_SIDETONE_SH3L_REG 0x9D
344#define LM49453_P1_SIDETONE_SH3H_REG 0x9E
345#define LM49453_P1_SIDETONE_SH3U_REG 0x9F
346#define LM49453_P1_SIDETONE_SA4L_REG 0xA0
347#define LM49453_P1_SIDETONE_SA4H_REG 0xA1
348#define LM49453_P1_SIDETONE_SAB4U_REG 0xA2
349#define LM49453_P1_SIDETONE_SB4L_REG 0xA3
350#define LM49453_P1_SIDETONE_SB4H_REG 0xA4
351#define LM49453_P1_SIDETONE_SH4L_REG 0xA5
352#define LM49453_P1_SIDETONE_SH4H_REG 0xA6
353#define LM49453_P1_SIDETONE_SH4U_REG 0xA7
354#define LM49453_P1_SIDETONE_SA5L_REG 0xA8
355#define LM49453_P1_SIDETONE_SA5H_REG 0xA9
356#define LM49453_P1_SIDETONE_SAB5U_REG 0xAA
357#define LM49453_P1_SIDETONE_SB5L_REG 0xAB
358#define LM49453_P1_SIDETONE_SB5H_REG 0xAC
359#define LM49453_P1_SIDETONE_SH5L_REG 0xAD
360#define LM49453_P1_SIDETONE_SH5H_REG 0xAE
361#define LM49453_P1_SIDETONE_SH5U_REG 0xAF
362
363/* CHARGE PUMP CONFIG */
364#define LM49453_P1_CP_CONFIG1_REG 0xB0
365#define LM49453_P1_CP_CONFIG2_REG 0xB1
366#define LM49453_P1_CP_CONFIG3_REG 0xB2
367#define LM49453_P1_CP_CONFIG4_REG 0xB3
368#define LM49453_P1_CP_LA_VTH1L_REG 0xB4
369#define LM49453_P1_CP_LA_VTH1M_REG 0xB5
370#define LM49453_P1_CP_LA_VTH2L_REG 0xB6
371#define LM49453_P1_CP_LA_VTH2M_REG 0xB7
372#define LM49453_P1_CP_LA_VTH3L_REG 0xB8
373#define LM49453_P1_CP_LA_VTH3H_REG 0xB9
374#define LM49453_P1_CP_CLK_DIV_REG 0xBA
375
376/* DAC */
377#define LM49453_P1_DAC_CHOP_REG 0xC0
378
379#define LM49453_CLK_SRC_MCLK 1
380#endif
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 0bb511a0388d..35179e2c23c9 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <asm/div64.h> 25#include <asm/div64.h>
26#include <sound/max98095.h> 26#include <sound/max98095.h>
27#include <sound/jack.h>
27#include "max98095.h" 28#include "max98095.h"
28 29
29enum max98095_type { 30enum max98095_type {
@@ -51,6 +52,8 @@ struct max98095_priv {
51 u8 lin_state; 52 u8 lin_state;
52 unsigned int mic1pre; 53 unsigned int mic1pre;
53 unsigned int mic2pre; 54 unsigned int mic2pre;
55 struct snd_soc_jack *headphone_jack;
56 struct snd_soc_jack *mic_jack;
54}; 57};
55 58
56static const u8 max98095_reg_def[M98095_REG_CNT] = { 59static const u8 max98095_reg_def[M98095_REG_CNT] = {
@@ -2173,9 +2176,125 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec)
2173 max98095_handle_bq_pdata(codec); 2176 max98095_handle_bq_pdata(codec);
2174} 2177}
2175 2178
2179static irqreturn_t max98095_report_jack(int irq, void *data)
2180{
2181 struct snd_soc_codec *codec = data;
2182 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2183 unsigned int value;
2184 int hp_report = 0;
2185 int mic_report = 0;
2186
2187 /* Read the Jack Status Register */
2188 value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS);
2189
2190 /* If ddone is not set, then detection isn't finished yet */
2191 if ((value & M98095_DDONE) == 0)
2192 return IRQ_NONE;
2193
2194 /* if hp, check its bit, and if set, clear it */
2195 if ((value & M98095_HP_IN || value & M98095_LO_IN) &&
2196 max98095->headphone_jack)
2197 hp_report |= SND_JACK_HEADPHONE;
2198
2199 /* if mic, check its bit, and if set, clear it */
2200 if ((value & M98095_MIC_IN) && max98095->mic_jack)
2201 mic_report |= SND_JACK_MICROPHONE;
2202
2203 if (max98095->headphone_jack == max98095->mic_jack) {
2204 snd_soc_jack_report(max98095->headphone_jack,
2205 hp_report | mic_report,
2206 SND_JACK_HEADSET);
2207 } else {
2208 if (max98095->headphone_jack)
2209 snd_soc_jack_report(max98095->headphone_jack,
2210 hp_report, SND_JACK_HEADPHONE);
2211 if (max98095->mic_jack)
2212 snd_soc_jack_report(max98095->mic_jack,
2213 mic_report, SND_JACK_MICROPHONE);
2214 }
2215
2216 return IRQ_HANDLED;
2217}
2218
2219int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 int ret = 0;
2223 int detect_enable = M98095_JDEN;
2224 unsigned int slew = M98095_DEFAULT_SLEW_DELAY;
2225
2226 if (max98095->pdata->jack_detect_pin5en)
2227 detect_enable |= M98095_PIN5EN;
2228
2229 if (max98095->pdata->jack_detect_delay)
2230 slew = max98095->pdata->jack_detect_delay;
2231
2232 ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew);
2233 if (ret < 0) {
2234 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2235 return ret;
2236 }
2237
2238 /* configure auto detection to be enabled */
2239 ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable);
2240 if (ret < 0) {
2241 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2242 return ret;
2243 }
2244
2245 return ret;
2246}
2247
2248int max98095_jack_detect_disable(struct snd_soc_codec *codec)
2249{
2250 int ret = 0;
2251
2252 /* configure auto detection to be disabled */
2253 ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0);
2254 if (ret < 0) {
2255 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2256 return ret;
2257 }
2258
2259 return ret;
2260}
2261
2262int max98095_jack_detect(struct snd_soc_codec *codec,
2263 struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack)
2264{
2265 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2266 struct i2c_client *client = to_i2c_client(codec->dev);
2267 int ret = 0;
2268
2269 max98095->headphone_jack = hp_jack;
2270 max98095->mic_jack = mic_jack;
2271
2272 /* only progress if we have at least 1 jack pointer */
2273 if (!hp_jack && !mic_jack)
2274 return -EINVAL;
2275
2276 max98095_jack_detect_enable(codec);
2277
2278 /* enable interrupts for headphone jack detection */
2279 ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN,
2280 M98095_IDDONE, M98095_IDDONE);
2281 if (ret < 0) {
2282 dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret);
2283 return ret;
2284 }
2285
2286 max98095_report_jack(client->irq, codec);
2287 return 0;
2288}
2289
2176#ifdef CONFIG_PM 2290#ifdef CONFIG_PM
2177static int max98095_suspend(struct snd_soc_codec *codec) 2291static int max98095_suspend(struct snd_soc_codec *codec)
2178{ 2292{
2293 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2294
2295 if (max98095->headphone_jack || max98095->mic_jack)
2296 max98095_jack_detect_disable(codec);
2297
2179 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2298 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2180 2299
2181 return 0; 2300 return 0;
@@ -2183,8 +2302,16 @@ static int max98095_suspend(struct snd_soc_codec *codec)
2183 2302
2184static int max98095_resume(struct snd_soc_codec *codec) 2303static int max98095_resume(struct snd_soc_codec *codec)
2185{ 2304{
2305 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2306 struct i2c_client *client = to_i2c_client(codec->dev);
2307
2186 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2308 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2187 2309
2310 if (max98095->headphone_jack || max98095->mic_jack) {
2311 max98095_jack_detect_enable(codec);
2312 max98095_report_jack(client->irq, codec);
2313 }
2314
2188 return 0; 2315 return 0;
2189} 2316}
2190#else 2317#else
@@ -2227,6 +2354,7 @@ static int max98095_probe(struct snd_soc_codec *codec)
2227{ 2354{
2228 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2355 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2229 struct max98095_cdata *cdata; 2356 struct max98095_cdata *cdata;
2357 struct i2c_client *client;
2230 int ret = 0; 2358 int ret = 0;
2231 2359
2232 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 2360 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
@@ -2238,6 +2366,8 @@ static int max98095_probe(struct snd_soc_codec *codec)
2238 /* reset the codec, the DSP core, and disable all interrupts */ 2366 /* reset the codec, the DSP core, and disable all interrupts */
2239 max98095_reset(codec); 2367 max98095_reset(codec);
2240 2368
2369 client = to_i2c_client(codec->dev);
2370
2241 /* initialize private data */ 2371 /* initialize private data */
2242 2372
2243 max98095->sysclk = (unsigned)-1; 2373 max98095->sysclk = (unsigned)-1;
@@ -2266,11 +2396,23 @@ static int max98095_probe(struct snd_soc_codec *codec)
2266 max98095->mic1pre = 0; 2396 max98095->mic1pre = 0;
2267 max98095->mic2pre = 0; 2397 max98095->mic2pre = 0;
2268 2398
2399 if (client->irq) {
2400 /* register an audio interrupt */
2401 ret = request_threaded_irq(client->irq, NULL,
2402 max98095_report_jack,
2403 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
2404 "max98095", codec);
2405 if (ret) {
2406 dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
2407 goto err_access;
2408 }
2409 }
2410
2269 ret = snd_soc_read(codec, M98095_0FF_REV_ID); 2411 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2270 if (ret < 0) { 2412 if (ret < 0) {
2271 dev_err(codec->dev, "Failure reading hardware revision: %d\n", 2413 dev_err(codec->dev, "Failure reading hardware revision: %d\n",
2272 ret); 2414 ret);
2273 goto err_access; 2415 goto err_irq;
2274 } 2416 }
2275 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A'); 2417 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
2276 2418
@@ -2306,14 +2448,28 @@ static int max98095_probe(struct snd_soc_codec *codec)
2306 2448
2307 max98095_add_widgets(codec); 2449 max98095_add_widgets(codec);
2308 2450
2451 return 0;
2452
2453err_irq:
2454 if (client->irq)
2455 free_irq(client->irq, codec);
2309err_access: 2456err_access:
2310 return ret; 2457 return ret;
2311} 2458}
2312 2459
2313static int max98095_remove(struct snd_soc_codec *codec) 2460static int max98095_remove(struct snd_soc_codec *codec)
2314{ 2461{
2462 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2463 struct i2c_client *client = to_i2c_client(codec->dev);
2464
2315 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2465 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2316 2466
2467 if (max98095->headphone_jack || max98095->mic_jack)
2468 max98095_jack_detect_disable(codec);
2469
2470 if (client->irq)
2471 free_irq(client->irq, codec);
2472
2317 return 0; 2473 return 0;
2318} 2474}
2319 2475
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
index 891584a0eb03..2ebbe4e894bf 100644
--- a/sound/soc/codecs/max98095.h
+++ b/sound/soc/codecs/max98095.h
@@ -175,11 +175,23 @@
175 175
176/* MAX98095 Registers Bit Fields */ 176/* MAX98095 Registers Bit Fields */
177 177
178/* M98095_007_JACK_AUTO_STS */
179 #define M98095_MIC_IN (1<<3)
180 #define M98095_LO_IN (1<<5)
181 #define M98095_HP_IN (1<<6)
182 #define M98095_DDONE (1<<7)
183
178/* M98095_00F_HOST_CFG */ 184/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0) 185 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1) 186 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2) 187 #define M98095_MDLLEN (1<<2)
182 188
189/* M98095_013_JACK_INT_EN */
190 #define M98095_IMIC_IN (1<<3)
191 #define M98095_ILO_IN (1<<5)
192 #define M98095_IHP_IN (1<<6)
193 #define M98095_IDDONE (1<<7)
194
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */ 195/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF 196 #define M98095_CLKMODE_MASK 0xFF
185 197
@@ -255,6 +267,10 @@
255 #define M98095_EQ2EN (1<<1) 267 #define M98095_EQ2EN (1<<1)
256 #define M98095_EQ1EN (1<<0) 268 #define M98095_EQ1EN (1<<0)
257 269
270/* M98095_089_JACK_DET_AUTO */
271 #define M98095_PIN5EN (1<<2)
272 #define M98095_JDEN (1<<7)
273
258/* M98095_090_PWR_EN_IN */ 274/* M98095_090_PWR_EN_IN */
259 #define M98095_INEN (1<<7) 275 #define M98095_INEN (1<<7)
260 #define M98095_MB2EN (1<<3) 276 #define M98095_MB2EN (1<<3)
@@ -296,4 +312,10 @@
296#define M98095_174_DAI1_BQ_BASE 0x74 312#define M98095_174_DAI1_BQ_BASE 0x74
297#define M98095_17E_DAI2_BQ_BASE 0x7E 313#define M98095_17E_DAI2_BQ_BASE 0x7E
298 314
315/* Default Delay used in Slew Rate Calculation for Jack detection */
316#define M98095_DEFAULT_SLEW_DELAY 0x18
317
318extern int max98095_jack_detect(struct snd_soc_codec *codec,
319 struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
320
299#endif 321#endif
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
new file mode 100644
index 000000000000..22cb5bf59273
--- /dev/null
+++ b/sound/soc/codecs/ml26124.c
@@ -0,0 +1,681 @@
1/*
2 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/platform_device.h>
26#include <linux/regmap.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/tlv.h>
32#include "ml26124.h"
33
34#define DVOL_CTL_DVMUTE_ON BIT(4) /* Digital volume MUTE On */
35#define DVOL_CTL_DVMUTE_OFF 0 /* Digital volume MUTE Off */
36#define ML26124_SAI_NO_DELAY BIT(1)
37#define ML26124_SAI_FRAME_SYNC (BIT(5) | BIT(0)) /* For mono (Telecodec) */
38#define ML26134_CACHESIZE 212
39#define ML26124_VMID BIT(1)
40#define ML26124_RATES (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\
41 SNDRV_PCM_RATE_48000)
42#define ML26124_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |\
43 SNDRV_PCM_FMTBIT_S32_LE)
44#define ML26124_NUM_REGISTER ML26134_CACHESIZE
45
46struct ml26124_priv {
47 u32 mclk;
48 u32 rate;
49 struct regmap *regmap;
50 int clk_in;
51 struct snd_pcm_substream *substream;
52};
53
54struct clk_coeff {
55 u32 mclk;
56 u32 rate;
57 u8 pllnl;
58 u8 pllnh;
59 u8 pllml;
60 u8 pllmh;
61 u8 plldiv;
62};
63
64/* ML26124 configuration */
65static const DECLARE_TLV_DB_SCALE(digital_tlv, -7150, 50, 0);
66
67static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0);
68static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0);
69static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0);
70static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0);
71static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0);
72
73static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
74 "A-law"};
75
76static const struct soc_enum ml26124_adc_companding_enum
77 = SOC_ENUM_SINGLE(ML26124_SAI_TRANS_CTL, 6, 3, ml26124_companding);
78
79static const struct soc_enum ml26124_dac_companding_enum
80 = SOC_ENUM_SINGLE(ML26124_SAI_RCV_CTL, 6, 3, ml26124_companding);
81
82static const struct snd_kcontrol_new ml26124_snd_controls[] = {
83 SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0,
84 0xff, 1, digital_tlv),
85 SOC_SINGLE_TLV("Playback Digital Volume", ML26124_PLBAK_DIG_VOL, 0,
86 0xff, 1, digital_tlv),
87 SOC_SINGLE_TLV("Digital Boost Volume", ML26124_DIGI_BOOST_VOL, 0,
88 0x3f, 0, boost_vol),
89 SOC_SINGLE_TLV("EQ Band0 Volume", ML26124_EQ_GAIN_BRAND0, 0,
90 0xff, 1, digital_tlv),
91 SOC_SINGLE_TLV("EQ Band1 Volume", ML26124_EQ_GAIN_BRAND1, 0,
92 0xff, 1, digital_tlv),
93 SOC_SINGLE_TLV("EQ Band2 Volume", ML26124_EQ_GAIN_BRAND2, 0,
94 0xff, 1, digital_tlv),
95 SOC_SINGLE_TLV("EQ Band3 Volume", ML26124_EQ_GAIN_BRAND3, 0,
96 0xff, 1, digital_tlv),
97 SOC_SINGLE_TLV("EQ Band4 Volume", ML26124_EQ_GAIN_BRAND4, 0,
98 0xff, 1, digital_tlv),
99 SOC_SINGLE_TLV("ALC Target Level", ML26124_ALC_TARGET_LEV, 0,
100 0xf, 1, alclvl),
101 SOC_SINGLE_TLV("ALC Min Input Volume", ML26124_ALC_MAXMIN_GAIN, 0,
102 7, 0, mingain),
103 SOC_SINGLE_TLV("ALC Max Input Volume", ML26124_ALC_MAXMIN_GAIN, 4,
104 7, 1, maxgain),
105 SOC_SINGLE_TLV("Playback Limiter Min Input Volume",
106 ML26124_PL_MAXMIN_GAIN, 0, 7, 0, mingain),
107 SOC_SINGLE_TLV("Playback Limiter Max Input Volume",
108 ML26124_PL_MAXMIN_GAIN, 4, 7, 1, maxgain),
109 SOC_SINGLE_TLV("Playback Boost Volume", ML26124_PLYBAK_BOST_VOL, 0,
110 0x3f, 0, boost_vol),
111 SOC_SINGLE("DC High Pass Filter Switch", ML26124_FILTER_EN, 0, 1, 0),
112 SOC_SINGLE("Noise High Pass Filter Switch", ML26124_FILTER_EN, 1, 1, 0),
113 SOC_SINGLE("ZC Switch", ML26124_PW_ZCCMP_PW_MNG, 1,
114 1, 0),
115 SOC_SINGLE("EQ Band0 Switch", ML26124_FILTER_EN, 2, 1, 0),
116 SOC_SINGLE("EQ Band1 Switch", ML26124_FILTER_EN, 3, 1, 0),
117 SOC_SINGLE("EQ Band2 Switch", ML26124_FILTER_EN, 4, 1, 0),
118 SOC_SINGLE("EQ Band3 Switch", ML26124_FILTER_EN, 5, 1, 0),
119 SOC_SINGLE("EQ Band4 Switch", ML26124_FILTER_EN, 6, 1, 0),
120 SOC_SINGLE("Play Limiter", ML26124_DVOL_CTL, 0, 1, 0),
121 SOC_SINGLE("Capture Limiter", ML26124_DVOL_CTL, 1, 1, 0),
122 SOC_SINGLE("Digital Volume Fade Switch", ML26124_DVOL_CTL, 3, 1, 0),
123 SOC_SINGLE("Digital Switch", ML26124_DVOL_CTL, 4, 1, 0),
124 SOC_ENUM("DAC Companding", ml26124_dac_companding_enum),
125 SOC_ENUM("ADC Companding", ml26124_adc_companding_enum),
126};
127
128static const struct snd_kcontrol_new ml26124_output_mixer_controls[] = {
129 SOC_DAPM_SINGLE("DAC Switch", ML26124_SPK_AMP_OUT, 1, 1, 0),
130 SOC_DAPM_SINGLE("Line in loopback Switch", ML26124_SPK_AMP_OUT, 3, 1,
131 0),
132 SOC_DAPM_SINGLE("PGA Switch", ML26124_SPK_AMP_OUT, 5, 1, 0),
133};
134
135/* Input mux */
136static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in",
137 "Digital MIC in", "Analog MIC Differential in"};
138
139static const struct soc_enum ml26124_insel_enum =
140 SOC_ENUM_SINGLE(ML26124_MIC_IF_CTL, 0, 3, ml26124_input_select);
141
142static const struct snd_kcontrol_new ml26124_input_mux_controls =
143 SOC_DAPM_ENUM("Input Select", ml26124_insel_enum);
144
145static const struct snd_kcontrol_new ml26124_line_control =
146 SOC_DAPM_SINGLE("Switch", ML26124_PW_LOUT_PW_MNG, 1, 1, 0);
147
148static const struct snd_soc_dapm_widget ml26124_dapm_widgets[] = {
149 SND_SOC_DAPM_SUPPLY("MCLKEN", ML26124_CLK_EN, 0, 0, NULL, 0),
150 SND_SOC_DAPM_SUPPLY("PLLEN", ML26124_CLK_EN, 1, 0, NULL, 0),
151 SND_SOC_DAPM_SUPPLY("PLLOE", ML26124_CLK_EN, 2, 0, NULL, 0),
152 SND_SOC_DAPM_SUPPLY("MICBIAS", ML26124_PW_REF_PW_MNG, 2, 0, NULL, 0),
153 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
154 &ml26124_output_mixer_controls[0],
155 ARRAY_SIZE(ml26124_output_mixer_controls)),
156 SND_SOC_DAPM_DAC("DAC", "Playback", ML26124_PW_DAC_PW_MNG, 1, 0),
157 SND_SOC_DAPM_ADC("ADC", "Capture", ML26124_PW_IN_PW_MNG, 1, 0),
158 SND_SOC_DAPM_PGA("PGA", ML26124_PW_IN_PW_MNG, 3, 0, NULL, 0),
159 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
160 &ml26124_input_mux_controls),
161 SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
162 &ml26124_line_control),
163 SND_SOC_DAPM_INPUT("MDIN"),
164 SND_SOC_DAPM_INPUT("MIN"),
165 SND_SOC_DAPM_INPUT("LIN"),
166 SND_SOC_DAPM_OUTPUT("SPOUT"),
167 SND_SOC_DAPM_OUTPUT("LOUT"),
168};
169
170static const struct snd_soc_dapm_route ml26124_intercon[] = {
171 /* Supply */
172 {"DAC", NULL, "MCLKEN"},
173 {"ADC", NULL, "MCLKEN"},
174 {"DAC", NULL, "PLLEN"},
175 {"ADC", NULL, "PLLEN"},
176 {"DAC", NULL, "PLLOE"},
177 {"ADC", NULL, "PLLOE"},
178
179 /* output mixer */
180 {"Output Mixer", "DAC Switch", "DAC"},
181 {"Output Mixer", "Line in loopback Switch", "LIN"},
182
183 /* outputs */
184 {"LOUT", NULL, "Output Mixer"},
185 {"SPOUT", NULL, "Output Mixer"},
186 {"Line Out Enable", NULL, "LOUT"},
187
188 /* input */
189 {"ADC", NULL, "Input Mux"},
190 {"Input Mux", "Analog MIC SingleEnded in", "PGA"},
191 {"Input Mux", "Analog MIC Differential in", "PGA"},
192 {"PGA", NULL, "MIN"},
193};
194
195/* PLLOutputFreq(Hz) = InputMclkFreq(Hz) * PLLM / (PLLN * PLLDIV) */
196static const struct clk_coeff coeff_div[] = {
197 {12288000, 16000, 0xc, 0x0, 0x20, 0x0, 0x4},
198 {12288000, 32000, 0xc, 0x0, 0x20, 0x0, 0x4},
199 {12288000, 48000, 0xc, 0x0, 0x30, 0x0, 0x4},
200};
201
202static struct reg_default ml26124_reg[] = {
203 /* CLOCK control Register */
204 {0x00, 0x00 }, /* Sampling Rate */
205 {0x02, 0x00}, /* PLL NL */
206 {0x04, 0x00}, /* PLLNH */
207 {0x06, 0x00}, /* PLLML */
208 {0x08, 0x00}, /* MLLMH */
209 {0x0a, 0x00}, /* PLLDIV */
210 {0x0c, 0x00}, /* Clock Enable */
211 {0x0e, 0x00}, /* CLK Input/Output Control */
212
213 /* System Control Register */
214 {0x10, 0x00}, /* Software RESET */
215 {0x12, 0x00}, /* Record/Playback Run */
216 {0x14, 0x00}, /* Mic Input/Output control */
217
218 /* Power Management Register */
219 {0x20, 0x00}, /* Reference Power Management */
220 {0x22, 0x00}, /* Input Power Management */
221 {0x24, 0x00}, /* DAC Power Management */
222 {0x26, 0x00}, /* SP-AMP Power Management */
223 {0x28, 0x00}, /* LINEOUT Power Management */
224 {0x2a, 0x00}, /* VIDEO Power Management */
225 {0x2e, 0x00}, /* AC-CMP Power Management */
226
227 /* Analog reference Control Register */
228 {0x30, 0x04}, /* MICBIAS Voltage Control */
229
230 /* Input/Output Amplifier Control Register */
231 {0x32, 0x10}, /* MIC Input Volume */
232 {0x38, 0x00}, /* Mic Boost Volume */
233 {0x3a, 0x33}, /* Speaker AMP Volume */
234 {0x48, 0x00}, /* AMP Volume Control Function Enable */
235 {0x4a, 0x00}, /* Amplifier Volume Fader Control */
236
237 /* Analog Path Control Register */
238 {0x54, 0x00}, /* Speaker AMP Output Control */
239 {0x5a, 0x00}, /* Mic IF Control */
240 {0xe8, 0x01}, /* Mic Select Control */
241
242 /* Audio Interface Control Register */
243 {0x60, 0x00}, /* SAI-Trans Control */
244 {0x62, 0x00}, /* SAI-Receive Control */
245 {0x64, 0x00}, /* SAI Mode select */
246
247 /* DSP Control Register */
248 {0x66, 0x01}, /* Filter Func Enable */
249 {0x68, 0x00}, /* Volume Control Func Enable */
250 {0x6A, 0x00}, /* Mixer & Volume Control*/
251 {0x6C, 0xff}, /* Record Digital Volume */
252 {0x70, 0xff}, /* Playback Digital Volume */
253 {0x72, 0x10}, /* Digital Boost Volume */
254 {0x74, 0xe7}, /* EQ gain Band0 */
255 {0x76, 0xe7}, /* EQ gain Band1 */
256 {0x78, 0xe7}, /* EQ gain Band2 */
257 {0x7A, 0xe7}, /* EQ gain Band3 */
258 {0x7C, 0xe7}, /* EQ gain Band4 */
259 {0x7E, 0x00}, /* HPF2 CutOff*/
260 {0x80, 0x00}, /* EQ Band0 Coef0L */
261 {0x82, 0x00}, /* EQ Band0 Coef0H */
262 {0x84, 0x00}, /* EQ Band0 Coef0L */
263 {0x86, 0x00}, /* EQ Band0 Coef0H */
264 {0x88, 0x00}, /* EQ Band1 Coef0L */
265 {0x8A, 0x00}, /* EQ Band1 Coef0H */
266 {0x8C, 0x00}, /* EQ Band1 Coef0L */
267 {0x8E, 0x00}, /* EQ Band1 Coef0H */
268 {0x90, 0x00}, /* EQ Band2 Coef0L */
269 {0x92, 0x00}, /* EQ Band2 Coef0H */
270 {0x94, 0x00}, /* EQ Band2 Coef0L */
271 {0x96, 0x00}, /* EQ Band2 Coef0H */
272 {0x98, 0x00}, /* EQ Band3 Coef0L */
273 {0x9A, 0x00}, /* EQ Band3 Coef0H */
274 {0x9C, 0x00}, /* EQ Band3 Coef0L */
275 {0x9E, 0x00}, /* EQ Band3 Coef0H */
276 {0xA0, 0x00}, /* EQ Band4 Coef0L */
277 {0xA2, 0x00}, /* EQ Band4 Coef0H */
278 {0xA4, 0x00}, /* EQ Band4 Coef0L */
279 {0xA6, 0x00}, /* EQ Band4 Coef0H */
280
281 /* ALC Control Register */
282 {0xb0, 0x00}, /* ALC Mode */
283 {0xb2, 0x02}, /* ALC Attack Time */
284 {0xb4, 0x03}, /* ALC Decay Time */
285 {0xb6, 0x00}, /* ALC Hold Time */
286 {0xb8, 0x0b}, /* ALC Target Level */
287 {0xba, 0x70}, /* ALC Max/Min Gain */
288 {0xbc, 0x00}, /* Noise Gate Threshold */
289 {0xbe, 0x00}, /* ALC ZeroCross TimeOut */
290
291 /* Playback Limiter Control Register */
292 {0xc0, 0x04}, /* PL Attack Time */
293 {0xc2, 0x05}, /* PL Decay Time */
294 {0xc4, 0x0d}, /* PL Target Level */
295 {0xc6, 0x70}, /* PL Max/Min Gain */
296 {0xc8, 0x10}, /* Playback Boost Volume */
297 {0xca, 0x00}, /* PL ZeroCross TimeOut */
298
299 /* Video Amplifier Control Register */
300 {0xd0, 0x01}, /* VIDEO AMP Gain Control */
301 {0xd2, 0x01}, /* VIDEO AMP Setup 1 */
302 {0xd4, 0x01}, /* VIDEO AMP Control2 */
303};
304
305/* Get sampling rate value of sampling rate setting register (0x0) */
306static inline int get_srate(int rate)
307{
308 int srate;
309
310 switch (rate) {
311 case 16000:
312 srate = 3;
313 break;
314 case 32000:
315 srate = 6;
316 break;
317 case 48000:
318 srate = 8;
319 break;
320 default:
321 return -EINVAL;
322 }
323 return srate;
324}
325
326static inline int get_coeff(int mclk, int rate)
327{
328 int i;
329
330 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
331 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
332 return i;
333 }
334 return -EINVAL;
335}
336
337static int ml26124_hw_params(struct snd_pcm_substream *substream,
338 struct snd_pcm_hw_params *hw_params,
339 struct snd_soc_dai *dai)
340{
341 struct snd_soc_codec *codec = dai->codec;
342 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
343 int i = get_coeff(priv->mclk, params_rate(hw_params));
344
345 priv->substream = substream;
346 priv->rate = params_rate(hw_params);
347
348 if (priv->clk_in) {
349 switch (priv->mclk / params_rate(hw_params)) {
350 case 256:
351 snd_soc_update_bits(codec, ML26124_CLK_CTL,
352 BIT(0) | BIT(1), 1);
353 break;
354 case 512:
355 snd_soc_update_bits(codec, ML26124_CLK_CTL,
356 BIT(0) | BIT(1), 2);
357 break;
358 case 1024:
359 snd_soc_update_bits(codec, ML26124_CLK_CTL,
360 BIT(0) | BIT(1), 3);
361 break;
362 default:
363 dev_err(codec->dev, "Unsupported MCLKI\n");
364 break;
365 }
366 } else {
367 snd_soc_update_bits(codec, ML26124_CLK_CTL,
368 BIT(0) | BIT(1), 0);
369 }
370
371 switch (params_rate(hw_params)) {
372 case 16000:
373 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
374 get_srate(params_rate(hw_params)));
375 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
376 coeff_div[i].pllnl);
377 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
378 coeff_div[i].pllnh);
379 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
380 coeff_div[i].pllml);
381 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
382 coeff_div[i].pllmh);
383 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
384 coeff_div[i].plldiv);
385 break;
386 case 32000:
387 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
388 get_srate(params_rate(hw_params)));
389 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
390 coeff_div[i].pllnl);
391 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
392 coeff_div[i].pllnh);
393 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
394 coeff_div[i].pllml);
395 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
396 coeff_div[i].pllmh);
397 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
398 coeff_div[i].plldiv);
399 break;
400 case 48000:
401 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
402 get_srate(params_rate(hw_params)));
403 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
404 coeff_div[i].pllnl);
405 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
406 coeff_div[i].pllnh);
407 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
408 coeff_div[i].pllml);
409 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
410 coeff_div[i].pllmh);
411 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
412 coeff_div[i].plldiv);
413 break;
414 default:
415 pr_err("%s:this rate is no support for ml26124\n", __func__);
416 return -EINVAL;
417 }
418
419 return 0;
420}
421
422static int ml26124_mute(struct snd_soc_dai *dai, int mute)
423{
424 struct snd_soc_codec *codec = dai->codec;
425 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
426
427 switch (priv->substream->stream) {
428 case SNDRV_PCM_STREAM_CAPTURE:
429 snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
430 break;
431 case SNDRV_PCM_STREAM_PLAYBACK:
432 snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
433 break;
434 }
435
436 if (mute)
437 snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
438 DVOL_CTL_DVMUTE_ON);
439 else
440 snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
441 DVOL_CTL_DVMUTE_OFF);
442
443 return 0;
444}
445
446static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
447 unsigned int fmt)
448{
449 unsigned char mode;
450 struct snd_soc_codec *codec = codec_dai->codec;
451
452 /* set master/slave audio interface */
453 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
454 case SND_SOC_DAIFMT_CBM_CFM:
455 mode = 1;
456 break;
457 case SND_SOC_DAIFMT_CBS_CFS:
458 mode = 0;
459 break;
460 default:
461 return -EINVAL;
462 }
463 snd_soc_update_bits(codec, ML26124_SAI_MODE_SEL, BIT(0), mode);
464
465 /* interface format */
466 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
467 case SND_SOC_DAIFMT_I2S:
468 break;
469 default:
470 return -EINVAL;
471 }
472
473 /* clock inversion */
474 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
475 case SND_SOC_DAIFMT_NB_NF:
476 break;
477 default:
478 return -EINVAL;
479 }
480
481 return 0;
482}
483
484static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
485 int clk_id, unsigned int freq, int dir)
486{
487 struct snd_soc_codec *codec = codec_dai->codec;
488 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
489
490 switch (clk_id) {
491 case ML26124_USE_PLLOUT:
492 priv->clk_in = ML26124_USE_PLLOUT;
493 break;
494 case ML26124_USE_MCLKI:
495 priv->clk_in = ML26124_USE_MCLKI;
496 break;
497 default:
498 return -EINVAL;
499 }
500
501 priv->mclk = freq;
502
503 return 0;
504}
505
506static int ml26124_set_bias_level(struct snd_soc_codec *codec,
507 enum snd_soc_bias_level level)
508{
509 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
510
511 switch (level) {
512 case SND_SOC_BIAS_ON:
513 snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
514 ML26124_R26_MASK, ML26124_BLT_PREAMP_ON);
515 msleep(100);
516 snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
517 ML26124_R26_MASK,
518 ML26124_MICBEN_ON | ML26124_BLT_ALL_ON);
519 break;
520 case SND_SOC_BIAS_PREPARE:
521 break;
522 case SND_SOC_BIAS_STANDBY:
523 /* VMID ON */
524 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
525 snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
526 ML26124_VMID, ML26124_VMID);
527 msleep(500);
528 regcache_sync(priv->regmap);
529 }
530 break;
531 case SND_SOC_BIAS_OFF:
532 /* VMID OFF */
533 snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
534 ML26124_VMID, 0);
535 break;
536 }
537 codec->dapm.bias_level = level;
538 return 0;
539}
540
541static const struct snd_soc_dai_ops ml26124_dai_ops = {
542 .hw_params = ml26124_hw_params,
543 .digital_mute = ml26124_mute,
544 .set_fmt = ml26124_set_dai_fmt,
545 .set_sysclk = ml26124_set_dai_sysclk,
546};
547
548static struct snd_soc_dai_driver ml26124_dai = {
549 .name = "ml26124-hifi",
550 .playback = {
551 .stream_name = "Playback",
552 .channels_min = 1,
553 .channels_max = 2,
554 .rates = ML26124_RATES,
555 .formats = ML26124_FORMATS,},
556 .capture = {
557 .stream_name = "Capture",
558 .channels_min = 1,
559 .channels_max = 2,
560 .rates = ML26124_RATES,
561 .formats = ML26124_FORMATS,},
562 .ops = &ml26124_dai_ops,
563 .symmetric_rates = 1,
564};
565
566#ifdef CONFIG_PM
567static int ml26124_suspend(struct snd_soc_codec *codec)
568{
569 ml26124_set_bias_level(codec, SND_SOC_BIAS_OFF);
570
571 return 0;
572}
573
574static int ml26124_resume(struct snd_soc_codec *codec)
575{
576 ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
577
578 return 0;
579}
580#else
581#define ml26124_suspend NULL
582#define ml26124_resume NULL
583#endif
584
585static int ml26124_probe(struct snd_soc_codec *codec)
586{
587 int ret;
588 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
589 codec->control_data = priv->regmap;
590
591 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
592 if (ret < 0) {
593 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
594 return ret;
595 }
596
597 /* Software Reset */
598 snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
599 snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
600
601 ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
602
603 return 0;
604}
605
606static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
607 .probe = ml26124_probe,
608 .suspend = ml26124_suspend,
609 .resume = ml26124_resume,
610 .set_bias_level = ml26124_set_bias_level,
611 .dapm_widgets = ml26124_dapm_widgets,
612 .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
613 .dapm_routes = ml26124_intercon,
614 .num_dapm_routes = ARRAY_SIZE(ml26124_intercon),
615 .controls = ml26124_snd_controls,
616 .num_controls = ARRAY_SIZE(ml26124_snd_controls),
617};
618
619static const struct regmap_config ml26124_i2c_regmap = {
620 .val_bits = 8,
621 .reg_bits = 8,
622 .max_register = ML26124_NUM_REGISTER,
623 .reg_defaults = ml26124_reg,
624 .num_reg_defaults = ARRAY_SIZE(ml26124_reg),
625 .cache_type = REGCACHE_RBTREE,
626 .write_flag_mask = 0x01,
627};
628
629static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
630 const struct i2c_device_id *id)
631{
632 struct ml26124_priv *priv;
633 int ret;
634
635 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
636 if (!priv)
637 return -ENOMEM;
638
639 i2c_set_clientdata(i2c, priv);
640
641 priv->regmap = regmap_init_i2c(i2c, &ml26124_i2c_regmap);
642 if (IS_ERR(priv->regmap)) {
643 ret = PTR_ERR(priv->regmap);
644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret);
645 return ret;
646 }
647
648 return snd_soc_register_codec(&i2c->dev,
649 &soc_codec_dev_ml26124, &ml26124_dai, 1);
650}
651
652static __devexit int ml26124_i2c_remove(struct i2c_client *client)
653{
654 struct ml26124_priv *priv = i2c_get_clientdata(client);
655
656 snd_soc_unregister_codec(&client->dev);
657 regmap_exit(priv->regmap);
658 return 0;
659}
660
661static const struct i2c_device_id ml26124_i2c_id[] = {
662 { "ml26124", 0 },
663 { }
664};
665MODULE_DEVICE_TABLE(i2c, ml26124_i2c_id);
666
667static struct i2c_driver ml26124_i2c_driver = {
668 .driver = {
669 .name = "ml26124",
670 .owner = THIS_MODULE,
671 },
672 .probe = ml26124_i2c_probe,
673 .remove = __devexit_p(ml26124_i2c_remove),
674 .id_table = ml26124_i2c_id,
675};
676
677module_i2c_driver(ml26124_i2c_driver);
678
679MODULE_AUTHOR("Tomoya MORINAGA <tomoya.rohm@gmail.com>");
680MODULE_DESCRIPTION("LAPIS Semiconductor ML26124 ALSA SoC codec driver");
681MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ml26124.h b/sound/soc/codecs/ml26124.h
new file mode 100644
index 000000000000..5ea0cbb8c46c
--- /dev/null
+++ b/sound/soc/codecs/ml26124.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18#ifndef ML26124_H
19#define ML26124_H
20
21/* Clock Control Register */
22#define ML26124_SMPLING_RATE 0x00
23#define ML26124_PLLNL 0x02
24#define ML26124_PLLNH 0x04
25#define ML26124_PLLML 0x06
26#define ML26124_PLLMH 0x08
27#define ML26124_PLLDIV 0x0a
28#define ML26124_CLK_EN 0x0c
29#define ML26124_CLK_CTL 0x0e
30
31/* System Control Register */
32#define ML26124_SW_RST 0x10
33#define ML26124_REC_PLYBAK_RUN 0x12
34#define ML26124_MIC_TIM 0x14
35
36/* Power Mnagement Register */
37#define ML26124_PW_REF_PW_MNG 0x20
38#define ML26124_PW_IN_PW_MNG 0x22
39#define ML26124_PW_DAC_PW_MNG 0x24
40#define ML26124_PW_SPAMP_PW_MNG 0x26
41#define ML26124_PW_LOUT_PW_MNG 0x28
42#define ML26124_PW_VOUT_PW_MNG 0x2a
43#define ML26124_PW_ZCCMP_PW_MNG 0x2e
44
45/* Analog Reference Control Register */
46#define ML26124_PW_MICBIAS_VOL 0x30
47
48/* Input/Output Amplifier Control Register */
49#define ML26124_PW_MIC_IN_VOL 0x32
50#define ML26124_PW_MIC_BOST_VOL 0x38
51#define ML26124_PW_SPK_AMP_VOL 0x3a
52#define ML26124_PW_AMP_VOL_FUNC 0x48
53#define ML26124_PW_AMP_VOL_FADE 0x4a
54
55/* Analog Path Control Register */
56#define ML26124_SPK_AMP_OUT 0x54
57#define ML26124_MIC_IF_CTL 0x5a
58#define ML26124_MIC_SELECT 0xe8
59
60/* Audio Interface Control Register */
61#define ML26124_SAI_TRANS_CTL 0x60
62#define ML26124_SAI_RCV_CTL 0x62
63#define ML26124_SAI_MODE_SEL 0x64
64
65/* DSP Control Register */
66#define ML26124_FILTER_EN 0x66
67#define ML26124_DVOL_CTL 0x68
68#define ML26124_MIXER_VOL_CTL 0x6a
69#define ML26124_RECORD_DIG_VOL 0x6c
70#define ML26124_PLBAK_DIG_VOL 0x70
71#define ML26124_DIGI_BOOST_VOL 0x72
72#define ML26124_EQ_GAIN_BRAND0 0x74
73#define ML26124_EQ_GAIN_BRAND1 0x76
74#define ML26124_EQ_GAIN_BRAND2 0x78
75#define ML26124_EQ_GAIN_BRAND3 0x7a
76#define ML26124_EQ_GAIN_BRAND4 0x7c
77#define ML26124_HPF2_CUTOFF 0x7e
78#define ML26124_EQBRAND0_F0L 0x80
79#define ML26124_EQBRAND0_F0H 0x82
80#define ML26124_EQBRAND0_F1L 0x84
81#define ML26124_EQBRAND0_F1H 0x86
82#define ML26124_EQBRAND1_F0L 0x88
83#define ML26124_EQBRAND1_F0H 0x8a
84#define ML26124_EQBRAND1_F1L 0x8c
85#define ML26124_EQBRAND1_F1H 0x8e
86#define ML26124_EQBRAND2_F0L 0x90
87#define ML26124_EQBRAND2_F0H 0x92
88#define ML26124_EQBRAND2_F1L 0x94
89#define ML26124_EQBRAND2_F1H 0x96
90#define ML26124_EQBRAND3_F0L 0x98
91#define ML26124_EQBRAND3_F0H 0x9a
92#define ML26124_EQBRAND3_F1L 0x9c
93#define ML26124_EQBRAND3_F1H 0x9e
94#define ML26124_EQBRAND4_F0L 0xa0
95#define ML26124_EQBRAND4_F0H 0xa2
96#define ML26124_EQBRAND4_F1L 0xa4
97#define ML26124_EQBRAND4_F1H 0xa6
98
99/* ALC Control Register */
100#define ML26124_ALC_MODE 0xb0
101#define ML26124_ALC_ATTACK_TIM 0xb2
102#define ML26124_ALC_DECAY_TIM 0xb4
103#define ML26124_ALC_HOLD_TIM 0xb6
104#define ML26124_ALC_TARGET_LEV 0xb8
105#define ML26124_ALC_MAXMIN_GAIN 0xba
106#define ML26124_NOIS_GATE_THRSH 0xbc
107#define ML26124_ALC_ZERO_TIMOUT 0xbe
108
109/* Playback Limiter Control Register */
110#define ML26124_PL_ATTACKTIME 0xc0
111#define ML26124_PL_DECAYTIME 0xc2
112#define ML26124_PL_TARGETTIME 0xc4
113#define ML26124_PL_MAXMIN_GAIN 0xc6
114#define ML26124_PLYBAK_BOST_VOL 0xc8
115#define ML26124_PL_0CROSS_TIMOUT 0xca
116
117/* Video Amplifer Control Register */
118#define ML26124_VIDEO_AMP_GAIN_CTL 0xd0
119#define ML26124_VIDEO_AMP_SETUP1 0xd2
120#define ML26124_VIDEO_AMP_CTL2 0xd4
121
122/* Clock select for machine driver */
123#define ML26124_USE_PLL 0
124#define ML26124_USE_MCLKI_256FS 1
125#define ML26124_USE_MCLKI_512FS 2
126#define ML26124_USE_MCLKI_1024FS 3
127
128/* Register Mask */
129#define ML26124_R0_MASK 0xf
130#define ML26124_R2_MASK 0xff
131#define ML26124_R4_MASK 0x1
132#define ML26124_R6_MASK 0xf
133#define ML26124_R8_MASK 0x3f
134#define ML26124_Ra_MASK 0x1f
135#define ML26124_Rc_MASK 0x1f
136#define ML26124_Re_MASK 0x7
137#define ML26124_R10_MASK 0x1
138#define ML26124_R12_MASK 0x17
139#define ML26124_R14_MASK 0x3f
140#define ML26124_R20_MASK 0x47
141#define ML26124_R22_MASK 0xa
142#define ML26124_R24_MASK 0x2
143#define ML26124_R26_MASK 0x1f
144#define ML26124_R28_MASK 0x2
145#define ML26124_R2a_MASK 0x2
146#define ML26124_R2e_MASK 0x2
147#define ML26124_R30_MASK 0x7
148#define ML26124_R32_MASK 0x3f
149#define ML26124_R38_MASK 0x38
150#define ML26124_R3a_MASK 0x3f
151#define ML26124_R48_MASK 0x3
152#define ML26124_R4a_MASK 0x7
153#define ML26124_R54_MASK 0x2a
154#define ML26124_R5a_MASK 0x3
155#define ML26124_Re8_MASK 0x3
156#define ML26124_R60_MASK 0xff
157#define ML26124_R62_MASK 0xff
158#define ML26124_R64_MASK 0x1
159#define ML26124_R66_MASK 0xff
160#define ML26124_R68_MASK 0x3b
161#define ML26124_R6a_MASK 0xf3
162#define ML26124_R6c_MASK 0xff
163#define ML26124_R70_MASK 0xff
164
165#define ML26124_MCLKEN BIT(0)
166#define ML26124_PLLEN BIT(1)
167#define ML26124_PLLOE BIT(2)
168#define ML26124_MCLKOE BIT(3)
169
170#define ML26124_BLT_ALL_ON 0x1f
171#define ML26124_BLT_PREAMP_ON 0x13
172
173#define ML26124_MICBEN_ON BIT(2)
174
175enum ml26124_regs {
176 ML26124_MCLK = 0,
177};
178
179enum ml26124_clk_in {
180 ML26124_USE_PLLOUT = 0,
181 ML26124_USE_MCLKI,
182};
183
184#endif
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 20c324c7c349..95147e451982 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1361,8 +1361,7 @@ static int get_coeff(int mclk, int rate, int timesofbclk)
1361static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, 1361static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
1362 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1362 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1363{ 1363{
1364 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1364 struct snd_soc_codec *codec = dai->codec;
1365 struct snd_soc_codec *codec = rtd->codec;
1366 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); 1365 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1367 int timesofbclk = 32, coeff; 1366 int timesofbclk = 32, coeff;
1368 unsigned int iface = 0; 1367 unsigned int iface = 0;
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index d1926266fe00..9538d41c1e5c 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -84,8 +84,8 @@ static struct regulator_consumer_supply ldo_consumer[] = {
84 84
85static struct regulator_init_data ldo_init_data = { 85static struct regulator_init_data ldo_init_data = {
86 .constraints = { 86 .constraints = {
87 .min_uV = 850000, 87 .min_uV = 1200000,
88 .max_uV = 1600000, 88 .max_uV = 1200000,
89 .valid_modes_mask = REGULATOR_MODE_NORMAL, 89 .valid_modes_mask = REGULATOR_MODE_NORMAL,
90 .valid_ops_mask = REGULATOR_CHANGE_STATUS, 90 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
91 }, 91 },
@@ -197,9 +197,9 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
197 SND_SOC_DAPM_OUTPUT("HP_OUT"), 197 SND_SOC_DAPM_OUTPUT("HP_OUT"),
198 SND_SOC_DAPM_OUTPUT("LINE_OUT"), 198 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
199 199
200 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0, 200 SND_SOC_DAPM_SUPPLY("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
201 mic_bias_event, 201 mic_bias_event,
202 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 202 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
203 203
204 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0, 204 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
205 small_pop_event, 205 small_pop_event,
@@ -664,8 +664,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
664 struct snd_pcm_hw_params *params, 664 struct snd_pcm_hw_params *params,
665 struct snd_soc_dai *dai) 665 struct snd_soc_dai *dai)
666{ 666{
667 struct snd_soc_pcm_runtime *rtd = substream->private_data; 667 struct snd_soc_codec *codec = dai->codec;
668 struct snd_soc_codec *codec = rtd->codec;
669 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 668 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
670 int channels = params_channels(params); 669 int channels = params_channels(params);
671 int i2s_ctl = 0; 670 int i2s_ctl = 0;
@@ -1450,17 +1449,7 @@ static struct i2c_driver sgtl5000_i2c_driver = {
1450 .id_table = sgtl5000_id, 1449 .id_table = sgtl5000_id,
1451}; 1450};
1452 1451
1453static int __init sgtl5000_modinit(void) 1452module_i2c_driver(sgtl5000_i2c_driver);
1454{
1455 return i2c_add_driver(&sgtl5000_i2c_driver);
1456}
1457module_init(sgtl5000_modinit);
1458
1459static void __exit sgtl5000_exit(void)
1460{
1461 i2c_del_driver(&sgtl5000_i2c_driver);
1462}
1463module_exit(sgtl5000_exit);
1464 1453
1465MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver"); 1454MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1466MODULE_AUTHOR("Zeng Zhaoming <zengzm.kernel@gmail.com>"); 1455MODULE_AUTHOR("Zeng Zhaoming <zengzm.kernel@gmail.com>");
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index de2b20544ceb..4c94fd211fb0 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -254,8 +254,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
254 struct snd_pcm_hw_params *params, 254 struct snd_pcm_hw_params *params,
255 struct snd_soc_dai *dai) 255 struct snd_soc_dai *dai)
256{ 256{
257 struct snd_soc_pcm_runtime *rtd = substream->private_data; 257 struct snd_soc_codec *codec = dai->codec;
258 struct snd_soc_codec *codec = rtd->codec;
259 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 258 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
260 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3; 259 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
261 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params)); 260 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
@@ -291,8 +290,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
291static int ssm2602_startup(struct snd_pcm_substream *substream, 290static int ssm2602_startup(struct snd_pcm_substream *substream,
292 struct snd_soc_dai *dai) 291 struct snd_soc_dai *dai)
293{ 292{
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 293 struct snd_soc_codec *codec = dai->codec;
295 struct snd_soc_codec *codec = rtd->codec;
296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 294 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
297 struct snd_pcm_runtime *master_runtime; 295 struct snd_pcm_runtime *master_runtime;
298 296
@@ -328,8 +326,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
328static void ssm2602_shutdown(struct snd_pcm_substream *substream, 326static void ssm2602_shutdown(struct snd_pcm_substream *substream,
329 struct snd_soc_dai *dai) 327 struct snd_soc_dai *dai)
330{ 328{
331 struct snd_soc_pcm_runtime *rtd = substream->private_data; 329 struct snd_soc_codec *codec = dai->codec;
332 struct snd_soc_codec *codec = rtd->codec;
333 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 330 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
334 331
335 if (ssm2602->master_substream == substream) 332 if (ssm2602->master_substream == substream)
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 7db6fa515028..8d717f4b5a87 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -609,8 +609,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
609 struct snd_pcm_hw_params *params, 609 struct snd_pcm_hw_params *params,
610 struct snd_soc_dai *dai) 610 struct snd_soc_dai *dai)
611{ 611{
612 struct snd_soc_pcm_runtime *rtd = substream->private_data; 612 struct snd_soc_codec *codec = dai->codec;
613 struct snd_soc_codec *codec = rtd->codec;
614 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); 613 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
615 unsigned int rate; 614 unsigned int rate;
616 int i, mcs = -1, ir = -1; 615 int i, mcs = -1, ir = -1;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 16d55f91a653..8c758b214a25 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -34,8 +34,6 @@
34 34
35#include "tlv320aic23.h" 35#include "tlv320aic23.h"
36 36
37#define AIC23_VERSION "0.1"
38
39/* 37/*
40 * AIC23 register cache 38 * AIC23 register cache
41 */ 39 */
@@ -325,8 +323,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
325 struct snd_pcm_hw_params *params, 323 struct snd_pcm_hw_params *params,
326 struct snd_soc_dai *dai) 324 struct snd_soc_dai *dai)
327{ 325{
328 struct snd_soc_pcm_runtime *rtd = substream->private_data; 326 struct snd_soc_codec *codec = dai->codec;
329 struct snd_soc_codec *codec = rtd->codec;
330 u16 iface_reg; 327 u16 iface_reg;
331 int ret; 328 int ret;
332 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 329 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
@@ -371,8 +368,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
371static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream, 368static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai) 369 struct snd_soc_dai *dai)
373{ 370{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 371 struct snd_soc_codec *codec = dai->codec;
375 struct snd_soc_codec *codec = rtd->codec;
376 372
377 /* set active */ 373 /* set active */
378 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001); 374 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -383,8 +379,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
383static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, 379static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
384 struct snd_soc_dai *dai) 380 struct snd_soc_dai *dai)
385{ 381{
386 struct snd_soc_pcm_runtime *rtd = substream->private_data; 382 struct snd_soc_codec *codec = dai->codec;
387 struct snd_soc_codec *codec = rtd->codec;
388 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 383 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
389 384
390 /* deactivate */ 385 /* deactivate */
@@ -548,8 +543,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
548 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 543 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
549 int ret; 544 int ret;
550 545
551 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
552
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type); 546 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
554 if (ret < 0) { 547 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 548 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 802064b5030d..85944e953578 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -126,8 +126,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params, 126 struct snd_pcm_hw_params *params,
127 struct snd_soc_dai *dai) 127 struct snd_soc_dai *dai)
128{ 128{
129 struct snd_soc_pcm_runtime *rtd = substream->private_data; 129 struct snd_soc_codec *codec = dai->codec;
130 struct snd_soc_codec *codec = rtd->codec;
131 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); 130 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
132 int fsref, divisor, wlen, pval, jval, dval, qval; 131 int fsref, divisor, wlen, pval, jval, dval, qval;
133 u16 reg; 132 u16 reg;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 8d20f6ec20f3..bde2d1ade0c6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -802,8 +802,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
802 struct snd_pcm_hw_params *params, 802 struct snd_pcm_hw_params *params,
803 struct snd_soc_dai *dai) 803 struct snd_soc_dai *dai)
804{ 804{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data; 805 struct snd_soc_codec *codec = dai->codec;
806 struct snd_soc_codec *codec =rtd->codec;
807 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 806 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
808 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 807 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
809 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 808 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 4587ddd0fbf8..0dd41077ab79 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -62,8 +62,10 @@
62#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ 62#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
63 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate)))) 63 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
64 64
65static void dac33_calculate_times(struct snd_pcm_substream *substream); 65static void dac33_calculate_times(struct snd_pcm_substream *substream,
66static int dac33_prepare_chip(struct snd_pcm_substream *substream); 66 struct snd_soc_codec *codec);
67static int dac33_prepare_chip(struct snd_pcm_substream *substream,
68 struct snd_soc_codec *codec);
67 69
68enum dac33_state { 70enum dac33_state {
69 DAC33_IDLE = 0, 71 DAC33_IDLE = 0,
@@ -427,8 +429,8 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w,
427 switch (event) { 429 switch (event) {
428 case SND_SOC_DAPM_PRE_PMU: 430 case SND_SOC_DAPM_PRE_PMU:
429 if (likely(dac33->substream)) { 431 if (likely(dac33->substream)) {
430 dac33_calculate_times(dac33->substream); 432 dac33_calculate_times(dac33->substream, w->codec);
431 dac33_prepare_chip(dac33->substream); 433 dac33_prepare_chip(dac33->substream, w->codec);
432 } 434 }
433 break; 435 break;
434 case SND_SOC_DAPM_POST_PMD: 436 case SND_SOC_DAPM_POST_PMD:
@@ -799,8 +801,7 @@ static void dac33_oscwait(struct snd_soc_codec *codec)
799static int dac33_startup(struct snd_pcm_substream *substream, 801static int dac33_startup(struct snd_pcm_substream *substream,
800 struct snd_soc_dai *dai) 802 struct snd_soc_dai *dai)
801{ 803{
802 struct snd_soc_pcm_runtime *rtd = substream->private_data; 804 struct snd_soc_codec *codec = dai->codec;
803 struct snd_soc_codec *codec = rtd->codec;
804 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 805 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
805 806
806 /* Stream started, save the substream pointer */ 807 /* Stream started, save the substream pointer */
@@ -812,8 +813,7 @@ static int dac33_startup(struct snd_pcm_substream *substream,
812static void dac33_shutdown(struct snd_pcm_substream *substream, 813static void dac33_shutdown(struct snd_pcm_substream *substream,
813 struct snd_soc_dai *dai) 814 struct snd_soc_dai *dai)
814{ 815{
815 struct snd_soc_pcm_runtime *rtd = substream->private_data; 816 struct snd_soc_codec *codec = dai->codec;
816 struct snd_soc_codec *codec = rtd->codec;
817 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 817 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
818 818
819 dac33->substream = NULL; 819 dac33->substream = NULL;
@@ -825,8 +825,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
825 struct snd_pcm_hw_params *params, 825 struct snd_pcm_hw_params *params,
826 struct snd_soc_dai *dai) 826 struct snd_soc_dai *dai)
827{ 827{
828 struct snd_soc_pcm_runtime *rtd = substream->private_data; 828 struct snd_soc_codec *codec = dai->codec;
829 struct snd_soc_codec *codec = rtd->codec;
830 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 829 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
831 830
832 /* Check parameters for validity */ 831 /* Check parameters for validity */
@@ -868,10 +867,9 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
868 * writes happens in different order, than dac33 might end up in unknown state. 867 * writes happens in different order, than dac33 might end up in unknown state.
869 * Use the known, working sequence of register writes to initialize the dac33. 868 * Use the known, working sequence of register writes to initialize the dac33.
870 */ 869 */
871static int dac33_prepare_chip(struct snd_pcm_substream *substream) 870static int dac33_prepare_chip(struct snd_pcm_substream *substream,
871 struct snd_soc_codec *codec)
872{ 872{
873 struct snd_soc_pcm_runtime *rtd = substream->private_data;
874 struct snd_soc_codec *codec = rtd->codec;
875 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 873 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
876 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 874 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
877 u8 aictrl_a, aictrl_b, fifoctrl_a; 875 u8 aictrl_a, aictrl_b, fifoctrl_a;
@@ -1067,10 +1065,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1067 return 0; 1065 return 0;
1068} 1066}
1069 1067
1070static void dac33_calculate_times(struct snd_pcm_substream *substream) 1068static void dac33_calculate_times(struct snd_pcm_substream *substream,
1069 struct snd_soc_codec *codec)
1071{ 1070{
1072 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1073 struct snd_soc_codec *codec = rtd->codec;
1074 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1071 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1075 unsigned int period_size = substream->runtime->period_size; 1072 unsigned int period_size = substream->runtime->period_size;
1076 unsigned int rate = substream->runtime->rate; 1073 unsigned int rate = substream->runtime->rate;
@@ -1128,8 +1125,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1128static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1125static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1129 struct snd_soc_dai *dai) 1126 struct snd_soc_dai *dai)
1130{ 1127{
1131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1128 struct snd_soc_codec *codec = dai->codec;
1132 struct snd_soc_codec *codec = rtd->codec;
1133 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1129 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1134 int ret = 0; 1130 int ret = 0;
1135 1131
@@ -1161,8 +1157,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1161 struct snd_pcm_substream *substream, 1157 struct snd_pcm_substream *substream,
1162 struct snd_soc_dai *dai) 1158 struct snd_soc_dai *dai)
1163{ 1159{
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1160 struct snd_soc_codec *codec = dai->codec;
1165 struct snd_soc_codec *codec = rtd->codec;
1166 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1161 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1167 unsigned long long t0, t1, t_now; 1162 unsigned long long t0, t1, t_now;
1168 unsigned int time_delta, uthr; 1163 unsigned int time_delta, uthr;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 170cf9a8fc79..391fcfc7b63b 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1685,8 +1685,7 @@ static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
1685static int twl4030_startup(struct snd_pcm_substream *substream, 1685static int twl4030_startup(struct snd_pcm_substream *substream,
1686 struct snd_soc_dai *dai) 1686 struct snd_soc_dai *dai)
1687{ 1687{
1688 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1688 struct snd_soc_codec *codec = dai->codec;
1689 struct snd_soc_codec *codec = rtd->codec;
1690 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1689 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1691 1690
1692 if (twl4030->master_substream) { 1691 if (twl4030->master_substream) {
@@ -1715,8 +1714,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1715static void twl4030_shutdown(struct snd_pcm_substream *substream, 1714static void twl4030_shutdown(struct snd_pcm_substream *substream,
1716 struct snd_soc_dai *dai) 1715 struct snd_soc_dai *dai)
1717{ 1716{
1718 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1717 struct snd_soc_codec *codec = dai->codec;
1719 struct snd_soc_codec *codec = rtd->codec;
1720 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1718 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1721 1719
1722 if (twl4030->master_substream == substream) 1720 if (twl4030->master_substream == substream)
@@ -1740,8 +1738,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1740 struct snd_pcm_hw_params *params, 1738 struct snd_pcm_hw_params *params,
1741 struct snd_soc_dai *dai) 1739 struct snd_soc_dai *dai)
1742{ 1740{
1743 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1741 struct snd_soc_codec *codec = dai->codec;
1744 struct snd_soc_codec *codec = rtd->codec;
1745 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1742 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1746 u8 mode, old_mode, format, old_format; 1743 u8 mode, old_mode, format, old_format;
1747 1744
@@ -1974,8 +1971,7 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
1974static int twl4030_voice_startup(struct snd_pcm_substream *substream, 1971static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1975 struct snd_soc_dai *dai) 1972 struct snd_soc_dai *dai)
1976{ 1973{
1977 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1974 struct snd_soc_codec *codec = dai->codec;
1978 struct snd_soc_codec *codec = rtd->codec;
1979 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1975 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1980 u8 mode; 1976 u8 mode;
1981 1977
@@ -2007,8 +2003,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2007static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, 2003static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2008 struct snd_soc_dai *dai) 2004 struct snd_soc_dai *dai)
2009{ 2005{
2010 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2006 struct snd_soc_codec *codec = dai->codec;
2011 struct snd_soc_codec *codec = rtd->codec;
2012 2007
2013 /* Enable voice digital filters */ 2008 /* Enable voice digital filters */
2014 twl4030_voice_enable(codec, substream->stream, 0); 2009 twl4030_voice_enable(codec, substream->stream, 0);
@@ -2017,8 +2012,7 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2017static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, 2012static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2018 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 2013 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2019{ 2014{
2020 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2015 struct snd_soc_codec *codec = dai->codec;
2021 struct snd_soc_codec *codec = rtd->codec;
2022 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2016 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2023 u8 old_mode, mode; 2017 u8 old_mode, mode;
2024 2018
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 2d8c6b825e57..ccbc88aa8497 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1340,8 +1340,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1340static int twl6040_startup(struct snd_pcm_substream *substream, 1340static int twl6040_startup(struct snd_pcm_substream *substream,
1341 struct snd_soc_dai *dai) 1341 struct snd_soc_dai *dai)
1342{ 1342{
1343 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1343 struct snd_soc_codec *codec = dai->codec;
1344 struct snd_soc_codec *codec = rtd->codec;
1345 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1344 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1346 1345
1347 snd_pcm_hw_constraint_list(substream->runtime, 0, 1346 snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -1355,8 +1354,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1355 struct snd_pcm_hw_params *params, 1354 struct snd_pcm_hw_params *params,
1356 struct snd_soc_dai *dai) 1355 struct snd_soc_dai *dai)
1357{ 1356{
1358 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1357 struct snd_soc_codec *codec = dai->codec;
1359 struct snd_soc_codec *codec = rtd->codec;
1360 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1358 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1361 int rate; 1359 int rate;
1362 1360
@@ -1392,8 +1390,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1392static int twl6040_prepare(struct snd_pcm_substream *substream, 1390static int twl6040_prepare(struct snd_pcm_substream *substream,
1393 struct snd_soc_dai *dai) 1391 struct snd_soc_dai *dai)
1394{ 1392{
1395 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1393 struct snd_soc_codec *codec = dai->codec;
1396 struct snd_soc_codec *codec = rtd->codec;
1397 struct twl6040 *twl6040 = codec->control_data; 1394 struct twl6040 *twl6040 = codec->control_data;
1398 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1395 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1399 int ret; 1396 int ret;
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 797b0dde2c68..6c3d43b8ee85 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -159,8 +159,7 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
159static int uda134x_startup(struct snd_pcm_substream *substream, 159static int uda134x_startup(struct snd_pcm_substream *substream,
160 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
161{ 161{
162 struct snd_soc_pcm_runtime *rtd = substream->private_data; 162 struct snd_soc_codec *codec = dai->codec;
163 struct snd_soc_codec *codec =rtd->codec;
164 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 163 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
165 struct snd_pcm_runtime *master_runtime; 164 struct snd_pcm_runtime *master_runtime;
166 165
@@ -191,8 +190,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
191static void uda134x_shutdown(struct snd_pcm_substream *substream, 190static void uda134x_shutdown(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai) 191 struct snd_soc_dai *dai)
193{ 192{
194 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_codec *codec = dai->codec;
195 struct snd_soc_codec *codec = rtd->codec;
196 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 194 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
197 195
198 if (uda134x->master_substream == substream) 196 if (uda134x->master_substream == substream)
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 4f1b23d7e404..2502214b84ab 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -502,8 +502,7 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
502static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, 502static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
503 struct snd_soc_dai *dai) 503 struct snd_soc_dai *dai)
504{ 504{
505 struct snd_soc_pcm_runtime *rtd = substream->private_data; 505 struct snd_soc_codec *codec = dai->codec;
506 struct snd_soc_codec *codec = rtd->codec;
507 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); 506 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
508 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 507 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
509 508
@@ -528,8 +527,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
528 struct snd_pcm_hw_params *params, 527 struct snd_pcm_hw_params *params,
529 struct snd_soc_dai *dai) 528 struct snd_soc_dai *dai)
530{ 529{
531 struct snd_soc_pcm_runtime *rtd = substream->private_data; 530 struct snd_soc_codec *codec = dai->codec;
532 struct snd_soc_codec *codec = rtd->codec;
533 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 531 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
534 532
535 /* set WSPLL power and divider if running from this clock */ 533 /* set WSPLL power and divider if running from this clock */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 3d868dc40092..7b24d6d192e1 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -293,8 +293,7 @@ static const struct snd_kcontrol_new wl1273_controls[] = {
293static int wl1273_startup(struct snd_pcm_substream *substream, 293static int wl1273_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_dai *dai) 294 struct snd_soc_dai *dai)
295{ 295{
296 struct snd_soc_pcm_runtime *rtd = substream->private_data; 296 struct snd_soc_codec *codec = dai->codec;
297 struct snd_soc_codec *codec = rtd->codec;
298 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); 297 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
299 298
300 switch (wl1273->mode) { 299 switch (wl1273->mode) {
@@ -329,8 +328,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params, 328 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai) 329 struct snd_soc_dai *dai)
331{ 330{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data; 331 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
333 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(rtd->codec);
334 struct wl1273_core *core = wl1273->core; 332 struct wl1273_core *core = wl1273->core;
335 unsigned int rate, width, r; 333 unsigned int rate, width, r;
336 334
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index b9c185ce64e4..0594636b9107 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2454,7 +2454,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2454 2454
2455 wm5100->dev = &i2c->dev; 2455 wm5100->dev = &i2c->dev;
2456 2456
2457 wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); 2457 wm5100->regmap = devm_regmap_init_i2c(i2c, &wm5100_regmap);
2458 if (IS_ERR(wm5100->regmap)) { 2458 if (IS_ERR(wm5100->regmap)) {
2459 ret = PTR_ERR(wm5100->regmap); 2459 ret = PTR_ERR(wm5100->regmap);
2460 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2460 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2479,7 +2479,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2479 if (ret != 0) { 2479 if (ret != 0) {
2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", 2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2481 ret); 2481 ret);
2482 goto err_regmap; 2482 goto err;
2483 } 2483 }
2484 2484
2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), 2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
@@ -2487,7 +2487,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2487 if (ret != 0) { 2487 if (ret != 0) {
2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", 2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2489 ret); 2489 ret);
2490 goto err_regmap; 2490 goto err;
2491 } 2491 }
2492 2492
2493 if (wm5100->pdata.ldo_ena) { 2493 if (wm5100->pdata.ldo_ena) {
@@ -2660,8 +2660,6 @@ err_ldo:
2660err_enable: 2660err_enable:
2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2662 wm5100->core_supplies); 2662 wm5100->core_supplies);
2663err_regmap:
2664 regmap_exit(wm5100->regmap);
2665err: 2663err:
2666 return ret; 2664 return ret;
2667} 2665}
@@ -2682,7 +2680,6 @@ static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
2682 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2680 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2683 gpio_free(wm5100->pdata.ldo_ena); 2681 gpio_free(wm5100->pdata.ldo_ena);
2684 } 2682 }
2685 regmap_exit(wm5100->regmap);
2686 2683
2687 return 0; 2684 return 0;
2688} 2685}
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 898979d23010..5dc31ebcd0e7 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -138,8 +138,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
138 return ret; 138 return ret;
139 139
140 /* now hit the volume update bits (always bit 8) */ 140 /* now hit the volume update bits (always bit 8) */
141 val = wm8400_read(codec, reg); 141 val = snd_soc_read(codec, reg);
142 return wm8400_write(codec, reg, val | 0x0100); 142 return snd_soc_write(codec, reg, val | 0x0100);
143} 143}
144 144
145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
@@ -362,8 +362,8 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
362{ 362{
363 u16 reg, fakepower; 363 u16 reg, fakepower;
364 364
365 reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2); 365 reg = snd_soc_read(w->codec, WM8400_POWER_MANAGEMENT_2);
366 fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS); 366 fakepower = snd_soc_read(w->codec, WM8400_INTDRIVBITS);
367 367
368 if (fakepower & ((1 << WM8400_INMIXL_PWR) | 368 if (fakepower & ((1 << WM8400_INMIXL_PWR) |
369 (1 << WM8400_AINLMUX_PWR))) { 369 (1 << WM8400_AINLMUX_PWR))) {
@@ -378,7 +378,7 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
378 } else { 378 } else {
379 reg &= ~WM8400_AINR_ENA; 379 reg &= ~WM8400_AINR_ENA;
380 } 380 }
381 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); 381 snd_soc_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
382 382
383 return 0; 383 return 0;
384} 384}
@@ -394,7 +394,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
394 394
395 switch (reg_shift) { 395 switch (reg_shift) {
396 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : 396 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
397 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1); 397 reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER1);
398 if (reg & WM8400_LDLO) { 398 if (reg & WM8400_LDLO) {
399 printk(KERN_WARNING 399 printk(KERN_WARNING
400 "Cannot set as Output Mixer 1 LDLO Set\n"); 400 "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -402,7 +402,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
402 } 402 }
403 break; 403 break;
404 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): 404 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
405 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2); 405 reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER2);
406 if (reg & WM8400_RDRO) { 406 if (reg & WM8400_RDRO) {
407 printk(KERN_WARNING 407 printk(KERN_WARNING
408 "Cannot set as Output Mixer 2 RDRO Set\n"); 408 "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -410,7 +410,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
410 } 410 }
411 break; 411 break;
412 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): 412 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
413 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 413 reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
414 if (reg & WM8400_LDSPK) { 414 if (reg & WM8400_LDSPK) {
415 printk(KERN_WARNING 415 printk(KERN_WARNING
416 "Cannot set as Speaker Mixer LDSPK Set\n"); 416 "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -418,7 +418,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
418 } 418 }
419 break; 419 break;
420 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): 420 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
421 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 421 reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
422 if (reg & WM8400_RDSPK) { 422 if (reg & WM8400_RDSPK) {
423 printk(KERN_WARNING 423 printk(KERN_WARNING
424 "Cannot set as Speaker Mixer RDSPK Set\n"); 424 "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -1021,13 +1021,13 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1021 wm8400->fll_in = freq_in; 1021 wm8400->fll_in = freq_in;
1022 1022
1023 /* We *must* disable the FLL before any changes */ 1023 /* We *must* disable the FLL before any changes */
1024 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2); 1024 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_2);
1025 reg &= ~WM8400_FLL_ENA; 1025 reg &= ~WM8400_FLL_ENA;
1026 wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg); 1026 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
1027 1027
1028 reg = wm8400_read(codec, WM8400_FLL_CONTROL_1); 1028 reg = snd_soc_read(codec, WM8400_FLL_CONTROL_1);
1029 reg &= ~WM8400_FLL_OSC_ENA; 1029 reg &= ~WM8400_FLL_OSC_ENA;
1030 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1030 snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
1031 1031
1032 if (!freq_out) 1032 if (!freq_out)
1033 return 0; 1033 return 0;
@@ -1035,15 +1035,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1035 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); 1035 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
1036 reg |= WM8400_FLL_FRAC | factors.fratio; 1036 reg |= WM8400_FLL_FRAC | factors.fratio;
1037 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT; 1037 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
1038 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1038 snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
1039 1039
1040 wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k); 1040 snd_soc_write(codec, WM8400_FLL_CONTROL_2, factors.k);
1041 wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n); 1041 snd_soc_write(codec, WM8400_FLL_CONTROL_3, factors.n);
1042 1042
1043 reg = wm8400_read(codec, WM8400_FLL_CONTROL_4); 1043 reg = snd_soc_read(codec, WM8400_FLL_CONTROL_4);
1044 reg &= ~WM8400_FLL_OUTDIV_MASK; 1044 reg &= ~WM8400_FLL_OUTDIV_MASK;
1045 reg |= factors.outdiv; 1045 reg |= factors.outdiv;
1046 wm8400_write(codec, WM8400_FLL_CONTROL_4, reg); 1046 snd_soc_write(codec, WM8400_FLL_CONTROL_4, reg);
1047 1047
1048 return 0; 1048 return 0;
1049} 1049}
@@ -1057,8 +1057,8 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
1057 struct snd_soc_codec *codec = codec_dai->codec; 1057 struct snd_soc_codec *codec = codec_dai->codec;
1058 u16 audio1, audio3; 1058 u16 audio1, audio3;
1059 1059
1060 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1060 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
1061 audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3); 1061 audio3 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_3);
1062 1062
1063 /* set master/slave audio interface */ 1063 /* set master/slave audio interface */
1064 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1064 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1099,8 +1099,8 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
1099 return -EINVAL; 1099 return -EINVAL;
1100 } 1100 }
1101 1101
1102 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1102 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1103 wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3); 1103 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
1104 return 0; 1104 return 0;
1105} 1105}
1106 1106
@@ -1112,24 +1112,24 @@ static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1112 1112
1113 switch (div_id) { 1113 switch (div_id) {
1114 case WM8400_MCLK_DIV: 1114 case WM8400_MCLK_DIV:
1115 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1115 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1116 ~WM8400_MCLK_DIV_MASK; 1116 ~WM8400_MCLK_DIV_MASK;
1117 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1117 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1118 break; 1118 break;
1119 case WM8400_DACCLK_DIV: 1119 case WM8400_DACCLK_DIV:
1120 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1120 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1121 ~WM8400_DAC_CLKDIV_MASK; 1121 ~WM8400_DAC_CLKDIV_MASK;
1122 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1122 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1123 break; 1123 break;
1124 case WM8400_ADCCLK_DIV: 1124 case WM8400_ADCCLK_DIV:
1125 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1125 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1126 ~WM8400_ADC_CLKDIV_MASK; 1126 ~WM8400_ADC_CLKDIV_MASK;
1127 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1127 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1128 break; 1128 break;
1129 case WM8400_BCLK_DIV: 1129 case WM8400_BCLK_DIV:
1130 reg = wm8400_read(codec, WM8400_CLOCKING_1) & 1130 reg = snd_soc_read(codec, WM8400_CLOCKING_1) &
1131 ~WM8400_BCLK_DIV_MASK; 1131 ~WM8400_BCLK_DIV_MASK;
1132 wm8400_write(codec, WM8400_CLOCKING_1, reg | div); 1132 snd_soc_write(codec, WM8400_CLOCKING_1, reg | div);
1133 break; 1133 break;
1134 default: 1134 default:
1135 return -EINVAL; 1135 return -EINVAL;
@@ -1145,9 +1145,8 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
1145 struct snd_pcm_hw_params *params, 1145 struct snd_pcm_hw_params *params,
1146 struct snd_soc_dai *dai) 1146 struct snd_soc_dai *dai)
1147{ 1147{
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1148 struct snd_soc_codec *codec = dai->codec;
1149 struct snd_soc_codec *codec = rtd->codec; 1149 u16 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
1150 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1151 1150
1152 audio1 &= ~WM8400_AIF_WL_MASK; 1151 audio1 &= ~WM8400_AIF_WL_MASK;
1153 /* bit size */ 1152 /* bit size */
@@ -1165,19 +1164,19 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
1165 break; 1164 break;
1166 } 1165 }
1167 1166
1168 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1167 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1169 return 0; 1168 return 0;
1170} 1169}
1171 1170
1172static int wm8400_mute(struct snd_soc_dai *dai, int mute) 1171static int wm8400_mute(struct snd_soc_dai *dai, int mute)
1173{ 1172{
1174 struct snd_soc_codec *codec = dai->codec; 1173 struct snd_soc_codec *codec = dai->codec;
1175 u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; 1174 u16 val = snd_soc_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
1176 1175
1177 if (mute) 1176 if (mute)
1178 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1177 snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1179 else 1178 else
1180 wm8400_write(codec, WM8400_DAC_CTRL, val); 1179 snd_soc_write(codec, WM8400_DAC_CTRL, val);
1181 1180
1182 return 0; 1181 return 0;
1183} 1182}
@@ -1196,9 +1195,9 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1196 1195
1197 case SND_SOC_BIAS_PREPARE: 1196 case SND_SOC_BIAS_PREPARE:
1198 /* VMID=2*50k */ 1197 /* VMID=2*50k */
1199 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1198 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
1200 ~WM8400_VMID_MODE_MASK; 1199 ~WM8400_VMID_MODE_MASK;
1201 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2); 1200 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
1202 break; 1201 break;
1203 1202
1204 case SND_SOC_BIAS_STANDBY: 1203 case SND_SOC_BIAS_STANDBY:
@@ -1212,74 +1211,74 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1212 return ret; 1211 return ret;
1213 } 1212 }
1214 1213
1215 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1214 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
1216 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA); 1215 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
1217 1216
1218 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ 1217 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1219 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1218 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1220 WM8400_BUFDCOPEN | WM8400_POBCTRL); 1219 WM8400_BUFDCOPEN | WM8400_POBCTRL);
1221 1220
1222 msleep(50); 1221 msleep(50);
1223 1222
1224 /* Enable VREF & VMID at 2x50k */ 1223 /* Enable VREF & VMID at 2x50k */
1225 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1224 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1226 val |= 0x2 | WM8400_VREF_ENA; 1225 val |= 0x2 | WM8400_VREF_ENA;
1227 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1226 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1228 1227
1229 /* Enable BUFIOEN */ 1228 /* Enable BUFIOEN */
1230 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1229 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1231 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1230 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1232 WM8400_BUFIOEN); 1231 WM8400_BUFIOEN);
1233 1232
1234 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1233 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1235 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN); 1234 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
1236 } 1235 }
1237 1236
1238 /* VMID=2*300k */ 1237 /* VMID=2*300k */
1239 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1238 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
1240 ~WM8400_VMID_MODE_MASK; 1239 ~WM8400_VMID_MODE_MASK;
1241 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4); 1240 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
1242 break; 1241 break;
1243 1242
1244 case SND_SOC_BIAS_OFF: 1243 case SND_SOC_BIAS_OFF:
1245 /* Enable POBCTRL and SOFT_ST */ 1244 /* Enable POBCTRL and SOFT_ST */
1246 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1245 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1247 WM8400_POBCTRL | WM8400_BUFIOEN); 1246 WM8400_POBCTRL | WM8400_BUFIOEN);
1248 1247
1249 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ 1248 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1250 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1249 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1251 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1250 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1252 WM8400_BUFIOEN); 1251 WM8400_BUFIOEN);
1253 1252
1254 /* mute DAC */ 1253 /* mute DAC */
1255 val = wm8400_read(codec, WM8400_DAC_CTRL); 1254 val = snd_soc_read(codec, WM8400_DAC_CTRL);
1256 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1255 snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1257 1256
1258 /* Enable any disabled outputs */ 1257 /* Enable any disabled outputs */
1259 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1258 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1260 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA | 1259 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
1261 WM8400_OUT4_ENA | WM8400_LOUT_ENA | 1260 WM8400_OUT4_ENA | WM8400_LOUT_ENA |
1262 WM8400_ROUT_ENA; 1261 WM8400_ROUT_ENA;
1263 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1262 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1264 1263
1265 /* Disable VMID */ 1264 /* Disable VMID */
1266 val &= ~WM8400_VMID_MODE_MASK; 1265 val &= ~WM8400_VMID_MODE_MASK;
1267 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1266 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1268 1267
1269 msleep(300); 1268 msleep(300);
1270 1269
1271 /* Enable all output discharge bits */ 1270 /* Enable all output discharge bits */
1272 wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE | 1271 snd_soc_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
1273 WM8400_DIS_RLINE | WM8400_DIS_OUT3 | 1272 WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
1274 WM8400_DIS_OUT4 | WM8400_DIS_LOUT | 1273 WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
1275 WM8400_DIS_ROUT); 1274 WM8400_DIS_ROUT);
1276 1275
1277 /* Disable VREF */ 1276 /* Disable VREF */
1278 val &= ~WM8400_VREF_ENA; 1277 val &= ~WM8400_VREF_ENA;
1279 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1278 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1280 1279
1281 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1280 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1282 wm8400_write(codec, WM8400_ANTIPOP2, 0x0); 1281 snd_soc_write(codec, WM8400_ANTIPOP2, 0x0);
1283 1282
1284 ret = regulator_bulk_disable(ARRAY_SIZE(power), 1283 ret = regulator_bulk_disable(ARRAY_SIZE(power),
1285 &power[0]); 1284 &power[0]);
@@ -1385,19 +1384,19 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec)
1385 1384
1386 wm8400_codec_reset(codec); 1385 wm8400_codec_reset(codec);
1387 1386
1388 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1387 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1389 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA); 1388 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
1390 1389
1391 /* Latch volume update bits */ 1390 /* Latch volume update bits */
1392 reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); 1391 reg = snd_soc_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
1393 wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 1392 snd_soc_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
1394 reg & WM8400_IPVU); 1393 reg & WM8400_IPVU);
1395 reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); 1394 reg = snd_soc_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
1396 wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 1395 snd_soc_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
1397 reg & WM8400_IPVU); 1396 reg & WM8400_IPVU);
1398 1397
1399 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1398 snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1400 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1399 snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1401 1400
1402 if (!schedule_work(&priv->work)) { 1401 if (!schedule_work(&priv->work)) {
1403 ret = -EINVAL; 1402 ret = -EINVAL;
@@ -1414,8 +1413,8 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec)
1414{ 1413{
1415 u16 reg; 1414 u16 reg;
1416 1415
1417 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1416 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1418 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1417 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
1419 reg & (~WM8400_CODEC_ENA)); 1418 reg & (~WM8400_CODEC_ENA));
1420 1419
1421 regulator_bulk_free(ARRAY_SIZE(power), power); 1420 regulator_bulk_free(ARRAY_SIZE(power), power);
@@ -1428,7 +1427,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
1428 .remove = wm8400_codec_remove, 1427 .remove = wm8400_codec_remove,
1429 .suspend = wm8400_suspend, 1428 .suspend = wm8400_suspend,
1430 .resume = wm8400_resume, 1429 .resume = wm8400_resume,
1431 .read = wm8400_read, 1430 .read = snd_soc_read,
1432 .write = wm8400_write, 1431 .write = wm8400_write,
1433 .set_bias_level = wm8400_set_bias_level, 1432 .set_bias_level = wm8400_set_bias_level,
1434 1433
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9166126bd312..56a049555e2c 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -392,8 +392,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
392 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
393 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
394{ 394{
395 struct snd_soc_pcm_runtime *rtd = substream->private_data; 395 struct snd_soc_codec *codec = dai->codec;
396 struct snd_soc_codec *codec = rtd->codec;
397 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f; 396 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
398 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1; 397 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
399 398
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 7fea2c3bf7e7..1c3ffb290cdc 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -145,8 +145,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params, 145 struct snd_pcm_hw_params *params,
146 struct snd_soc_dai *dai) 146 struct snd_soc_dai *dai)
147{ 147{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 148 struct snd_soc_codec *codec = dai->codec;
149 struct snd_soc_codec *codec = rtd->codec;
150 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 149 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
151 int i; 150 int i;
152 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 151 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index fc3d59e49084..1467f97dce21 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -88,8 +88,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params, 88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
90{ 90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 struct snd_soc_codec *codec = dai->codec;
92 struct snd_soc_codec *codec = rtd->codec;
93 u16 dac = snd_soc_read(codec, WM8728_DACCTL); 92 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
94 93
95 dac &= ~0x18; 94 dac &= ~0x18;
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 4fe9d191e277..d0520124616d 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -329,8 +329,7 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params, 329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai) 330 struct snd_soc_dai *dai)
331{ 331{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data; 332 struct snd_soc_codec *codec = dai->codec;
333 struct snd_soc_codec *codec = rtd->codec;
334 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); 333 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
335 int i; 334 int i;
336 u16 clocking = 0; 335 u16 clocking = 0;
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 3941f50bf187..6e849cb04243 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -203,8 +203,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params, 203 struct snd_pcm_hw_params *params,
204 struct snd_soc_dai *dai) 204 struct snd_soc_dai *dai)
205{ 205{
206 struct snd_soc_pcm_runtime *rtd = substream->private_data; 206 struct snd_soc_codec *codec = dai->codec;
207 struct snd_soc_codec *codec = rtd->codec;
208 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 207 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
209 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 208 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
210 int i; 209 int i;
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e4c50ce7d9c0..89151ca5e776 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -547,8 +547,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
547 struct snd_pcm_hw_params *params, 547 struct snd_pcm_hw_params *params,
548 struct snd_soc_dai *dai) 548 struct snd_soc_dai *dai)
549{ 549{
550 struct snd_soc_pcm_runtime *rtd = substream->private_data; 550 struct snd_soc_codec *codec = dai->codec;
551 struct snd_soc_codec *codec = rtd->codec;
552 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 551 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
553 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 552 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
554 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 553 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index e27e7b62b365..a26482cd7654 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -931,8 +931,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
931 struct snd_pcm_hw_params *params, 931 struct snd_pcm_hw_params *params,
932 struct snd_soc_dai *dai) 932 struct snd_soc_dai *dai)
933{ 933{
934 struct snd_soc_pcm_runtime *rtd = substream->private_data; 934 struct snd_soc_codec *codec = dai->codec;
935 struct snd_soc_codec *codec = rtd->codec;
936 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 935 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
937 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3; 936 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
938 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f; 937 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
@@ -1161,8 +1160,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1161 struct snd_pcm_hw_params *params, 1160 struct snd_pcm_hw_params *params,
1162 struct snd_soc_dai *dai) 1161 struct snd_soc_dai *dai)
1163{ 1162{
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1163 struct snd_soc_codec *codec = dai->codec;
1165 struct snd_soc_codec *codec = rtd->codec;
1166 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1164 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1167 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0; 1165 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
1168 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3; 1166 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index f18c554efc98..077c9628c70d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -610,8 +610,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
610 struct snd_pcm_hw_params *params, 610 struct snd_pcm_hw_params *params,
611 struct snd_soc_dai *dai) 611 struct snd_soc_dai *dai)
612{ 612{
613 struct snd_soc_pcm_runtime *rtd = substream->private_data; 613 struct snd_soc_codec *codec = dai->codec;
614 struct snd_soc_codec *codec = rtd->codec;
615 u16 reg; 614 u16 reg;
616 615
617 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; 616 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index c91fb2f99c13..86b8a2926591 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1432,8 +1432,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1432 struct snd_pcm_hw_params *params, 1432 struct snd_pcm_hw_params *params,
1433 struct snd_soc_dai *dai) 1433 struct snd_soc_dai *dai)
1434{ 1434{
1435 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1435 struct snd_soc_codec *codec = dai->codec;
1436 struct snd_soc_codec *codec =rtd->codec;
1437 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1436 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1438 int fs = params_rate(params); 1437 int fs = params_rate(params);
1439 int bclk; 1438 int bclk;
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index d2883affea3b..481a3d9cfe48 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -371,8 +371,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
371 struct snd_pcm_hw_params *params, 371 struct snd_pcm_hw_params *params,
372 struct snd_soc_dai *dai) 372 struct snd_soc_dai *dai)
373{ 373{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_codec *codec = dai->codec;
375 struct snd_soc_codec *codec = rtd->codec;
376 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F; 375 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
377 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1; 376 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
378 u16 companding = snd_soc_read(codec, 377 u16 companding = snd_soc_read(codec,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 840d72086d04..8bc659d8dd2e 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -505,8 +505,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
505 struct snd_pcm_hw_params *params, 505 struct snd_pcm_hw_params *params,
506 struct snd_soc_dai *dai) 506 struct snd_soc_dai *dai)
507{ 507{
508 struct snd_soc_pcm_runtime *rtd = substream->private_data; 508 struct snd_soc_codec *codec = dai->codec;
509 struct snd_soc_codec *codec = rtd->codec;
510 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 509 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
511 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 510 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
512 int i; 511 int i;
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 15d467ff91b4..0cfce9999c89 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1478,7 +1478,8 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1478 1478
1479static int wm8962_dsp2_write_config(struct snd_soc_codec *codec) 1479static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1480{ 1480{
1481 return 0; 1481 return regcache_sync_region(codec->control_data,
1482 WM8962_HDBASS_AI_1, WM8962_MAX_REGISTER);
1482} 1483}
1483 1484
1484static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val) 1485static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
@@ -1755,10 +1756,22 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
1755SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 1756SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
1756 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 1757 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
1757 1758
1759SOC_SINGLE("3D Switch", WM8962_THREED1, 0, 1, 0),
1760SND_SOC_BYTES_MASK("3D Coefficients", WM8962_THREED1, 4, WM8962_THREED_ENA),
1761
1762SOC_SINGLE("DF1 Switch", WM8962_DF1, 0, 1, 0),
1763SND_SOC_BYTES_MASK("DF1 Coefficients", WM8962_DF1, 7, WM8962_DF1_ENA),
1764
1765SOC_SINGLE("DRC Switch", WM8962_DRC_1, 0, 1, 0),
1766SND_SOC_BYTES_MASK("DRC Coefficients", WM8962_DRC_1, 5, WM8962_DRC_ENA),
1767
1758WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT), 1768WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
1769SND_SOC_BYTES("VSS Coefficients", WM8962_VSS_XHD2_1, 148),
1759WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT), 1770WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
1760WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT), 1771WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
1772SND_SOC_BYTES("HPF Coefficients", WM8962_LHPF2, 1),
1761WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT), 1773WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
1774SND_SOC_BYTES("HD Bass Coefficients", WM8962_HDBASS_AI_1, 30),
1762}; 1775};
1763 1776
1764static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 1777static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2519,8 +2532,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2519 struct snd_pcm_hw_params *params, 2532 struct snd_pcm_hw_params *params,
2520 struct snd_soc_dai *dai) 2533 struct snd_soc_dai *dai)
2521{ 2534{
2522 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2535 struct snd_soc_codec *codec = dai->codec;
2523 struct snd_soc_codec *codec = rtd->codec;
2524 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2536 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2525 int i; 2537 int i;
2526 int aif0 = 0; 2538 int aif0 = 0;
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 28fe59e3ce01..eef783f6b6d6 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -478,8 +478,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
478 struct snd_pcm_hw_params *params, 478 struct snd_pcm_hw_params *params,
479 struct snd_soc_dai *dai) 479 struct snd_soc_dai *dai)
480{ 480{
481 struct snd_soc_pcm_runtime *rtd = substream->private_data; 481 struct snd_soc_codec *codec = dai->codec;
482 struct snd_soc_codec *codec = rtd->codec;
483 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); 482 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
484 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 483 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
485 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 484 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 72d5fdcd3cc2..a5be3adecf75 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -723,8 +723,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
723 struct snd_pcm_hw_params *params, 723 struct snd_pcm_hw_params *params,
724 struct snd_soc_dai *dai) 724 struct snd_soc_dai *dai)
725{ 725{
726 struct snd_soc_pcm_runtime *rtd = substream->private_data; 726 struct snd_soc_codec *codec = dai->codec;
727 struct snd_soc_codec *codec = rtd->codec;
728 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 727 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
729 /* Word length mask = 0x60 */ 728 /* Word length mask = 0x60 */
730 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 729 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 6cdf6a2bc283..1d4c5cf47b06 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -668,8 +668,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
668 struct snd_pcm_hw_params *params, 668 struct snd_pcm_hw_params *params,
669 struct snd_soc_dai *dai) 669 struct snd_soc_dai *dai)
670{ 670{
671 struct snd_soc_pcm_runtime *rtd = substream->private_data; 671 struct snd_soc_codec *codec = dai->codec;
672 struct snd_soc_codec *codec = rtd->codec;
673 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 672 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
674 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; 673 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
675 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; 674 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 9d242351e6e8..db63c97ddf51 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1112,8 +1112,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1112 struct snd_pcm_hw_params *params, 1112 struct snd_pcm_hw_params *params,
1113 struct snd_soc_dai *dai) 1113 struct snd_soc_dai *dai)
1114{ 1114{
1115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1115 struct snd_soc_codec *codec = dai->codec;
1116 struct snd_soc_codec *codec = rtd->codec;
1117 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1); 1116 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1118 1117
1119 audio1 &= ~WM8990_AIF_WL_MASK; 1118 audio1 &= ~WM8990_AIF_WL_MASK;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 7c49642af052..44f72dc27711 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -689,6 +689,9 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
689 if (!wm8994->jackdet || !wm8994->jack_cb) 689 if (!wm8994->jackdet || !wm8994->jack_cb)
690 return; 690 return;
691 691
692 if (!wm8994->jackdet || !wm8994->jack_cb)
693 return;
694
692 if (wm8994->active_refcount) 695 if (wm8994->active_refcount)
693 mode = WM1811_JACKDET_MODE_AUDIO; 696 mode = WM1811_JACKDET_MODE_AUDIO;
694 697
@@ -1900,24 +1903,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1900 struct wm8994 *control = wm8994->wm8994; 1903 struct wm8994 *control = wm8994->wm8994;
1901 int reg_offset, ret; 1904 int reg_offset, ret;
1902 struct fll_div fll; 1905 struct fll_div fll;
1903 u16 reg, aif1, aif2; 1906 u16 reg, clk1, aif_reg, aif_src;
1904 unsigned long timeout; 1907 unsigned long timeout;
1905 bool was_enabled; 1908 bool was_enabled;
1906 1909
1907 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1908 & WM8994_AIF1CLK_ENA;
1909
1910 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
1911 & WM8994_AIF2CLK_ENA;
1912
1913 switch (id) { 1910 switch (id) {
1914 case WM8994_FLL1: 1911 case WM8994_FLL1:
1915 reg_offset = 0; 1912 reg_offset = 0;
1916 id = 0; 1913 id = 0;
1914 aif_src = 0x10;
1917 break; 1915 break;
1918 case WM8994_FLL2: 1916 case WM8994_FLL2:
1919 reg_offset = 0x20; 1917 reg_offset = 0x20;
1920 id = 1; 1918 id = 1;
1919 aif_src = 0x18;
1921 break; 1920 break;
1922 default: 1921 default:
1923 return -EINVAL; 1922 return -EINVAL;
@@ -1959,11 +1958,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1959 if (ret < 0) 1958 if (ret < 0)
1960 return ret; 1959 return ret;
1961 1960
1962 /* Gate the AIF clocks while we reclock */ 1961 /* Make sure that we're not providing SYSCLK right now */
1963 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, 1962 clk1 = snd_soc_read(codec, WM8994_CLOCKING_1);
1964 WM8994_AIF1CLK_ENA, 0); 1963 if (clk1 & WM8994_SYSCLK_SRC)
1965 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, 1964 aif_reg = WM8994_AIF2_CLOCKING_1;
1966 WM8994_AIF2CLK_ENA, 0); 1965 else
1966 aif_reg = WM8994_AIF1_CLOCKING_1;
1967 reg = snd_soc_read(codec, aif_reg);
1968
1969 if ((reg & WM8994_AIF1CLK_ENA) &&
1970 (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
1971 dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n",
1972 id + 1);
1973 return -EBUSY;
1974 }
1967 1975
1968 /* We always need to disable the FLL while reconfiguring */ 1976 /* We always need to disable the FLL while reconfiguring */
1969 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, 1977 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
@@ -2049,12 +2057,6 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2049 wm8994->fll[id].out = freq_out; 2057 wm8994->fll[id].out = freq_out;
2050 wm8994->fll[id].src = src; 2058 wm8994->fll[id].src = src;
2051 2059
2052 /* Enable any gated AIF clocks */
2053 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2054 WM8994_AIF1CLK_ENA, aif1);
2055 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2056 WM8994_AIF2CLK_ENA, aif2);
2057
2058 configure_clock(codec); 2060 configure_clock(codec);
2059 2061
2060 return 0; 2062 return 0;
@@ -2624,33 +2626,6 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2624 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2626 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2625} 2627}
2626 2628
2627static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2628 struct snd_soc_dai *dai)
2629{
2630 struct snd_soc_codec *codec = dai->codec;
2631 int rate_reg = 0;
2632
2633 switch (dai->id) {
2634 case 1:
2635 rate_reg = WM8994_AIF1_RATE;
2636 break;
2637 case 2:
2638 rate_reg = WM8994_AIF2_RATE;
2639 break;
2640 default:
2641 break;
2642 }
2643
2644 /* If the DAI is idle then configure the divider tree for the
2645 * lowest output rate to save a little power if the clock is
2646 * still active (eg, because it is system clock).
2647 */
2648 if (rate_reg && !dai->playback_active && !dai->capture_active)
2649 snd_soc_update_bits(codec, rate_reg,
2650 WM8994_AIF1_SR_MASK |
2651 WM8994_AIF1CLK_RATE_MASK, 0x9);
2652}
2653
2654static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2629static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
2655{ 2630{
2656 struct snd_soc_codec *codec = codec_dai->codec; 2631 struct snd_soc_codec *codec = codec_dai->codec;
@@ -2732,7 +2707,6 @@ static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
2732 .set_sysclk = wm8994_set_dai_sysclk, 2707 .set_sysclk = wm8994_set_dai_sysclk,
2733 .set_fmt = wm8994_set_dai_fmt, 2708 .set_fmt = wm8994_set_dai_fmt,
2734 .hw_params = wm8994_hw_params, 2709 .hw_params = wm8994_hw_params,
2735 .shutdown = wm8994_aif_shutdown,
2736 .digital_mute = wm8994_aif_mute, 2710 .digital_mute = wm8994_aif_mute,
2737 .set_pll = wm8994_set_fll, 2711 .set_pll = wm8994_set_fll,
2738 .set_tristate = wm8994_set_tristate, 2712 .set_tristate = wm8994_set_tristate,
@@ -2742,7 +2716,6 @@ static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
2742 .set_sysclk = wm8994_set_dai_sysclk, 2716 .set_sysclk = wm8994_set_dai_sysclk,
2743 .set_fmt = wm8994_set_dai_fmt, 2717 .set_fmt = wm8994_set_dai_fmt,
2744 .hw_params = wm8994_hw_params, 2718 .hw_params = wm8994_hw_params,
2745 .shutdown = wm8994_aif_shutdown,
2746 .digital_mute = wm8994_aif_mute, 2719 .digital_mute = wm8994_aif_mute,
2747 .set_pll = wm8994_set_fll, 2720 .set_pll = wm8994_set_fll,
2748 .set_tristate = wm8994_set_tristate, 2721 .set_tristate = wm8994_set_tristate,
@@ -3247,9 +3220,6 @@ static void wm8958_default_micdet(u16 status, void *data)
3247 3220
3248 wm8958_micd_set_rate(codec); 3221 wm8958_micd_set_rate(codec);
3249 3222
3250 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
3251 SND_JACK_HEADSET);
3252
3253 /* If we have jackdet that will detect removal */ 3223 /* If we have jackdet that will detect removal */
3254 if (wm8994->jackdet) { 3224 if (wm8994->jackdet) {
3255 mutex_lock(&wm8994->accdet_lock); 3225 mutex_lock(&wm8994->accdet_lock);
@@ -3262,14 +3232,13 @@ static void wm8958_default_micdet(u16 status, void *data)
3262 3232
3263 mutex_unlock(&wm8994->accdet_lock); 3233 mutex_unlock(&wm8994->accdet_lock);
3264 3234
3265 if (wm8994->pdata->jd_ext_cap) { 3235 if (wm8994->pdata->jd_ext_cap)
3266 mutex_lock(&codec->mutex);
3267 snd_soc_dapm_disable_pin(&codec->dapm, 3236 snd_soc_dapm_disable_pin(&codec->dapm,
3268 "MICBIAS2"); 3237 "MICBIAS2");
3269 snd_soc_dapm_sync(&codec->dapm);
3270 mutex_unlock(&codec->mutex);
3271 }
3272 } 3238 }
3239
3240 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
3241 SND_JACK_HEADSET);
3273 } 3242 }
3274 3243
3275 /* Report short circuit as a button */ 3244 /* Report short circuit as a button */
@@ -3358,16 +3327,11 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3358 3327
3359 /* If required for an external cap force MICBIAS on */ 3328 /* If required for an external cap force MICBIAS on */
3360 if (wm8994->pdata->jd_ext_cap) { 3329 if (wm8994->pdata->jd_ext_cap) {
3361 mutex_lock(&codec->mutex);
3362
3363 if (present) 3330 if (present)
3364 snd_soc_dapm_force_enable_pin(&codec->dapm, 3331 snd_soc_dapm_force_enable_pin(&codec->dapm,
3365 "MICBIAS2"); 3332 "MICBIAS2");
3366 else 3333 else
3367 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); 3334 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3368
3369 snd_soc_dapm_sync(&codec->dapm);
3370 mutex_unlock(&codec->mutex);
3371 } 3335 }
3372 3336
3373 if (present) 3337 if (present)
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index cacc6a86b46f..7c095939c179 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -236,9 +236,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
236static int ac97_prepare(struct snd_pcm_substream *substream, 236static int ac97_prepare(struct snd_pcm_substream *substream,
237 struct snd_soc_dai *dai) 237 struct snd_soc_dai *dai)
238{ 238{
239 struct snd_pcm_runtime *runtime = substream->runtime; 239 struct snd_soc_codec *codec = dai->codec;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct snd_soc_codec *codec = rtd->codec;
242 int reg; 240 int reg;
243 u16 vra; 241 u16 vra;
244 242
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index b342ae50bcd6..260386365d58 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -467,9 +467,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
467static int ac97_prepare(struct snd_pcm_substream *substream, 467static int ac97_prepare(struct snd_pcm_substream *substream,
468 struct snd_soc_dai *dai) 468 struct snd_soc_dai *dai)
469{ 469{
470 struct snd_pcm_runtime *runtime = substream->runtime; 470 struct snd_soc_codec *codec = dai->codec;
471 struct snd_soc_pcm_runtime *rtd = substream->private_data;
472 struct snd_soc_codec *codec =rtd->codec;
473 int reg; 471 int reg;
474 u16 vra; 472 u16 vra;
475 473
@@ -487,9 +485,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
487static int ac97_aux_prepare(struct snd_pcm_substream *substream, 485static int ac97_aux_prepare(struct snd_pcm_substream *substream,
488 struct snd_soc_dai *dai) 486 struct snd_soc_dai *dai)
489{ 487{
490 struct snd_pcm_runtime *runtime = substream->runtime; 488 struct snd_soc_codec *codec = dai->codec;
491 struct snd_soc_pcm_runtime *rtd = substream->private_data;
492 struct snd_soc_codec *codec = rtd->codec;
493 u16 vra, xsle; 489 u16 vra, xsle;
494 490
495 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 491 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 0678637abd66..bdffab33e160 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -87,17 +87,13 @@
87 * struct ep93xx_ac97_info - EP93xx AC97 controller info structure 87 * struct ep93xx_ac97_info - EP93xx AC97 controller info structure
88 * @lock: mutex serializing access to the bus (slot 1 & 2 ops) 88 * @lock: mutex serializing access to the bus (slot 1 & 2 ops)
89 * @dev: pointer to the platform device dev structure 89 * @dev: pointer to the platform device dev structure
90 * @mem: physical memory resource for the registers
91 * @regs: mapped AC97 controller registers 90 * @regs: mapped AC97 controller registers
92 * @irq: AC97 interrupt number
93 * @done: bus ops wait here for an interrupt 91 * @done: bus ops wait here for an interrupt
94 */ 92 */
95struct ep93xx_ac97_info { 93struct ep93xx_ac97_info {
96 struct mutex lock; 94 struct mutex lock;
97 struct device *dev; 95 struct device *dev;
98 struct resource *mem;
99 void __iomem *regs; 96 void __iomem *regs;
100 int irq;
101 struct completion done; 97 struct completion done;
102}; 98};
103 99
@@ -359,66 +355,50 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = {
359static int __devinit ep93xx_ac97_probe(struct platform_device *pdev) 355static int __devinit ep93xx_ac97_probe(struct platform_device *pdev)
360{ 356{
361 struct ep93xx_ac97_info *info; 357 struct ep93xx_ac97_info *info;
358 struct resource *res;
359 unsigned int irq;
362 int ret; 360 int ret;
363 361
364 info = kzalloc(sizeof(struct ep93xx_ac97_info), GFP_KERNEL); 362 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
365 if (!info) 363 if (!info)
366 return -ENOMEM; 364 return -ENOMEM;
367 365
368 dev_set_drvdata(&pdev->dev, info); 366 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
369 367 if (!res)
370 mutex_init(&info->lock); 368 return -ENODEV;
371 init_completion(&info->done);
372 info->dev = &pdev->dev;
373 369
374 info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 370 info->regs = devm_request_and_ioremap(&pdev->dev, res);
375 if (!info->mem) { 371 if (!info->regs)
376 ret = -ENXIO; 372 return -ENXIO;
377 goto fail_free_info;
378 }
379 373
380 info->irq = platform_get_irq(pdev, 0); 374 irq = platform_get_irq(pdev, 0);
381 if (!info->irq) { 375 if (!irq)
382 ret = -ENXIO; 376 return -ENODEV;
383 goto fail_free_info;
384 }
385 377
386 if (!request_mem_region(info->mem->start, resource_size(info->mem), 378 ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt,
387 pdev->name)) { 379 IRQF_TRIGGER_HIGH, pdev->name, info);
388 ret = -EBUSY; 380 if (ret)
389 goto fail_free_info; 381 goto fail;
390 }
391 382
392 info->regs = ioremap(info->mem->start, resource_size(info->mem)); 383 dev_set_drvdata(&pdev->dev, info);
393 if (!info->regs) {
394 ret = -ENOMEM;
395 goto fail_release_mem;
396 }
397 384
398 ret = request_irq(info->irq, ep93xx_ac97_interrupt, IRQF_TRIGGER_HIGH, 385 mutex_init(&info->lock);
399 pdev->name, info); 386 init_completion(&info->done);
400 if (ret) 387 info->dev = &pdev->dev;
401 goto fail_unmap_mem;
402 388
403 ep93xx_ac97_info = info; 389 ep93xx_ac97_info = info;
404 platform_set_drvdata(pdev, info); 390 platform_set_drvdata(pdev, info);
405 391
406 ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai); 392 ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai);
407 if (ret) 393 if (ret)
408 goto fail_free_irq; 394 goto fail;
409 395
410 return 0; 396 return 0;
411 397
412fail_free_irq: 398fail:
413 platform_set_drvdata(pdev, NULL); 399 platform_set_drvdata(pdev, NULL);
414 free_irq(info->irq, info); 400 ep93xx_ac97_info = NULL;
415fail_unmap_mem: 401 dev_set_drvdata(&pdev->dev, NULL);
416 iounmap(info->regs);
417fail_release_mem:
418 release_mem_region(info->mem->start, resource_size(info->mem));
419fail_free_info:
420 kfree(info);
421
422 return ret; 402 return ret;
423} 403}
424 404
@@ -431,11 +411,9 @@ static int __devexit ep93xx_ac97_remove(struct platform_device *pdev)
431 /* disable the AC97 controller */ 411 /* disable the AC97 controller */
432 ep93xx_ac97_write_reg(info, AC97GCR, 0); 412 ep93xx_ac97_write_reg(info, AC97GCR, 0);
433 413
434 free_irq(info->irq, info);
435 iounmap(info->regs);
436 release_mem_region(info->mem->start, resource_size(info->mem));
437 platform_set_drvdata(pdev, NULL); 414 platform_set_drvdata(pdev, NULL);
438 kfree(info); 415 ep93xx_ac97_info = NULL;
416 dev_set_drvdata(&pdev->dev, NULL);
439 417
440 return 0; 418 return 0;
441} 419}
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index f7a62348e3fe..8df8f6dc474f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -63,7 +63,6 @@ struct ep93xx_i2s_info {
63 struct clk *sclk; 63 struct clk *sclk;
64 struct clk *lrclk; 64 struct clk *lrclk;
65 struct ep93xx_pcm_dma_params *dma_params; 65 struct ep93xx_pcm_dma_params *dma_params;
66 struct resource *mem;
67 void __iomem *regs; 66 void __iomem *regs;
68}; 67};
69 68
@@ -373,38 +372,22 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
373 struct resource *res; 372 struct resource *res;
374 int err; 373 int err;
375 374
376 info = kzalloc(sizeof(struct ep93xx_i2s_info), GFP_KERNEL); 375 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
377 if (!info) { 376 if (!info)
378 err = -ENOMEM; 377 return -ENOMEM;
379 goto fail;
380 }
381
382 dev_set_drvdata(&pdev->dev, info);
383 info->dma_params = ep93xx_i2s_dma_params;
384 378
385 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 379 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
386 if (!res) { 380 if (!res)
387 err = -ENODEV; 381 return -ENODEV;
388 goto fail_free_info;
389 }
390 382
391 info->mem = request_mem_region(res->start, resource_size(res), 383 info->regs = devm_request_and_ioremap(&pdev->dev, res);
392 pdev->name); 384 if (!info->regs)
393 if (!info->mem) { 385 return -ENXIO;
394 err = -EBUSY;
395 goto fail_free_info;
396 }
397
398 info->regs = ioremap(info->mem->start, resource_size(info->mem));
399 if (!info->regs) {
400 err = -ENXIO;
401 goto fail_release_mem;
402 }
403 386
404 info->mclk = clk_get(&pdev->dev, "mclk"); 387 info->mclk = clk_get(&pdev->dev, "mclk");
405 if (IS_ERR(info->mclk)) { 388 if (IS_ERR(info->mclk)) {
406 err = PTR_ERR(info->mclk); 389 err = PTR_ERR(info->mclk);
407 goto fail_unmap_mem; 390 goto fail;
408 } 391 }
409 392
410 info->sclk = clk_get(&pdev->dev, "sclk"); 393 info->sclk = clk_get(&pdev->dev, "sclk");
@@ -419,6 +402,9 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
419 goto fail_put_sclk; 402 goto fail_put_sclk;
420 } 403 }
421 404
405 dev_set_drvdata(&pdev->dev, info);
406 info->dma_params = ep93xx_i2s_dma_params;
407
422 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); 408 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai);
423 if (err) 409 if (err)
424 goto fail_put_lrclk; 410 goto fail_put_lrclk;
@@ -426,17 +412,12 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
426 return 0; 412 return 0;
427 413
428fail_put_lrclk: 414fail_put_lrclk:
415 dev_set_drvdata(&pdev->dev, NULL);
429 clk_put(info->lrclk); 416 clk_put(info->lrclk);
430fail_put_sclk: 417fail_put_sclk:
431 clk_put(info->sclk); 418 clk_put(info->sclk);
432fail_put_mclk: 419fail_put_mclk:
433 clk_put(info->mclk); 420 clk_put(info->mclk);
434fail_unmap_mem:
435 iounmap(info->regs);
436fail_release_mem:
437 release_mem_region(info->mem->start, resource_size(info->mem));
438fail_free_info:
439 kfree(info);
440fail: 421fail:
441 return err; 422 return err;
442} 423}
@@ -446,12 +427,10 @@ static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
446 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 427 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
447 428
448 snd_soc_unregister_dai(&pdev->dev); 429 snd_soc_unregister_dai(&pdev->dev);
430 dev_set_drvdata(&pdev->dev, NULL);
449 clk_put(info->lrclk); 431 clk_put(info->lrclk);
450 clk_put(info->sclk); 432 clk_put(info->sclk);
451 clk_put(info->mclk); 433 clk_put(info->mclk);
452 iounmap(info->regs);
453 release_mem_region(info->mem->start, resource_size(info->mem));
454 kfree(info);
455 return 0; 434 return 0;
456} 435}
457 436
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d754d34d68a6..0094789c43ff 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,18 +1,31 @@
1config SND_MPC52xx_DMA 1config SND_SOC_FSL_SSI
2 tristate 2 tristate
3 3
4# ASoC platform support for the Freescale PowerPC SOCs that have an SSI and 4config SND_SOC_FSL_UTILS
5# an Elo DMA controller, such as the MPC8610 and P1022. You will still need to
6# select a platform driver and a codec driver.
7config SND_SOC_POWERPC_SSI
8 tristate 5 tristate
6
7menuconfig SND_POWERPC_SOC
8 tristate "SoC Audio for Freescale PowerPC CPUs"
9 depends on FSL_SOC 9 depends on FSL_SOC
10 help
11 Say Y or M if you want to add support for codecs attached to
12 the PowerPC CPUs.
13
14if SND_POWERPC_SOC
15
16config SND_MPC52xx_DMA
17 tristate
18
19config SND_SOC_POWERPC_DMA
20 tristate
10 21
11config SND_SOC_MPC8610_HPCD 22config SND_SOC_MPC8610_HPCD
12 tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" 23 tristate "ALSA SoC support for the Freescale MPC8610 HPCD board"
13 # I2C is necessary for the CS4270 driver 24 # I2C is necessary for the CS4270 driver
14 depends on MPC8610_HPCD && I2C 25 depends on MPC8610_HPCD && I2C
15 select SND_SOC_POWERPC_SSI 26 select SND_SOC_FSL_SSI
27 select SND_SOC_FSL_UTILS
28 select SND_SOC_POWERPC_DMA
16 select SND_SOC_CS4270 29 select SND_SOC_CS4270
17 select SND_SOC_CS4270_VD33_ERRATA 30 select SND_SOC_CS4270_VD33_ERRATA
18 default y if MPC8610_HPCD 31 default y if MPC8610_HPCD
@@ -23,7 +36,9 @@ config SND_SOC_P1022_DS
23 tristate "ALSA SoC support for the Freescale P1022 DS board" 36 tristate "ALSA SoC support for the Freescale P1022 DS board"
24 # I2C is necessary for the WM8776 driver 37 # I2C is necessary for the WM8776 driver
25 depends on P1022_DS && I2C 38 depends on P1022_DS && I2C
26 select SND_SOC_POWERPC_SSI 39 select SND_SOC_FSL_SSI
40 select SND_SOC_FSL_UTILS
41 select SND_SOC_POWERPC_DMA
27 select SND_SOC_WM8776 42 select SND_SOC_WM8776
28 default y if P1022_DS 43 default y if P1022_DS
29 help 44 help
@@ -65,3 +80,95 @@ config SND_MPC52xx_SOC_EFIKA
65 help 80 help
66 Say Y if you want to add support for sound on the Efika. 81 Say Y if you want to add support for sound on the Efika.
67 82
83endif # SND_POWERPC_SOC
84
85menuconfig SND_IMX_SOC
86 tristate "SoC Audio for Freescale i.MX CPUs"
87 depends on ARCH_MXC
88 help
89 Say Y or M if you want to add support for codecs attached to
90 the i.MX CPUs.
91
92if SND_IMX_SOC
93
94config SND_SOC_IMX_SSI
95 tristate
96
97config SND_SOC_IMX_PCM
98 tristate
99
100config SND_SOC_IMX_PCM_FIQ
101 tristate
102 select FIQ
103 select SND_SOC_IMX_PCM
104
105config SND_SOC_IMX_PCM_DMA
106 tristate
107 select SND_SOC_DMAENGINE_PCM
108 select SND_SOC_IMX_PCM
109
110config SND_SOC_IMX_AUDMUX
111 tristate
112
113config SND_MXC_SOC_WM1133_EV1
114 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
115 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
116 select SND_SOC_WM8350
117 select SND_SOC_IMX_PCM_FIQ
118 select SND_SOC_IMX_AUDMUX
119 select SND_SOC_IMX_SSI
120 help
121 Enable support for audio on the i.MX31ADS with the WM1133-EV1
122 PMIC board with WM8835x fitted.
123
124config SND_SOC_MX27VIS_AIC32X4
125 tristate "SoC audio support for Visstrim M10 boards"
126 depends on MACH_IMX27_VISSTRIM_M10 && I2C
127 select SND_SOC_TLV320AIC32X4
128 select SND_SOC_IMX_PCM_DMA
129 select SND_SOC_IMX_AUDMUX
130 select SND_SOC_IMX_SSI
131 help
132 Say Y if you want to add support for SoC audio on Visstrim SM10
133 board with TLV320AIC32X4 codec.
134
135config SND_SOC_PHYCORE_AC97
136 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
137 depends on MACH_PCM043 || MACH_PCA100
138 select SND_SOC_AC97_BUS
139 select SND_SOC_WM9712
140 select SND_SOC_IMX_PCM_FIQ
141 select SND_SOC_IMX_AUDMUX
142 select SND_SOC_IMX_SSI
143 help
144 Say Y if you want to add support for SoC audio on Phytec phyCORE
145 and phyCARD boards in AC97 mode
146
147config SND_SOC_EUKREA_TLV320
148 tristate "Eukrea TLV320"
149 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
150 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
151 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
152 || MACH_EUKREA_MBIMXSD51_BASEBOARD
153 depends on I2C
154 select SND_SOC_TLV320AIC23
155 select SND_SOC_IMX_PCM_FIQ
156 select SND_SOC_IMX_AUDMUX
157 select SND_SOC_IMX_SSI
158 help
159 Enable I2S based access to the TLV320AIC23B codec attached
160 to the SSI interface
161
162config SND_SOC_IMX_SGTL5000
163 tristate "SoC Audio support for i.MX boards with sgtl5000"
164 depends on OF && I2C
165 select SND_SOC_SGTL5000
166 select SND_SOC_IMX_PCM_DMA
167 select SND_SOC_IMX_AUDMUX
168 select SND_SOC_FSL_SSI
169 select SND_SOC_FSL_UTILS
170 help
171 Say Y if you want to add support for SoC audio on an i.MX board with
172 a sgtl5000 codec.
173
174endif # SND_IMX_SOC
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b4a38c0ac58c..638d3852601a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -8,8 +8,11 @@ obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
8 8
9# Freescale PowerPC SSI/DMA Platform Support 9# Freescale PowerPC SSI/DMA Platform Support
10snd-soc-fsl-ssi-objs := fsl_ssi.o 10snd-soc-fsl-ssi-objs := fsl_ssi.o
11snd-soc-fsl-utils-objs := fsl_utils.o
11snd-soc-fsl-dma-objs := fsl_dma.o 12snd-soc-fsl-dma-objs := fsl_dma.o
12obj-$(CONFIG_SND_SOC_POWERPC_SSI) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o 13obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
14obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
15obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
13 16
14# MPC5200 Platform Support 17# MPC5200 Platform Support
15obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o 18obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
@@ -20,3 +23,27 @@ obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
20obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o 23obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
21obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o 24obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
22 25
26# i.MX Platform Support
27snd-soc-imx-ssi-objs := imx-ssi.o
28snd-soc-imx-audmux-objs := imx-audmux.o
29
30obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
31obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
32
33obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
34snd-soc-imx-pcm-y := imx-pcm.o
35snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
36snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
37
38# i.MX Machine Support
39snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
40snd-soc-phycore-ac97-objs := phycore-ac97.o
41snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
42snd-soc-wm1133-ev1-objs := wm1133-ev1.o
43snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
44
45obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
46obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
47obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
48obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
49obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 7d4475cfdb24..efb9ede01208 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -7,7 +7,7 @@
7 * which is Copyright 2009 Simtec Electronics 7 * which is Copyright 2009 Simtec Electronics
8 * and on sound/soc/imx/phycore-ac97.c which is 8 * and on sound/soc/imx/phycore-ac97.c which is
9 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 9 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
10 * 10 *
11 * 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
12 * 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
13 * 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
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2eb407fa3b48..4ed2afd47782 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -11,11 +11,15 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/clk.h>
16#include <linux/device.h> 18#include <linux/device.h>
17#include <linux/delay.h> 19#include <linux/delay.h>
18#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
19#include <linux/of_platform.h> 23#include <linux/of_platform.h>
20 24
21#include <sound/core.h> 25#include <sound/core.h>
@@ -25,6 +29,26 @@
25#include <sound/soc.h> 29#include <sound/soc.h>
26 30
27#include "fsl_ssi.h" 31#include "fsl_ssi.h"
32#include "imx-pcm.h"
33
34#ifdef PPC
35#define read_ssi(addr) in_be32(addr)
36#define write_ssi(val, addr) out_be32(addr, val)
37#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set)
38#elif defined ARM
39#define read_ssi(addr) readl(addr)
40#define write_ssi(val, addr) writel(val, addr)
41/*
42 * FIXME: Proper locking should be added at write_ssi_mask caller level
43 * to ensure this register read/modify/write sequence is race free.
44 */
45static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
46{
47 u32 val = readl(addr);
48 val = (val & ~clear) | set;
49 writel(val, addr);
50}
51#endif
28 52
29/** 53/**
30 * FSLSSI_I2S_RATES: sample rates supported by the I2S 54 * FSLSSI_I2S_RATES: sample rates supported by the I2S
@@ -94,6 +118,13 @@ struct fsl_ssi_private {
94 struct device_attribute dev_attr; 118 struct device_attribute dev_attr;
95 struct platform_device *pdev; 119 struct platform_device *pdev;
96 120
121 bool new_binding;
122 bool ssi_on_imx;
123 struct clk *clk;
124 struct platform_device *imx_pcm_pdev;
125 struct imx_pcm_dma_params dma_params_tx;
126 struct imx_pcm_dma_params dma_params_rx;
127
97 struct { 128 struct {
98 unsigned int rfrc; 129 unsigned int rfrc;
99 unsigned int tfrc; 130 unsigned int tfrc;
@@ -145,7 +176,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
145 were interrupted for. We mask it with the Interrupt Enable register 176 were interrupted for. We mask it with the Interrupt Enable register
146 so that we only check for events that we're interested in. 177 so that we only check for events that we're interested in.
147 */ 178 */
148 sisr = in_be32(&ssi->sisr) & SIER_FLAGS; 179 sisr = read_ssi(&ssi->sisr) & SIER_FLAGS;
149 180
150 if (sisr & CCSR_SSI_SISR_RFRC) { 181 if (sisr & CCSR_SSI_SISR_RFRC) {
151 ssi_private->stats.rfrc++; 182 ssi_private->stats.rfrc++;
@@ -260,7 +291,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
260 291
261 /* Clear the bits that we set */ 292 /* Clear the bits that we set */
262 if (sisr2) 293 if (sisr2)
263 out_be32(&ssi->sisr, sisr2); 294 write_ssi(sisr2, &ssi->sisr);
264 295
265 return ret; 296 return ret;
266} 297}
@@ -295,7 +326,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
295 * SSI needs to be disabled before updating the registers we set 326 * SSI needs to be disabled before updating the registers we set
296 * here. 327 * here.
297 */ 328 */
298 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 329 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
299 330
300 /* 331 /*
301 * Program the SSI into I2S Slave Non-Network Synchronous mode. 332 * Program the SSI into I2S Slave Non-Network Synchronous mode.
@@ -303,20 +334,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
303 * 334 *
304 * FIXME: Little-endian samples require a different shift dir 335 * FIXME: Little-endian samples require a different shift dir
305 */ 336 */
306 clrsetbits_be32(&ssi->scr, 337 write_ssi_mask(&ssi->scr,
307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 338 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 339 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
309 | (synchronous ? CCSR_SSI_SCR_SYN : 0)); 340 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
310 341
311 out_be32(&ssi->stcr, 342 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
313 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 343 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
314 CCSR_SSI_STCR_TSCKP); 344 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
315 345
316 out_be32(&ssi->srcr, 346 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
317 CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
318 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS | 347 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
319 CCSR_SSI_SRCR_RSCKP); 348 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
320 349
321 /* 350 /*
322 * The DC and PM bits are only used if the SSI is the clock 351 * The DC and PM bits are only used if the SSI is the clock
@@ -324,7 +353,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
324 */ 353 */
325 354
326 /* Enable the interrupts and DMA requests */ 355 /* Enable the interrupts and DMA requests */
327 out_be32(&ssi->sier, SIER_FLAGS); 356 write_ssi(SIER_FLAGS, &ssi->sier);
328 357
329 /* 358 /*
330 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We 359 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -339,9 +368,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
339 * make this value larger (and maybe we should), but this way 368 * make this value larger (and maybe we should), but this way
340 * data will be written to memory as soon as it's available. 369 * data will be written to memory as soon as it's available.
341 */ 370 */
342 out_be32(&ssi->sfcsr, 371 write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
343 CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) | 372 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
344 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2)); 373 &ssi->sfcsr);
345 374
346 /* 375 /*
347 * We keep the SSI disabled because if we enable it, then the 376 * We keep the SSI disabled because if we enable it, then the
@@ -393,6 +422,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
393 ssi_private->second_stream = substream; 422 ssi_private->second_stream = substream;
394 } 423 }
395 424
425 if (ssi_private->ssi_on_imx)
426 snd_soc_dai_set_dma_data(dai, substream,
427 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
428 &ssi_private->dma_params_tx :
429 &ssi_private->dma_params_rx);
430
396 return 0; 431 return 0;
397} 432}
398 433
@@ -417,7 +452,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
417 unsigned int sample_size = 452 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params)); 453 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 454 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN; 455 int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
421 456
422 /* 457 /*
423 * If we're in synchronous mode, and the SSI is already enabled, 458 * If we're in synchronous mode, and the SSI is already enabled,
@@ -439,9 +474,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
439 /* In synchronous mode, the SSI uses STCCR for capture */ 474 /* In synchronous mode, the SSI uses STCCR for capture */
440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 475 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
441 ssi_private->cpu_dai_drv.symmetric_rates) 476 ssi_private->cpu_dai_drv.symmetric_rates)
442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); 477 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
443 else 478 else
444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); 479 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
445 480
446 return 0; 481 return 0;
447} 482}
@@ -466,19 +501,19 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
466 case SNDRV_PCM_TRIGGER_START: 501 case SNDRV_PCM_TRIGGER_START:
467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 502 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 503 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
469 setbits32(&ssi->scr, 504 write_ssi_mask(&ssi->scr, 0,
470 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 505 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
471 else 506 else
472 setbits32(&ssi->scr, 507 write_ssi_mask(&ssi->scr, 0,
473 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 508 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
474 break; 509 break;
475 510
476 case SNDRV_PCM_TRIGGER_STOP: 511 case SNDRV_PCM_TRIGGER_STOP:
477 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 512 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
478 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 514 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0);
480 else 515 else
481 clrbits32(&ssi->scr, CCSR_SSI_SCR_RE); 516 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
482 break; 517 break;
483 518
484 default: 519 default:
@@ -510,7 +545,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 if (!ssi_private->first_stream) { 545 if (!ssi_private->first_stream) {
511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 546 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
512 547
513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 548 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
514 } 549 }
515} 550}
516 551
@@ -622,12 +657,6 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
622 if (!of_device_is_available(np)) 657 if (!of_device_is_available(np))
623 return -ENODEV; 658 return -ENODEV;
624 659
625 /* Check for a codec-handle property. */
626 if (!of_get_property(np, "codec-handle", NULL)) {
627 dev_err(&pdev->dev, "missing codec-handle property\n");
628 return -ENODEV;
629 }
630
631 /* We only support the SSI in "I2S Slave" mode */ 660 /* We only support the SSI in "I2S Slave" mode */
632 sprop = of_get_property(np, "fsl,mode", NULL); 661 sprop = of_get_property(np, "fsl,mode", NULL);
633 if (!sprop || strcmp(sprop, "i2s-slave")) { 662 if (!sprop || strcmp(sprop, "i2s-slave")) {
@@ -692,6 +721,50 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
692 /* Older 8610 DTs didn't have the fifo-depth property */ 721 /* Older 8610 DTs didn't have the fifo-depth property */
693 ssi_private->fifo_depth = 8; 722 ssi_private->fifo_depth = 8;
694 723
724 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
725 u32 dma_events[2];
726 ssi_private->ssi_on_imx = true;
727
728 ssi_private->clk = clk_get(&pdev->dev, NULL);
729 if (IS_ERR(ssi_private->clk)) {
730 ret = PTR_ERR(ssi_private->clk);
731 dev_err(&pdev->dev, "could not get clock: %d\n", ret);
732 goto error_irq;
733 }
734 clk_prepare_enable(ssi_private->clk);
735
736 /*
737 * We have burstsize be "fifo_depth - 2" to match the SSI
738 * watermark setting in fsl_ssi_startup().
739 */
740 ssi_private->dma_params_tx.burstsize =
741 ssi_private->fifo_depth - 2;
742 ssi_private->dma_params_rx.burstsize =
743 ssi_private->fifo_depth - 2;
744 ssi_private->dma_params_tx.dma_addr =
745 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
746 ssi_private->dma_params_rx.dma_addr =
747 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
748 /*
749 * TODO: This is a temporary solution and should be changed
750 * to use generic DMA binding later when the helplers get in.
751 */
752 ret = of_property_read_u32_array(pdev->dev.of_node,
753 "fsl,ssi-dma-events", dma_events, 2);
754 if (ret) {
755 dev_err(&pdev->dev, "could not get dma events\n");
756 goto error_clk;
757 }
758 ssi_private->dma_params_tx.dma = dma_events[0];
759 ssi_private->dma_params_rx.dma = dma_events[1];
760
761 ssi_private->dma_params_tx.shared_peripheral =
762 of_device_is_compatible(of_get_parent(np),
763 "fsl,spba-bus");
764 ssi_private->dma_params_rx.shared_peripheral =
765 ssi_private->dma_params_tx.shared_peripheral;
766 }
767
695 /* Initialize the the device_attribute structure */ 768 /* Initialize the the device_attribute structure */
696 dev_attr = &ssi_private->dev_attr; 769 dev_attr = &ssi_private->dev_attr;
697 sysfs_attr_init(&dev_attr->attr); 770 sysfs_attr_init(&dev_attr->attr);
@@ -715,6 +788,26 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
715 goto error_dev; 788 goto error_dev;
716 } 789 }
717 790
791 if (ssi_private->ssi_on_imx) {
792 ssi_private->imx_pcm_pdev =
793 platform_device_register_simple("imx-pcm-audio",
794 -1, NULL, 0);
795 if (IS_ERR(ssi_private->imx_pcm_pdev)) {
796 ret = PTR_ERR(ssi_private->imx_pcm_pdev);
797 goto error_dev;
798 }
799 }
800
801 /*
802 * If codec-handle property is missing from SSI node, we assume
803 * that the machine driver uses new binding which does not require
804 * SSI driver to trigger machine driver's probe.
805 */
806 if (!of_get_property(np, "codec-handle", NULL)) {
807 ssi_private->new_binding = true;
808 goto done;
809 }
810
718 /* Trigger the machine driver's probe function. The platform driver 811 /* Trigger the machine driver's probe function. The platform driver
719 * name of the machine driver is taken from /compatible property of the 812 * name of the machine driver is taken from /compatible property of the
720 * device tree. We also pass the address of the CPU DAI driver 813 * device tree. We also pass the address of the CPU DAI driver
@@ -736,15 +829,24 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
736 goto error_dai; 829 goto error_dai;
737 } 830 }
738 831
832done:
739 return 0; 833 return 0;
740 834
741error_dai: 835error_dai:
836 if (ssi_private->ssi_on_imx)
837 platform_device_unregister(ssi_private->imx_pcm_pdev);
742 snd_soc_unregister_dai(&pdev->dev); 838 snd_soc_unregister_dai(&pdev->dev);
743 839
744error_dev: 840error_dev:
745 dev_set_drvdata(&pdev->dev, NULL); 841 dev_set_drvdata(&pdev->dev, NULL);
746 device_remove_file(&pdev->dev, dev_attr); 842 device_remove_file(&pdev->dev, dev_attr);
747 843
844error_clk:
845 if (ssi_private->ssi_on_imx) {
846 clk_disable_unprepare(ssi_private->clk);
847 clk_put(ssi_private->clk);
848 }
849
748error_irq: 850error_irq:
749 free_irq(ssi_private->irq, ssi_private); 851 free_irq(ssi_private->irq, ssi_private);
750 852
@@ -764,7 +866,13 @@ static int fsl_ssi_remove(struct platform_device *pdev)
764{ 866{
765 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 867 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
766 868
767 platform_device_unregister(ssi_private->pdev); 869 if (!ssi_private->new_binding)
870 platform_device_unregister(ssi_private->pdev);
871 if (ssi_private->ssi_on_imx) {
872 platform_device_unregister(ssi_private->imx_pcm_pdev);
873 clk_disable_unprepare(ssi_private->clk);
874 clk_put(ssi_private->clk);
875 }
768 snd_soc_unregister_dai(&pdev->dev); 876 snd_soc_unregister_dai(&pdev->dev);
769 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 877 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
770 878
@@ -779,6 +887,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
779 887
780static const struct of_device_id fsl_ssi_ids[] = { 888static const struct of_device_id fsl_ssi_ids[] = {
781 { .compatible = "fsl,mpc8610-ssi", }, 889 { .compatible = "fsl,mpc8610-ssi", },
890 { .compatible = "fsl,imx21-ssi", },
782 {} 891 {}
783}; 892};
784MODULE_DEVICE_TABLE(of, fsl_ssi_ids); 893MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c
new file mode 100644
index 000000000000..b9e42b503a37
--- /dev/null
+++ b/sound/soc/fsl/fsl_utils.c
@@ -0,0 +1,91 @@
1/**
2 * Freescale ALSA SoC Machine driver utility
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2010 Freescale Semiconductor, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/module.h>
14#include <linux/of_address.h>
15#include <sound/soc.h>
16
17#include "fsl_utils.h"
18
19/**
20 * fsl_asoc_get_dma_channel - determine the dma channel for a SSI node
21 *
22 * @ssi_np: pointer to the SSI device tree node
23 * @name: name of the phandle pointing to the dma channel
24 * @dai: ASoC DAI link pointer to be filled with platform_name
25 * @dma_channel_id: dma channel id to be returned
26 * @dma_id: dma id to be returned
27 *
28 * This function determines the dma and channel id for given SSI node. It
29 * also discovers the platform_name for the ASoC DAI link.
30 */
31int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
32 const char *name,
33 struct snd_soc_dai_link *dai,
34 unsigned int *dma_channel_id,
35 unsigned int *dma_id)
36{
37 struct resource res;
38 struct device_node *dma_channel_np, *dma_np;
39 const u32 *iprop;
40 int ret;
41
42 dma_channel_np = of_parse_phandle(ssi_np, name, 0);
43 if (!dma_channel_np)
44 return -EINVAL;
45
46 if (!of_device_is_compatible(dma_channel_np, "fsl,ssi-dma-channel")) {
47 of_node_put(dma_channel_np);
48 return -EINVAL;
49 }
50
51 /* Determine the dev_name for the device_node. This code mimics the
52 * behavior of of_device_make_bus_id(). We need this because ASoC uses
53 * the dev_name() of the device to match the platform (DMA) device with
54 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
55 * now).
56 *
57 * dai->platform name should already point to an allocated buffer.
58 */
59 ret = of_address_to_resource(dma_channel_np, 0, &res);
60 if (ret) {
61 of_node_put(dma_channel_np);
62 return ret;
63 }
64 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
65 (unsigned long long) res.start, dma_channel_np->name);
66
67 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
68 if (!iprop) {
69 of_node_put(dma_channel_np);
70 return -EINVAL;
71 }
72 *dma_channel_id = be32_to_cpup(iprop);
73
74 dma_np = of_get_parent(dma_channel_np);
75 iprop = of_get_property(dma_np, "cell-index", NULL);
76 if (!iprop) {
77 of_node_put(dma_np);
78 return -EINVAL;
79 }
80 *dma_id = be32_to_cpup(iprop);
81
82 of_node_put(dma_np);
83 of_node_put(dma_channel_np);
84
85 return 0;
86}
87EXPORT_SYMBOL(fsl_asoc_get_dma_channel);
88
89MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
90MODULE_DESCRIPTION("Freescale ASoC utility code");
91MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h
new file mode 100644
index 000000000000..b2951126527c
--- /dev/null
+++ b/sound/soc/fsl/fsl_utils.h
@@ -0,0 +1,26 @@
1/**
2 * Freescale ALSA SoC Machine driver utility
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2010 Freescale Semiconductor, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef _FSL_UTILS_H
14#define _FSL_UTILS_H
15
16#define DAI_NAME_SIZE 32
17
18struct snd_soc_dai_link;
19struct device_node;
20
21int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name,
22 struct snd_soc_dai_link *dai,
23 unsigned int *dma_channel_id,
24 unsigned int *dma_id);
25
26#endif /* _FSL_UTILS_H */
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 1765a197acb0..1765a197acb0 100644
--- a/sound/soc/imx/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
diff --git a/sound/soc/imx/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index 04ebbab8d7b9..04ebbab8d7b9 100644
--- a/sound/soc/imx/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/fsl/imx-pcm-dma.c
index 6b818de2fc03..f3c0a5ef35c8 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -109,7 +109,8 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
110 110
111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); 111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
112 dma_data->peripheral_type = IMX_DMATYPE_SSI; 112 dma_data->peripheral_type = dma_params->shared_peripheral ?
113 IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
113 dma_data->priority = DMA_PRIO_HIGH; 114 dma_data->priority = DMA_PRIO_HIGH;
114 dma_data->dma_request = dma_params->dma; 115 dma_data->dma_request = dma_params->dma;
115 116
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 456b7d723d66..456b7d723d66 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
index 93dc360b1777..93dc360b1777 100644
--- a/sound/soc/imx/imx-pcm.c
+++ b/sound/soc/fsl/imx-pcm.c
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index b5f5c3acf34d..83c0ed7d55c9 100644
--- a/sound/soc/imx/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -22,6 +22,7 @@ struct imx_pcm_dma_params {
22 int dma; 22 int dma;
23 unsigned long dma_addr; 23 unsigned long dma_addr;
24 int burstsize; 24 int burstsize;
25 bool shared_peripheral; /* The peripheral is on SPBA bus */
25}; 26};
26 27
27int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 28int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
new file mode 100644
index 000000000000..e1a7441ec133
--- /dev/null
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -0,0 +1,190 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_platform.h>
16#include <sound/soc.h>
17
18#include "../codecs/sgtl5000.h"
19#include "imx-audmux.h"
20
21#define DAI_NAME_SIZE 32
22
23struct imx_sgtl5000_data {
24 struct snd_soc_dai_link dai;
25 struct snd_soc_card card;
26 char codec_dai_name[DAI_NAME_SIZE];
27 char platform_name[DAI_NAME_SIZE];
28 unsigned int clk_frequency;
29};
30
31static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
32{
33 struct imx_sgtl5000_data *data = container_of(rtd->card,
34 struct imx_sgtl5000_data, card);
35 struct device *dev = rtd->card->dev;
36 int ret;
37
38 ret = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK,
39 data->clk_frequency, SND_SOC_CLOCK_IN);
40 if (ret) {
41 dev_err(dev, "could not set codec driver clock params\n");
42 return ret;
43 }
44
45 return 0;
46}
47
48static const struct snd_soc_dapm_widget imx_sgtl5000_dapm_widgets[] = {
49 SND_SOC_DAPM_MIC("Mic Jack", NULL),
50 SND_SOC_DAPM_LINE("Line In Jack", NULL),
51 SND_SOC_DAPM_HP("Headphone Jack", NULL),
52 SND_SOC_DAPM_SPK("Line Out Jack", NULL),
53 SND_SOC_DAPM_SPK("Ext Spk", NULL),
54};
55
56static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
57{
58 struct device_node *np = pdev->dev.of_node;
59 struct device_node *ssi_np, *codec_np;
60 struct platform_device *ssi_pdev;
61 struct imx_sgtl5000_data *data;
62 int int_port, ext_port;
63 int ret;
64
65 ret = of_property_read_u32(np, "mux-int-port", &int_port);
66 if (ret) {
67 dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
68 return ret;
69 }
70 ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
71 if (ret) {
72 dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
73 return ret;
74 }
75
76 /*
77 * The port numbering in the hardware manual starts at 1, while
78 * the audmux API expects it starts at 0.
79 */
80 int_port--;
81 ext_port--;
82 ret = imx_audmux_v2_configure_port(int_port,
83 IMX_AUDMUX_V2_PTCR_SYN |
84 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
85 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
86 IMX_AUDMUX_V2_PTCR_TFSDIR |
87 IMX_AUDMUX_V2_PTCR_TCLKDIR,
88 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
89 if (ret) {
90 dev_err(&pdev->dev, "audmux internal port setup failed\n");
91 return ret;
92 }
93 imx_audmux_v2_configure_port(ext_port,
94 IMX_AUDMUX_V2_PTCR_SYN |
95 IMX_AUDMUX_V2_PTCR_TCSEL(int_port),
96 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
97 if (ret) {
98 dev_err(&pdev->dev, "audmux external port setup failed\n");
99 return ret;
100 }
101
102 ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
103 codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
104 if (!ssi_np || !codec_np) {
105 dev_err(&pdev->dev, "phandle missing or invalid\n");
106 return -EINVAL;
107 }
108
109 ssi_pdev = of_find_device_by_node(ssi_np);
110 if (!ssi_pdev) {
111 dev_err(&pdev->dev, "failed to find SSI platform device\n");
112 return -EINVAL;
113 }
114
115 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
116 if (!data)
117 return -ENOMEM;
118
119 ret = of_property_read_u32(codec_np, "clock-frequency",
120 &data->clk_frequency);
121 if (ret) {
122 dev_err(&pdev->dev, "clock-frequency missing or invalid\n");
123 return ret;
124 }
125
126 data->dai.name = "HiFi";
127 data->dai.stream_name = "HiFi";
128 data->dai.codec_dai_name = "sgtl5000";
129 data->dai.codec_of_node = codec_np;
130 data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
131 data->dai.platform_name = "imx-pcm-audio";
132 data->dai.init = &imx_sgtl5000_dai_init;
133 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
134 SND_SOC_DAIFMT_CBM_CFM;
135
136 data->card.dev = &pdev->dev;
137 ret = snd_soc_of_parse_card_name(&data->card, "model");
138 if (ret)
139 return ret;
140 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
141 if (ret)
142 return ret;
143 data->card.num_links = 1;
144 data->card.dai_link = &data->dai;
145 data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
146 data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
147
148 ret = snd_soc_register_card(&data->card);
149 if (ret) {
150 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
151 return ret;
152 }
153
154 platform_set_drvdata(pdev, data);
155 of_node_put(ssi_np);
156 of_node_put(codec_np);
157
158 return 0;
159}
160
161static int __devexit imx_sgtl5000_remove(struct platform_device *pdev)
162{
163 struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
164
165 snd_soc_unregister_card(&data->card);
166
167 return 0;
168}
169
170static const struct of_device_id imx_sgtl5000_dt_ids[] = {
171 { .compatible = "fsl,imx-audio-sgtl5000", },
172 { /* sentinel */ }
173};
174MODULE_DEVICE_TABLE(of, imx_sgtl5000_dt_ids);
175
176static struct platform_driver imx_sgtl5000_driver = {
177 .driver = {
178 .name = "imx-sgtl5000",
179 .owner = THIS_MODULE,
180 .of_match_table = imx_sgtl5000_dt_ids,
181 },
182 .probe = imx_sgtl5000_probe,
183 .remove = __devexit_p(imx_sgtl5000_remove),
184};
185module_platform_driver(imx_sgtl5000_driver);
186
187MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
188MODULE_DESCRIPTION("Freescale i.MX SGTL5000 ASoC machine driver");
189MODULE_LICENSE("GPL v2");
190MODULE_ALIAS("platform:imx-sgtl5000");
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 4f81ed456325..cf3ed0362c9c 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -28,7 +28,7 @@
28 * value. When we read the same register two times (and the register still 28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work 29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay. 30 * around this by not polling these bits but only wait a fixed delay.
31 * 31 *
32 */ 32 */
33 33
34#include <linux/clk.h> 34#include <linux/clk.h>
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index 5744e86ca878..5744e86ca878 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 3fea5a15ffe8..60bcba1bc30e 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -14,18 +14,16 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/of_i2c.h>
18#include <sound/soc.h> 17#include <sound/soc.h>
19#include <asm/fsl_guts.h> 18#include <asm/fsl_guts.h>
20 19
21#include "fsl_dma.h" 20#include "fsl_dma.h"
22#include "fsl_ssi.h" 21#include "fsl_ssi.h"
22#include "fsl_utils.h"
23 23
24/* There's only one global utilities register */ 24/* There's only one global utilities register */
25static phys_addr_t guts_phys; 25static phys_addr_t guts_phys;
26 26
27#define DAI_NAME_SIZE 32
28
29/** 27/**
30 * mpc8610_hpcd_data: machine-specific ASoC device data 28 * mpc8610_hpcd_data: machine-specific ASoC device data
31 * 29 *
@@ -43,7 +41,6 @@ struct mpc8610_hpcd_data {
43 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ 41 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
44 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ 42 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
45 char codec_dai_name[DAI_NAME_SIZE]; 43 char codec_dai_name[DAI_NAME_SIZE];
46 char codec_name[DAI_NAME_SIZE];
47 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ 44 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
48}; 45};
49 46
@@ -181,141 +178,6 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
181}; 178};
182 179
183/** 180/**
184 * get_node_by_phandle_name - get a node by its phandle name
185 *
186 * This function takes a node, the name of a property in that node, and a
187 * compatible string. Assuming the property is a phandle to another node,
188 * it returns that node, (optionally) if that node is compatible.
189 *
190 * If the property is not a phandle, or the node it points to is not compatible
191 * with the specific string, then NULL is returned.
192 */
193static struct device_node *get_node_by_phandle_name(struct device_node *np,
194 const char *name,
195 const char *compatible)
196{
197 const phandle *ph;
198 int len;
199
200 ph = of_get_property(np, name, &len);
201 if (!ph || (len != sizeof(phandle)))
202 return NULL;
203
204 np = of_find_node_by_phandle(*ph);
205 if (!np)
206 return NULL;
207
208 if (compatible && !of_device_is_compatible(np, compatible)) {
209 of_node_put(np);
210 return NULL;
211 }
212
213 return np;
214}
215
216/**
217 * get_parent_cell_index -- return the cell-index of the parent of a node
218 *
219 * Return the value of the cell-index property of the parent of the given
220 * node. This is used for DMA channel nodes that need to know the DMA ID
221 * of the controller they are on.
222 */
223static int get_parent_cell_index(struct device_node *np)
224{
225 struct device_node *parent = of_get_parent(np);
226 const u32 *iprop;
227
228 if (!parent)
229 return -1;
230
231 iprop = of_get_property(parent, "cell-index", NULL);
232 of_node_put(parent);
233
234 if (!iprop)
235 return -1;
236
237 return be32_to_cpup(iprop);
238}
239
240/**
241 * codec_node_dev_name - determine the dev_name for a codec node
242 *
243 * This function determines the dev_name for an I2C node. This is the name
244 * that would be returned by dev_name() if this device_node were part of a
245 * 'struct device' It's ugly and hackish, but it works.
246 *
247 * The dev_name for such devices include the bus number and I2C address. For
248 * example, "cs4270.0-004f".
249 */
250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
251{
252 const u32 *iprop;
253 int addr;
254 char temp[DAI_NAME_SIZE];
255 struct i2c_client *i2c;
256
257 of_modalias_node(np, temp, DAI_NAME_SIZE);
258
259 iprop = of_get_property(np, "reg", NULL);
260 if (!iprop)
261 return -EINVAL;
262
263 addr = be32_to_cpup(iprop);
264
265 /* We need the adapter number */
266 i2c = of_find_i2c_device_by_node(np);
267 if (!i2c)
268 return -ENODEV;
269
270 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
271
272 return 0;
273}
274
275static int get_dma_channel(struct device_node *ssi_np,
276 const char *name,
277 struct snd_soc_dai_link *dai,
278 unsigned int *dma_channel_id,
279 unsigned int *dma_id)
280{
281 struct resource res;
282 struct device_node *dma_channel_np;
283 const u32 *iprop;
284 int ret;
285
286 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
287 "fsl,ssi-dma-channel");
288 if (!dma_channel_np)
289 return -EINVAL;
290
291 /* Determine the dev_name for the device_node. This code mimics the
292 * behavior of of_device_make_bus_id(). We need this because ASoC uses
293 * the dev_name() of the device to match the platform (DMA) device with
294 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
295 * now).
296 *
297 * dai->platform name should already point to an allocated buffer.
298 */
299 ret = of_address_to_resource(dma_channel_np, 0, &res);
300 if (ret)
301 return ret;
302 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
303 (unsigned long long) res.start, dma_channel_np->name);
304
305 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
306 if (!iprop) {
307 of_node_put(dma_channel_np);
308 return -EINVAL;
309 }
310
311 *dma_channel_id = be32_to_cpup(iprop);
312 *dma_id = get_parent_cell_index(dma_channel_np);
313 of_node_put(dma_channel_np);
314
315 return 0;
316}
317
318/**
319 * mpc8610_hpcd_probe: platform probe function for the machine driver 181 * mpc8610_hpcd_probe: platform probe function for the machine driver
320 * 182 *
321 * Although this is a machine driver, the SSI node is the "master" node with 183 * Although this is a machine driver, the SSI node is the "master" node with
@@ -352,16 +214,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
352 machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); 214 machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
353 machine_data->dai[0].ops = &mpc8610_hpcd_ops; 215 machine_data->dai[0].ops = &mpc8610_hpcd_ops;
354 216
355 /* Determine the codec name, it will be used as the codec DAI name */ 217 /* ASoC core can match codec with device node */
356 ret = codec_node_dev_name(codec_np, machine_data->codec_name, 218 machine_data->dai[0].codec_of_node = codec_np;
357 DAI_NAME_SIZE);
358 if (ret) {
359 dev_err(&pdev->dev, "invalid codec node %s\n",
360 codec_np->full_name);
361 ret = -EINVAL;
362 goto error;
363 }
364 machine_data->dai[0].codec_name = machine_data->codec_name;
365 219
366 /* The DAI name from the codec (snd_soc_dai_driver.name) */ 220 /* The DAI name from the codec (snd_soc_dai_driver.name) */
367 machine_data->dai[0].codec_dai_name = "cs4270-hifi"; 221 machine_data->dai[0].codec_dai_name = "cs4270-hifi";
@@ -458,9 +312,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
458 312
459 /* Find the playback DMA channel to use. */ 313 /* Find the playback DMA channel to use. */
460 machine_data->dai[0].platform_name = machine_data->platform_name[0]; 314 machine_data->dai[0].platform_name = machine_data->platform_name[0];
461 ret = get_dma_channel(np, "fsl,playback-dma", &machine_data->dai[0], 315 ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma",
462 &machine_data->dma_channel_id[0], 316 &machine_data->dai[0],
463 &machine_data->dma_id[0]); 317 &machine_data->dma_channel_id[0],
318 &machine_data->dma_id[0]);
464 if (ret) { 319 if (ret) {
465 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n"); 320 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
466 goto error; 321 goto error;
@@ -468,9 +323,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
468 323
469 /* Find the capture DMA channel to use. */ 324 /* Find the capture DMA channel to use. */
470 machine_data->dai[1].platform_name = machine_data->platform_name[1]; 325 machine_data->dai[1].platform_name = machine_data->platform_name[1];
471 ret = get_dma_channel(np, "fsl,capture-dma", &machine_data->dai[1], 326 ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma",
472 &machine_data->dma_channel_id[1], 327 &machine_data->dai[1],
473 &machine_data->dma_id[1]); 328 &machine_data->dma_channel_id[1],
329 &machine_data->dma_id[1]);
474 if (ret) { 330 if (ret) {
475 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n"); 331 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
476 goto error; 332 goto error;
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index f6d04ad4bb39..f6d04ad4bb39 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 982a1c944983..50adf4032bcc 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -14,12 +14,12 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/of_i2c.h>
18#include <sound/soc.h> 17#include <sound/soc.h>
19#include <asm/fsl_guts.h> 18#include <asm/fsl_guts.h>
20 19
21#include "fsl_dma.h" 20#include "fsl_dma.h"
22#include "fsl_ssi.h" 21#include "fsl_ssi.h"
22#include "fsl_utils.h"
23 23
24/* P1022-specific PMUXCR and DMUXCR bit definitions */ 24/* P1022-specific PMUXCR and DMUXCR bit definitions */
25 25
@@ -57,8 +57,6 @@ static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
57/* There's only one global utilities register */ 57/* There's only one global utilities register */
58static phys_addr_t guts_phys; 58static phys_addr_t guts_phys;
59 59
60#define DAI_NAME_SIZE 32
61
62/** 60/**
63 * machine_data: machine-specific ASoC device data 61 * machine_data: machine-specific ASoC device data
64 * 62 *
@@ -75,7 +73,6 @@ struct machine_data {
75 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */ 73 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
76 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ 74 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
77 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ 75 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
78 char codec_name[DAI_NAME_SIZE];
79 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ 76 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
80}; 77};
81 78
@@ -191,136 +188,6 @@ static struct snd_soc_ops p1022_ds_ops = {
191}; 188};
192 189
193/** 190/**
194 * get_node_by_phandle_name - get a node by its phandle name
195 *
196 * This function takes a node, the name of a property in that node, and a
197 * compatible string. Assuming the property is a phandle to another node,
198 * it returns that node, (optionally) if that node is compatible.
199 *
200 * If the property is not a phandle, or the node it points to is not compatible
201 * with the specific string, then NULL is returned.
202 */
203static struct device_node *get_node_by_phandle_name(struct device_node *np,
204 const char *name, const char *compatible)
205{
206 np = of_parse_phandle(np, name, 0);
207 if (!np)
208 return NULL;
209
210 if (!of_device_is_compatible(np, compatible)) {
211 of_node_put(np);
212 return NULL;
213 }
214
215 return np;
216}
217
218/**
219 * get_parent_cell_index -- return the cell-index of the parent of a node
220 *
221 * Return the value of the cell-index property of the parent of the given
222 * node. This is used for DMA channel nodes that need to know the DMA ID
223 * of the controller they are on.
224 */
225static int get_parent_cell_index(struct device_node *np)
226{
227 struct device_node *parent = of_get_parent(np);
228 const u32 *iprop;
229 int ret = -1;
230
231 if (!parent)
232 return -1;
233
234 iprop = of_get_property(parent, "cell-index", NULL);
235 if (iprop)
236 ret = be32_to_cpup(iprop);
237
238 of_node_put(parent);
239
240 return ret;
241}
242
243/**
244 * codec_node_dev_name - determine the dev_name for a codec node
245 *
246 * This function determines the dev_name for an I2C node. This is the name
247 * that would be returned by dev_name() if this device_node were part of a
248 * 'struct device' It's ugly and hackish, but it works.
249 *
250 * The dev_name for such devices include the bus number and I2C address. For
251 * example, "cs4270-codec.0-004f".
252 */
253static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
254{
255 const u32 *iprop;
256 int addr;
257 char temp[DAI_NAME_SIZE];
258 struct i2c_client *i2c;
259
260 of_modalias_node(np, temp, DAI_NAME_SIZE);
261
262 iprop = of_get_property(np, "reg", NULL);
263 if (!iprop)
264 return -EINVAL;
265
266 addr = be32_to_cpup(iprop);
267
268 /* We need the adapter number */
269 i2c = of_find_i2c_device_by_node(np);
270 if (!i2c)
271 return -ENODEV;
272
273 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
274
275 return 0;
276}
277
278static int get_dma_channel(struct device_node *ssi_np,
279 const char *name,
280 struct snd_soc_dai_link *dai,
281 unsigned int *dma_channel_id,
282 unsigned int *dma_id)
283{
284 struct resource res;
285 struct device_node *dma_channel_np;
286 const u32 *iprop;
287 int ret;
288
289 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
290 "fsl,ssi-dma-channel");
291 if (!dma_channel_np)
292 return -EINVAL;
293
294 /* Determine the dev_name for the device_node. This code mimics the
295 * behavior of of_device_make_bus_id(). We need this because ASoC uses
296 * the dev_name() of the device to match the platform (DMA) device with
297 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
298 * now).
299 *
300 * dai->platform name should already point to an allocated buffer.
301 */
302 ret = of_address_to_resource(dma_channel_np, 0, &res);
303 if (ret) {
304 of_node_put(dma_channel_np);
305 return ret;
306 }
307 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
308 (unsigned long long) res.start, dma_channel_np->name);
309
310 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
311 if (!iprop) {
312 of_node_put(dma_channel_np);
313 return -EINVAL;
314 }
315
316 *dma_channel_id = be32_to_cpup(iprop);
317 *dma_id = get_parent_cell_index(dma_channel_np);
318 of_node_put(dma_channel_np);
319
320 return 0;
321}
322
323/**
324 * p1022_ds_probe: platform probe function for the machine driver 191 * p1022_ds_probe: platform probe function for the machine driver
325 * 192 *
326 * Although this is a machine driver, the SSI node is the "master" node with 193 * Although this is a machine driver, the SSI node is the "master" node with
@@ -357,15 +224,8 @@ static int p1022_ds_probe(struct platform_device *pdev)
357 mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); 224 mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
358 mdata->dai[0].ops = &p1022_ds_ops; 225 mdata->dai[0].ops = &p1022_ds_ops;
359 226
360 /* Determine the codec name, it will be used as the codec DAI name */ 227 /* ASoC core can match codec with device node */
361 ret = codec_node_dev_name(codec_np, mdata->codec_name, DAI_NAME_SIZE); 228 mdata->dai[0].codec_of_node = codec_np;
362 if (ret) {
363 dev_err(&pdev->dev, "invalid codec node %s\n",
364 codec_np->full_name);
365 ret = -EINVAL;
366 goto error;
367 }
368 mdata->dai[0].codec_name = mdata->codec_name;
369 229
370 /* We register two DAIs per SSI, one for playback and the other for 230 /* We register two DAIs per SSI, one for playback and the other for
371 * capture. We support codecs that have separate DAIs for both playback 231 * capture. We support codecs that have separate DAIs for both playback
@@ -462,9 +322,9 @@ static int p1022_ds_probe(struct platform_device *pdev)
462 322
463 /* Find the playback DMA channel to use. */ 323 /* Find the playback DMA channel to use. */
464 mdata->dai[0].platform_name = mdata->platform_name[0]; 324 mdata->dai[0].platform_name = mdata->platform_name[0];
465 ret = get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0], 325 ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
466 &mdata->dma_channel_id[0], 326 &mdata->dma_channel_id[0],
467 &mdata->dma_id[0]); 327 &mdata->dma_id[0]);
468 if (ret) { 328 if (ret) {
469 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n"); 329 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
470 goto error; 330 goto error;
@@ -472,9 +332,9 @@ static int p1022_ds_probe(struct platform_device *pdev)
472 332
473 /* Find the capture DMA channel to use. */ 333 /* Find the capture DMA channel to use. */
474 mdata->dai[1].platform_name = mdata->platform_name[1]; 334 mdata->dai[1].platform_name = mdata->platform_name[1];
475 ret = get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1], 335 ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
476 &mdata->dma_channel_id[1], 336 &mdata->dma_channel_id[1],
477 &mdata->dma_id[1]); 337 &mdata->dma_id[1]);
478 if (ret) { 338 if (ret) {
479 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n"); 339 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
480 goto error; 340 goto error;
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index f8da6dd115ed..f8da6dd115ed 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index fe54a69073e5..fe54a69073e5 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
deleted file mode 100644
index 810acaa09009..000000000000
--- a/sound/soc/imx/Kconfig
+++ /dev/null
@@ -1,79 +0,0 @@
1menuconfig SND_IMX_SOC
2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MXC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the i.MX SSI interface.
7
8
9if SND_IMX_SOC
10
11config SND_SOC_IMX_SSI
12 tristate
13
14config SND_SOC_IMX_PCM
15 tristate
16
17config SND_MXC_SOC_FIQ
18 tristate
19 select FIQ
20 select SND_SOC_IMX_PCM
21
22config SND_MXC_SOC_MX2
23 select SND_SOC_DMAENGINE_PCM
24 tristate
25 select SND_SOC_IMX_PCM
26
27config SND_SOC_IMX_AUDMUX
28 tristate
29
30config SND_MXC_SOC_WM1133_EV1
31 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
32 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
33 select SND_SOC_WM8350
34 select SND_MXC_SOC_FIQ
35 select SND_SOC_IMX_AUDMUX
36 select SND_SOC_IMX_SSI
37 help
38 Enable support for audio on the i.MX31ADS with the WM1133-EV1
39 PMIC board with WM8835x fitted.
40
41config SND_SOC_MX27VIS_AIC32X4
42 tristate "SoC audio support for Visstrim M10 boards"
43 depends on MACH_IMX27_VISSTRIM_M10 && I2C
44 select SND_SOC_TLV320AIC32X4
45 select SND_MXC_SOC_MX2
46 select SND_SOC_IMX_AUDMUX
47 select SND_SOC_IMX_SSI
48 help
49 Say Y if you want to add support for SoC audio on Visstrim SM10
50 board with TLV320AIC32X4 codec.
51
52config SND_SOC_PHYCORE_AC97
53 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
54 depends on MACH_PCM043 || MACH_PCA100
55 select SND_SOC_AC97_BUS
56 select SND_SOC_WM9712
57 select SND_MXC_SOC_FIQ
58 select SND_SOC_IMX_AUDMUX
59 select SND_SOC_IMX_SSI
60 help
61 Say Y if you want to add support for SoC audio on Phytec phyCORE
62 and phyCARD boards in AC97 mode
63
64config SND_SOC_EUKREA_TLV320
65 tristate "Eukrea TLV320"
66 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
67 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
68 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
69 || MACH_EUKREA_MBIMXSD51_BASEBOARD
70 depends on I2C
71 select SND_SOC_TLV320AIC23
72 select SND_MXC_SOC_FIQ
73 select SND_SOC_IMX_AUDMUX
74 select SND_SOC_IMX_SSI
75 help
76 Enable I2S based access to the TLV320AIC23B codec attached
77 to the SSI interface
78
79endif # SND_IMX_SOC
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
deleted file mode 100644
index f5db3e92d0d1..000000000000
--- a/sound/soc/imx/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
1# i.MX Platform Support
2snd-soc-imx-ssi-objs := imx-ssi.o
3snd-soc-imx-audmux-objs := imx-audmux.o
4
5obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
6obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
7
8obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
9snd-soc-imx-pcm-y := imx-pcm.o
10snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
11snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
12
13# i.MX Machine Support
14snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
15snd-soc-phycore-ac97-objs := phycore-ac97.o
16snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
17snd-soc-wm1133-ev1-objs := wm1133-ev1.o
18
19obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
20obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
21obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
22obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index a5af7c42e62b..41349670adab 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -346,7 +346,7 @@ static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
346 346
347 /* Playback */ 347 /* Playback */
348 dma_config = &i2s->pcm_config_playback.dma_config; 348 dma_config = &i2s->pcm_config_playback.dma_config;
349 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT, 349 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT;
350 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 350 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
351 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; 351 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
352 dma_config->flags = JZ4740_DMA_SRC_AUTOINC; 352 dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
@@ -355,7 +355,7 @@ static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
355 355
356 /* Capture */ 356 /* Capture */
357 dma_config = &i2s->pcm_config_capture.dma_config; 357 dma_config = &i2s->pcm_config_capture.dma_config;
358 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT, 358 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT;
359 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 359 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
360 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; 360 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
361 dma_config->flags = JZ4740_DMA_DST_AUTOINC; 361 dma_config->flags = JZ4740_DMA_DST_AUTOINC;
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 609abd51e55f..453b0925a0b5 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -165,7 +165,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
165 struct pxa2xx_pcm_dma_params *dma_data; 165 struct pxa2xx_pcm_dma_params *dma_data;
166 166
167 BUG_ON(IS_ERR(clk_i2s)); 167 BUG_ON(IS_ERR(clk_i2s));
168 clk_enable(clk_i2s); 168 clk_prepare_enable(clk_i2s);
169 clk_ena = 1; 169 clk_ena = 1;
170 pxa_i2s_wait(); 170 pxa_i2s_wait();
171 171
@@ -258,7 +258,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
258 SACR0 &= ~SACR0_ENB; 258 SACR0 &= ~SACR0_ENB;
259 pxa_i2s_wait(); 259 pxa_i2s_wait();
260 if (clk_ena) { 260 if (clk_ena) {
261 clk_disable(clk_i2s); 261 clk_disable_unprepare(clk_i2s);
262 clk_ena = 0; 262 clk_ena = 0;
263 } 263 }
264 } 264 }
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e19c24ade414..8a17048dba42 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -54,7 +54,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
54#endif 54#endif
55 55
56static DEFINE_MUTEX(client_mutex); 56static DEFINE_MUTEX(client_mutex);
57static LIST_HEAD(card_list);
58static LIST_HEAD(dai_list); 57static LIST_HEAD(dai_list);
59static LIST_HEAD(platform_list); 58static LIST_HEAD(platform_list);
60static LIST_HEAD(codec_list); 59static LIST_HEAD(codec_list);
@@ -567,19 +566,16 @@ int snd_soc_suspend(struct device *dev)
567 } 566 }
568 567
569 for (i = 0; i < card->num_rtd; i++) { 568 for (i = 0; i < card->num_rtd; i++) {
570 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
571 569
572 if (card->rtd[i].dai_link->ignore_suspend) 570 if (card->rtd[i].dai_link->ignore_suspend)
573 continue; 571 continue;
574 572
575 snd_soc_dapm_stream_event(&card->rtd[i], 573 snd_soc_dapm_stream_event(&card->rtd[i],
576 SNDRV_PCM_STREAM_PLAYBACK, 574 SNDRV_PCM_STREAM_PLAYBACK,
577 codec_dai,
578 SND_SOC_DAPM_STREAM_SUSPEND); 575 SND_SOC_DAPM_STREAM_SUSPEND);
579 576
580 snd_soc_dapm_stream_event(&card->rtd[i], 577 snd_soc_dapm_stream_event(&card->rtd[i],
581 SNDRV_PCM_STREAM_CAPTURE, 578 SNDRV_PCM_STREAM_CAPTURE,
582 codec_dai,
583 SND_SOC_DAPM_STREAM_SUSPEND); 579 SND_SOC_DAPM_STREAM_SUSPEND);
584 } 580 }
585 581
@@ -683,17 +679,16 @@ static void soc_resume_deferred(struct work_struct *work)
683 } 679 }
684 680
685 for (i = 0; i < card->num_rtd; i++) { 681 for (i = 0; i < card->num_rtd; i++) {
686 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
687 682
688 if (card->rtd[i].dai_link->ignore_suspend) 683 if (card->rtd[i].dai_link->ignore_suspend)
689 continue; 684 continue;
690 685
691 snd_soc_dapm_stream_event(&card->rtd[i], 686 snd_soc_dapm_stream_event(&card->rtd[i],
692 SNDRV_PCM_STREAM_PLAYBACK, codec_dai, 687 SNDRV_PCM_STREAM_PLAYBACK,
693 SND_SOC_DAPM_STREAM_RESUME); 688 SND_SOC_DAPM_STREAM_RESUME);
694 689
695 snd_soc_dapm_stream_event(&card->rtd[i], 690 snd_soc_dapm_stream_event(&card->rtd[i],
696 SNDRV_PCM_STREAM_CAPTURE, codec_dai, 691 SNDRV_PCM_STREAM_CAPTURE,
697 SND_SOC_DAPM_STREAM_RESUME); 692 SND_SOC_DAPM_STREAM_RESUME);
698 } 693 }
699 694
@@ -783,15 +778,9 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
783 struct snd_soc_dai *codec_dai, *cpu_dai; 778 struct snd_soc_dai *codec_dai, *cpu_dai;
784 const char *platform_name; 779 const char *platform_name;
785 780
786 if (rtd->complete)
787 return 1;
788 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); 781 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
789 782
790 /* do we already have the CPU DAI for this link ? */ 783 /* Find CPU DAI from registered DAIs*/
791 if (rtd->cpu_dai) {
792 goto find_codec;
793 }
794 /* no, then find CPU DAI from registered DAIs*/
795 list_for_each_entry(cpu_dai, &dai_list, list) { 784 list_for_each_entry(cpu_dai, &dai_list, list) {
796 if (dai_link->cpu_dai_of_node) { 785 if (dai_link->cpu_dai_of_node) {
797 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 786 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
@@ -802,18 +791,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
802 } 791 }
803 792
804 rtd->cpu_dai = cpu_dai; 793 rtd->cpu_dai = cpu_dai;
805 goto find_codec;
806 } 794 }
807 dev_dbg(card->dev, "CPU DAI %s not registered\n",
808 dai_link->cpu_dai_name);
809 795
810find_codec: 796 if (!rtd->cpu_dai) {
811 /* do we already have the CODEC for this link ? */ 797 dev_dbg(card->dev, "CPU DAI %s not registered\n",
812 if (rtd->codec) { 798 dai_link->cpu_dai_name);
813 goto find_platform; 799 return -EPROBE_DEFER;
814 } 800 }
815 801
816 /* no, then find CODEC from registered CODECs*/ 802 /* Find CODEC from registered CODECs */
817 list_for_each_entry(codec, &codec_list, list) { 803 list_for_each_entry(codec, &codec_list, list) {
818 if (dai_link->codec_of_node) { 804 if (dai_link->codec_of_node) {
819 if (codec->dev->of_node != dai_link->codec_of_node) 805 if (codec->dev->of_node != dai_link->codec_of_node)
@@ -835,28 +821,28 @@ find_codec:
835 dai_link->codec_dai_name)) { 821 dai_link->codec_dai_name)) {
836 822
837 rtd->codec_dai = codec_dai; 823 rtd->codec_dai = codec_dai;
838 goto find_platform;
839 } 824 }
840 } 825 }
841 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
842 dai_link->codec_dai_name);
843 826
844 goto find_platform; 827 if (!rtd->codec_dai) {
828 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
829 dai_link->codec_dai_name);
830 return -EPROBE_DEFER;
831 }
845 } 832 }
846 dev_dbg(card->dev, "CODEC %s not registered\n",
847 dai_link->codec_name);
848 833
849find_platform: 834 if (!rtd->codec) {
850 /* do we need a platform? */ 835 dev_dbg(card->dev, "CODEC %s not registered\n",
851 if (rtd->platform) 836 dai_link->codec_name);
852 goto out; 837 return -EPROBE_DEFER;
838 }
853 839
854 /* if there's no platform we match on the empty platform */ 840 /* if there's no platform we match on the empty platform */
855 platform_name = dai_link->platform_name; 841 platform_name = dai_link->platform_name;
856 if (!platform_name && !dai_link->platform_of_node) 842 if (!platform_name && !dai_link->platform_of_node)
857 platform_name = "snd-soc-dummy"; 843 platform_name = "snd-soc-dummy";
858 844
859 /* no, then find one from the set of registered platforms */ 845 /* find one from the set of registered platforms */
860 list_for_each_entry(platform, &platform_list, list) { 846 list_for_each_entry(platform, &platform_list, list) {
861 if (dai_link->platform_of_node) { 847 if (dai_link->platform_of_node) {
862 if (platform->dev->of_node != 848 if (platform->dev->of_node !=
@@ -868,20 +854,16 @@ find_platform:
868 } 854 }
869 855
870 rtd->platform = platform; 856 rtd->platform = platform;
871 goto out;
872 } 857 }
873 858 if (!rtd->platform) {
874 dev_dbg(card->dev, "platform %s not registered\n", 859 dev_dbg(card->dev, "platform %s not registered\n",
875 dai_link->platform_name); 860 dai_link->platform_name);
876 return 0; 861 return -EPROBE_DEFER;
877
878out:
879 /* mark rtd as complete if we found all 4 of our client devices */
880 if (rtd->codec && rtd->codec_dai && rtd->platform && rtd->cpu_dai) {
881 rtd->complete = 1;
882 card->num_rtd++;
883 } 862 }
884 return 1; 863
864 card->num_rtd++;
865
866 return 0;
885} 867}
886 868
887static void soc_remove_codec(struct snd_soc_codec *codec) 869static void soc_remove_codec(struct snd_soc_codec *codec)
@@ -1068,6 +1050,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1068{ 1050{
1069 int ret = 0; 1051 int ret = 0;
1070 const struct snd_soc_platform_driver *driver = platform->driver; 1052 const struct snd_soc_platform_driver *driver = platform->driver;
1053 struct snd_soc_dai *dai;
1071 1054
1072 platform->card = card; 1055 platform->card = card;
1073 platform->dapm.card = card; 1056 platform->dapm.card = card;
@@ -1081,6 +1064,14 @@ static int soc_probe_platform(struct snd_soc_card *card,
1081 snd_soc_dapm_new_controls(&platform->dapm, 1064 snd_soc_dapm_new_controls(&platform->dapm,
1082 driver->dapm_widgets, driver->num_dapm_widgets); 1065 driver->dapm_widgets, driver->num_dapm_widgets);
1083 1066
1067 /* Create DAPM widgets for each DAI stream */
1068 list_for_each_entry(dai, &dai_list, list) {
1069 if (dai->dev != platform->dev)
1070 continue;
1071
1072 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai);
1073 }
1074
1084 if (driver->probe) { 1075 if (driver->probe) {
1085 ret = driver->probe(platform); 1076 ret = driver->probe(platform);
1086 if (ret < 0) { 1077 if (ret < 0) {
@@ -1216,9 +1207,12 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1216 /* probe the cpu_dai */ 1207 /* probe the cpu_dai */
1217 if (!cpu_dai->probed && 1208 if (!cpu_dai->probed &&
1218 cpu_dai->driver->probe_order == order) { 1209 cpu_dai->driver->probe_order == order) {
1210 cpu_dai->dapm.card = card;
1219 if (!try_module_get(cpu_dai->dev->driver->owner)) 1211 if (!try_module_get(cpu_dai->dev->driver->owner))
1220 return -ENODEV; 1212 return -ENODEV;
1221 1213
1214 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai);
1215
1222 if (cpu_dai->driver->probe) { 1216 if (cpu_dai->driver->probe) {
1223 ret = cpu_dai->driver->probe(cpu_dai); 1217 ret = cpu_dai->driver->probe(cpu_dai);
1224 if (ret < 0) { 1218 if (ret < 0) {
@@ -1332,6 +1326,20 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1332} 1326}
1333#endif 1327#endif
1334 1328
1329static int soc_check_aux_dev(struct snd_soc_card *card, int num)
1330{
1331 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1332 struct snd_soc_codec *codec;
1333
1334 /* find CODEC from registered CODECs*/
1335 list_for_each_entry(codec, &codec_list, list) {
1336 if (!strcmp(codec->name, aux_dev->codec_name))
1337 return 0;
1338 }
1339
1340 return -EPROBE_DEFER;
1341}
1342
1335static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1343static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1336{ 1344{
1337 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1345 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
@@ -1352,7 +1360,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1352 } 1360 }
1353 /* codec not found */ 1361 /* codec not found */
1354 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); 1362 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
1355 goto out; 1363 return -EPROBE_DEFER;
1356 1364
1357found: 1365found:
1358 ret = soc_probe_codec(card, codec); 1366 ret = soc_probe_codec(card, codec);
@@ -1402,7 +1410,7 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1402 return 0; 1410 return 0;
1403} 1411}
1404 1412
1405static void snd_soc_instantiate_card(struct snd_soc_card *card) 1413static int snd_soc_instantiate_card(struct snd_soc_card *card)
1406{ 1414{
1407 struct snd_soc_codec *codec; 1415 struct snd_soc_codec *codec;
1408 struct snd_soc_codec_conf *codec_conf; 1416 struct snd_soc_codec_conf *codec_conf;
@@ -1410,21 +1418,20 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1410 struct snd_soc_dai_link *dai_link; 1418 struct snd_soc_dai_link *dai_link;
1411 int ret, i, order; 1419 int ret, i, order;
1412 1420
1413 mutex_lock(&card->mutex); 1421 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
1414
1415 if (card->instantiated) {
1416 mutex_unlock(&card->mutex);
1417 return;
1418 }
1419 1422
1420 /* bind DAIs */ 1423 /* bind DAIs */
1421 for (i = 0; i < card->num_links; i++) 1424 for (i = 0; i < card->num_links; i++) {
1422 soc_bind_dai_link(card, i); 1425 ret = soc_bind_dai_link(card, i);
1426 if (ret != 0)
1427 goto base_error;
1428 }
1423 1429
1424 /* bind completed ? */ 1430 /* check aux_devs too */
1425 if (card->num_rtd != card->num_links) { 1431 for (i = 0; i < card->num_aux_devs; i++) {
1426 mutex_unlock(&card->mutex); 1432 ret = soc_check_aux_dev(card, i);
1427 return; 1433 if (ret != 0)
1434 goto base_error;
1428 } 1435 }
1429 1436
1430 /* initialize the register cache for each available codec */ 1437 /* initialize the register cache for each available codec */
@@ -1444,10 +1451,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1444 } 1451 }
1445 } 1452 }
1446 ret = snd_soc_init_codec_cache(codec, compress_type); 1453 ret = snd_soc_init_codec_cache(codec, compress_type);
1447 if (ret < 0) { 1454 if (ret < 0)
1448 mutex_unlock(&card->mutex); 1455 goto base_error;
1449 return;
1450 }
1451 } 1456 }
1452 1457
1453 /* card bind complete so register a sound card */ 1458 /* card bind complete so register a sound card */
@@ -1456,8 +1461,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1456 if (ret < 0) { 1461 if (ret < 0) {
1457 pr_err("asoc: can't create sound card for card %s: %d\n", 1462 pr_err("asoc: can't create sound card for card %s: %d\n",
1458 card->name, ret); 1463 card->name, ret);
1459 mutex_unlock(&card->mutex); 1464 goto base_error;
1460 return;
1461 } 1465 }
1462 card->snd_card->dev = card->dev; 1466 card->snd_card->dev = card->dev;
1463 1467
@@ -1597,7 +1601,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1597 card->instantiated = 1; 1601 card->instantiated = 1;
1598 snd_soc_dapm_sync(&card->dapm); 1602 snd_soc_dapm_sync(&card->dapm);
1599 mutex_unlock(&card->mutex); 1603 mutex_unlock(&card->mutex);
1600 return; 1604
1605 return 0;
1601 1606
1602probe_aux_dev_err: 1607probe_aux_dev_err:
1603 for (i = 0; i < card->num_aux_devs; i++) 1608 for (i = 0; i < card->num_aux_devs; i++)
@@ -1612,18 +1617,10 @@ card_probe_error:
1612 1617
1613 snd_card_free(card->snd_card); 1618 snd_card_free(card->snd_card);
1614 1619
1620base_error:
1615 mutex_unlock(&card->mutex); 1621 mutex_unlock(&card->mutex);
1616}
1617 1622
1618/* 1623 return ret;
1619 * Attempt to initialise any uninitialised cards. Must be called with
1620 * client_mutex.
1621 */
1622static void snd_soc_instantiate_cards(void)
1623{
1624 struct snd_soc_card *card;
1625 list_for_each_entry(card, &card_list, list)
1626 snd_soc_instantiate_card(card);
1627} 1624}
1628 1625
1629/* probes a new socdev */ 1626/* probes a new socdev */
@@ -2525,6 +2522,87 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2525EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 2522EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
2526 2523
2527/** 2524/**
2525 * snd_soc_get_volsw_sx - single mixer get callback
2526 * @kcontrol: mixer control
2527 * @ucontrol: control element information
2528 *
2529 * Callback to get the value of a single mixer control, or a double mixer
2530 * control that spans 2 registers.
2531 *
2532 * Returns 0 for success.
2533 */
2534int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
2535 struct snd_ctl_elem_value *ucontrol)
2536{
2537 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2538 struct soc_mixer_control *mc =
2539 (struct soc_mixer_control *)kcontrol->private_value;
2540
2541 unsigned int reg = mc->reg;
2542 unsigned int reg2 = mc->rreg;
2543 unsigned int shift = mc->shift;
2544 unsigned int rshift = mc->rshift;
2545 int max = mc->max;
2546 int min = mc->min;
2547 int mask = (1 << (fls(min + max) - 1)) - 1;
2548
2549 ucontrol->value.integer.value[0] =
2550 ((snd_soc_read(codec, reg) >> shift) - min) & mask;
2551
2552 if (snd_soc_volsw_is_stereo(mc))
2553 ucontrol->value.integer.value[1] =
2554 ((snd_soc_read(codec, reg2) >> rshift) - min) & mask;
2555
2556 return 0;
2557}
2558EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx);
2559
2560/**
2561 * snd_soc_put_volsw_sx - double mixer set callback
2562 * @kcontrol: mixer control
2563 * @uinfo: control element information
2564 *
2565 * Callback to set the value of a double mixer control that spans 2 registers.
2566 *
2567 * Returns 0 for success.
2568 */
2569int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
2570 struct snd_ctl_elem_value *ucontrol)
2571{
2572 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2573 struct soc_mixer_control *mc =
2574 (struct soc_mixer_control *)kcontrol->private_value;
2575
2576 unsigned int reg = mc->reg;
2577 unsigned int reg2 = mc->rreg;
2578 unsigned int shift = mc->shift;
2579 unsigned int rshift = mc->rshift;
2580 int max = mc->max;
2581 int min = mc->min;
2582 int mask = (1 << (fls(min + max) - 1)) - 1;
2583 int err = 0;
2584 unsigned short val, val_mask, val2 = 0;
2585
2586 val_mask = mask << shift;
2587 val = (ucontrol->value.integer.value[0] + min) & mask;
2588 val = val << shift;
2589
2590 if (snd_soc_update_bits_locked(codec, reg, val_mask, val))
2591 return err;
2592
2593 if (snd_soc_volsw_is_stereo(mc)) {
2594 val_mask = mask << rshift;
2595 val2 = (ucontrol->value.integer.value[1] + min) & mask;
2596 val2 = val2 << rshift;
2597
2598 if (snd_soc_update_bits_locked(codec, reg2, val_mask, val2))
2599 return err;
2600 }
2601 return 0;
2602}
2603EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx);
2604
2605/**
2528 * snd_soc_info_volsw_s8 - signed mixer info callback 2606 * snd_soc_info_volsw_s8 - signed mixer info callback
2529 * @kcontrol: mixer control 2607 * @kcontrol: mixer control
2530 * @uinfo: control element information 2608 * @uinfo: control element information
@@ -2645,99 +2723,6 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2645} 2723}
2646EXPORT_SYMBOL_GPL(snd_soc_limit_volume); 2724EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2647 2725
2648/**
2649 * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
2650 * mixer info callback
2651 * @kcontrol: mixer control
2652 * @uinfo: control element information
2653 *
2654 * Returns 0 for success.
2655 */
2656int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2657 struct snd_ctl_elem_info *uinfo)
2658{
2659 struct soc_mixer_control *mc =
2660 (struct soc_mixer_control *)kcontrol->private_value;
2661 int max = mc->max;
2662 int min = mc->min;
2663
2664 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2665 uinfo->count = 2;
2666 uinfo->value.integer.min = 0;
2667 uinfo->value.integer.max = max-min;
2668
2669 return 0;
2670}
2671EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
2672
2673/**
2674 * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
2675 * mixer get callback
2676 * @kcontrol: mixer control
2677 * @uinfo: control element information
2678 *
2679 * Returns 0 for success.
2680 */
2681int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2682 struct snd_ctl_elem_value *ucontrol)
2683{
2684 struct soc_mixer_control *mc =
2685 (struct soc_mixer_control *)kcontrol->private_value;
2686 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2687 unsigned int mask = (1<<mc->shift)-1;
2688 int min = mc->min;
2689 int val = snd_soc_read(codec, mc->reg) & mask;
2690 int valr = snd_soc_read(codec, mc->rreg) & mask;
2691
2692 ucontrol->value.integer.value[0] = ((val & 0xff)-min) & mask;
2693 ucontrol->value.integer.value[1] = ((valr & 0xff)-min) & mask;
2694 return 0;
2695}
2696EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
2697
2698/**
2699 * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
2700 * mixer put callback
2701 * @kcontrol: mixer control
2702 * @uinfo: control element information
2703 *
2704 * Returns 0 for success.
2705 */
2706int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2707 struct snd_ctl_elem_value *ucontrol)
2708{
2709 struct soc_mixer_control *mc =
2710 (struct soc_mixer_control *)kcontrol->private_value;
2711 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2712 unsigned int mask = (1<<mc->shift)-1;
2713 int min = mc->min;
2714 int ret;
2715 unsigned int val, valr, oval, ovalr;
2716
2717 val = ((ucontrol->value.integer.value[0]+min) & 0xff);
2718 val &= mask;
2719 valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
2720 valr &= mask;
2721
2722 oval = snd_soc_read(codec, mc->reg) & mask;
2723 ovalr = snd_soc_read(codec, mc->rreg) & mask;
2724
2725 ret = 0;
2726 if (oval != val) {
2727 ret = snd_soc_write(codec, mc->reg, val);
2728 if (ret < 0)
2729 return ret;
2730 }
2731 if (ovalr != valr) {
2732 ret = snd_soc_write(codec, mc->rreg, valr);
2733 if (ret < 0)
2734 return ret;
2735 }
2736
2737 return 0;
2738}
2739EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2740
2741int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, 2726int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2742 struct snd_ctl_elem_info *uinfo) 2727 struct snd_ctl_elem_info *uinfo)
2743{ 2728{
@@ -3058,7 +3043,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3058 */ 3043 */
3059int snd_soc_register_card(struct snd_soc_card *card) 3044int snd_soc_register_card(struct snd_soc_card *card)
3060{ 3045{
3061 int i; 3046 int i, ret;
3062 3047
3063 if (!card->name || !card->dev) 3048 if (!card->name || !card->dev)
3064 return -EINVAL; 3049 return -EINVAL;
@@ -3120,15 +3105,13 @@ int snd_soc_register_card(struct snd_soc_card *card)
3120 INIT_LIST_HEAD(&card->dapm_dirty); 3105 INIT_LIST_HEAD(&card->dapm_dirty);
3121 card->instantiated = 0; 3106 card->instantiated = 0;
3122 mutex_init(&card->mutex); 3107 mutex_init(&card->mutex);
3108 mutex_init(&card->dapm_mutex);
3123 3109
3124 mutex_lock(&client_mutex); 3110 ret = snd_soc_instantiate_card(card);
3125 list_add(&card->list, &card_list); 3111 if (ret != 0)
3126 snd_soc_instantiate_cards(); 3112 soc_cleanup_card_debugfs(card);
3127 mutex_unlock(&client_mutex);
3128
3129 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
3130 3113
3131 return 0; 3114 return ret;
3132} 3115}
3133EXPORT_SYMBOL_GPL(snd_soc_register_card); 3116EXPORT_SYMBOL_GPL(snd_soc_register_card);
3134 3117
@@ -3142,9 +3125,6 @@ int snd_soc_unregister_card(struct snd_soc_card *card)
3142{ 3125{
3143 if (card->instantiated) 3126 if (card->instantiated)
3144 soc_cleanup_card_resources(card); 3127 soc_cleanup_card_resources(card);
3145 mutex_lock(&client_mutex);
3146 list_del(&card->list);
3147 mutex_unlock(&client_mutex);
3148 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); 3128 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
3149 3129
3150 return 0; 3130 return 0;
@@ -3235,12 +3215,12 @@ int snd_soc_register_dai(struct device *dev,
3235 3215
3236 dai->dev = dev; 3216 dai->dev = dev;
3237 dai->driver = dai_drv; 3217 dai->driver = dai_drv;
3218 dai->dapm.dev = dev;
3238 if (!dai->driver->ops) 3219 if (!dai->driver->ops)
3239 dai->driver->ops = &null_dai_ops; 3220 dai->driver->ops = &null_dai_ops;
3240 3221
3241 mutex_lock(&client_mutex); 3222 mutex_lock(&client_mutex);
3242 list_add(&dai->list, &dai_list); 3223 list_add(&dai->list, &dai_list);
3243 snd_soc_instantiate_cards();
3244 mutex_unlock(&client_mutex); 3224 mutex_unlock(&client_mutex);
3245 3225
3246 pr_debug("Registered DAI '%s'\n", dai->name); 3226 pr_debug("Registered DAI '%s'\n", dai->name);
@@ -3311,6 +3291,7 @@ int snd_soc_register_dais(struct device *dev,
3311 dai->id = dai->driver->id; 3291 dai->id = dai->driver->id;
3312 else 3292 else
3313 dai->id = i; 3293 dai->id = i;
3294 dai->dapm.dev = dev;
3314 if (!dai->driver->ops) 3295 if (!dai->driver->ops)
3315 dai->driver->ops = &null_dai_ops; 3296 dai->driver->ops = &null_dai_ops;
3316 3297
@@ -3321,9 +3302,6 @@ int snd_soc_register_dais(struct device *dev,
3321 pr_debug("Registered DAI '%s'\n", dai->name); 3302 pr_debug("Registered DAI '%s'\n", dai->name);
3322 } 3303 }
3323 3304
3324 mutex_lock(&client_mutex);
3325 snd_soc_instantiate_cards();
3326 mutex_unlock(&client_mutex);
3327 return 0; 3305 return 0;
3328 3306
3329err: 3307err:
@@ -3381,7 +3359,6 @@ int snd_soc_register_platform(struct device *dev,
3381 3359
3382 mutex_lock(&client_mutex); 3360 mutex_lock(&client_mutex);
3383 list_add(&platform->list, &platform_list); 3361 list_add(&platform->list, &platform_list);
3384 snd_soc_instantiate_cards();
3385 mutex_unlock(&client_mutex); 3362 mutex_unlock(&client_mutex);
3386 3363
3387 pr_debug("Registered platform '%s'\n", platform->name); 3364 pr_debug("Registered platform '%s'\n", platform->name);
@@ -3540,7 +3517,6 @@ int snd_soc_register_codec(struct device *dev,
3540 3517
3541 mutex_lock(&client_mutex); 3518 mutex_lock(&client_mutex);
3542 list_add(&codec->list, &codec_list); 3519 list_add(&codec->list, &codec_list);
3543 snd_soc_instantiate_cards();
3544 mutex_unlock(&client_mutex); 3520 mutex_unlock(&client_mutex);
3545 3521
3546 pr_debug("Registered codec '%s'\n", codec->name); 3522 pr_debug("Registered codec '%s'\n", codec->name);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 5cbd2d7623b8..589e16b9a483 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -206,7 +206,23 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
206 return -1; 206 return -1;
207} 207}
208 208
209static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, 209static inline void soc_widget_lock(struct snd_soc_dapm_widget *w)
210{
211 if (w->codec && !w->codec->using_regmap)
212 mutex_lock(&w->codec->mutex);
213 else if (w->platform)
214 mutex_lock(&w->platform->mutex);
215}
216
217static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w)
218{
219 if (w->codec && !w->codec->using_regmap)
220 mutex_unlock(&w->codec->mutex);
221 else if (w->platform)
222 mutex_unlock(&w->platform->mutex);
223}
224
225static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
210 unsigned short reg, unsigned int mask, unsigned int value) 226 unsigned short reg, unsigned int mask, unsigned int value)
211{ 227{
212 bool change; 228 bool change;
@@ -219,18 +235,24 @@ static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
219 if (ret != 0) 235 if (ret != 0)
220 return ret; 236 return ret;
221 } else { 237 } else {
238 soc_widget_lock(w);
222 ret = soc_widget_read(w, reg); 239 ret = soc_widget_read(w, reg);
223 if (ret < 0) 240 if (ret < 0) {
241 soc_widget_unlock(w);
224 return ret; 242 return ret;
243 }
225 244
226 old = ret; 245 old = ret;
227 new = (old & ~mask) | (value & mask); 246 new = (old & ~mask) | (value & mask);
228 change = old != new; 247 change = old != new;
229 if (change) { 248 if (change) {
230 ret = soc_widget_write(w, reg, new); 249 ret = soc_widget_write(w, reg, new);
231 if (ret < 0) 250 if (ret < 0) {
251 soc_widget_unlock(w);
232 return ret; 252 return ret;
253 }
233 } 254 }
255 soc_widget_unlock(w);
234 } 256 }
235 257
236 return change; 258 return change;
@@ -847,7 +869,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
847 else 869 else
848 val = w->off_val; 870 val = w->off_val;
849 871
850 soc_widget_update_bits(w, -(w->reg + 1), 872 soc_widget_update_bits_locked(w, -(w->reg + 1),
851 w->mask << w->shift, val << w->shift); 873 w->mask << w->shift, val << w->shift);
852 874
853 return 0; 875 return 0;
@@ -861,9 +883,9 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
861 struct snd_kcontrol *kcontrol, int event) 883 struct snd_kcontrol *kcontrol, int event)
862{ 884{
863 if (SND_SOC_DAPM_EVENT_ON(event)) 885 if (SND_SOC_DAPM_EVENT_ON(event))
864 return regulator_enable(w->priv); 886 return regulator_enable(w->regulator);
865 else 887 else
866 return regulator_disable_deferred(w->priv, w->shift); 888 return regulator_disable_deferred(w->regulator, w->shift);
867} 889}
868EXPORT_SYMBOL_GPL(dapm_regulator_event); 890EXPORT_SYMBOL_GPL(dapm_regulator_event);
869 891
@@ -1105,7 +1127,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
1105 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 1127 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
1106 value, mask, reg, card->pop_time); 1128 value, mask, reg, card->pop_time);
1107 pop_wait(card->pop_time); 1129 pop_wait(card->pop_time);
1108 soc_widget_update_bits(w, reg, mask, value); 1130 soc_widget_update_bits_locked(w, reg, mask, value);
1109 } 1131 }
1110 1132
1111 list_for_each_entry(w, pending, power_list) { 1133 list_for_each_entry(w, pending, power_list) {
@@ -1235,7 +1257,7 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
1235 w->name, ret); 1257 w->name, ret);
1236 } 1258 }
1237 1259
1238 ret = snd_soc_update_bits(w->codec, update->reg, update->mask, 1260 ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
1239 update->val); 1261 update->val);
1240 if (ret < 0) 1262 if (ret < 0)
1241 pr_err("%s DAPM update failed: %d\n", w->name, ret); 1263 pr_err("%s DAPM update failed: %d\n", w->name, ret);
@@ -1419,12 +1441,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1419 trace_snd_soc_dapm_start(card); 1441 trace_snd_soc_dapm_start(card);
1420 1442
1421 list_for_each_entry(d, &card->dapm_list, list) { 1443 list_for_each_entry(d, &card->dapm_list, list) {
1422 if (d->n_widgets || d->codec == NULL) { 1444 if (d->idle_bias_off)
1423 if (d->idle_bias_off) 1445 d->target_bias_level = SND_SOC_BIAS_OFF;
1424 d->target_bias_level = SND_SOC_BIAS_OFF; 1446 else
1425 else 1447 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1426 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1427 }
1428 } 1448 }
1429 1449
1430 dapm_reset(card); 1450 dapm_reset(card);
@@ -1469,32 +1489,6 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1469 1489
1470 } 1490 }
1471 1491
1472 /* If there are no DAPM widgets then try to figure out power from the
1473 * event type.
1474 */
1475 if (!dapm->n_widgets) {
1476 switch (event) {
1477 case SND_SOC_DAPM_STREAM_START:
1478 case SND_SOC_DAPM_STREAM_RESUME:
1479 dapm->target_bias_level = SND_SOC_BIAS_ON;
1480 break;
1481 case SND_SOC_DAPM_STREAM_STOP:
1482 if (dapm->codec && dapm->codec->active)
1483 dapm->target_bias_level = SND_SOC_BIAS_ON;
1484 else
1485 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1486 break;
1487 case SND_SOC_DAPM_STREAM_SUSPEND:
1488 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1489 break;
1490 case SND_SOC_DAPM_STREAM_NOP:
1491 dapm->target_bias_level = dapm->bias_level;
1492 break;
1493 default:
1494 break;
1495 }
1496 }
1497
1498 /* Force all contexts in the card to the same bias state if 1492 /* Force all contexts in the card to the same bias state if
1499 * they're not ground referenced. 1493 * they're not ground referenced.
1500 */ 1494 */
@@ -1707,7 +1701,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1707#endif 1701#endif
1708 1702
1709/* test and update the power status of a mux widget */ 1703/* test and update the power status of a mux widget */
1710int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1704static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1711 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) 1705 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1712{ 1706{
1713 struct snd_soc_dapm_path *path; 1707 struct snd_soc_dapm_path *path;
@@ -1746,10 +1740,22 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1746 1740
1747 return 0; 1741 return 0;
1748} 1742}
1743
1744int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1745 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1746{
1747 struct snd_soc_card *card = widget->dapm->card;
1748 int ret;
1749
1750 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1751 ret = soc_dapm_mux_update_power(widget, kcontrol, mux, e);
1752 mutex_unlock(&card->dapm_mutex);
1753 return ret;
1754}
1749EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); 1755EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
1750 1756
1751/* test and update the power status of a mixer or switch widget */ 1757/* test and update the power status of a mixer or switch widget */
1752int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1758static int soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1753 struct snd_kcontrol *kcontrol, int connect) 1759 struct snd_kcontrol *kcontrol, int connect)
1754{ 1760{
1755 struct snd_soc_dapm_path *path; 1761 struct snd_soc_dapm_path *path;
@@ -1778,6 +1784,18 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1778 1784
1779 return 0; 1785 return 0;
1780} 1786}
1787
1788int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1789 struct snd_kcontrol *kcontrol, int connect)
1790{
1791 struct snd_soc_card *card = widget->dapm->card;
1792 int ret;
1793
1794 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1795 ret = soc_dapm_mixer_update_power(widget, kcontrol, connect);
1796 mutex_unlock(&card->dapm_mutex);
1797 return ret;
1798}
1781EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); 1799EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
1782 1800
1783/* show dapm widget status in sys fs */ 1801/* show dapm widget status in sys fs */
@@ -1937,6 +1955,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1937 */ 1955 */
1938int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 1956int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1939{ 1957{
1958 int ret;
1959
1940 /* 1960 /*
1941 * Suppress early reports (eg, jacks syncing their state) to avoid 1961 * Suppress early reports (eg, jacks syncing their state) to avoid
1942 * silly DAPM runs during card startup. 1962 * silly DAPM runs during card startup.
@@ -1944,7 +1964,10 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1944 if (!dapm->card || !dapm->card->instantiated) 1964 if (!dapm->card || !dapm->card->instantiated)
1945 return 0; 1965 return 0;
1946 1966
1947 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 1967 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1968 ret = dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
1969 mutex_unlock(&dapm->card->dapm_mutex);
1970 return ret;
1948} 1971}
1949EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1972EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1950 1973
@@ -2110,6 +2133,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2110{ 2133{
2111 int i, ret; 2134 int i, ret;
2112 2135
2136 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2113 for (i = 0; i < num; i++) { 2137 for (i = 0; i < num; i++) {
2114 ret = snd_soc_dapm_add_route(dapm, route); 2138 ret = snd_soc_dapm_add_route(dapm, route);
2115 if (ret < 0) { 2139 if (ret < 0) {
@@ -2119,6 +2143,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2119 } 2143 }
2120 route++; 2144 route++;
2121 } 2145 }
2146 mutex_unlock(&dapm->card->dapm_mutex);
2122 2147
2123 return 0; 2148 return 0;
2124} 2149}
@@ -2191,12 +2216,14 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
2191 int i, err; 2216 int i, err;
2192 int ret = 0; 2217 int ret = 0;
2193 2218
2219 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2194 for (i = 0; i < num; i++) { 2220 for (i = 0; i < num; i++) {
2195 err = snd_soc_dapm_weak_route(dapm, route); 2221 err = snd_soc_dapm_weak_route(dapm, route);
2196 if (err) 2222 if (err)
2197 ret = err; 2223 ret = err;
2198 route++; 2224 route++;
2199 } 2225 }
2226 mutex_unlock(&dapm->card->dapm_mutex);
2200 2227
2201 return ret; 2228 return ret;
2202} 2229}
@@ -2215,6 +2242,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2215 struct snd_soc_dapm_widget *w; 2242 struct snd_soc_dapm_widget *w;
2216 unsigned int val; 2243 unsigned int val;
2217 2244
2245 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2246
2218 list_for_each_entry(w, &dapm->card->widgets, list) 2247 list_for_each_entry(w, &dapm->card->widgets, list)
2219 { 2248 {
2220 if (w->new) 2249 if (w->new)
@@ -2224,8 +2253,10 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2224 w->kcontrols = kzalloc(w->num_kcontrols * 2253 w->kcontrols = kzalloc(w->num_kcontrols *
2225 sizeof(struct snd_kcontrol *), 2254 sizeof(struct snd_kcontrol *),
2226 GFP_KERNEL); 2255 GFP_KERNEL);
2227 if (!w->kcontrols) 2256 if (!w->kcontrols) {
2257 mutex_unlock(&dapm->card->dapm_mutex);
2228 return -ENOMEM; 2258 return -ENOMEM;
2259 }
2229 } 2260 }
2230 2261
2231 switch(w->id) { 2262 switch(w->id) {
@@ -2265,6 +2296,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2265 } 2296 }
2266 2297
2267 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 2298 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
2299 mutex_unlock(&dapm->card->dapm_mutex);
2268 return 0; 2300 return 0;
2269} 2301}
2270EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 2302EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -2324,6 +2356,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2324 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2356 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2325 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2357 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2326 struct snd_soc_codec *codec = widget->codec; 2358 struct snd_soc_codec *codec = widget->codec;
2359 struct snd_soc_card *card = codec->card;
2327 struct soc_mixer_control *mc = 2360 struct soc_mixer_control *mc =
2328 (struct soc_mixer_control *)kcontrol->private_value; 2361 (struct soc_mixer_control *)kcontrol->private_value;
2329 unsigned int reg = mc->reg; 2362 unsigned int reg = mc->reg;
@@ -2350,7 +2383,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2350 /* old connection must be powered down */ 2383 /* old connection must be powered down */
2351 connect = invert ? 1 : 0; 2384 connect = invert ? 1 : 0;
2352 2385
2353 mutex_lock(&codec->mutex); 2386 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2354 2387
2355 change = snd_soc_test_bits(widget->codec, reg, mask, val); 2388 change = snd_soc_test_bits(widget->codec, reg, mask, val);
2356 if (change) { 2389 if (change) {
@@ -2366,13 +2399,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2366 update.val = val; 2399 update.val = val;
2367 widget->dapm->update = &update; 2400 widget->dapm->update = &update;
2368 2401
2369 snd_soc_dapm_mixer_update_power(widget, kcontrol, connect); 2402 soc_dapm_mixer_update_power(widget, kcontrol, connect);
2370 2403
2371 widget->dapm->update = NULL; 2404 widget->dapm->update = NULL;
2372 } 2405 }
2373 } 2406 }
2374 2407
2375 mutex_unlock(&codec->mutex); 2408 mutex_unlock(&card->dapm_mutex);
2376 return 0; 2409 return 0;
2377} 2410}
2378EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 2411EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
@@ -2421,6 +2454,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2421 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2454 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2422 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2455 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2423 struct snd_soc_codec *codec = widget->codec; 2456 struct snd_soc_codec *codec = widget->codec;
2457 struct snd_soc_card *card = codec->card;
2424 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2458 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2425 unsigned int val, mux, change; 2459 unsigned int val, mux, change;
2426 unsigned int mask, bitmask; 2460 unsigned int mask, bitmask;
@@ -2441,7 +2475,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2441 mask |= (bitmask - 1) << e->shift_r; 2475 mask |= (bitmask - 1) << e->shift_r;
2442 } 2476 }
2443 2477
2444 mutex_lock(&codec->mutex); 2478 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2445 2479
2446 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2480 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2447 if (change) { 2481 if (change) {
@@ -2457,13 +2491,13 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2457 update.val = val; 2491 update.val = val;
2458 widget->dapm->update = &update; 2492 widget->dapm->update = &update;
2459 2493
2460 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2494 soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2461 2495
2462 widget->dapm->update = NULL; 2496 widget->dapm->update = NULL;
2463 } 2497 }
2464 } 2498 }
2465 2499
2466 mutex_unlock(&codec->mutex); 2500 mutex_unlock(&card->dapm_mutex);
2467 return change; 2501 return change;
2468} 2502}
2469EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 2503EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
@@ -2500,6 +2534,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2500 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2534 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2501 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2535 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2502 struct snd_soc_codec *codec = widget->codec; 2536 struct snd_soc_codec *codec = widget->codec;
2537 struct snd_soc_card *card = codec->card;
2503 struct soc_enum *e = 2538 struct soc_enum *e =
2504 (struct soc_enum *)kcontrol->private_value; 2539 (struct soc_enum *)kcontrol->private_value;
2505 int change; 2540 int change;
@@ -2509,7 +2544,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2509 if (ucontrol->value.enumerated.item[0] >= e->max) 2544 if (ucontrol->value.enumerated.item[0] >= e->max)
2510 return -EINVAL; 2545 return -EINVAL;
2511 2546
2512 mutex_lock(&codec->mutex); 2547 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2513 2548
2514 change = widget->value != ucontrol->value.enumerated.item[0]; 2549 change = widget->value != ucontrol->value.enumerated.item[0];
2515 if (change) { 2550 if (change) {
@@ -2518,11 +2553,11 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2518 2553
2519 widget->value = ucontrol->value.enumerated.item[0]; 2554 widget->value = ucontrol->value.enumerated.item[0];
2520 2555
2521 snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e); 2556 soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
2522 } 2557 }
2523 } 2558 }
2524 2559
2525 mutex_unlock(&codec->mutex); 2560 mutex_unlock(&card->dapm_mutex);
2526 return ret; 2561 return ret;
2527} 2562}
2528EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 2563EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
@@ -2587,6 +2622,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2587 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2622 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2588 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2623 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2589 struct snd_soc_codec *codec = widget->codec; 2624 struct snd_soc_codec *codec = widget->codec;
2625 struct snd_soc_card *card = codec->card;
2590 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2626 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2591 unsigned int val, mux, change; 2627 unsigned int val, mux, change;
2592 unsigned int mask; 2628 unsigned int mask;
@@ -2605,7 +2641,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2605 mask |= e->mask << e->shift_r; 2641 mask |= e->mask << e->shift_r;
2606 } 2642 }
2607 2643
2608 mutex_lock(&codec->mutex); 2644 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2609 2645
2610 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2646 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2611 if (change) { 2647 if (change) {
@@ -2621,13 +2657,13 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2621 update.val = val; 2657 update.val = val;
2622 widget->dapm->update = &update; 2658 widget->dapm->update = &update;
2623 2659
2624 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2660 soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2625 2661
2626 widget->dapm->update = NULL; 2662 widget->dapm->update = NULL;
2627 } 2663 }
2628 } 2664 }
2629 2665
2630 mutex_unlock(&codec->mutex); 2666 mutex_unlock(&card->dapm_mutex);
2631 return change; 2667 return change;
2632} 2668}
2633EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2669EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
@@ -2664,12 +2700,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2664 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 2700 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2665 const char *pin = (const char *)kcontrol->private_value; 2701 const char *pin = (const char *)kcontrol->private_value;
2666 2702
2667 mutex_lock(&card->mutex); 2703 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2668 2704
2669 ucontrol->value.integer.value[0] = 2705 ucontrol->value.integer.value[0] =
2670 snd_soc_dapm_get_pin_status(&card->dapm, pin); 2706 snd_soc_dapm_get_pin_status(&card->dapm, pin);
2671 2707
2672 mutex_unlock(&card->mutex); 2708 mutex_unlock(&card->dapm_mutex);
2673 2709
2674 return 0; 2710 return 0;
2675} 2711}
@@ -2687,17 +2723,16 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2687 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 2723 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2688 const char *pin = (const char *)kcontrol->private_value; 2724 const char *pin = (const char *)kcontrol->private_value;
2689 2725
2690 mutex_lock(&card->mutex); 2726 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2691 2727
2692 if (ucontrol->value.integer.value[0]) 2728 if (ucontrol->value.integer.value[0])
2693 snd_soc_dapm_enable_pin(&card->dapm, pin); 2729 snd_soc_dapm_enable_pin(&card->dapm, pin);
2694 else 2730 else
2695 snd_soc_dapm_disable_pin(&card->dapm, pin); 2731 snd_soc_dapm_disable_pin(&card->dapm, pin);
2696 2732
2697 snd_soc_dapm_sync(&card->dapm); 2733 mutex_unlock(&card->dapm_mutex);
2698
2699 mutex_unlock(&card->mutex);
2700 2734
2735 snd_soc_dapm_sync(&card->dapm);
2701 return 0; 2736 return 0;
2702} 2737}
2703EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 2738EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
@@ -2715,9 +2750,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2715 2750
2716 switch (w->id) { 2751 switch (w->id) {
2717 case snd_soc_dapm_regulator_supply: 2752 case snd_soc_dapm_regulator_supply:
2718 w->priv = devm_regulator_get(dapm->dev, w->name); 2753 w->regulator = devm_regulator_get(dapm->dev, w->name);
2719 if (IS_ERR(w->priv)) { 2754 if (IS_ERR(w->regulator)) {
2720 ret = PTR_ERR(w->priv); 2755 ret = PTR_ERR(w->regulator);
2721 dev_err(dapm->dev, "Failed to request %s: %d\n", 2756 dev_err(dapm->dev, "Failed to request %s: %d\n",
2722 w->name, ret); 2757 w->name, ret);
2723 return NULL; 2758 return NULL;
@@ -2815,6 +2850,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2815 struct snd_soc_dapm_widget *w; 2850 struct snd_soc_dapm_widget *w;
2816 int i; 2851 int i;
2817 2852
2853 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2818 for (i = 0; i < num; i++) { 2854 for (i = 0; i < num; i++) {
2819 w = snd_soc_dapm_new_control(dapm, widget); 2855 w = snd_soc_dapm_new_control(dapm, widget);
2820 if (!w) { 2856 if (!w) {
@@ -2825,6 +2861,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2825 } 2861 }
2826 widget++; 2862 widget++;
2827 } 2863 }
2864 mutex_unlock(&dapm->card->dapm_mutex);
2828 return 0; 2865 return 0;
2829} 2866}
2830EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2867EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
@@ -2932,37 +2969,61 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
2932 return 0; 2969 return 0;
2933} 2970}
2934 2971
2935static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, 2972static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2936 int stream, struct snd_soc_dai *dai, 2973 int event)
2937 int event)
2938{ 2974{
2939 struct snd_soc_dapm_widget *w;
2940 2975
2941 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 2976 struct snd_soc_dapm_widget *w_cpu, *w_codec;
2942 w = dai->playback_widget; 2977 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2943 else 2978 struct snd_soc_dai *codec_dai = rtd->codec_dai;
2944 w = dai->capture_widget;
2945 2979
2946 if (!w) 2980 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2947 return; 2981 w_cpu = cpu_dai->playback_widget;
2982 w_codec = codec_dai->playback_widget;
2983 } else {
2984 w_cpu = cpu_dai->capture_widget;
2985 w_codec = codec_dai->capture_widget;
2986 }
2948 2987
2949 dapm_mark_dirty(w, "stream event"); 2988 if (w_cpu) {
2950 2989
2951 switch (event) { 2990 dapm_mark_dirty(w_cpu, "stream event");
2952 case SND_SOC_DAPM_STREAM_START: 2991
2953 w->active = 1; 2992 switch (event) {
2954 break; 2993 case SND_SOC_DAPM_STREAM_START:
2955 case SND_SOC_DAPM_STREAM_STOP: 2994 w_cpu->active = 1;
2956 w->active = 0; 2995 break;
2957 break; 2996 case SND_SOC_DAPM_STREAM_STOP:
2958 case SND_SOC_DAPM_STREAM_SUSPEND: 2997 w_cpu->active = 0;
2959 case SND_SOC_DAPM_STREAM_RESUME: 2998 break;
2960 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2999 case SND_SOC_DAPM_STREAM_SUSPEND:
2961 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 3000 case SND_SOC_DAPM_STREAM_RESUME:
2962 break; 3001 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
3002 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
3003 break;
3004 }
2963 } 3005 }
2964 3006
2965 dapm_power_widgets(dapm, event); 3007 if (w_codec) {
3008
3009 dapm_mark_dirty(w_codec, "stream event");
3010
3011 switch (event) {
3012 case SND_SOC_DAPM_STREAM_START:
3013 w_codec->active = 1;
3014 break;
3015 case SND_SOC_DAPM_STREAM_STOP:
3016 w_codec->active = 0;
3017 break;
3018 case SND_SOC_DAPM_STREAM_SUSPEND:
3019 case SND_SOC_DAPM_STREAM_RESUME:
3020 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
3021 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
3022 break;
3023 }
3024 }
3025
3026 dapm_power_widgets(&rtd->card->dapm, event);
2966} 3027}
2967 3028
2968/** 3029/**
@@ -2976,15 +3037,14 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2976 * 3037 *
2977 * Returns 0 for success else error. 3038 * Returns 0 for success else error.
2978 */ 3039 */
2979int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 3040void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2980 struct snd_soc_dai *dai, int event) 3041 int event)
2981{ 3042{
2982 struct snd_soc_codec *codec = rtd->codec; 3043 struct snd_soc_card *card = rtd->card;
2983 3044
2984 mutex_lock(&codec->mutex); 3045 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2985 soc_dapm_stream_event(&codec->dapm, stream, dai, event); 3046 soc_dapm_stream_event(rtd, stream, event);
2986 mutex_unlock(&codec->mutex); 3047 mutex_unlock(&card->dapm_mutex);
2987 return 0;
2988} 3048}
2989 3049
2990/** 3050/**
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index ee4353f843ea..7f8b3b7428bb 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -36,6 +36,7 @@
36int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, 36int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
37 struct snd_soc_jack *jack) 37 struct snd_soc_jack *jack)
38{ 38{
39 mutex_init(&jack->mutex);
39 jack->codec = codec; 40 jack->codec = codec;
40 INIT_LIST_HEAD(&jack->pins); 41 INIT_LIST_HEAD(&jack->pins);
41 INIT_LIST_HEAD(&jack->jack_zones); 42 INIT_LIST_HEAD(&jack->jack_zones);
@@ -75,7 +76,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
75 codec = jack->codec; 76 codec = jack->codec;
76 dapm = &codec->dapm; 77 dapm = &codec->dapm;
77 78
78 mutex_lock(&codec->mutex); 79 mutex_lock(&jack->mutex);
79 80
80 oldstatus = jack->status; 81 oldstatus = jack->status;
81 82
@@ -109,7 +110,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
109 snd_jack_report(jack->jack, jack->status); 110 snd_jack_report(jack->jack, jack->status);
110 111
111out: 112out:
112 mutex_unlock(&codec->mutex); 113 mutex_unlock(&jack->mutex);
113} 114}
114EXPORT_SYMBOL_GPL(snd_soc_jack_report); 115EXPORT_SYMBOL_GPL(snd_soc_jack_report);
115 116
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 0ad8dcacd2f3..26a60b4061cf 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -308,7 +308,7 @@ static void close_delayed_work(struct work_struct *work)
308 if (codec_dai->pop_wait == 1) { 308 if (codec_dai->pop_wait == 1) {
309 codec_dai->pop_wait = 0; 309 codec_dai->pop_wait = 0;
310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
311 codec_dai, SND_SOC_DAPM_STREAM_STOP); 311 SND_SOC_DAPM_STREAM_STOP);
312 } 312 }
313 313
314 mutex_unlock(&rtd->pcm_mutex); 314 mutex_unlock(&rtd->pcm_mutex);
@@ -373,7 +373,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
373 /* powered down playback stream now */ 373 /* powered down playback stream now */
374 snd_soc_dapm_stream_event(rtd, 374 snd_soc_dapm_stream_event(rtd,
375 SNDRV_PCM_STREAM_PLAYBACK, 375 SNDRV_PCM_STREAM_PLAYBACK,
376 codec_dai,
377 SND_SOC_DAPM_STREAM_STOP); 376 SND_SOC_DAPM_STREAM_STOP);
378 } else { 377 } else {
379 /* start delayed pop wq here for playback streams */ 378 /* start delayed pop wq here for playback streams */
@@ -384,7 +383,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
384 } else { 383 } else {
385 /* capture streams can be powered down now */ 384 /* capture streams can be powered down now */
386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, 385 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
387 codec_dai, SND_SOC_DAPM_STREAM_STOP); 386 SND_SOC_DAPM_STREAM_STOP);
388 } 387 }
389 388
390 mutex_unlock(&rtd->pcm_mutex); 389 mutex_unlock(&rtd->pcm_mutex);
@@ -453,8 +452,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
453 cancel_delayed_work(&rtd->delayed_work); 452 cancel_delayed_work(&rtd->delayed_work);
454 } 453 }
455 454
456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai, 455 snd_soc_dapm_stream_event(rtd, substream->stream,
457 SND_SOC_DAPM_STREAM_START); 456 SND_SOC_DAPM_STREAM_START);
458 457
459 snd_soc_dai_digital_mute(codec_dai, 0); 458 snd_soc_dai_digital_mute(codec_dai, 0);
460 459
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index ce1b773c351f..556cac29ea15 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -4,20 +4,29 @@ config SND_SOC_TEGRA
4 help 4 help
5 Say Y or M here if you want support for SoC audio on Tegra. 5 Say Y or M here if you want support for SoC audio on Tegra.
6 6
7config SND_SOC_TEGRA_I2S 7config SND_SOC_TEGRA20_DAS
8 tristate 8 tristate
9 depends on SND_SOC_TEGRA 9 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
10 help
11 Say Y or M if you want to add support for the Tegra20 DAS module.
12 You will also need to select the individual machine drivers to
13 support below.
14
15config SND_SOC_TEGRA20_I2S
16 tristate
17 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
18 select SND_SOC_TEGRA20_DAS
10 help 19 help
11 Say Y or M if you want to add support for codecs attached to the 20 Say Y or M if you want to add support for codecs attached to the
12 Tegra I2S interface. You will also need to select the individual 21 Tegra20 I2S interface. You will also need to select the individual
13 machine drivers to support below. 22 machine drivers to support below.
14 23
15config SND_SOC_TEGRA_SPDIF 24config SND_SOC_TEGRA20_SPDIF
16 tristate 25 tristate
17 depends on SND_SOC_TEGRA 26 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
18 default m 27 default m
19 help 28 help
20 Say Y or M if you want to add support for the SPDIF interface. 29 Say Y or M if you want to add support for the Tegra20 SPDIF interface.
21 You will also need to select the individual machine drivers to support 30 You will also need to select the individual machine drivers to support
22 below. 31 below.
23 32
@@ -32,7 +41,7 @@ config SND_SOC_TEGRA_WM8903
32 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 41 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
33 depends on SND_SOC_TEGRA && I2C 42 depends on SND_SOC_TEGRA && I2C
34 depends on MACH_HAS_SND_SOC_TEGRA_WM8903 43 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
35 select SND_SOC_TEGRA_I2S 44 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
36 select SND_SOC_WM8903 45 select SND_SOC_WM8903
37 help 46 help
38 Say Y or M here if you want to add support for SoC audio on Tegra 47 Say Y or M here if you want to add support for SoC audio on Tegra
@@ -42,17 +51,17 @@ config SND_SOC_TEGRA_WM8903
42config SND_SOC_TEGRA_TRIMSLICE 51config SND_SOC_TEGRA_TRIMSLICE
43 tristate "SoC Audio support for TrimSlice board" 52 tristate "SoC Audio support for TrimSlice board"
44 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C 53 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
45 select SND_SOC_TEGRA_I2S 54 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
46 select SND_SOC_TLV320AIC23 55 select SND_SOC_TLV320AIC23
47 help 56 help
48 Say Y or M here if you want to add support for SoC audio on the 57 Say Y or M here if you want to add support for SoC audio on the
49 TrimSlice platform. 58 TrimSlice platform.
50 59
51config SND_SOC_TEGRA_ALC5632 60config SND_SOC_TEGRA_ALC5632
52 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" 61 tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
53 depends on SND_SOC_TEGRA && I2C 62 depends on SND_SOC_TEGRA && I2C
54 select SND_SOC_TEGRA_I2S 63 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
55 select SND_SOC_ALC5632 64 select SND_SOC_ALC5632
56 help 65 help
57 Say Y or M here if you want to add support for SoC audio on the 66 Say Y or M here if you want to add support for SoC audio on the
58 Toshiba AC100 netbook. 67 Toshiba AC100 netbook.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 8e584b8fcfba..4726b909664d 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,15 +1,15 @@
1# Tegra platform Support 1# Tegra platform Support
2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o 2snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-spdif-objs := tegra_spdif.o
6snd-soc-tegra-utils-objs += tegra_asoc_utils.o 3snd-soc-tegra-utils-objs += tegra_asoc_utils.o
4snd-soc-tegra20-das-objs := tegra20_das.o
5snd-soc-tegra20-i2s-objs := tegra20_i2s.o
6snd-soc-tegra20-spdif-objs := tegra20_spdif.o
7 7
8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o 8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
11obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o 9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
12obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o 10obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o
11obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o
12obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o
13 13
14# Tegra machine Support 14# Tegra machine Support
15snd-soc-tegra-wm8903-objs := tegra_wm8903.o 15snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
new file mode 100644
index 000000000000..812696d9c863
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.c
@@ -0,0 +1,260 @@
1/*
2 * tegra20_das.c - Tegra20 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/debugfs.h>
24#include <linux/device.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30#include <sound/soc.h>
31#include "tegra20_das.h"
32
33#define DRV_NAME "tegra20-das"
34
35static struct tegra20_das *das;
36
37static inline void tegra20_das_write(u32 reg, u32 val)
38{
39 __raw_writel(val, das->regs + reg);
40}
41
42static inline u32 tegra20_das_read(u32 reg)
43{
44 return __raw_readl(das->regs + reg);
45}
46
47int tegra20_das_connect_dap_to_dac(int dap, int dac)
48{
49 u32 addr;
50 u32 reg;
51
52 if (!das)
53 return -ENODEV;
54
55 addr = TEGRA20_DAS_DAP_CTRL_SEL +
56 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
57 reg = dac << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
58
59 tegra20_das_write(addr, reg);
60
61 return 0;
62}
63EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dac);
64
65int tegra20_das_connect_dap_to_dap(int dap, int otherdap, int master,
66 int sdata1rx, int sdata2rx)
67{
68 u32 addr;
69 u32 reg;
70
71 if (!das)
72 return -ENODEV;
73
74 addr = TEGRA20_DAS_DAP_CTRL_SEL +
75 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
76 reg = otherdap << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
77 !!sdata2rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
78 !!sdata1rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
79 !!master << TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
80
81 tegra20_das_write(addr, reg);
82
83 return 0;
84}
85EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dap);
86
87int tegra20_das_connect_dac_to_dap(int dac, int dap)
88{
89 u32 addr;
90 u32 reg;
91
92 if (!das)
93 return -ENODEV;
94
95 addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL +
96 (dac * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
97 reg = dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
98 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
99 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
100
101 tegra20_das_write(addr, reg);
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap);
106
107#ifdef CONFIG_DEBUG_FS
108static int tegra20_das_show(struct seq_file *s, void *unused)
109{
110 int i;
111 u32 addr;
112 u32 reg;
113
114 for (i = 0; i < TEGRA20_DAS_DAP_CTRL_SEL_COUNT; i++) {
115 addr = TEGRA20_DAS_DAP_CTRL_SEL +
116 (i * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
117 reg = tegra20_das_read(addr);
118 seq_printf(s, "TEGRA20_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
119 }
120
121 for (i = 0; i < TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
122 addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL +
123 (i * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
124 reg = tegra20_das_read(addr);
125 seq_printf(s, "TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
126 i, reg);
127 }
128
129 return 0;
130}
131
132static int tegra20_das_debug_open(struct inode *inode, struct file *file)
133{
134 return single_open(file, tegra20_das_show, inode->i_private);
135}
136
137static const struct file_operations tegra20_das_debug_fops = {
138 .open = tegra20_das_debug_open,
139 .read = seq_read,
140 .llseek = seq_lseek,
141 .release = single_release,
142};
143
144static void tegra20_das_debug_add(struct tegra20_das *das)
145{
146 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
147 snd_soc_debugfs_root, das,
148 &tegra20_das_debug_fops);
149}
150
151static void tegra20_das_debug_remove(struct tegra20_das *das)
152{
153 if (das->debug)
154 debugfs_remove(das->debug);
155}
156#else
157static inline void tegra20_das_debug_add(struct tegra20_das *das)
158{
159}
160
161static inline void tegra20_das_debug_remove(struct tegra20_das *das)
162{
163}
164#endif
165
166static int __devinit tegra20_das_probe(struct platform_device *pdev)
167{
168 struct resource *res, *region;
169 int ret = 0;
170
171 if (das)
172 return -ENODEV;
173
174 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL);
175 if (!das) {
176 dev_err(&pdev->dev, "Can't allocate tegra20_das\n");
177 ret = -ENOMEM;
178 goto err;
179 }
180 das->dev = &pdev->dev;
181
182 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
183 if (!res) {
184 dev_err(&pdev->dev, "No memory resource\n");
185 ret = -ENODEV;
186 goto err;
187 }
188
189 region = devm_request_mem_region(&pdev->dev, res->start,
190 resource_size(res), pdev->name);
191 if (!region) {
192 dev_err(&pdev->dev, "Memory region already claimed\n");
193 ret = -EBUSY;
194 goto err;
195 }
196
197 das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
198 if (!das->regs) {
199 dev_err(&pdev->dev, "ioremap failed\n");
200 ret = -ENOMEM;
201 goto err;
202 }
203
204 ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
205 TEGRA20_DAS_DAP_SEL_DAC1);
206 if (ret) {
207 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
208 goto err;
209 }
210 ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_1,
211 TEGRA20_DAS_DAC_SEL_DAP1);
212 if (ret) {
213 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
214 goto err;
215 }
216
217 tegra20_das_debug_add(das);
218
219 platform_set_drvdata(pdev, das);
220
221 return 0;
222
223err:
224 das = NULL;
225 return ret;
226}
227
228static int __devexit tegra20_das_remove(struct platform_device *pdev)
229{
230 if (!das)
231 return -ENODEV;
232
233 tegra20_das_debug_remove(das);
234
235 das = NULL;
236
237 return 0;
238}
239
240static const struct of_device_id tegra20_das_of_match[] __devinitconst = {
241 { .compatible = "nvidia,tegra20-das", },
242 {},
243};
244
245static struct platform_driver tegra20_das_driver = {
246 .probe = tegra20_das_probe,
247 .remove = __devexit_p(tegra20_das_remove),
248 .driver = {
249 .name = DRV_NAME,
250 .owner = THIS_MODULE,
251 .of_match_table = tegra20_das_of_match,
252 },
253};
254module_platform_driver(tegra20_das_driver);
255
256MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
257MODULE_DESCRIPTION("Tegra20 DAS driver");
258MODULE_LICENSE("GPL");
259MODULE_ALIAS("platform:" DRV_NAME);
260MODULE_DEVICE_TABLE(of, tegra20_das_of_match);
diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h
new file mode 100644
index 000000000000..ade4fe080c45
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.h
@@ -0,0 +1,135 @@
1/*
2 * tegra20_das.h - Definitions for Tegra20 DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - 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 __TEGRA20_DAS_H__
24#define __TEGRA20_DAS_H__
25
26/* Register TEGRA20_DAS_DAP_CTRL_SEL */
27#define TEGRA20_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA20_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA20_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA20_DAS_DAP_SEL_DAC1 0
41#define TEGRA20_DAS_DAP_SEL_DAC2 1
42#define TEGRA20_DAS_DAP_SEL_DAC3 2
43#define TEGRA20_DAS_DAP_SEL_DAP1 16
44#define TEGRA20_DAS_DAP_SEL_DAP2 17
45#define TEGRA20_DAS_DAP_SEL_DAP3 18
46#define TEGRA20_DAS_DAP_SEL_DAP4 19
47#define TEGRA20_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA20_DAS_DAC_SEL_DAP1 0
67#define TEGRA20_DAS_DAC_SEL_DAP2 1
68#define TEGRA20_DAS_DAC_SEL_DAP3 2
69#define TEGRA20_DAS_DAC_SEL_DAP4 3
70#define TEGRA20_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA20_DAS_DAP_ID_1 0
77#define TEGRA20_DAS_DAP_ID_2 1
78#define TEGRA20_DAS_DAP_ID_3 2
79#define TEGRA20_DAS_DAP_ID_4 3
80#define TEGRA20_DAS_DAP_ID_5 4
81
82#define TEGRA20_DAS_DAC_ID_1 0
83#define TEGRA20_DAS_DAC_ID_2 1
84#define TEGRA20_DAS_DAC_ID_3 2
85
86struct tegra20_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: TEGRA20_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA20_DAS_DAP_SEL_DAC*
112 */
113extern int tegra20_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: TEGRA20_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA20_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 tegra20_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: TEGRA20_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA20_DAS_DAC_SEL_DAP*
132 */
133extern int tegra20_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/tegra20_i2s.c
index 33509de52540..9427f36e6a25 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * tegra_i2s.c - Tegra I2S driver 2 * tegra20_i2s.c - Tegra20 I2S driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,102 +29,101 @@
29 */ 29 */
30 30
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h> 32#include <linux/debugfs.h>
34#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/io.h>
35#include <linux/module.h>
36#include <linux/of.h>
35#include <linux/platform_device.h> 37#include <linux/platform_device.h>
36#include <linux/seq_file.h> 38#include <linux/seq_file.h>
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/io.h>
39#include <linux/of.h>
40#include <mach/iomap.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/pcm.h> 41#include <sound/pcm.h>
43#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
44#include <sound/soc.h> 43#include <sound/soc.h>
45 44
46#include "tegra_i2s.h" 45#include "tegra20_i2s.h"
47 46
48#define DRV_NAME "tegra-i2s" 47#define DRV_NAME "tegra20-i2s"
49 48
50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val) 49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
51{ 50{
52 __raw_writel(val, i2s->regs + reg); 51 __raw_writel(val, i2s->regs + reg);
53} 52}
54 53
55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg) 54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
56{ 55{
57 return __raw_readl(i2s->regs + reg); 56 return __raw_readl(i2s->regs + reg);
58} 57}
59 58
60#ifdef CONFIG_DEBUG_FS 59#ifdef CONFIG_DEBUG_FS
61static int tegra_i2s_show(struct seq_file *s, void *unused) 60static int tegra20_i2s_show(struct seq_file *s, void *unused)
62{ 61{
63#define REG(r) { r, #r } 62#define REG(r) { r, #r }
64 static const struct { 63 static const struct {
65 int offset; 64 int offset;
66 const char *name; 65 const char *name;
67 } regs[] = { 66 } regs[] = {
68 REG(TEGRA_I2S_CTRL), 67 REG(TEGRA20_I2S_CTRL),
69 REG(TEGRA_I2S_STATUS), 68 REG(TEGRA20_I2S_STATUS),
70 REG(TEGRA_I2S_TIMING), 69 REG(TEGRA20_I2S_TIMING),
71 REG(TEGRA_I2S_FIFO_SCR), 70 REG(TEGRA20_I2S_FIFO_SCR),
72 REG(TEGRA_I2S_PCM_CTRL), 71 REG(TEGRA20_I2S_PCM_CTRL),
73 REG(TEGRA_I2S_NW_CTRL), 72 REG(TEGRA20_I2S_NW_CTRL),
74 REG(TEGRA_I2S_TDM_CTRL), 73 REG(TEGRA20_I2S_TDM_CTRL),
75 REG(TEGRA_I2S_TDM_TX_RX_CTRL), 74 REG(TEGRA20_I2S_TDM_TX_RX_CTRL),
76 }; 75 };
77#undef REG 76#undef REG
78 77
79 struct tegra_i2s *i2s = s->private; 78 struct tegra20_i2s *i2s = s->private;
80 int i; 79 int i;
81 80
82 for (i = 0; i < ARRAY_SIZE(regs); i++) { 81 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_i2s_read(i2s, regs[i].offset); 82 u32 val = tegra20_i2s_read(i2s, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val); 83 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 } 84 }
86 85
87 return 0; 86 return 0;
88} 87}
89 88
90static int tegra_i2s_debug_open(struct inode *inode, struct file *file) 89static int tegra20_i2s_debug_open(struct inode *inode, struct file *file)
91{ 90{
92 return single_open(file, tegra_i2s_show, inode->i_private); 91 return single_open(file, tegra20_i2s_show, inode->i_private);
93} 92}
94 93
95static const struct file_operations tegra_i2s_debug_fops = { 94static const struct file_operations tegra20_i2s_debug_fops = {
96 .open = tegra_i2s_debug_open, 95 .open = tegra20_i2s_debug_open,
97 .read = seq_read, 96 .read = seq_read,
98 .llseek = seq_lseek, 97 .llseek = seq_lseek,
99 .release = single_release, 98 .release = single_release,
100}; 99};
101 100
102static void tegra_i2s_debug_add(struct tegra_i2s *i2s) 101static void tegra20_i2s_debug_add(struct tegra20_i2s *i2s)
103{ 102{
104 i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO, 103 i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
105 snd_soc_debugfs_root, i2s, 104 snd_soc_debugfs_root, i2s,
106 &tegra_i2s_debug_fops); 105 &tegra20_i2s_debug_fops);
107} 106}
108 107
109static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) 108static void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s)
110{ 109{
111 if (i2s->debug) 110 if (i2s->debug)
112 debugfs_remove(i2s->debug); 111 debugfs_remove(i2s->debug);
113} 112}
114#else 113#else
115static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) 114static inline void tegra20_i2s_debug_add(struct tegra20_i2s *i2s, int id)
116{ 115{
117} 116}
118 117
119static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s) 118static inline void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s)
120{ 119{
121} 120}
122#endif 121#endif
123 122
124static int tegra_i2s_set_fmt(struct snd_soc_dai *dai, 123static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
125 unsigned int fmt) 124 unsigned int fmt)
126{ 125{
127 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 126 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
128 127
129 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 128 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
130 case SND_SOC_DAIFMT_NB_NF: 129 case SND_SOC_DAIFMT_NB_NF:
@@ -133,10 +132,10 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
133 return -EINVAL; 132 return -EINVAL;
134 } 133 }
135 134
136 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE; 135 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE;
137 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 136 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
138 case SND_SOC_DAIFMT_CBS_CFS: 137 case SND_SOC_DAIFMT_CBS_CFS:
139 i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE; 138 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
140 break; 139 break;
141 case SND_SOC_DAIFMT_CBM_CFM: 140 case SND_SOC_DAIFMT_CBM_CFM:
142 break; 141 break;
@@ -144,28 +143,28 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
144 return -EINVAL; 143 return -EINVAL;
145 } 144 }
146 145
147 i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK | 146 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
148 TEGRA_I2S_CTRL_LRCK_MASK); 147 TEGRA20_I2S_CTRL_LRCK_MASK);
149 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 148 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
150 case SND_SOC_DAIFMT_DSP_A: 149 case SND_SOC_DAIFMT_DSP_A:
151 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP; 150 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
152 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 151 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
153 break; 152 break;
154 case SND_SOC_DAIFMT_DSP_B: 153 case SND_SOC_DAIFMT_DSP_B:
155 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP; 154 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
156 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW; 155 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
157 break; 156 break;
158 case SND_SOC_DAIFMT_I2S: 157 case SND_SOC_DAIFMT_I2S:
159 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S; 158 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
160 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 159 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
161 break; 160 break;
162 case SND_SOC_DAIFMT_RIGHT_J: 161 case SND_SOC_DAIFMT_RIGHT_J:
163 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM; 162 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
164 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 163 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
165 break; 164 break;
166 case SND_SOC_DAIFMT_LEFT_J: 165 case SND_SOC_DAIFMT_LEFT_J:
167 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM; 166 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
168 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 167 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
169 break; 168 break;
170 default: 169 default:
171 return -EINVAL; 170 return -EINVAL;
@@ -174,27 +173,27 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
174 return 0; 173 return 0;
175} 174}
176 175
177static int tegra_i2s_hw_params(struct snd_pcm_substream *substream, 176static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
178 struct snd_pcm_hw_params *params, 177 struct snd_pcm_hw_params *params,
179 struct snd_soc_dai *dai) 178 struct snd_soc_dai *dai)
180{ 179{
181 struct device *dev = substream->pcm->card->dev; 180 struct device *dev = substream->pcm->card->dev;
182 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 181 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
183 u32 reg; 182 u32 reg;
184 int ret, sample_size, srate, i2sclock, bitcnt; 183 int ret, sample_size, srate, i2sclock, bitcnt;
185 184
186 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK; 185 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
187 switch (params_format(params)) { 186 switch (params_format(params)) {
188 case SNDRV_PCM_FORMAT_S16_LE: 187 case SNDRV_PCM_FORMAT_S16_LE:
189 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16; 188 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16;
190 sample_size = 16; 189 sample_size = 16;
191 break; 190 break;
192 case SNDRV_PCM_FORMAT_S24_LE: 191 case SNDRV_PCM_FORMAT_S24_LE:
193 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24; 192 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24;
194 sample_size = 24; 193 sample_size = 24;
195 break; 194 break;
196 case SNDRV_PCM_FORMAT_S32_LE: 195 case SNDRV_PCM_FORMAT_S32_LE:
197 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32; 196 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32;
198 sample_size = 32; 197 sample_size = 32;
199 break; 198 break;
200 default: 199 default:
@@ -213,79 +212,73 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
213 } 212 }
214 213
215 bitcnt = (i2sclock / (2 * srate)) - 1; 214 bitcnt = (i2sclock / (2 * srate)) - 1;
216 if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 215 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
217 return -EINVAL; 216 return -EINVAL;
218 reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 217 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
219 218
220 if (i2sclock % (2 * srate)) 219 if (i2sclock % (2 * srate))
221 reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE; 220 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
222 221
223 if (!i2s->clk_refs) 222 clk_enable(i2s->clk_i2s);
224 clk_enable(i2s->clk_i2s);
225 223
226 tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg); 224 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg);
227 225
228 tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR, 226 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR,
229 TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | 227 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
230 TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); 228 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
231 229
232 if (!i2s->clk_refs) 230 clk_disable(i2s->clk_i2s);
233 clk_disable(i2s->clk_i2s);
234 231
235 return 0; 232 return 0;
236} 233}
237 234
238static void tegra_i2s_start_playback(struct tegra_i2s *i2s) 235static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
239{ 236{
240 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE; 237 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE;
241 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 238 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
242} 239}
243 240
244static void tegra_i2s_stop_playback(struct tegra_i2s *i2s) 241static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
245{ 242{
246 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE; 243 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE;
247 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 244 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
248} 245}
249 246
250static void tegra_i2s_start_capture(struct tegra_i2s *i2s) 247static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
251{ 248{
252 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE; 249 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE;
253 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 250 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
254} 251}
255 252
256static void tegra_i2s_stop_capture(struct tegra_i2s *i2s) 253static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
257{ 254{
258 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE; 255 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE;
259 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 256 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
260} 257}
261 258
262static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 259static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
263 struct snd_soc_dai *dai) 260 struct snd_soc_dai *dai)
264{ 261{
265 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 262 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
266 263
267 switch (cmd) { 264 switch (cmd) {
268 case SNDRV_PCM_TRIGGER_START: 265 case SNDRV_PCM_TRIGGER_START:
269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 266 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
270 case SNDRV_PCM_TRIGGER_RESUME: 267 case SNDRV_PCM_TRIGGER_RESUME:
271 if (!i2s->clk_refs) 268 clk_enable(i2s->clk_i2s);
272 clk_enable(i2s->clk_i2s);
273 i2s->clk_refs++;
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
275 tegra_i2s_start_playback(i2s); 270 tegra20_i2s_start_playback(i2s);
276 else 271 else
277 tegra_i2s_start_capture(i2s); 272 tegra20_i2s_start_capture(i2s);
278 break; 273 break;
279 case SNDRV_PCM_TRIGGER_STOP: 274 case SNDRV_PCM_TRIGGER_STOP:
280 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 275 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
281 case SNDRV_PCM_TRIGGER_SUSPEND: 276 case SNDRV_PCM_TRIGGER_SUSPEND:
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 277 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
283 tegra_i2s_stop_playback(i2s); 278 tegra20_i2s_stop_playback(i2s);
284 else 279 else
285 tegra_i2s_stop_capture(i2s); 280 tegra20_i2s_stop_capture(i2s);
286 i2s->clk_refs--; 281 clk_disable(i2s->clk_i2s);
287 if (!i2s->clk_refs)
288 clk_disable(i2s->clk_i2s);
289 break; 282 break;
290 default: 283 default:
291 return -EINVAL; 284 return -EINVAL;
@@ -294,9 +287,9 @@ static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
294 return 0; 287 return 0;
295} 288}
296 289
297static int tegra_i2s_probe(struct snd_soc_dai *dai) 290static int tegra20_i2s_probe(struct snd_soc_dai *dai)
298{ 291{
299 struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai); 292 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
300 293
301 dai->capture_dma_data = &i2s->capture_dma_data; 294 dai->capture_dma_data = &i2s->capture_dma_data;
302 dai->playback_dma_data = &i2s->playback_dma_data; 295 dai->playback_dma_data = &i2s->playback_dma_data;
@@ -304,14 +297,14 @@ static int tegra_i2s_probe(struct snd_soc_dai *dai)
304 return 0; 297 return 0;
305} 298}
306 299
307static const struct snd_soc_dai_ops tegra_i2s_dai_ops = { 300static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
308 .set_fmt = tegra_i2s_set_fmt, 301 .set_fmt = tegra20_i2s_set_fmt,
309 .hw_params = tegra_i2s_hw_params, 302 .hw_params = tegra20_i2s_hw_params,
310 .trigger = tegra_i2s_trigger, 303 .trigger = tegra20_i2s_trigger,
311}; 304};
312 305
313static const struct snd_soc_dai_driver tegra_i2s_dai_template = { 306static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
314 .probe = tegra_i2s_probe, 307 .probe = tegra20_i2s_probe,
315 .playback = { 308 .playback = {
316 .channels_min = 2, 309 .channels_min = 2,
317 .channels_max = 2, 310 .channels_max = 2,
@@ -324,27 +317,27 @@ static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
324 .rates = SNDRV_PCM_RATE_8000_96000, 317 .rates = SNDRV_PCM_RATE_8000_96000,
325 .formats = SNDRV_PCM_FMTBIT_S16_LE, 318 .formats = SNDRV_PCM_FMTBIT_S16_LE,
326 }, 319 },
327 .ops = &tegra_i2s_dai_ops, 320 .ops = &tegra20_i2s_dai_ops,
328 .symmetric_rates = 1, 321 .symmetric_rates = 1,
329}; 322};
330 323
331static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) 324static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
332{ 325{
333 struct tegra_i2s * i2s; 326 struct tegra20_i2s *i2s;
334 struct resource *mem, *memregion, *dmareq; 327 struct resource *mem, *memregion, *dmareq;
335 u32 of_dma[2]; 328 u32 of_dma[2];
336 u32 dma_ch; 329 u32 dma_ch;
337 int ret; 330 int ret;
338 331
339 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL); 332 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
340 if (!i2s) { 333 if (!i2s) {
341 dev_err(&pdev->dev, "Can't allocate tegra_i2s\n"); 334 dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
342 ret = -ENOMEM; 335 ret = -ENOMEM;
343 goto err; 336 goto err;
344 } 337 }
345 dev_set_drvdata(&pdev->dev, i2s); 338 dev_set_drvdata(&pdev->dev, i2s);
346 339
347 i2s->dai = tegra_i2s_dai_template; 340 i2s->dai = tegra20_i2s_dai_template;
348 i2s->dai.name = dev_name(&pdev->dev); 341 i2s->dai.name = dev_name(&pdev->dev);
349 342
350 i2s->clk_i2s = clk_get(&pdev->dev, NULL); 343 i2s->clk_i2s = clk_get(&pdev->dev, NULL);
@@ -390,17 +383,17 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
390 goto err_clk_put; 383 goto err_clk_put;
391 } 384 }
392 385
393 i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2; 386 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
394 i2s->capture_dma_data.wrap = 4; 387 i2s->capture_dma_data.wrap = 4;
395 i2s->capture_dma_data.width = 32; 388 i2s->capture_dma_data.width = 32;
396 i2s->capture_dma_data.req_sel = dma_ch; 389 i2s->capture_dma_data.req_sel = dma_ch;
397 390
398 i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1; 391 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
399 i2s->playback_dma_data.wrap = 4; 392 i2s->playback_dma_data.wrap = 4;
400 i2s->playback_dma_data.width = 32; 393 i2s->playback_dma_data.width = 32;
401 i2s->playback_dma_data.req_sel = dma_ch; 394 i2s->playback_dma_data.req_sel = dma_ch;
402 395
403 i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED; 396 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
404 397
405 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); 398 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
406 if (ret) { 399 if (ret) {
@@ -409,47 +402,56 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
409 goto err_clk_put; 402 goto err_clk_put;
410 } 403 }
411 404
412 tegra_i2s_debug_add(i2s); 405 ret = tegra_pcm_platform_register(&pdev->dev);
406 if (ret) {
407 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
408 goto err_unregister_dai;
409 }
410
411 tegra20_i2s_debug_add(i2s);
413 412
414 return 0; 413 return 0;
415 414
415err_unregister_dai:
416 snd_soc_unregister_dai(&pdev->dev);
416err_clk_put: 417err_clk_put:
417 clk_put(i2s->clk_i2s); 418 clk_put(i2s->clk_i2s);
418err: 419err:
419 return ret; 420 return ret;
420} 421}
421 422
422static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev) 423static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev)
423{ 424{
424 struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev); 425 struct tegra20_i2s *i2s = dev_get_drvdata(&pdev->dev);
425 426
427 tegra_pcm_platform_unregister(&pdev->dev);
426 snd_soc_unregister_dai(&pdev->dev); 428 snd_soc_unregister_dai(&pdev->dev);
427 429
428 tegra_i2s_debug_remove(i2s); 430 tegra20_i2s_debug_remove(i2s);
429 431
430 clk_put(i2s->clk_i2s); 432 clk_put(i2s->clk_i2s);
431 433
432 return 0; 434 return 0;
433} 435}
434 436
435static const struct of_device_id tegra_i2s_of_match[] __devinitconst = { 437static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = {
436 { .compatible = "nvidia,tegra20-i2s", }, 438 { .compatible = "nvidia,tegra20-i2s", },
437 {}, 439 {},
438}; 440};
439 441
440static struct platform_driver tegra_i2s_driver = { 442static struct platform_driver tegra20_i2s_driver = {
441 .driver = { 443 .driver = {
442 .name = DRV_NAME, 444 .name = DRV_NAME,
443 .owner = THIS_MODULE, 445 .owner = THIS_MODULE,
444 .of_match_table = tegra_i2s_of_match, 446 .of_match_table = tegra20_i2s_of_match,
445 }, 447 },
446 .probe = tegra_i2s_platform_probe, 448 .probe = tegra20_i2s_platform_probe,
447 .remove = __devexit_p(tegra_i2s_platform_remove), 449 .remove = __devexit_p(tegra20_i2s_platform_remove),
448}; 450};
449module_platform_driver(tegra_i2s_driver); 451module_platform_driver(tegra20_i2s_driver);
450 452
451MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 453MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
452MODULE_DESCRIPTION("Tegra I2S ASoC driver"); 454MODULE_DESCRIPTION("Tegra20 I2S ASoC driver");
453MODULE_LICENSE("GPL"); 455MODULE_LICENSE("GPL");
454MODULE_ALIAS("platform:" DRV_NAME); 456MODULE_ALIAS("platform:" DRV_NAME);
455MODULE_DEVICE_TABLE(of, tegra_i2s_of_match); 457MODULE_DEVICE_TABLE(of, tegra20_i2s_of_match);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
new file mode 100644
index 000000000000..86ab327dbd26
--- /dev/null
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -0,0 +1,165 @@
1/*
2 * tegra20_i2s.h - Definitions for Tegra20 I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - 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 __TEGRA20_I2S_H__
32#define __TEGRA20_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA20_I2S1_BASE and TEGRA20_I2S2_BASE */
37
38#define TEGRA20_I2S_CTRL 0x00
39#define TEGRA20_I2S_STATUS 0x04
40#define TEGRA20_I2S_TIMING 0x08
41#define TEGRA20_I2S_FIFO_SCR 0x0c
42#define TEGRA20_I2S_PCM_CTRL 0x10
43#define TEGRA20_I2S_NW_CTRL 0x14
44#define TEGRA20_I2S_TDM_CTRL 0x20
45#define TEGRA20_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA20_I2S_FIFO1 0x40
47#define TEGRA20_I2S_FIFO2 0x80
48
49/* Fields in TEGRA20_I2S_CTRL */
50
51#define TEGRA20_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA20_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA20_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA20_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA20_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA20_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA20_I2S_LRCK_LEFT_LOW 0
59#define TEGRA20_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA20_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA20_I2S_CTRL_LRCK_MASK (1 << TEGRA20_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA20_I2S_CTRL_LRCK_L_LOW (TEGRA20_I2S_LRCK_LEFT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA20_I2S_CTRL_LRCK_R_LOW (TEGRA20_I2S_LRCK_RIGHT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA20_I2S_BIT_FORMAT_I2S 0
67#define TEGRA20_I2S_BIT_FORMAT_RJM 1
68#define TEGRA20_I2S_BIT_FORMAT_LJM 2
69#define TEGRA20_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA20_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA20_I2S_CTRL_BIT_FORMAT_I2S (TEGRA20_I2S_BIT_FORMAT_I2S << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA20_I2S_CTRL_BIT_FORMAT_RJM (TEGRA20_I2S_BIT_FORMAT_RJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA20_I2S_CTRL_BIT_FORMAT_LJM (TEGRA20_I2S_BIT_FORMAT_LJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA20_I2S_CTRL_BIT_FORMAT_DSP (TEGRA20_I2S_BIT_FORMAT_DSP << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA20_I2S_BIT_SIZE_16 0
79#define TEGRA20_I2S_BIT_SIZE_20 1
80#define TEGRA20_I2S_BIT_SIZE_24 2
81#define TEGRA20_I2S_BIT_SIZE_32 3
82
83#define TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA20_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA20_I2S_CTRL_BIT_SIZE_16 (TEGRA20_I2S_BIT_SIZE_16 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA20_I2S_CTRL_BIT_SIZE_20 (TEGRA20_I2S_BIT_SIZE_20 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA20_I2S_CTRL_BIT_SIZE_24 (TEGRA20_I2S_BIT_SIZE_24 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA20_I2S_CTRL_BIT_SIZE_32 (TEGRA20_I2S_BIT_SIZE_32 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA20_I2S_FIFO_16_LSB 0
91#define TEGRA20_I2S_FIFO_20_LSB 1
92#define TEGRA20_I2S_FIFO_24_LSB 2
93#define TEGRA20_I2S_FIFO_32 3
94#define TEGRA20_I2S_FIFO_PACKED 7
95
96#define TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA20_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA20_I2S_FIFO_16_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA20_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA20_I2S_FIFO_20_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA20_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA20_I2S_FIFO_24_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA20_I2S_CTRL_FIFO_FORMAT_32 (TEGRA20_I2S_FIFO_32 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA20_I2S_FIFO_PACKED << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA20_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA20_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA20_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA20_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA20_I2S_STATUS */
110
111#define TEGRA20_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA20_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA20_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA20_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA20_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA20_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA20_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA20_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA20_I2S_TIMING */
121
122#define TEGRA20_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA20_I2S_FIFO_SCR */
128
129#define TEGRA20_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA20_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA20_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA20_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA20_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra20_i2s {
156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
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_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 475428cf270e..ef5d49ed5658 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * tegra_spdif.c - Tegra SPDIF driver 2 * tegra20_spdif.c - Tegra20 SPDIF driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc. 5 * Copyright (C) 2011-2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -21,120 +21,119 @@
21 */ 21 */
22 22
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/module.h>
25#include <linux/debugfs.h> 24#include <linux/debugfs.h>
26#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/io.h>
27#include <linux/module.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/seq_file.h> 29#include <linux/seq_file.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/io.h>
31#include <mach/iomap.h>
32#include <sound/core.h> 31#include <sound/core.h>
33#include <sound/pcm.h> 32#include <sound/pcm.h>
34#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
35#include <sound/soc.h> 34#include <sound/soc.h>
36 35
37#include "tegra_spdif.h" 36#include "tegra20_spdif.h"
38 37
39#define DRV_NAME "tegra-spdif" 38#define DRV_NAME "tegra20-spdif"
40 39
41static inline void tegra_spdif_write(struct tegra_spdif *spdif, u32 reg, 40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
42 u32 val) 41 u32 val)
43{ 42{
44 __raw_writel(val, spdif->regs + reg); 43 __raw_writel(val, spdif->regs + reg);
45} 44}
46 45
47static inline u32 tegra_spdif_read(struct tegra_spdif *spdif, u32 reg) 46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
48{ 47{
49 return __raw_readl(spdif->regs + reg); 48 return __raw_readl(spdif->regs + reg);
50} 49}
51 50
52#ifdef CONFIG_DEBUG_FS 51#ifdef CONFIG_DEBUG_FS
53static int tegra_spdif_show(struct seq_file *s, void *unused) 52static int tegra20_spdif_show(struct seq_file *s, void *unused)
54{ 53{
55#define REG(r) { r, #r } 54#define REG(r) { r, #r }
56 static const struct { 55 static const struct {
57 int offset; 56 int offset;
58 const char *name; 57 const char *name;
59 } regs[] = { 58 } regs[] = {
60 REG(TEGRA_SPDIF_CTRL), 59 REG(TEGRA20_SPDIF_CTRL),
61 REG(TEGRA_SPDIF_STATUS), 60 REG(TEGRA20_SPDIF_STATUS),
62 REG(TEGRA_SPDIF_STROBE_CTRL), 61 REG(TEGRA20_SPDIF_STROBE_CTRL),
63 REG(TEGRA_SPDIF_DATA_FIFO_CSR), 62 REG(TEGRA20_SPDIF_DATA_FIFO_CSR),
64 REG(TEGRA_SPDIF_CH_STA_RX_A), 63 REG(TEGRA20_SPDIF_CH_STA_RX_A),
65 REG(TEGRA_SPDIF_CH_STA_RX_B), 64 REG(TEGRA20_SPDIF_CH_STA_RX_B),
66 REG(TEGRA_SPDIF_CH_STA_RX_C), 65 REG(TEGRA20_SPDIF_CH_STA_RX_C),
67 REG(TEGRA_SPDIF_CH_STA_RX_D), 66 REG(TEGRA20_SPDIF_CH_STA_RX_D),
68 REG(TEGRA_SPDIF_CH_STA_RX_E), 67 REG(TEGRA20_SPDIF_CH_STA_RX_E),
69 REG(TEGRA_SPDIF_CH_STA_RX_F), 68 REG(TEGRA20_SPDIF_CH_STA_RX_F),
70 REG(TEGRA_SPDIF_CH_STA_TX_A), 69 REG(TEGRA20_SPDIF_CH_STA_TX_A),
71 REG(TEGRA_SPDIF_CH_STA_TX_B), 70 REG(TEGRA20_SPDIF_CH_STA_TX_B),
72 REG(TEGRA_SPDIF_CH_STA_TX_C), 71 REG(TEGRA20_SPDIF_CH_STA_TX_C),
73 REG(TEGRA_SPDIF_CH_STA_TX_D), 72 REG(TEGRA20_SPDIF_CH_STA_TX_D),
74 REG(TEGRA_SPDIF_CH_STA_TX_E), 73 REG(TEGRA20_SPDIF_CH_STA_TX_E),
75 REG(TEGRA_SPDIF_CH_STA_TX_F), 74 REG(TEGRA20_SPDIF_CH_STA_TX_F),
76 }; 75 };
77#undef REG 76#undef REG
78 77
79 struct tegra_spdif *spdif = s->private; 78 struct tegra20_spdif *spdif = s->private;
80 int i; 79 int i;
81 80
82 for (i = 0; i < ARRAY_SIZE(regs); i++) { 81 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_spdif_read(spdif, regs[i].offset); 82 u32 val = tegra20_spdif_read(spdif, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val); 83 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 } 84 }
86 85
87 return 0; 86 return 0;
88} 87}
89 88
90static int tegra_spdif_debug_open(struct inode *inode, struct file *file) 89static int tegra20_spdif_debug_open(struct inode *inode, struct file *file)
91{ 90{
92 return single_open(file, tegra_spdif_show, inode->i_private); 91 return single_open(file, tegra20_spdif_show, inode->i_private);
93} 92}
94 93
95static const struct file_operations tegra_spdif_debug_fops = { 94static const struct file_operations tegra20_spdif_debug_fops = {
96 .open = tegra_spdif_debug_open, 95 .open = tegra20_spdif_debug_open,
97 .read = seq_read, 96 .read = seq_read,
98 .llseek = seq_lseek, 97 .llseek = seq_lseek,
99 .release = single_release, 98 .release = single_release,
100}; 99};
101 100
102static void tegra_spdif_debug_add(struct tegra_spdif *spdif) 101static void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
103{ 102{
104 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO, 103 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
105 snd_soc_debugfs_root, spdif, 104 snd_soc_debugfs_root, spdif,
106 &tegra_spdif_debug_fops); 105 &tegra20_spdif_debug_fops);
107} 106}
108 107
109static void tegra_spdif_debug_remove(struct tegra_spdif *spdif) 108static void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
110{ 109{
111 if (spdif->debug) 110 if (spdif->debug)
112 debugfs_remove(spdif->debug); 111 debugfs_remove(spdif->debug);
113} 112}
114#else 113#else
115static inline void tegra_spdif_debug_add(struct tegra_spdif *spdif) 114static inline void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
116{ 115{
117} 116}
118 117
119static inline void tegra_spdif_debug_remove(struct tegra_spdif *spdif) 118static inline void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
120{ 119{
121} 120}
122#endif 121#endif
123 122
124static int tegra_spdif_hw_params(struct snd_pcm_substream *substream, 123static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 124 struct snd_pcm_hw_params *params,
126 struct snd_soc_dai *dai) 125 struct snd_soc_dai *dai)
127{ 126{
128 struct device *dev = substream->pcm->card->dev; 127 struct device *dev = substream->pcm->card->dev;
129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 128 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
130 int ret, spdifclock; 129 int ret, spdifclock;
131 130
132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; 131 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK;
133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; 132 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
134 switch (params_format(params)) { 133 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE: 134 case SNDRV_PCM_FORMAT_S16_LE:
136 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_PACK; 135 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK;
137 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_BIT_MODE_16BIT; 136 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
138 break; 137 break;
139 default: 138 default:
140 return -EINVAL; 139 return -EINVAL;
@@ -175,39 +174,35 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
175 return 0; 174 return 0;
176} 175}
177 176
178static void tegra_spdif_start_playback(struct tegra_spdif *spdif) 177static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
179{ 178{
180 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_TX_EN; 179 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN;
181 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl); 180 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
182} 181}
183 182
184static void tegra_spdif_stop_playback(struct tegra_spdif *spdif) 183static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
185{ 184{
186 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_TX_EN; 185 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN;
187 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl); 186 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
188} 187}
189 188
190static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 189static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
191 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
192{ 191{
193 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 192 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
194 193
195 switch (cmd) { 194 switch (cmd) {
196 case SNDRV_PCM_TRIGGER_START: 195 case SNDRV_PCM_TRIGGER_START:
197 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 196 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
198 case SNDRV_PCM_TRIGGER_RESUME: 197 case SNDRV_PCM_TRIGGER_RESUME:
199 if (!spdif->clk_refs) 198 clk_enable(spdif->clk_spdif_out);
200 clk_enable(spdif->clk_spdif_out); 199 tegra20_spdif_start_playback(spdif);
201 spdif->clk_refs++;
202 tegra_spdif_start_playback(spdif);
203 break; 200 break;
204 case SNDRV_PCM_TRIGGER_STOP: 201 case SNDRV_PCM_TRIGGER_STOP:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 202 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 case SNDRV_PCM_TRIGGER_SUSPEND: 203 case SNDRV_PCM_TRIGGER_SUSPEND:
207 tegra_spdif_stop_playback(spdif); 204 tegra20_spdif_stop_playback(spdif);
208 spdif->clk_refs--; 205 clk_disable(spdif->clk_spdif_out);
209 if (!spdif->clk_refs)
210 clk_disable(spdif->clk_spdif_out);
211 break; 206 break;
212 default: 207 default:
213 return -EINVAL; 208 return -EINVAL;
@@ -216,9 +211,9 @@ static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
216 return 0; 211 return 0;
217} 212}
218 213
219static int tegra_spdif_probe(struct snd_soc_dai *dai) 214static int tegra20_spdif_probe(struct snd_soc_dai *dai)
220{ 215{
221 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 216 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
222 217
223 dai->capture_dma_data = NULL; 218 dai->capture_dma_data = NULL;
224 dai->playback_dma_data = &spdif->playback_dma_data; 219 dai->playback_dma_data = &spdif->playback_dma_data;
@@ -226,14 +221,14 @@ static int tegra_spdif_probe(struct snd_soc_dai *dai)
226 return 0; 221 return 0;
227} 222}
228 223
229static const struct snd_soc_dai_ops tegra_spdif_dai_ops = { 224static const struct snd_soc_dai_ops tegra20_spdif_dai_ops = {
230 .hw_params = tegra_spdif_hw_params, 225 .hw_params = tegra20_spdif_hw_params,
231 .trigger = tegra_spdif_trigger, 226 .trigger = tegra20_spdif_trigger,
232}; 227};
233 228
234static struct snd_soc_dai_driver tegra_spdif_dai = { 229static struct snd_soc_dai_driver tegra20_spdif_dai = {
235 .name = DRV_NAME, 230 .name = DRV_NAME,
236 .probe = tegra_spdif_probe, 231 .probe = tegra20_spdif_probe,
237 .playback = { 232 .playback = {
238 .channels_min = 2, 233 .channels_min = 2,
239 .channels_max = 2, 234 .channels_max = 2,
@@ -241,20 +236,21 @@ static struct snd_soc_dai_driver tegra_spdif_dai = {
241 SNDRV_PCM_RATE_48000, 236 SNDRV_PCM_RATE_48000,
242 .formats = SNDRV_PCM_FMTBIT_S16_LE, 237 .formats = SNDRV_PCM_FMTBIT_S16_LE,
243 }, 238 },
244 .ops = &tegra_spdif_dai_ops, 239 .ops = &tegra20_spdif_dai_ops,
245}; 240};
246 241
247static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev) 242static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
248{ 243{
249 struct tegra_spdif *spdif; 244 struct tegra20_spdif *spdif;
250 struct resource *mem, *memregion, *dmareq; 245 struct resource *mem, *memregion, *dmareq;
251 int ret; 246 int ret;
252 247
253 spdif = kzalloc(sizeof(struct tegra_spdif), GFP_KERNEL); 248 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
249 GFP_KERNEL);
254 if (!spdif) { 250 if (!spdif) {
255 dev_err(&pdev->dev, "Can't allocate tegra_spdif\n"); 251 dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
256 ret = -ENOMEM; 252 ret = -ENOMEM;
257 goto exit; 253 goto err;
258 } 254 }
259 dev_set_drvdata(&pdev->dev, spdif); 255 dev_set_drvdata(&pdev->dev, spdif);
260 256
@@ -262,7 +258,7 @@ static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
262 if (IS_ERR(spdif->clk_spdif_out)) { 258 if (IS_ERR(spdif->clk_spdif_out)) {
263 pr_err("Can't retrieve spdif clock\n"); 259 pr_err("Can't retrieve spdif clock\n");
264 ret = PTR_ERR(spdif->clk_spdif_out); 260 ret = PTR_ERR(spdif->clk_spdif_out);
265 goto err_free; 261 goto err;
266 } 262 }
267 263
268 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 264 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -279,82 +275,77 @@ static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
279 goto err_clk_put; 275 goto err_clk_put;
280 } 276 }
281 277
282 memregion = request_mem_region(mem->start, resource_size(mem), 278 memregion = devm_request_mem_region(&pdev->dev, mem->start,
283 DRV_NAME); 279 resource_size(mem), DRV_NAME);
284 if (!memregion) { 280 if (!memregion) {
285 dev_err(&pdev->dev, "Memory region already claimed\n"); 281 dev_err(&pdev->dev, "Memory region already claimed\n");
286 ret = -EBUSY; 282 ret = -EBUSY;
287 goto err_clk_put; 283 goto err_clk_put;
288 } 284 }
289 285
290 spdif->regs = ioremap(mem->start, resource_size(mem)); 286 spdif->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
291 if (!spdif->regs) { 287 if (!spdif->regs) {
292 dev_err(&pdev->dev, "ioremap failed\n"); 288 dev_err(&pdev->dev, "ioremap failed\n");
293 ret = -ENOMEM; 289 ret = -ENOMEM;
294 goto err_release; 290 goto err_clk_put;
295 } 291 }
296 292
297 spdif->playback_dma_data.addr = mem->start + TEGRA_SPDIF_DATA_OUT; 293 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
298 spdif->playback_dma_data.wrap = 4; 294 spdif->playback_dma_data.wrap = 4;
299 spdif->playback_dma_data.width = 32; 295 spdif->playback_dma_data.width = 32;
300 spdif->playback_dma_data.req_sel = dmareq->start; 296 spdif->playback_dma_data.req_sel = dmareq->start;
301 297
302 ret = snd_soc_register_dai(&pdev->dev, &tegra_spdif_dai); 298 ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai);
303 if (ret) { 299 if (ret) {
304 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 300 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
305 ret = -ENOMEM; 301 ret = -ENOMEM;
306 goto err_unmap; 302 goto err_clk_put;
307 } 303 }
308 304
309 tegra_spdif_debug_add(spdif); 305 ret = tegra_pcm_platform_register(&pdev->dev);
306 if (ret) {
307 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
308 goto err_unregister_dai;
309 }
310
311 tegra20_spdif_debug_add(spdif);
310 312
311 return 0; 313 return 0;
312 314
313err_unmap: 315err_unregister_dai:
314 iounmap(spdif->regs); 316 snd_soc_unregister_dai(&pdev->dev);
315err_release:
316 release_mem_region(mem->start, resource_size(mem));
317err_clk_put: 317err_clk_put:
318 clk_put(spdif->clk_spdif_out); 318 clk_put(spdif->clk_spdif_out);
319err_free: 319err:
320 kfree(spdif);
321exit:
322 return ret; 320 return ret;
323} 321}
324 322
325static int __devexit tegra_spdif_platform_remove(struct platform_device *pdev) 323static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev)
326{ 324{
327 struct tegra_spdif *spdif = dev_get_drvdata(&pdev->dev); 325 struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev);
328 struct resource *res;
329 326
327 tegra_pcm_platform_unregister(&pdev->dev);
330 snd_soc_unregister_dai(&pdev->dev); 328 snd_soc_unregister_dai(&pdev->dev);
331 329
332 tegra_spdif_debug_remove(spdif); 330 tegra20_spdif_debug_remove(spdif);
333
334 iounmap(spdif->regs);
335
336 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 release_mem_region(res->start, resource_size(res));
338 331
339 clk_put(spdif->clk_spdif_out); 332 clk_put(spdif->clk_spdif_out);
340 333
341 kfree(spdif);
342
343 return 0; 334 return 0;
344} 335}
345 336
346static struct platform_driver tegra_spdif_driver = { 337static struct platform_driver tegra20_spdif_driver = {
347 .driver = { 338 .driver = {
348 .name = DRV_NAME, 339 .name = DRV_NAME,
349 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
350 }, 341 },
351 .probe = tegra_spdif_platform_probe, 342 .probe = tegra20_spdif_platform_probe,
352 .remove = __devexit_p(tegra_spdif_platform_remove), 343 .remove = __devexit_p(tegra20_spdif_platform_remove),
353}; 344};
354 345
355module_platform_driver(tegra_spdif_driver); 346module_platform_driver(tegra20_spdif_driver);
356 347
357MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 348MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
358MODULE_DESCRIPTION("Tegra SPDIF ASoC driver"); 349MODULE_DESCRIPTION("Tegra20 SPDIF ASoC driver");
359MODULE_LICENSE("GPL"); 350MODULE_LICENSE("GPL");
360MODULE_ALIAS("platform:" DRV_NAME); 351MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
new file mode 100644
index 000000000000..823af4c6bb7c
--- /dev/null
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -0,0 +1,472 @@
1/*
2 * tegra20_spdif.h - Definitions for Tegra20 SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2008-2009, NVIDIA Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#ifndef __TEGRA20_SPDIF_H__
27#define __TEGRA20_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA20_SPDIF_BASE */
32
33#define TEGRA20_SPDIF_CTRL 0x0
34#define TEGRA20_SPDIF_STATUS 0x4
35#define TEGRA20_SPDIF_STROBE_CTRL 0x8
36#define TEGRA20_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA20_SPDIF_DATA_OUT 0x40
38#define TEGRA20_SPDIF_DATA_IN 0x80
39#define TEGRA20_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA20_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA20_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA20_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA20_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA20_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA20_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA20_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA20_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA20_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA20_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA20_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA20_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA20_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA20_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA20_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA20_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA20_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA20_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA20_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA20_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA20_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA20_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA20_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA20_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA20_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA20_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA20_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA20_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA20_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA20_SPDIF_CTRL_LBK_EN (1 << 15)
103
104/*
105 * Pack data mode:
106 * 0 = Single data (16 bit needs to be padded to match the
107 * interface data bit size).
108 * 1 = Packeted left/right channel data into a single word.
109 */
110#define TEGRA20_SPDIF_CTRL_PACK (1 << 14)
111
112/*
113 * 00 = 16bit data
114 * 01 = 20bit data
115 * 10 = 24bit data
116 * 11 = raw data
117 */
118#define TEGRA20_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA20_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA20_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA20_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA20_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA20_SPDIF_BIT_MODE_16BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA20_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA20_SPDIF_BIT_MODE_20BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA20_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA20_SPDIF_BIT_MODE_24BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA20_SPDIF_CTRL_BIT_MODE_RAW (TEGRA20_SPDIF_BIT_MODE_RAW << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA20_SPDIF_STATUS */
131
132/*
133 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
134 * write a 1 to the corresponding bit location to clear the status.
135 */
136
137/*
138 * Receiver(RX) shifter is busy receiving data.
139 * This bit is asserted when the receiver first locked onto the
140 * preamble of the data stream after RX_EN is asserted. This bit is
141 * deasserted when either,
142 * (a) the end of a frame is reached after RX_EN is deeasserted, or
143 * (b) the SPDIF data stream becomes inactive.
144 */
145#define TEGRA20_SPDIF_STATUS_RX_BSY (1 << 29)
146
147/*
148 * Transmitter(TX) shifter is busy transmitting data.
149 * This bit is asserted when TX_EN is asserted.
150 * This bit is deasserted when the end of a frame is reached after
151 * TX_EN is deasserted.
152 */
153#define TEGRA20_SPDIF_STATUS_TX_BSY (1 << 28)
154
155/*
156 * TX is busy shifting out channel status.
157 * This bit is asserted when both TX_EN and TC_EN are asserted and
158 * data from CH_STA_TX_A register is loaded into the internal shifter.
159 * This bit is deasserted when either,
160 * (a) the end of a frame is reached after TX_EN is deasserted, or
161 * (b) CH_STA_TX_F register is loaded into the internal shifter.
162 */
163#define TEGRA20_SPDIF_STATUS_TC_BSY (1 << 27)
164
165/*
166 * TX User data FIFO busy.
167 * This bit is asserted when TX_EN and TXU_EN are asserted and
168 * there's data in the TX user FIFO. This bit is deassert when either,
169 * (a) the end of a frame is reached after TX_EN is deasserted, or
170 * (b) there's no data left in the TX user FIFO.
171 */
172#define TEGRA20_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA20_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA20_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA20_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA20_SPDIF_STATUS_IS_B (1 << 22)
185
186/*
187 * RX channel block data receive status:
188 * 0=entire block not recieved yet.
189 * 1=received entire block of channel status,
190 */
191#define TEGRA20_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA20_SPDIF_STATUS_IS_U (1 << 20)
195
196/*
197 * RX User FIFO Status:
198 * 1=attention level reached, 0=attention level not reached.
199 */
200#define TEGRA20_SPDIF_STATUS_QS_RU (1 << 19)
201
202/*
203 * TX User FIFO Status:
204 * 1=attention level reached, 0=attention level not reached.
205 */
206#define TEGRA20_SPDIF_STATUS_QS_TU (1 << 18)
207
208/*
209 * RX Data FIFO Status:
210 * 1=attention level reached, 0=attention level not reached.
211 */
212#define TEGRA20_SPDIF_STATUS_QS_RX (1 << 17)
213
214/*
215 * TX Data FIFO Status:
216 * 1=attention level reached, 0=attention level not reached.
217 */
218#define TEGRA20_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA20_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA20_SPDIF_STROBE_CTRL_STROBE (1 << 15)
231
232/*
233 * Manual data strobe time within the bi-phase clock period (in terms of
234 * the number of over-sampling clocks).
235 */
236#define TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
238
239/*
240 * Manual SPDIFIN bi-phase clock period (in terms of the number of
241 * over-sampling clocks).
242 */
243#define TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
245
246/* Fields in SPDIF_DATA_FIFO_CSR */
247
248/* Clear Receiver User FIFO (RX USR.FIFO) */
249#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
292
293/* Clear Receiver Data FIFO (RX DATA.FIFO) */
294#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA20_SPDIF_DATA_OUT */
339
340/*
341 * This register has 5 different formats:
342 * 16-bit (BIT_MODE=00, PACK=0)
343 * 20-bit (BIT_MODE=01, PACK=0)
344 * 24-bit (BIT_MODE=10, PACK=0)
345 * raw (BIT_MODE=11, PACK=0)
346 * 16-bit packed (BIT_MODE=00, PACK=1)
347 */
348
349#define TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA20_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA20_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA20_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA20_SPDIF_DATA_IN */
379
380/*
381 * This register has 5 different formats:
382 * 16-bit (BIT_MODE=00, PACK=0)
383 * 20-bit (BIT_MODE=01, PACK=0)
384 * 24-bit (BIT_MODE=10, PACK=0)
385 * raw (BIT_MODE=11, PACK=0)
386 * 16-bit packed (BIT_MODE=00, PACK=1)
387 *
388 * Bits 31:24 are common to all modes except 16-bit packed
389 */
390
391#define TEGRA20_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA20_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA20_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA20_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA20_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA20_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA20_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA20_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA20_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA20_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA20_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA20_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA20_SPDIF_CH_STA_RX_F */
429
430/*
431 * The 6-word receive channel data page buffer holds a block (192 frames) of
432 * channel status information. The order of receive is from LSB to MSB
433 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
434 */
435
436/* Fields in TEGRA20_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA20_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA20_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA20_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA20_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA20_SPDIF_CH_STA_TX_F */
442
443/*
444 * The 6-word transmit channel data page buffer holds a block (192 frames) of
445 * channel status information. The order of transmission is from LSB to MSB
446 * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
447 */
448
449/* Fields in TEGRA20_SPDIF_USR_STA_RX_A */
450
451/*
452 * This 4-word deep FIFO receives user FIFO field information. The order of
453 * receive is from LSB to MSB bit.
454 */
455
456/* Fields in TEGRA20_SPDIF_USR_DAT_TX_A */
457
458/*
459 * This 4-word deep FIFO transmits user FIFO field information. The order of
460 * transmission is from LSB to MSB bit.
461 */
462
463struct tegra20_spdif {
464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data;
467 void __iomem *regs;
468 struct dentry *debug;
469 u32 reg_ctrl;
470};
471
472#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index e45ccd851f6a..32de7006daf0 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,16 +1,17 @@
1/* 1/*
2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3* 3 *
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5* 5 * Copyright (C) 2012 - NVIDIA, Inc.
6* Authors: Leon Romanovsky <leon@leon.nu> 6 *
7* Andrey Danin <danindrey@mail.ru> 7 * Authors: Leon Romanovsky <leon@leon.nu>
8* Marc Dietrich <marvin24@gmx.de> 8 * Andrey Danin <danindrey@mail.ru>
9* 9 * Marc Dietrich <marvin24@gmx.de>
10* This program is free software; you can redistribute it and/or modify 10 *
11* it under the terms of the GNU General Public License version 2 as 11 * This program is free software; you can redistribute it and/or modify
12* published by the Free Software Foundation. 12 * it under the terms of the GNU General Public License version 2 as
13*/ 13 * published by the Free Software Foundation.
14 */
14 15
15#include <asm/mach-types.h> 16#include <asm/mach-types.h>
16 17
@@ -28,9 +29,6 @@
28 29
29#include "../codecs/alc5632.h" 30#include "../codecs/alc5632.h"
30 31
31#include "tegra_das.h"
32#include "tegra_i2s.h"
33#include "tegra_pcm.h"
34#include "tegra_asoc_utils.h" 32#include "tegra_asoc_utils.h"
35 33
36#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
@@ -39,7 +37,6 @@
39 37
40struct tegra_alc5632 { 38struct tegra_alc5632 {
41 struct tegra_asoc_utils_data util_data; 39 struct tegra_asoc_utils_data util_data;
42 struct platform_device *pcm_dev;
43 int gpio_requested; 40 int gpio_requested;
44 int gpio_hp_det; 41 int gpio_hp_det;
45}; 42};
@@ -140,7 +137,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
140static struct snd_soc_dai_link tegra_alc5632_dai = { 137static struct snd_soc_dai_link tegra_alc5632_dai = {
141 .name = "ALC5632", 138 .name = "ALC5632",
142 .stream_name = "ALC5632 PCM", 139 .stream_name = "ALC5632 PCM",
143 .platform_name = "tegra-pcm-audio",
144 .codec_dai_name = "alc5632-hifi", 140 .codec_dai_name = "alc5632-hifi",
145 .init = tegra_alc5632_asoc_init, 141 .init = tegra_alc5632_asoc_init,
146 .ops = &tegra_alc5632_asoc_ops, 142 .ops = &tegra_alc5632_asoc_ops,
@@ -179,8 +175,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
179 platform_set_drvdata(pdev, card); 175 platform_set_drvdata(pdev, card);
180 snd_soc_card_set_drvdata(card, alc5632); 176 snd_soc_card_set_drvdata(card, alc5632);
181 177
182 alc5632->pcm_dev = ERR_PTR(-EINVAL);
183
184 if (!(pdev->dev.of_node)) { 178 if (!(pdev->dev.of_node)) {
185 dev_err(&pdev->dev, "Must be instantiated using device tree\n"); 179 dev_err(&pdev->dev, "Must be instantiated using device tree\n");
186 ret = -EINVAL; 180 ret = -EINVAL;
@@ -214,18 +208,11 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
214 goto err; 208 goto err;
215 } 209 }
216 210
217 alc5632->pcm_dev = platform_device_register_simple( 211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node;
218 "tegra-pcm-audio", -1, NULL, 0);
219 if (IS_ERR(alc5632->pcm_dev)) {
220 dev_err(&pdev->dev,
221 "Can't instantiate tegra-pcm-audio\n");
222 ret = PTR_ERR(alc5632->pcm_dev);
223 goto err;
224 }
225 212
226 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
227 if (ret) 214 if (ret)
228 goto err_unregister; 215 goto err;
229 216
230 ret = snd_soc_register_card(card); 217 ret = snd_soc_register_card(card);
231 if (ret) { 218 if (ret) {
@@ -238,9 +225,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
238 225
239err_fini_utils: 226err_fini_utils:
240 tegra_asoc_utils_fini(&alc5632->util_data); 227 tegra_asoc_utils_fini(&alc5632->util_data);
241err_unregister:
242 if (!IS_ERR(alc5632->pcm_dev))
243 platform_device_unregister(alc5632->pcm_dev);
244err: 228err:
245 return ret; 229 return ret;
246} 230}
@@ -259,8 +243,6 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
259 snd_soc_unregister_card(card); 243 snd_soc_unregister_card(card);
260 244
261 tegra_asoc_utils_fini(&machine->util_data); 245 tegra_asoc_utils_fini(&machine->util_data);
262 if (!IS_ERR(machine->pcm_dev))
263 platform_device_unregister(machine->pcm_dev);
264 246
265 return 0; 247 return 0;
266} 248}
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index f8428e410e05..266189d4ff13 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.c - Harmony machine ASoC driver 2 * tegra_asoc_utils.c - Harmony machine ASoC driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
28 29
29#include "tegra_asoc_utils.h" 30#include "tegra_asoc_utils.h"
30 31
@@ -40,7 +41,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
40 case 22050: 41 case 22050:
41 case 44100: 42 case 44100:
42 case 88200: 43 case 88200:
43 new_baseclock = 56448000; 44 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
45 new_baseclock = 56448000;
46 else
47 new_baseclock = 564480000;
44 break; 48 break;
45 case 8000: 49 case 8000:
46 case 16000: 50 case 16000:
@@ -48,7 +52,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
48 case 48000: 52 case 48000:
49 case 64000: 53 case 64000:
50 case 96000: 54 case 96000:
51 new_baseclock = 73728000; 55 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
56 new_baseclock = 73728000;
57 else
58 new_baseclock = 552960000;
52 break; 59 break;
53 default: 60 default:
54 return -EINVAL; 61 return -EINVAL;
@@ -78,7 +85,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
78 return err; 85 return err;
79 } 86 }
80 87
81 /* Don't set cdev1 rate; its locked to pll_a_out0 */ 88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
82 89
83 err = clk_enable(data->clk_pll_a); 90 err = clk_enable(data->clk_pll_a);
84 if (err) { 91 if (err) {
@@ -112,6 +119,15 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
112 119
113 data->dev = dev; 120 data->dev = dev;
114 121
122 if (!of_have_populated_dt())
123 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
124 else if (of_machine_is_compatible("nvidia,tegra20"))
125 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
126 else if (of_machine_is_compatible("nvidia,tegra30"))
127 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
128 else
129 return -EINVAL;
130
115 data->clk_pll_a = clk_get_sys(NULL, "pll_a"); 131 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
116 if (IS_ERR(data->clk_pll_a)) { 132 if (IS_ERR(data->clk_pll_a)) {
117 dev_err(data->dev, "Can't retrieve clk pll_a\n"); 133 dev_err(data->dev, "Can't retrieve clk pll_a\n");
@@ -126,15 +142,24 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
126 goto err_put_pll_a; 142 goto err_put_pll_a;
127 } 143 }
128 144
129 data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); 145 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
146 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
147 else
148 data->clk_cdev1 = clk_get_sys("extern1", NULL);
130 if (IS_ERR(data->clk_cdev1)) { 149 if (IS_ERR(data->clk_cdev1)) {
131 dev_err(data->dev, "Can't retrieve clk cdev1\n"); 150 dev_err(data->dev, "Can't retrieve clk cdev1\n");
132 ret = PTR_ERR(data->clk_cdev1); 151 ret = PTR_ERR(data->clk_cdev1);
133 goto err_put_pll_a_out0; 152 goto err_put_pll_a_out0;
134 } 153 }
135 154
155 ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100);
156 if (ret)
157 goto err_put_cdev1;
158
136 return 0; 159 return 0;
137 160
161err_put_cdev1:
162 clk_put(data->clk_cdev1);
138err_put_pll_a_out0: 163err_put_pll_a_out0:
139 clk_put(data->clk_pll_a_out0); 164 clk_put(data->clk_pll_a_out0);
140err_put_pll_a: 165err_put_pll_a:
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 4818195da25c..44db1dbb8f21 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver 2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -26,8 +26,14 @@
26struct clk; 26struct clk;
27struct device; 27struct device;
28 28
29enum tegra_asoc_utils_soc {
30 TEGRA_ASOC_UTILS_SOC_TEGRA20,
31 TEGRA_ASOC_UTILS_SOC_TEGRA30,
32};
33
29struct tegra_asoc_utils_data { 34struct tegra_asoc_utils_data {
30 struct device *dev; 35 struct device *dev;
36 enum tegra_asoc_utils_soc soc;
31 struct clk *clk_pll_a; 37 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0; 38 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1; 39 struct clk *clk_cdev1;
@@ -42,4 +48,3 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 48void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
43 49
44#endif 50#endif
45
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
deleted file mode 100644
index 3b3c1ba4d235..000000000000
--- a/sound/soc/tegra/tegra_das.c
+++ /dev/null
@@ -1,261 +0,0 @@
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 = devm_kzalloc(&pdev->dev, 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 err;
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;
188 }
189
190 region = devm_request_mem_region(&pdev->dev, res->start,
191 resource_size(res), pdev->name);
192 if (!region) {
193 dev_err(&pdev->dev, "Memory region already claimed\n");
194 ret = -EBUSY;
195 goto err;
196 }
197
198 das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
199 if (!das->regs) {
200 dev_err(&pdev->dev, "ioremap failed\n");
201 ret = -ENOMEM;
202 goto err;
203 }
204
205 ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
206 TEGRA_DAS_DAP_SEL_DAC1);
207 if (ret) {
208 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
209 goto err;
210 }
211 ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
212 TEGRA_DAS_DAC_SEL_DAP1);
213 if (ret) {
214 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
215 goto err;
216 }
217
218 tegra_das_debug_add(das);
219
220 platform_set_drvdata(pdev, das);
221
222 return 0;
223
224err:
225 das = NULL;
226 return ret;
227}
228
229static int __devexit tegra_das_remove(struct platform_device *pdev)
230{
231 if (!das)
232 return -ENODEV;
233
234 tegra_das_debug_remove(das);
235
236 das = NULL;
237
238 return 0;
239}
240
241static const struct of_device_id tegra_das_of_match[] __devinitconst = {
242 { .compatible = "nvidia,tegra20-das", },
243 {},
244};
245
246static struct platform_driver tegra_das_driver = {
247 .probe = tegra_das_probe,
248 .remove = __devexit_p(tegra_das_remove),
249 .driver = {
250 .name = DRV_NAME,
251 .owner = THIS_MODULE,
252 .of_match_table = tegra_das_of_match,
253 },
254};
255module_platform_driver(tegra_das_driver);
256
257MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
258MODULE_DESCRIPTION("Tegra DAS driver");
259MODULE_LICENSE("GPL");
260MODULE_ALIAS("platform:" DRV_NAME);
261MODULE_DEVICE_TABLE(of, tegra_das_of_match);
diff --git a/sound/soc/tegra/tegra_das.h b/sound/soc/tegra/tegra_das.h
deleted file mode 100644
index 2c96c7b3c459..000000000000
--- a/sound/soc/tegra/tegra_das.h
+++ /dev/null
@@ -1,135 +0,0 @@
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.h b/sound/soc/tegra/tegra_i2s.h
deleted file mode 100644
index 15ce1e2e8bde..000000000000
--- a/sound/soc/tegra/tegra_i2s.h
+++ /dev/null
@@ -1,166 +0,0 @@
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 snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
158 int clk_refs;
159 struct tegra_pcm_dma_params capture_dma_data;
160 struct tegra_pcm_dma_params playback_dma_data;
161 void __iomem *regs;
162 struct dentry *debug;
163 u32 reg_ctrl;
164};
165
166#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 8b4457137c7c..127348dc09b1 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -2,7 +2,7 @@
2 * tegra_pcm.c - Tegra PCM driver 2 * tegra_pcm.c - Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,8 +29,8 @@
29 * 29 *
30 */ 30 */
31 31
32#include <linux/module.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/module.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
@@ -39,8 +39,6 @@
39 39
40#include "tegra_pcm.h" 40#include "tegra_pcm.h"
41 41
42#define DRV_NAME "tegra-pcm-audio"
43
44static const struct snd_pcm_hardware tegra_pcm_hardware = { 42static const struct snd_pcm_hardware tegra_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP | 43 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
@@ -372,28 +370,18 @@ static struct snd_soc_platform_driver tegra_pcm_platform = {
372 .pcm_free = tegra_pcm_free, 370 .pcm_free = tegra_pcm_free,
373}; 371};
374 372
375static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev) 373int __devinit tegra_pcm_platform_register(struct device *dev)
376{ 374{
377 return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform); 375 return snd_soc_register_platform(dev, &tegra_pcm_platform);
378} 376}
377EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
379 378
380static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev) 379void __devexit tegra_pcm_platform_unregister(struct device *dev)
381{ 380{
382 snd_soc_unregister_platform(&pdev->dev); 381 snd_soc_unregister_platform(dev);
383 return 0;
384} 382}
385 383EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister);
386static struct platform_driver tegra_pcm_driver = {
387 .driver = {
388 .name = DRV_NAME,
389 .owner = THIS_MODULE,
390 },
391 .probe = tegra_pcm_platform_probe,
392 .remove = __devexit_p(tegra_pcm_platform_remove),
393};
394module_platform_driver(tegra_pcm_driver);
395 384
396MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 385MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
397MODULE_DESCRIPTION("Tegra PCM ASoC driver"); 386MODULE_DESCRIPTION("Tegra PCM ASoC driver");
398MODULE_LICENSE("GPL"); 387MODULE_LICENSE("GPL");
399MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index dbb90339fe0d..985d418a35e7 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -2,7 +2,7 @@
2 * tegra_pcm.h - Definitions for Tegra PCM driver 2 * tegra_pcm.h - Definitions for Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -52,4 +52,7 @@ struct tegra_runtime_data {
52 struct tegra_dma_channel *dma_chan; 52 struct tegra_dma_channel *dma_chan;
53}; 53};
54 54
55int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev);
57
55#endif 58#endif
diff --git a/sound/soc/tegra/tegra_spdif.h b/sound/soc/tegra/tegra_spdif.h
deleted file mode 100644
index 2e03db430279..000000000000
--- a/sound/soc/tegra/tegra_spdif.h
+++ /dev/null
@@ -1,473 +0,0 @@
1/*
2 * tegra_spdif.h - Definitions for Tegra SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2008-2009, NVIDIA Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#ifndef __TEGRA_SPDIF_H__
27#define __TEGRA_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA_SPDIF_BASE */
32
33#define TEGRA_SPDIF_CTRL 0x0
34#define TEGRA_SPDIF_STATUS 0x4
35#define TEGRA_SPDIF_STROBE_CTRL 0x8
36#define TEGRA_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA_SPDIF_DATA_OUT 0x40
38#define TEGRA_SPDIF_DATA_IN 0x80
39#define TEGRA_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA_SPDIF_CTRL_LBK_EN (1 << 15)
103
104/*
105 * Pack data mode:
106 * 0 = Single data (16 bit needs to be padded to match the
107 * interface data bit size).
108 * 1 = Packeted left/right channel data into a single word.
109 */
110#define TEGRA_SPDIF_CTRL_PACK (1 << 14)
111
112/*
113 * 00 = 16bit data
114 * 01 = 20bit data
115 * 10 = 24bit data
116 * 11 = raw data
117 */
118#define TEGRA_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA_SPDIF_BIT_MODE_16BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA_SPDIF_BIT_MODE_20BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA_SPDIF_BIT_MODE_24BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA_SPDIF_CTRL_BIT_MODE_RAW (TEGRA_SPDIF_BIT_MODE_RAW << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA_SPDIF_STATUS */
131
132/*
133 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
134 * write a 1 to the corresponding bit location to clear the status.
135 */
136
137/*
138 * Receiver(RX) shifter is busy receiving data.
139 * This bit is asserted when the receiver first locked onto the
140 * preamble of the data stream after RX_EN is asserted. This bit is
141 * deasserted when either,
142 * (a) the end of a frame is reached after RX_EN is deeasserted, or
143 * (b) the SPDIF data stream becomes inactive.
144 */
145#define TEGRA_SPDIF_STATUS_RX_BSY (1 << 29)
146
147/*
148 * Transmitter(TX) shifter is busy transmitting data.
149 * This bit is asserted when TX_EN is asserted.
150 * This bit is deasserted when the end of a frame is reached after
151 * TX_EN is deasserted.
152 */
153#define TEGRA_SPDIF_STATUS_TX_BSY (1 << 28)
154
155/*
156 * TX is busy shifting out channel status.
157 * This bit is asserted when both TX_EN and TC_EN are asserted and
158 * data from CH_STA_TX_A register is loaded into the internal shifter.
159 * This bit is deasserted when either,
160 * (a) the end of a frame is reached after TX_EN is deasserted, or
161 * (b) CH_STA_TX_F register is loaded into the internal shifter.
162 */
163#define TEGRA_SPDIF_STATUS_TC_BSY (1 << 27)
164
165/*
166 * TX User data FIFO busy.
167 * This bit is asserted when TX_EN and TXU_EN are asserted and
168 * there's data in the TX user FIFO. This bit is deassert when either,
169 * (a) the end of a frame is reached after TX_EN is deasserted, or
170 * (b) there's no data left in the TX user FIFO.
171 */
172#define TEGRA_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA_SPDIF_STATUS_IS_B (1 << 22)
185
186/*
187 * RX channel block data receive status:
188 * 0=entire block not recieved yet.
189 * 1=received entire block of channel status,
190 */
191#define TEGRA_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA_SPDIF_STATUS_IS_U (1 << 20)
195
196/*
197 * RX User FIFO Status:
198 * 1=attention level reached, 0=attention level not reached.
199 */
200#define TEGRA_SPDIF_STATUS_QS_RU (1 << 19)
201
202/*
203 * TX User FIFO Status:
204 * 1=attention level reached, 0=attention level not reached.
205 */
206#define TEGRA_SPDIF_STATUS_QS_TU (1 << 18)
207
208/*
209 * RX Data FIFO Status:
210 * 1=attention level reached, 0=attention level not reached.
211 */
212#define TEGRA_SPDIF_STATUS_QS_RX (1 << 17)
213
214/*
215 * TX Data FIFO Status:
216 * 1=attention level reached, 0=attention level not reached.
217 */
218#define TEGRA_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA_SPDIF_STROBE_CTRL_STROBE (1 << 15)
231
232/*
233 * Manual data strobe time within the bi-phase clock period (in terms of
234 * the number of over-sampling clocks).
235 */
236#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
238
239/*
240 * Manual SPDIFIN bi-phase clock period (in terms of the number of
241 * over-sampling clocks).
242 */
243#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
245
246/* Fields in SPDIF_DATA_FIFO_CSR */
247
248/* Clear Receiver User FIFO (RX USR.FIFO) */
249#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
292
293/* Clear Receiver Data FIFO (RX DATA.FIFO) */
294#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA_SPDIF_DATA_OUT */
339
340/*
341 * This register has 5 different formats:
342 * 16-bit (BIT_MODE=00, PACK=0)
343 * 20-bit (BIT_MODE=01, PACK=0)
344 * 24-bit (BIT_MODE=10, PACK=0)
345 * raw (BIT_MODE=11, PACK=0)
346 * 16-bit packed (BIT_MODE=00, PACK=1)
347 */
348
349#define TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA_SPDIF_DATA_IN */
379
380/*
381 * This register has 5 different formats:
382 * 16-bit (BIT_MODE=00, PACK=0)
383 * 20-bit (BIT_MODE=01, PACK=0)
384 * 24-bit (BIT_MODE=10, PACK=0)
385 * raw (BIT_MODE=11, PACK=0)
386 * 16-bit packed (BIT_MODE=00, PACK=1)
387 *
388 * Bits 31:24 are common to all modes except 16-bit packed
389 */
390
391#define TEGRA_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA_SPDIF_CH_STA_RX_F */
429
430/*
431 * The 6-word receive channel data page buffer holds a block (192 frames) of
432 * channel status information. The order of receive is from LSB to MSB
433 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
434 */
435
436/* Fields in TEGRA_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA_SPDIF_CH_STA_TX_F */
442
443/*
444 * The 6-word transmit channel data page buffer holds a block (192 frames) of
445 * channel status information. The order of transmission is from LSB to MSB
446 * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
447 */
448
449/* Fields in TEGRA_SPDIF_USR_STA_RX_A */
450
451/*
452 * This 4-word deep FIFO receives user FIFO field information. The order of
453 * receive is from LSB to MSB bit.
454 */
455
456/* Fields in TEGRA_SPDIF_USR_DAT_TX_A */
457
458/*
459 * This 4-word deep FIFO transmits user FIFO field information. The order of
460 * transmission is from LSB to MSB bit.
461 */
462
463struct tegra_spdif {
464 struct clk *clk_spdif_out;
465 int clk_refs;
466 struct tegra_pcm_dma_params capture_dma_data;
467 struct tegra_pcm_dma_params playback_dma_data;
468 void __iomem *regs;
469 struct dentry *debug;
470 u32 reg_ctrl;
471};
472
473#endif
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 566655e23b7d..0b0df49d9d33 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -2,7 +2,7 @@
2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec. 2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc. 5 * Copyright (C) 2010-2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -46,9 +46,6 @@
46 46
47#include "../codecs/wm8903.h" 47#include "../codecs/wm8903.h"
48 48
49#include "tegra_das.h"
50#include "tegra_i2s.h"
51#include "tegra_pcm.h"
52#include "tegra_asoc_utils.h" 49#include "tegra_asoc_utils.h"
53 50
54#define DRV_NAME "tegra-snd-wm8903" 51#define DRV_NAME "tegra-snd-wm8903"
@@ -61,7 +58,6 @@
61 58
62struct tegra_wm8903 { 59struct tegra_wm8903 {
63 struct tegra_wm8903_platform_data pdata; 60 struct tegra_wm8903_platform_data pdata;
64 struct platform_device *pcm_dev;
65 struct tegra_asoc_utils_data util_data; 61 struct tegra_asoc_utils_data util_data;
66 int gpio_requested; 62 int gpio_requested;
67}; 63};
@@ -354,8 +350,8 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
354 .name = "WM8903", 350 .name = "WM8903",
355 .stream_name = "WM8903 PCM", 351 .stream_name = "WM8903 PCM",
356 .codec_name = "wm8903.0-001a", 352 .codec_name = "wm8903.0-001a",
357 .platform_name = "tegra-pcm-audio", 353 .platform_name = "tegra20-i2s.0",
358 .cpu_dai_name = "tegra-i2s.0", 354 .cpu_dai_name = "tegra20-i2s.0",
359 .codec_dai_name = "wm8903-hifi", 355 .codec_dai_name = "wm8903-hifi",
360 .init = tegra_wm8903_init, 356 .init = tegra_wm8903_init,
361 .ops = &tegra_wm8903_ops, 357 .ops = &tegra_wm8903_ops,
@@ -392,7 +388,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
392 ret = -ENOMEM; 388 ret = -ENOMEM;
393 goto err; 389 goto err;
394 } 390 }
395 machine->pcm_dev = ERR_PTR(-EINVAL);
396 391
397 card->dev = &pdev->dev; 392 card->dev = &pdev->dev;
398 platform_set_drvdata(pdev, card); 393 platform_set_drvdata(pdev, card);
@@ -428,14 +423,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
428 goto err; 423 goto err;
429 } 424 }
430 425
431 machine->pcm_dev = platform_device_register_simple( 426 tegra_wm8903_dai.platform_name = NULL;
432 "tegra-pcm-audio", -1, NULL, 0); 427 tegra_wm8903_dai.platform_of_node =
433 if (IS_ERR(machine->pcm_dev)) { 428 tegra_wm8903_dai.cpu_dai_of_node;
434 dev_err(&pdev->dev,
435 "Can't instantiate tegra-pcm-audio\n");
436 ret = PTR_ERR(machine->pcm_dev);
437 goto err;
438 }
439 } else { 429 } else {
440 if (machine_is_harmony()) { 430 if (machine_is_harmony()) {
441 card->dapm_routes = harmony_audio_map; 431 card->dapm_routes = harmony_audio_map;
@@ -454,7 +444,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
454 444
455 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 445 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
456 if (ret) 446 if (ret)
457 goto err_unregister; 447 goto err;
458 448
459 ret = snd_soc_register_card(card); 449 ret = snd_soc_register_card(card);
460 if (ret) { 450 if (ret) {
@@ -467,9 +457,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
467 457
468err_fini_utils: 458err_fini_utils:
469 tegra_asoc_utils_fini(&machine->util_data); 459 tegra_asoc_utils_fini(&machine->util_data);
470err_unregister:
471 if (!IS_ERR(machine->pcm_dev))
472 platform_device_unregister(machine->pcm_dev);
473err: 460err:
474 return ret; 461 return ret;
475} 462}
@@ -497,8 +484,6 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
497 snd_soc_unregister_card(card); 484 snd_soc_unregister_card(card);
498 485
499 tegra_asoc_utils_fini(&machine->util_data); 486 tegra_asoc_utils_fini(&machine->util_data);
500 if (!IS_ERR(machine->pcm_dev))
501 platform_device_unregister(machine->pcm_dev);
502 487
503 return 0; 488 return 0;
504} 489}
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 2bdfc550cff8..0fd115e69a8a 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -38,9 +38,6 @@
38 38
39#include "../codecs/tlv320aic23.h" 39#include "../codecs/tlv320aic23.h"
40 40
41#include "tegra_das.h"
42#include "tegra_i2s.h"
43#include "tegra_pcm.h"
44#include "tegra_asoc_utils.h" 41#include "tegra_asoc_utils.h"
45 42
46#define DRV_NAME "tegra-snd-trimslice" 43#define DRV_NAME "tegra-snd-trimslice"
@@ -119,8 +116,8 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
119 .name = "TLV320AIC23", 116 .name = "TLV320AIC23",
120 .stream_name = "AIC23", 117 .stream_name = "AIC23",
121 .codec_name = "tlv320aic23-codec.2-001a", 118 .codec_name = "tlv320aic23-codec.2-001a",
122 .platform_name = "tegra-pcm-audio", 119 .platform_name = "tegra20-i2s.0",
123 .cpu_dai_name = "tegra-i2s.0", 120 .cpu_dai_name = "tegra20-i2s.0",
124 .codec_dai_name = "tlv320aic23-hifi", 121 .codec_dai_name = "tlv320aic23-hifi",
125 .ops = &trimslice_asoc_ops, 122 .ops = &trimslice_asoc_ops,
126}; 123};